Browse code

Add mulle-bootstrap show command.

Nat! authored on 15-02-2017 17:35:44
Showing 13 changed files
... ...
@@ -2,6 +2,12 @@
2 2
 
3 3
 > <font color="green">**Important: Setting values are delimited by LF.**</font>
4 4
 
5
+1. All files in lowercase are regular settings
6
+2. All files in uppercase are expansion settings (somewhar like an environment variable).These are not described here.
7
+3 Config settings are local to the system. They are not part of a
8
+distribution.
9
+
10
+
5 11
 Root Settings
6 12
 ===================
7 13
 
... ...
@@ -102,7 +108,7 @@ Setting Name                      |  Description
102 108
 `check_usr_local_include`         | do not fetch, if a system header of same      |
103 109
                                   | is present in `/usr/local/include`            | NO
104 110
 
105
-Build Config Settings
111
+##### Build Config Settings
106 112
 
107 113
 Setting Name                      |  Description                                  | Default
108 114
 ----------------------------------|-----------------------------------------------|--------------
... ...
@@ -47,14 +47,19 @@ trap_fail()
47 47
 
48 48
 bootstrap_technical_option_usage()
49 49
 {
50
-   if [ "${VERBOSE}" = "YES" -o "${MULLE_TRACE}" = "YES" ]
50
+   if [ ! -z "${MULLE_TRACE}" ]
51 51
    then
52 52
       cat <<EOF
53 53
    -le       : external command execution log output
54 54
    -lm       : extended dependency analysis output
55 55
    -ls       : extended settings log output
56 56
    -t        : enable shell trace
57
+   -tpwd     : emit shortened PWD during trace
58
+   -tr       : also trace resolver
59
+   -ts       : also trace settings
57 60
    -s        : be silent
61
+
62
+   [Check source for more options]
58 63
 EOF
59 64
    fi
60 65
 }
... ...
@@ -115,14 +120,12 @@ EOF
115 120
    bootstrap     : does install and build recursively [default]
116 121
    build         : builds fetched repositories
117 122
    clean         : cleans mulle-bootstrap produced files.
123
+   init          : initializes a bootstrap project
118 124
    install       : fetches required repositories recursively. Use it after
119 125
                    updating the repositories and embedded_repositories files.
120
-   init          : initializes a bootstrap project
121
-   systeminstall : install dependencies as system headers
122
-   git           : run git commands on fetched repositories
123
-   tag           : tag fetched repositories
124 126
    update        : updates repositories (fetch).
125 127
    upgrade       : updates and checks out repositories (pull).
128
+   show          : show repositories and brews
126 129
 
127 130
  Options are command specific. Use mulle-bootstrap <command> -h for help.
128 131
 EOF
... ...
@@ -130,7 +133,18 @@ EOF
130 133
    if [ "${UNAME}" = 'darwin' ]
131 134
    then
132 135
       cat <<EOF
133
-   xcode     : sets up xcodeproj settings
136
+   xcode         : sets up xcodeproj settings
137
+EOF
138
+   fi
139
+
140
+   if [ !  -z "${MULLE_TRACE}" ]
141
+   then
142
+      cat <<EOF
143
+
144
+   systeminstall : install dependencies as system headers
145
+   git           : run git commands on fetched repositories
146
+   status        : show status of repositories and brews
147
+   tag           : tag fetched repositories
134 148
 EOF
135 149
    fi
136 150
 
... ...
@@ -156,7 +170,7 @@ Well, do ya, punk?"
156 170
 }
157 171
 
158 172
 
159
-define_local_keyvalue()
173
+define_expansion()
160 174
 {
161 175
    local keyvalue
162 176
 
... ...
@@ -173,7 +187,7 @@ define_local_keyvalue()
173 187
    local key
174 188
    local value
175 189
 
176
-   key="`echo "${keyvalue}" | cut -d= -f1`"
190
+   key="`echo "${keyvalue}" | cut -d= -f1 | tr '[a-z]' '[A-Z]'`"
177 191
    if [ -z "${key}" ]
178 192
    then
179 193
       key="${keyvalue}"
... ...
@@ -500,6 +514,11 @@ bootstrap_should_defer_to_master()
500 514
       return 1
501 515
    fi
502 516
 
517
+   if [ "${MULLE_BOOTSTRAP_DONT_DEFER}" = "YES" ]
518
+   then
519
+      return 1
520
+   fi
521
+
503 522
    local masterpath
504 523
 
505 524
    . mulle-bootstrap-project.sh
... ...
@@ -567,7 +586,7 @@ bootstrap_main()
567 586
 
568 587
          -D*)  # just like C
569 588
             # define key values (by putting them into .bootstrap.local)
570
-            define_local_keyvalue "`echo "$1" | sed s'/^-D[ ]*//'`"
589
+            define_expansion "`echo "$1" | sed s'/^-D[ ]*//'`"
571 590
          ;;
572 591
 
573 592
          -V|--verbose-build)
... ...
@@ -633,6 +652,8 @@ bootstrap_main()
633 652
    MULLE_EXECUTABLE_FAIL_PREFIX="${MULLE_BOOTSTRAP_EXECUTABLE} ${command}"
634 653
    [ $# -eq 0 ] || shift
635 654
 
655
+   MULLE_EXECUTABLE_OPTIONS="$@"
656
+
636 657
    case "${command}" in
637 658
       bootstrap)
638 659
          _bootstrap_main "$@"
... ...
@@ -674,6 +695,13 @@ bootstrap_main()
674 695
          emancipate_main "$@" || exit 1
675 696
       ;;
676 697
 
698
+      expansion)
699
+         . mulle-bootstrap-settings.sh
700
+
701
+         expansion_main "$@" || exit 1
702
+      ;;
703
+
704
+
677 705
       flags)
678 706
          . mulle-bootstrap-flags.sh
679 707
 
... ...
@@ -686,6 +714,10 @@ bootstrap_main()
686 714
          git_main "$@" || exit 1
687 715
       ;;
688 716
 
717
+      help)
718
+         mulle_bootstrap_usage "$@" || exit 1
719
+      ;;
720
+
689 721
       init)
690 722
          . mulle-bootstrap-init.sh
691 723
 
... ...
@@ -715,6 +747,12 @@ bootstrap_main()
715 747
          install_main "$@" || exit 1
716 748
       ;;
717 749
 
750
+      show)
751
+         . mulle-bootstrap-show.sh
752
+
753
+         show_main "$@" || exit 1
754
+      ;;
755
+
718 756
       status)
719 757
          . mulle-bootstrap-status.sh
720 758
 
... ...
@@ -836,6 +874,7 @@ brew_main()
836 874
    fi
837 875
 
838 876
    MULLE_EXECUTABLE_FAIL_PREFIX="${MULLE_BOOTSTRAP_EXECUTABLE} ${command}"
877
+   MULLE_EXECUTABLE_OPTIONS="$@"
839 878
 
840 879
    case "${command}" in
841 880
       build)
... ...
@@ -880,6 +919,10 @@ brew_main()
880 919
          flags_main "$@" || exit 1
881 920
       ;;
882 921
 
922
+      help)
923
+         mulle_brew_usage "$@" || exit 1
924
+      ;;
925
+
883 926
       init)
884 927
          . mulle-bootstrap-init.sh
885 928
 
... ...
@@ -903,6 +946,12 @@ brew_main()
903 946
          setting_main "$@" || exit 1
904 947
       ;;
905 948
 
949
+      show)
950
+         . mulle-bootstrap-show.sh
951
+
952
+         show_main "$@" || exit 1
953
+      ;;
954
+
906 955
       uname)
907 956
          echo "${UNAME}"
908 957
          exit 0
... ...
@@ -101,7 +101,7 @@ _bootstrap_auto_copy()
101 101
             if [ -z "${match}" ] ## has lowercase (not environment)
102 102
             then
103 103
                log_fluff "Copy expanded value of \"${filepath}\""
104
-               value="`_read_expanded_setting "${filepath}" "${name}" "" "${tmpdir}"`"
104
+               value="`read_expanded_setting "${filepath}" "" "${tmpdir}"`"
105 105
                redirect_exekutor "${dstfilepath}" echo "${value}"
106 106
             else
107 107
                exekutor cp -a ${COPYMOVETARFLAGS} "${filepath}" "${dstfilepath}"
... ...
@@ -168,46 +168,44 @@ _bootstrap_merge_expanded_settings_in_front()
168 168
 
169 169
    local settings1
170 170
    local settings2
171
-   local name
172 171
 
173
-   name="`basename -- "$1"`"
174 172
    srcbootstrap="`dirname -- "${1}"`"
175 173
 
176
-   settings1="`_read_expanded_setting "$1" "${name}" "" "${srcbootstrap}"`"
174
+   settings1="`read_expanded_setting "$1" "" "${srcbootstrap}"`"
177 175
    if [ ! -z "$2" ]
178 176
    then
179
-      settings2="`_read_setting "$2" "${name}"`"
177
+      settings2="`read_setting "$2"`"
180 178
    fi
181 179
 
182 180
    _merge_settings_in_front "${settings1}" "${settings2}"
183 181
 }
184 182
 
185 183
 
186
-_make_master_clones()
187
-{
188
-   local clones="$1"
184
+# _make_master_clones()
185
+# {
186
+#    local clones="$1"
189 187
 
190
-   local clone
191
-   local name       # name of the clone
192
-   local url        # url of clone
193
-   local branch
194
-   local scm
195
-   local tag
196
-   local stashdir   # dir of repository (usually inside stashes)
188
+#    local clone
189
+#    local name       # name of the clone
190
+#    local url        # url of clone
191
+#    local branch
192
+#    local scm
193
+#    local tag
194
+#    local stashdir   # dir of repository (usually inside stashes)
197 195
 
198
-   IFS="
199
-"
200
-   for clone in ${clones}
201
-   do
202
-      IFS="${DEFAULT_IFS}"
196
+#    IFS="
197
+# "
198
+#    for clone in ${clones}
199
+#    do
200
+#       IFS="${DEFAULT_IFS}"
203 201
 
204
-      parse_clone "${clone}"
202
+#       parse_clone "${clone}"
205 203
 
206
-      echo "${url};${name};${branch};${scm};${tag}" | sed 's/;*$//'
207
-   done
204
+#       echo "${url};${name};${branch};${scm};${tag}" | sed 's/;*$//'
205
+#    done
208 206
 
209
-   IFS="${DEFAULT_IFS}"
210
-}
207
+#    IFS="${DEFAULT_IFS}"
208
+# }
211 209
 
212 210
 
213 211
 _remove_dstdir_from_clones()
... ...
@@ -215,12 +213,11 @@ _remove_dstdir_from_clones()
215 213
    local clones="$1"
216 214
 
217 215
    local clone
218
-   local name       # name of the clone
219 216
    local url        # url of clone
217
+   local dstdir       # name of the clone
220 218
    local branch
221 219
    local scm
222 220
    local tag
223
-   local stashdir   # dir of repository (usually inside stashes)
224 221
 
225 222
    IFS="
226 223
 "
... ...
@@ -228,7 +225,7 @@ _remove_dstdir_from_clones()
228 225
    do
229 226
       IFS="${DEFAULT_IFS}"
230 227
 
231
-      parse_clone "${clone}"
228
+      parse_raw_clone "${clone}"
232 229
 
233 230
       echo "${url};;${branch};${scm};${tag}" | sed 's/;*$//'
234 231
    done
... ...
@@ -279,26 +276,21 @@ _bootstrap_auto_merge_root_settings()
279 276
       #
280 277
       if [ "${settingname}" = "repositories" ]
281 278
       then
282
-         local newcontents
279
+         local additions
283 280
 
284
-         newcontents="`_bootstrap_merge_expanded_settings_in_front "${srcfile}" ""`"
285
-         if is_master_bootstrap_project
286
-         then
287
-            newcontents="`_make_master_clones "${newcontents}"`"
288
-         else
289
-            newcontents="`_remove_dstdir_from_clones "${newcontents}"`"
290
-         fi
281
+         additions="`_bootstrap_merge_expanded_settings_in_front "${srcfile}" ""`"
282
+         additions="`_remove_dstdir_from_clones "${additions}"`"
291 283
 
292 284
          if [ -f "${dstfile}" ]
293 285
          then
294
-            local contents2
286
+            local contents
295 287
 
296 288
             contents="`cat "${dstfile}"`"
297
-            newcontents="`merge_repository_contents "${contents}" "${newcontents}"`"
289
+            additions="`merge_repository_contents "${contents}" "${additions}"`"
290
+         else
291
+            log_fluff "Copying expanded \"repositories\" from \"${srcfile}\""
298 292
          fi
299
-         log_fluff "Copying expanded \"repositories\" from \"${srcfile}\""
300
-
301
-         redirect_exekutor "${dstfile}" echo "${newcontents}"
293
+         redirect_exekutor "${dstfile}" echo "${additions}"
302 294
          continue
303 295
       fi
304 296
 
... ...
@@ -359,7 +351,7 @@ _bootstrap_auto_embedded_copy()
359 351
 
360 352
    dst="${BOOTSTRAP_DIR}.auto/.deep/${name}.d"
361 353
 
362
-   [ -d "${dst}" ] && internal_fail "${dst} already exists"
354
+   rmdir_safer "${dst}"
363 355
    mkdir_if_missing "${dst}"
364 356
 
365 357
    # copy over our stuff
... ...
@@ -506,7 +498,7 @@ bootstrap_create_build_folders()
506 498
 
507 499
 bootstrap_auto_final()
508 500
 {
509
-   [ -d "${BOOTSTRAP_DIR}.auto" ] || internal_fail "${BOOTSTRAP_DIR}.auto does not exists"
501
+   exekutor [ -d "${BOOTSTRAP_DIR}.auto" ] || internal_fail "${BOOTSTRAP_DIR}.auto does not exist"
510 502
 
511 503
    log_fluff "Creating ${C_MAGENTA}${C_BOLD}build_order${C_VERBOSE} from repositories"
512 504
 
... ...
@@ -89,38 +89,101 @@ fetch_brew_if_needed()
89 89
 }
90 90
 
91 91
 
92
+walk_brews()
93
+{
94
+   local brews="$1"; shift
95
+   local callback="$1"; shift
96
+
97
+   local formula
98
+
99
+   IFS="
100
+"
101
+   for formula in ${brews}
102
+   do
103
+      IFS="${DEFAULT_IFS}"
104
+      if ! ${callback} "${formula}" "$@"
105
+      then
106
+         break
107
+      fi
108
+   done
109
+
110
+   IFS="${DEFAULT_IFS}"
111
+
112
+}
113
+
114
+
115
+_brew_action()
116
+{
117
+   local formula="$1" ; shift
118
+   local brewcmd="$1"
119
+
120
+   if [ "${OPTION_CHECK_USR_LOCAL_INCLUDE}" = "YES" ] && has_usr_local_include "${formula}"
121
+   then
122
+      log_info "${C_MAGENTA}${C_BOLD}${formula}${C_INFO} is a system library, so not installing it"
123
+      return
124
+   fi
125
+
126
+   local versions
127
+
128
+   case "${brewcmd}" in
129
+      install)
130
+         versions="`exekutor ${BREW} ls --versions "${formula}" 2> /dev/null`"
131
+
132
+         if [ -z "${versions}" ]
133
+         then
134
+            log_fluff "brew install \"${formula}\""
135
+            exekutor "${BREW}" install "${formula}" || exit 1
136
+
137
+            log_info "Force linking it, in case it was keg-only"
138
+            exekutor "${BREW}" link --force "${formula}" || exit 1
139
+         else
140
+            log_info "\"${formula}\" is already installed."
141
+         fi
142
+      ;;
143
+
144
+      upgrade)
145
+         log_fluff "brew upgrade \"${formula}\""
146
+         exekutor "${BREW}" upgrade "${formula}"
147
+      ;;
148
+   esac
149
+}
150
+
151
+
152
+find_brews()
153
+{
154
+   log_fluff "Looking for brew formulae"
155
+
156
+   brews="`read_root_setting "brews" | sort | sort -u`"
157
+   if [ ! -z "${brews}" ]
158
+   then
159
+      log_info "Setting read from .bootstrap.auto folder. \
160
+You might want to use mulle-bootstrap instead of mulle-brew."
161
+      echo "${brews}"
162
+      return
163
+   fi
164
+
165
+   (
166
+      MULLE_BOOTSTRAP_SETTINGS_NO_AUTO=YES
167
+      read_root_setting "brews" | sort | sort -u
168
+   )
169
+}
170
+
92 171
 #
93 172
 # brews are now installed using a local brew
94 173
 # if we are on linx
95 174
 #
96 175
 _brew_install_brews()
97 176
 {
98
-   local brewcmd
99
-
100
-   brewcmd="$1" ; shift
101
-
177
+   local brewcmd="$1" ; shift
102 178
    local brews="$@"
103 179
 
104 180
    if [ -z "${brews}" ]
105 181
    then
106
-      log_fluff "Looking for brews"
107
-
108
-      brews="`read_root_setting "brews" | sort | sort -u`"
182
+      brews="`find_brews`"
109 183
       if [ -z "${brews}" ]
110 184
       then
111
-         brews="`(
112
-            MULLE_BOOTSTRAP_SETTINGS_NO_AUTO=YES
113
-            read_root_setting "brews" | sort | sort -u
114
-            )`"
115
-
116
-         if [ -z "${brews}" ]
117
-         then
118
-            log_fluff "No brews found"
119
-            return
120
-         fi
121
-      else
122
-         log_info "Setting read from .bootstrap.auto folder. \
123
-   You might want to use mulle-bootstrap instead of mulle-brew."
185
+         log_fluff "No brews found"
186
+         return
124 187
       fi
125 188
    fi
126 189
 
... ...
@@ -134,44 +197,7 @@ _brew_install_brews()
134 197
 
135 198
    local flag
136 199
 
137
-   IFS="
138
-"
139
-   for formula in ${brews}
140
-   do
141
-      IFS="${DEFAULT_IFS}"
142
-
143
-      if [ "${OPTION_CHECK_USR_LOCAL_INCLUDE}" = "YES" ] && has_usr_local_include "${formula}"
144
-      then
145
-         log_info "${C_MAGENTA}${C_BOLD}${formula}${C_INFO} is a system library, so not installing it"
146
-         continue
147
-      fi
148
-
149
-      local versions
150
-
151
-      case "${brewcmd}" in
152
-         install)
153
-            versions="`exekutor ${BREW} ls --versions "${formula}" 2> /dev/null`"
154
-
155
-            if [ -z "${versions}" ]
156
-            then
157
-               log_fluff "brew install \"${formula}\""
158
-               exekutor "${BREW}" install "${formula}" || exit 1
159
-
160
-               log_info "Force linking it, in case it was keg-only"
161
-               exekutor "${BREW}" link --force "${formula}" || exit 1
162
-            else
163
-               log_info "\"${formula}\" is already installed."
164
-            fi
165
-         ;;
166
-
167
-         upgrade)
168
-            log_fluff "brew upgrade \"${formula}\""
169
-            exekutor "${BREW}" upgrade "${formula}"
170
-         ;;
171
-      esac
172
-   done
173
-
174
-   IFS="${DEFAULT_IFS}"
200
+   walk_brews "_brew_action" "${brewcmd}"
175 201
 }
176 202
 
177 203
 
... ...
@@ -34,10 +34,10 @@ MULLE_BOOTSTRAP_CLEAN_SH="included"
34 34
 
35 35
 setup_clean_environment()
36 36
 {
37
-   [ -z "${DEPENDENCIES_DIR}"  ]  && internal_fail "DEPENDENCIES_DIR is empty"
38
-   [ -z "${CLONESBUILD_SUBDIR}" ] && internal_fail "CLONESBUILD_SUBDIR is empty"
39
-   [ -z "${ADDICTIONS_DIR}"   ]   && internal_fail "ADDICTIONS_DIR is empty"
40
-   [ -z "${STASHES_DEFAULT_DIR}"   ]      && internal_fail "STASHES_DEFAULT_DIR is empty"
37
+   [ -z "${DEPENDENCIES_DIR}"  ]   && internal_fail "DEPENDENCIES_DIR is empty"
38
+   [ -z "${CLONESBUILD_SUBDIR}" ]  && internal_fail "CLONESBUILD_SUBDIR is empty"
39
+   [ -z "${ADDICTIONS_DIR}" ]      && internal_fail "ADDICTIONS_DIR is empty"
40
+   [ -z "${STASHES_DEFAULT_DIR}" ] && internal_fail "STASHES_DEFAULT_DIR is empty"
41 41
 
42 42
    CLEAN_EMPTY_PARENTS="`read_config_setting "clean_empty_parent_folders" "YES"`"
43 43
 
... ...
@@ -77,17 +77,17 @@ ${BUILD_CLEANABLE_FILES}
77 77
 ${OUTPUT_CLEANABLE_SUBDIRS}
78 78
 ---
79 79
 
80
-   dist    : remove all clones, dependencies, addictions. It cleans
80
+   install : useful if you know, you don't want to rebuild.
81 81
 ---
82 82
 ${BUILD_CLEANABLE_SUBDIRS}
83
-${OUTPUT_CLEANABLE_SUBDIRS}
84
-${DIST_CLEANABLE_SUBDIRS}
83
+${INSTALL_CLEANABLE_SUBDIRS}
85 84
 ---
86 85
 
87
-   install  : useful if you know, you don't want to rebuild ever. It cleans
86
+   dist    : remove all clones, dependencies, addictions. It cleans
88 87
 ---
89 88
 ${BUILD_CLEANABLE_SUBDIRS}
90
-${INSTALL_CLEANABLE_SUBDIRS}
89
+${OUTPUT_CLEANABLE_SUBDIRS}
90
+${DIST_CLEANABLE_SUBDIRS}
91 91
 ---
92 92
 EOF
93 93
 }
... ...
@@ -212,28 +212,61 @@ clean_directories()
212 212
 }
213 213
 
214 214
 
215
+
216
+_print_stashdir()
217
+{
218
+   # local reposdir="$1"  # ususally .bootstrap.repos
219
+   # local name="$2"      # name of the clone
220
+   # local url="$3"       # URL of the clone
221
+   # local branch="$4"    # branch of the clone
222
+   # local scm="$5"       # scm to use for this clone
223
+   # local tag="$6"       # tag to checkout of the clone
224
+   local stashdir="$7"  # stashdir of this clone (absolute or relative to $PWD)
225
+
226
+   echo "${stashdir}"
227
+}
228
+
229
+
230
+print_stashdir_repositories()
231
+{
232
+   _operation_walk_repositories "_print_stashdir"
233
+}
234
+
235
+
236
+print_stashdir_embedded_repositories()
237
+{
238
+   _operation_walk_embedded_repositories "_print_stashdir"
239
+}
240
+
241
+
215 242
 #
216 243
 # dist cleaning is dangerous
217 244
 #
218 245
 _dist_clean()
219 246
 {
220
-   if is_master_bootstrap_project
221
-   then
222
-      fail "You can't dist clean a master repository"
223
-   fi
224
-
225
-   DIST_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "dist_clean_folders" "${REPOS_DIR}
247
+   DIST_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "dist_clean_folders" \
248
+"${REPOS_DIR}
249
+${DEPENDENCIES_DIR}
226 250
 ${ADDICTIONS_DIR}
227 251
 ${STASHES_DEFAULT_DIR}
228
-.bootstrap.auto"`"
229
-   EMBEDDED="`stashes_of_embedded_repositories "${REPOS_DIR}"`"
252
+${BOOTSTRAP_DIR}.auto"`"
230 253
 
231
-   if [ ! -z "$EMBEDDED" ]
254
+   #
255
+   # as a master we don't throw the minions out
256
+   #
257
+   if ! is_master_bootstrap_project
232 258
    then
233
-      DIST_CLEANABLE_SUBDIRS="${DIST_CLEANABLE_SUBDIRS}
234
-${EMBEDDED}"
259
+      local stashes
260
+
261
+      stashes="`print_stashdir_repositories`"
262
+      DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
263
+
264
+      stashes="`print_stashdir_embedded_repositories`"
265
+      DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
235 266
    fi
267
+
236 268
    clean_directories "${DIST_CLEANABLE_SUBDIRS}" "${flag}"
269
+
237 270
    clean_files "${DIST_CLEANABLE_FILES}"
238 271
 }
239 272
 
... ...
@@ -304,7 +337,7 @@ ${DEPENDENCIES_DIR}/tmp"`"
304 337
 
305 338
    case "${COMMAND}" in
306 339
       dist)
307
-         dist_clean
340
+         _dist_clean
308 341
       ;;
309 342
    esac
310 343
 }
... ...
@@ -108,7 +108,8 @@ common_settings_initialize()
108 108
    STASHES_DEFAULT_DIR="`read_sane_config_path_setting "stashes_dir" "stashes"`"
109 109
 
110 110
    # "repository" caches can and usually are outside the project folder
111
-   CACHES_DIR="`read_config_setting "cashes_dir" "${DEFAULT_CACHES_DIR}"`"
111
+   # this can be multiple paths!
112
+   CACHES_PATH="`read_config_setting "cashes_dir" "${DEFAULT_CACHES_PATH}"`"
112 113
 
113 114
    [ -z "${CLONESBUILD_SUBDIR}" ] && internal_fail "variable CLONESBUILD_SUBDIR is empty"
114 115
    [ -z "${BUILDLOGS_SUBDIR}" ]    && internal_fail "variable BUILDLOGS_SUBDIR is empty"
... ...
@@ -59,12 +59,17 @@ usage:
59 59
    mulle-bootstrap ${COMMAND} [options] [repositories]
60 60
 
61 61
    Options
62
-      -cs   :  check /usr/local for duplicates
63
-      -e    :  fetch embedded repositories only
64
-      -i    :  ignore wrongly checked out branches
65
-      -nr   :  ignore .bootstrap folders of fetched repositories
66
-      -u    :  try to update symlinked folders as well (not recommended)
67
-      -es   :  allow embedded symlinks (very experimental)
62
+      -c           :  use caches from CACHES_PATH to locate repositories
63
+      -cU          :  check /usr/local for duplicates
64
+      -e           :  fetch embedded repositories only
65
+      -es          :  allow embedded symlinks (very experimental)
66
+      -fb <branch> :  force to use branch for all repostories
67
+      -fs          :  follow symlinks when updating/upgrading (not recommended)
68
+      -l           :  allow creation of symlinks
69
+      -le          :  allow creation of embedded symlinks
70
+      -i           :  ignore wrongly checked out branches
71
+      -nc          :  don't use caches. Useful to counter flag -y
72
+      -ns          :  don't create symlinks. Useful to counter flag -y
68 73
 
69 74
    install  :  clone or symlink non-exisiting repositories and other resources
70 75
    update   :  execute a "fetch" in already fetched repositories
... ...
@@ -218,76 +223,73 @@ link_command()
218 223
 }
219 224
 
220 225
 
221
-ask_symlink_it()
226
+can_symlink_it()
222 227
 {
223
-   local  clone
224
-
225
-   clone="$1"
228
+   local  directory="$1"
226 229
 
227
-   if [ ! -d "${clone}" ]
230
+   if [ "${OPTION_ALLOW_CREATING_SYMLINKS}" != "YES" ]
228 231
    then
229
-      fail "You need to check out \"${clone}\" yourself, as it's not there."
232
+      return 1
230 233
    fi
231 234
 
232
-   #
233
-   # check if checked out
234
-   #
235
-   if [ -d "${clone}"/.git ]
235
+   case "${UNAME}" in
236
+      minwgw)
237
+         return 1
238
+      ;;
239
+   esac
240
+
241
+   if git_is_repository "${directory}"
236 242
    then
237 243
        # if bare repo, we can only clone anyway
238
-      if git_is_bare_repository "${clone}"
244
+      if git_is_bare_repository "${directory}"
239 245
       then
240
-         log_info "${clone} is a bare git repository. So cloning"
246
+         log_info "${directory} is a bare git repository. So cloning"
241 247
          log_info "is the only way to go."
242 248
          return 1
243 249
       fi
250
+   else
251
+      log_info "${directory} is not a git repository (yet ?)"
252
+      log_info "So symlinking is the only way to go."
253
+   fi
244 254
 
245
-      flag=1  # means clone it
246
-      if [ "${OPTION_ALLOW_CREATING_SYMLINKS}" = "YES" ]
247
-      then
248
-         local prompt
255
+  return 0
256
+}
249 257
 
250
-         prompt="Should ${clone} be symlinked instead of cloned ?
251
-NO is safe, but you often say YES here."
252 258
 
253
-         if [ ! -z "${tag}" ]
254
-         then
255
-            prompt="${prompt} (Since tag ${tag} is set, NO is more reasonable)"
256
-         fi
259
+ask_symlink_it()
260
+{
261
+   local  directory
257 262
 
258
-         user_say_yes "$prompt"
259
-         flag=$?
260
-      fi
263
+   directory="$1"
261 264
 
262
-      if [ $flag -ne 0 ]
263
-      then
264
-         return $flag
265
-      fi
265
+   if [ ! -d "${directory}" ]
266
+   then
267
+      fail "You need to check out \"${directory}\" yourself, as it's not there."
266 268
    fi
267 269
 
268
-   # can only symlink because not a .git repo yet
269
-   if [ "${OPTION_ALLOW_CREATING_SYMLINKS}" = "YES" ]
270
+   if ! can_symlink_it "${directory}"
270 271
    then
271
-      log_info "${clone} is not a git repository (yet ?)"
272
-      log_info "So symlinking is the only way to go."
273
-
274
-      return 0
272
+      return 1
275 273
    fi
276 274
 
277
-   case "${UNAME}" in
278
-      minwgw)
279
-         fail "Can't symlink on $UNAME, as symlinks don't exist"
280
-      ;;
275
+   #
276
+   # check if checked out
277
+   #
278
+   local prompt
281 279
 
282
-      *)
283
-         fail "Can't symlink embedded repositories by default. \
284
-Use --embedded-symlinks option to allow it"
285
-      ;;
286
-   esac
280
+   prompt="Should ${directory} be symlinked instead of cloned ?
281
+NO is safe, but you often say YES here."
282
+
283
+   if [ ! -z "${tag}" ]
284
+   then
285
+      prompt="${prompt} (Since tag ${tag} is set, NO is more reasonable)"
286
+   fi
287
+
288
+   user_say_yes "$prompt"
287 289
 }
288 290
 
289 291
 
290
-_search_for_repository_in_caches()
292
+_search_for_repository_in_cache()
291 293
 {
292 294
    local directory
293 295
    local name
... ...
@@ -340,12 +342,22 @@ _search_for_repository_in_caches()
340 342
 search_for_repository_in_caches()
341 343
 {
342 344
    local found
345
+   local directory
343 346
 
344
-   found="`_search_for_repository_in_caches "${CACHES_DIR}" "$@"`" || exit 1
345
-   if [ ! -z "${found}" ]
346
-   then
347
-      symlink_relpath "${found}" "${ROOT_DIR}"
348
-   fi
347
+   IFS=":"
348
+   for directory in ${CACHES_PATH}
349
+   do
350
+      IFS="${DEFAULT_IFS}"
351
+
352
+      found="`_search_for_repository_in_cache "${directory}" "$@"`" || exit 1
353
+      if [ ! -z "${found}" ]
354
+      then
355
+         symlink_relpath "${found}" "${ROOT_DIR}"
356
+         return
357
+      fi
358
+   done
359
+
360
+   IFS="${DEFAULT_IFS}"
349 361
 }
350 362
 
351 363
 
... ...
@@ -431,7 +443,7 @@ clone_or_symlink()
431 443
       ;;
432 444
 
433 445
       *)
434
-         if [ "${OPTION_ALLOW_SEARCH_PARENT}" = "YES" ]
446
+         if [ "${OPTION_ALLOW_SEARCH_CACHES}" = "YES" ]
435 447
          then
436 448
             found="`search_for_repository_in_caches "${name}" "${branch}"`"
437 449
             if [ -z "${found}" ]
... ...
@@ -441,7 +453,7 @@ clone_or_symlink()
441 453
 
442 454
             if [ ! -z "${found}" ]
443 455
             then
444
-               [ "${OPTION_ALLOW_AUTOCLONE_PARENT}" = "YES" ] || user_say_yes "There is a \"${found}\" folder in the parent directory of this project.
456
+               user_say_yes "There is a \"${found}\" folder in the parent directory of this project.
445 457
 (\"${PWD}\"). Use it ?"
446 458
                if [ $? -eq 0 ]
447 459
                then
... ...
@@ -837,7 +849,9 @@ did_upgrade_repository()
837 849
 
838 850
 did_upgrade_repositories()
839 851
 {
840
-   walk_clones "did_upgrade_repository" "${REPOS_DIR}" "$@"
852
+   local clones="$1"
853
+
854
+   walk_clones "${clones}" "did_upgrade_repository" "${REPOS_DIR}"
841 855
 }
842 856
 
843 857
 
... ...
@@ -869,7 +883,14 @@ required_action_for_clone()
869 883
 
870 884
    if [ "${clone}" = "${newclone}" ]
871 885
    then
872
-      log_fluff "URL ${url} repository line is unchanged"
886
+      if [ -e "${newstashdir}" ]
887
+      then
888
+         log_fluff "URL ${url} repository line is unchanged"
889
+         return
890
+      fi
891
+
892
+      log_fluff "\"${newstashdir}\" is missing, reget."
893
+      echo "clone"
873 894
       return
874 895
    fi
875 896
 
... ...
@@ -1191,7 +1212,8 @@ _fetch_once_deep_repository()
1191 1212
 
1192 1213
       local clones
1193 1214
 
1194
-      clones="`_read_setting "${autodir}/embedded_repositories" "embedded_repositories"`" ;
1215
+      # ugliness
1216
+      clones="`read_setting "${autodir}/embedded_repositories"`" ;
1195 1217
       work_clones "${reposdir}" "${clones}" "NO" > /dev/null
1196 1218
    ) || exit 1
1197 1219
 }
... ...
@@ -1263,32 +1285,29 @@ fetch_loop_repositories()
1263 1285
 assume_stashes_are_zombies()
1264 1286
 {
1265 1287
    zombify_embedded_repository_stashes
1266
-   if [ -z "${OPTION_EMBEDDED_ONLY}" ]
1267
-   then
1268
-      zombify_repository_stashes
1269
-      zombify_deep_embedded_repository_stashes
1270
-   fi
1288
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1289
+
1290
+   zombify_repository_stashes
1291
+   zombify_deep_embedded_repository_stashes
1271 1292
 }
1272 1293
 
1273 1294
 
1274 1295
 bury_zombies_in_graveyard()
1275 1296
 {
1276 1297
    bury_embedded_repository_zombies
1277
-   if [ -z "${OPTION_EMBEDDED_ONLY}" ]
1278
-   then
1279
-      bury_repository_zombies
1280
-      bury_deep_embedded_repository_zombies
1281
-   fi
1298
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1299
+
1300
+   bury_repository_zombies
1301
+   bury_deep_embedded_repository_zombies
1282 1302
 }
1283 1303
 
1284 1304
 
1285 1305
 run_post_fetch_scripts()
1286 1306
 {
1287
-   if [ -z "${OPTION_EMBEDDED_ONLY}" ]
1288
-   then
1289
-      did_fetch_repositories "$@"
1290
-      fetch__run_root_settings_script "post-fetch" "$@"
1291
-   fi
1307
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1308
+
1309
+   did_fetch_repositories "$@"
1310
+   fetch__run_root_settings_script "post-fetch" "$@"
1292 1311
 }
1293 1312
 
1294 1313
 
... ...
@@ -1301,11 +1320,10 @@ run_post_update_scripts()
1301 1320
 
1302 1321
 run_post_upgrade_scripts()
1303 1322
 {
1304
-   if [ -z "${OPTION_EMBEDDED_ONLY}" ]
1305
-   then
1306
-      did_upgrade_repositories "$@"
1307
-      fetch__run_root_settings_script "post-upgrade" "$@"
1308
-   fi
1323
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1324
+
1325
+   did_upgrade_repositories "$@"
1326
+   fetch__run_root_settings_script "post-upgrade" "$@"
1309 1327
 }
1310 1328
 
1311 1329
 
... ...
@@ -1322,18 +1340,14 @@ fetch_loop()
1322 1340
    is_master_bootstrap_project
1323 1341
    is_master=$?
1324 1342
 
1325
-   if [ "${is_master}" -ne 0 ]
1326
-   then
1327
-      assume_stashes_are_zombies
1328
-   else
1329
-      log_fluff "Skipping zombie checks, because project is master"
1330
-   fi
1343
+   # this is wrong, we just do "stashes" though
1344
+   assume_stashes_are_zombies
1331 1345
 
1332 1346
    bootstrap_auto_create
1333 1347
 
1334 1348
    fetch_once_embedded_repositories
1335 1349
 
1336
-   if [ -z "${OPTION_EMBEDDED_ONLY}" ]
1350
+   if [ "${OPTION_EMBEDDED_ONLY}" = "NO" ]
1337 1351
    then
1338 1352
       fetched="`fetch_loop_repositories`" || exit 1
1339 1353
       fetch_once_deep_embedded_repositories
... ...
@@ -1383,10 +1397,7 @@ _common_update()
1383 1397
    esac
1384 1398
 
1385 1399
    update_embedded_repositories > /dev/null
1386
-   if [ ! -z "${OPTION_EMBEDDED_ONLY}" ]
1387
-   then
1388
-      return
1389
-   fi
1400
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1390 1401
 
1391 1402
    update_repositories "$@" > /dev/null
1392 1403
    update_deep_embedded_repositories > /dev/null
... ...
@@ -1402,10 +1413,7 @@ _common_upgrade()
1402 1413
    esac
1403 1414
 
1404 1415
    upgrade_embedded_repositories
1405
-   if [ ! -z "${OPTION_EMBEDDED_ONLY}" ]
1406
-   then
1407
-      return
1408
-   fi
1416
+   [ "${OPTION_EMBEDDED_ONLY}" = "YES" ] && return
1409 1417
 
1410 1418
    local upgraded=""
1411 1419
 
... ...
@@ -1424,18 +1432,17 @@ _common_main()
1424 1432
    [ -z "${MULLE_BOOTSTRAP_LOCAL_ENVIRONMENT_SH}" ] && . mulle-bootstrap-local-environment.sh
1425 1433
    [ -z "${MULLE_BOOTSTRAP_SETTINGS_SH}" ]          && . mulle-bootstrap-settings.sh
1426 1434
 
1427
-   local OPTION_CHECK_USR_LOCAL_INCLUDE
1428
-   local OPTION_ALLOW_CREATING_SYMLINKS
1429
-   local OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS
1430
-   local OPTION_ALLOW_SEARCH_PARENT
1431
-   local OPTION_ALLOW_AUTOCLONE_PARENT
1432
-   local OPTION_EMBEDDED_ONLY
1435
+   local OPTION_CHECK_USR_LOCAL_INCLUDE="NO"
1436
+   local OPTION_ALLOW_CREATING_SYMLINKS="NO"
1437
+   local OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="NO"
1438
+   local OPTION_ALLOW_SEARCH_CACHES="NO"
1439
+   local OPTION_EMBEDDED_ONLY="NO"
1433 1440
 
1434 1441
    OPTION_CHECK_USR_LOCAL_INCLUDE="`read_config_setting "check_usr_local_include" "NO"`"
1435 1442
 
1436 1443
    case "${UNAME}" in
1437 1444
       mingw)
1438
-         OPTION_ALLOW_CREATING_SYMLINKS=
1445
+         OPTION_ALLOW_CREATING_SYMLINKS="NO"
1439 1446
       ;;
1440 1447
 
1441 1448
       *)
... ...
@@ -1443,8 +1450,7 @@ _common_main()
1443 1450
       ;;
1444 1451
    esac
1445 1452
 
1446
-   OPTION_ALLOW_SEARCH_PARENT="${MULLE_FLAG_ANSWER}"
1447
-   OPTION_ALLOW_AUTOCLONE_PARENT="${MULLE_FLAG_ANSWER}"
1453
+   OPTION_ALLOW_SEARCH_CACHES="${MULLE_FLAG_ANSWER}"
1448 1454
 
1449 1455
    #
1450 1456
    # it is useful, that fetch understands build options and
... ...
@@ -1457,24 +1463,11 @@ _common_main()
1457 1463
             ${USAGE}
1458 1464
          ;;
1459 1465
 
1460
-         -aa|--allow-autoclone-parent)
1461
-            OPTION_ALLOW_SEARCH_PARENT="YES"
1462
-            OPTION_ALLOW_AUTOCLONE_PARENT="YES"
1466
+         -c|--caches)
1467
+            OPTION_ALLOW_SEARCH_CACHES="YES"
1463 1468
          ;;
1464 1469
 
1465
-         -ap|--allow-parent-search)
1466
-            OPTION_ALLOW_SEARCH_PARENT="YES"
1467
-         ;;
1468
-
1469
-         -as|--allow-symlink-creation)
1470
-            OPTION_ALLOW_CREATING_SYMLINKS="YES"
1471
-         ;;
1472
-
1473
-         -aes|--allow-embedded-symlink-creation|--embedded-symlinks)
1474
-            OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="YES"
1475
-         ;;
1476
-
1477
-         -cs|--check-usr-local-include)
1470
+         -cu|--check-usr-local-include)
1478 1471
             OPTION_CHECK_USR_LOCAL_INCLUDE="YES"
1479 1472
          ;;
1480 1473
 
... ...
@@ -1482,21 +1475,38 @@ _common_main()
1482 1475
             OPTION_EMBEDDED_ONLY="YES"
1483 1476
          ;;
1484 1477
 
1478
+         -fb|--force-branch)
1479
+            shift
1480
+            [ $# -ne 0 ] || fail "branch missing"
1481
+
1482
+            OPTION_FORCE_BRANCH="$1"
1483
+            if [ -z "${OPTION_FORCE_BRANCH}" ]
1484
+            then
1485
+               OPTION_FORCE_BRANCH="master"
1486
+            fi
1487
+         ;;
1488
+
1485 1489
          -fs|--follow-symlinks)
1486 1490
             OPTION_ALLOW_FOLLOWING_SYMLINKS="YES"
1487 1491
          ;;
1488 1492
 
1489
-         -in|--ignore-branch)
1490
-            OPTION_IGNORE_BRANCH="YES"
1493
+         -l|--symlink-creation)
1494
+            OPTION_ALLOW_CREATING_SYMLINKS="YES"
1495
+         ;;
1496
+
1497
+         -le|--embedded-symlink-creation)
1498
+            OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="YES"
1491 1499
          ;;
1492 1500
 
1493
-         -np|--no-parent-search)
1494
-            OPTION_ALLOW_SEARCH_PARENT=
1501
+         -nc|--no-caches)
1502
+            OPTION_ALLOW_SEARCH_CACHES="NO"
1503
+            OPTION_ALLOW_CREATING_SYMLINKS="NO"
1495 1504
          ;;
1496 1505
 
1497 1506
          -ns|--no-symlink-creation|--no-symlinks)
1498
-            OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS=
1499
-            OPTION_ALLOW_CREATING_SYMLINKS=
1507
+            OPTION_ALLOW_FOLLOWING_SYMLINKS="NO"
1508
+            OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="NO"
1509
+            OPTION_ALLOW_CREATING_SYMLINKS="NO"
1500 1510
          ;;
1501 1511
 
1502 1512
          # build options with no parameters
... ...
@@ -201,7 +201,7 @@ assert_mulle_bootstrap_version()
201 201
    local version
202 202
 
203 203
    # has to be read before .auto is setup
204
-   version="`read_setting "${BOOTSTRAP_DIR}/version" "version"`"
204
+   version="`read_raw_setting "version"`"
205 205
 
206 206
    if check_version "$version" "${MULLE_BOOTSTRAP_VERSION_MAJOR}" "${MULLE_BOOTSTRAP_VERSION_MINOR}"
207 207
    then
... ...
@@ -436,9 +436,14 @@ local_environment_initialize()
436 436
    # our "sandbox" root, probably not changeable
437 437
    ROOT_DIR="`pwd -P`"
438 438
 
439
+   #
439 440
    # where we look for symlink sources
440
-   DEFAULT_CACHES_DIR="`dirname -- "${ROOT_DIR}"`"
441
+   # user can set also seT via environment "CACHES_PATH"
442
+   #
443
+   local parent
441 444
 
445
+   parent="`dirname -- "${ROOT_DIR}"`"
446
+   DEFAULT_CACHES_PATH="${CACHES_PATH:-${parent}}"
442 447
 
443 448
    log_fluff "${UNAME} detected"
444 449
    case "${UNAME}" in
... ...
@@ -206,6 +206,11 @@ walk_check()
206 206
       fi
207 207
    fi
208 208
 
209
+   if [ "${WALK_MISSING_REPOSITORIES}" = "YES" ]
210
+   then
211
+      return 0
212
+   fi
213
+
209 214
    if [ -L "${stashdir}" ]
210 215
    then
211 216
       # cat is for -e
... ...
@@ -340,9 +345,12 @@ _walk_deep_embedded_repositories()
340 345
          local filepath
341 346
 
342 347
          filepath="${BOOTSTRAP_DIR}.auto/.deep/${name}.d/embedded_repositories"
343
-         embedded_clones="`_read_setting "${filepath}" "embedded_repositories"`"
348
+         # sigh have to use read_setting here
349
+         embedded_clones="`read_setting "${filepath}"`"
344 350
 
345
-         STASHES_ROOT_DIR="${stashdir}" ;
351
+         PARENT_REPOSITORY_NAME="${name}"
352
+         STASHES_DEFAULT_DIR=""
353
+         STASHES_ROOT_DIR="${stashdir}"
346 354
          reposdir="${REPOS_DIR}/.deep/${name}.d"
347 355
          _walk_repositories "${embedded_clones}" "${callback}" "${permissions}" "${reposdir}"
348 356
       ) || exit 1
... ...
@@ -474,14 +482,29 @@ computed_stashdir()
474 482
 # this sets values to variables that should be declared
475 483
 # in the caller!
476 484
 #
477
-#   # parse_clone
478
-#   local name       # name of the clone
485
+#   # parse_raw_clone
479 486
 #   local url        # url of clone
487
+#   local dstdir
480 488
 #   local branch
481 489
 #   local scm
482 490
 #   local tag
483
-#   local stashdir   # dir of repository (usually inside stashes)
484 491
 #
492
+parse_raw_clone()
493
+{
494
+   IFS=";" read -r url dstdir branch scm tag <<< "${1}"
495
+}
496
+
497
+
498
+# this sets values to variables that should be declared
499
+# in the caller!
500
+#
501
+#   # parse_clone
502
+#   local name
503
+#   local url
504
+#   local branch
505
+#   local scm
506
+#   local tag
507
+#   local stashdir
485 508
 parse_clone()
486 509
 {
487 510
    local clone="$1"
... ...
@@ -496,10 +519,7 @@ parse_clone()
496 519
    #
497 520
    IFS=";" read -r url dstdir branch scm tag <<< "${clone}"
498 521
 
499
-   if [ "${OPTION_IGNORE_BRANCH}" = "YES" ]
500
-   then
501
-      branch=""
502
-   fi
522
+   branch="${OPTION_FORCE_BRANCH:-${branch}}"
503 523
 
504 524
    case "${url}" in
505 525
       */\.\./*|\.\./*|*/\.\.|\.\.)
... ...
@@ -536,8 +556,6 @@ parse_clone()
536 556
       log_trace2 "STASHDIR: \"${stashdir}\""
537 557
    fi
538 558
 
539
-   [ "${url}" = "Already up-to-date." ] && internal_fail "fail"
540
-
541 559
    [ -z "${url}" ]      && internal_fail "url is empty ($clone)"
542 560
    [ -z "${name}" ]     && internal_fail "name is empty ($clone)"
543 561
    [ -z "${stashdir}" ] && internal_fail "stashdir is empty ($clone)"
... ...
@@ -547,11 +565,42 @@ parse_clone()
547 565
 
548 566
 
549 567
 #
550
-# walk over clones given as parameters
551
-# call callback
568
+# walk over clones just give raw values
552 569
 #
570
+walk_raw_clones()
571
+{
572
+   local clones=$1; shift
573
+   local callback=$1; shift
574
+
575
+   local url
576
+   local dstdir
577
+   local branch
578
+   local scm
579
+   local tag
580
+
581
+   IFS="
582
+"
583
+   for clone in ${clones}
584
+   do
585
+      IFS="${DEFAULT_IFS}"
586
+
587
+      parse_raw_clone "${clone}"
588
+
589
+      "${callback}" "${url}" \
590
+                    "${dstdir}" \
591
+                    "${branch}" \
592
+                    "${scm}" \
593
+                    "${tag}" \
594
+                    "$@"
595
+   done
596
+
597
+   IFS="${DEFAULT_IFS}"
598
+}
599
+
600
+
553 601
 walk_clones()
554 602
 {
603
+   local clones=$1; shift
555 604
    local callback=$1; shift
556 605
    local reposdir=$1; shift
557 606
 
... ...
@@ -565,7 +614,7 @@ walk_clones()
565 614
 
566 615
    IFS="
567 616
 "
568
-   for clone in $*
617
+   for clone in ${clones}
569 618
    do
570 619
       IFS="${DEFAULT_IFS}"
571 620
 
... ...
@@ -577,7 +626,8 @@ walk_clones()
577 626
                     "${branch}" \
578 627
                     "${scm}" \
579 628
                     "${tag}" \
580
-                    "${stashdir}"
629
+                    "${stashdir}" \
630
+                    "$@"
581 631
    done
582 632
 
583 633
    IFS="${DEFAULT_IFS}"
... ...
@@ -797,7 +847,7 @@ ${clone}"
797 847
       local filename
798 848
 
799 849
       filename="${stashdir}/.bootstrap/repositories"
800
-      sub_repos="`_read_expanded_setting "${filename}" "repositories" "" "${stashdir}/.bootstrap"`"
850
+      sub_repos="`read_expanded_setting "${filename}" "" "${stashdir}/.bootstrap"`"
801 851
       if [ ! -z "${sub_repos}" ]
802 852
       then
803 853
          sub_repos="`unique_repository_contents "${sub_repos}" "${clones}"`"
... ...
@@ -33,7 +33,7 @@ MULLE_BOOTSTRAP_SCM_SH="included"
33 33
 
34 34
 git_is_repository()
35 35
 {
36
-   [ -d "${1}.git" ] || [ -d  "${1}/refs" -a  -f "${1}/HEAD" ]
36
+   [ -d "${1}/.git" ] || [ -d  "${1}/refs" -a -f "${1}/HEAD" ]
37 37
 }
38 38
 
39 39
 
... ...
@@ -40,6 +40,14 @@ EOF
40 40
   exit 1
41 41
 }
42 42
 
43
+expansion_usage()
44
+{
45
+    cat <<EOF >&2
46
+usage:
47
+   mulle-bootstrap expansion <name> [value]
48
+EOF
49
+  exit 1
50
+}
43 51
 
44 52
 setting_usage()
45 53
 {
... ...
@@ -95,6 +103,7 @@ warn_environment_setting()
95 103
 }
96 104
 
97 105
 
106
+# returns 2 if file is missing
98 107
 __read_setting()
99 108
 {
100 109
    local path="$1"
... ...
@@ -131,10 +140,8 @@ _copy_no_clobber_setting_file()
131 140
 _read_setting()
132 141
 {
133 142
    local apath="$1"
134
-   local name="$2"
135 143
 
136 144
    [ ! -z "${apath}" ] || fail "no path given to read_setting"
137
-   [ ! -z "${name}" ] || fail "no name given to read_setting"
138 145
 
139 146
    local value
140 147
 
... ...
@@ -149,13 +156,11 @@ _read_setting()
149 156
          yesno="not "
150 157
       fi
151 158
 
152
-      log_trace2 "Looking for setting ${name} in ${apath} (pwd=$PWD) : ${yesno}found"
159
+      log_trace2 "Looking for setting in \"${apath}\" (pwd=$PWD) : ${yesno}found"
153 160
    fi
154 161
 
155
-
156 162
    if [ "${READ_SETTING_RETURNS_PATH}" = "YES" ]
157 163
    then
158
-      value="${apath}"
159 164
       if [ ! -r "${apath}" ]
160 165
       then
161 166
          return 2
... ...
@@ -163,10 +168,13 @@ _read_setting()
163 168
 
164 169
       if [ "$MULLE_FLAG_LOG_VERBOSE" = "YES"  ]
165 170
       then
171
+         local name
172
+
173
+         name="`basename -- "${apath}"`"
166 174
          log_setting "${C_MAGENTA}${name}${C_SETTING} found as \"${apath}\""
167 175
       fi
168 176
 
169
-      echo "${value}"
177
+      echo "${apath}"
170 178
       return 0
171 179
    fi
172 180
 
... ...
@@ -175,16 +183,16 @@ _read_setting()
175 183
    #
176 184
    # remove empty lines, remove comment lines
177 185
    #
178
-   value="`__read_setting "${apath}"`"
179
-   rval=$?
180
-
181
-   if [ $rval -eq 2 ]
186
+   if ! value="`__read_setting "${apath}"`"
182 187
    then
183 188
       return 2   # it's grep :)
184 189
    fi
185 190
 
186 191
    if [ "${MULLE_FLAG_LOG_VERBOSE}" = "YES"  ]
187 192
    then
193
+      local name
194
+
195
+      name="`basename -- "${apath}"`"
188 196
       apath="`absolutepath "${apath}"`"
189 197
 
190 198
       # make some boring names less prominent
... ...
@@ -212,20 +220,31 @@ read_setting()
212 220
 }
213 221
 
214 222
 
223
+read_raw_setting()
224
+{
225
+   local name="$1"
226
+
227
+   [ $# -ne 1 ]     && internal_fail "parameterization error"
228
+   [ -z "${name}" ] && internal_fail "empty name in read_raw_setting"
229
+
230
+   if _read_setting "${BOOTSTRAP_DIR}.local/${name}"
231
+   then
232
+      return
233
+   fi
234
+   _read_setting "${BOOTSTRAP_DIR}/${name}"
235
+}
236
+
215 237
 #
216 238
 # this has to be flexible, because fetch and build settings read differently
217 239
 #
218 240
 _read_bootstrap_setting()
219 241
 {
220
-   local name
221
-
222
-   name="$1"
242
+   local name="$1"
223 243
 
224 244
    [ $# -ne 1 ]     && internal_fail "parameterization error"
225 245
    [ -z "${name}" ] && internal_fail "empty name in _read_bootstrap_setting"
226 246
 
227 247
    local value
228
-   local suffix
229 248
 
230 249
    #
231 250
    # to access unmerged data (needed for embedded repos)
... ...
@@ -237,13 +256,7 @@ _read_bootstrap_setting()
237 256
       suffix=".auto"
238 257
    fi
239 258
 
240
-   value="`_read_setting "${BOOTSTRAP_DIR}${suffix}/${name}" "${name}"`"
241
-   if [ $? -ne 0 ]
242
-   then
243
-      return 2
244
-   fi
245
-
246
-   echo "${value}"
259
+   _read_setting "${BOOTSTRAP_DIR}${suffix}/${name}"
247 260
 }
248 261
 
249 262
 
... ...
@@ -305,7 +318,7 @@ _read_home_setting()
305 318
       log_trace2 "Looking for setting \"${name}\" in \"~/.mulle-bootstrap\""
306 319
    fi
307 320
 
308
-   value="`_read_setting "${HOME}/.mulle-bootstrap/${name}" "${name}"`"
321
+   value="`_read_setting "${HOME}/.mulle-bootstrap/${name}"`"
309 322
    if [ $? -ne 0 ]
310 323
    then
311 324
       return 2
... ...
@@ -352,7 +365,7 @@ read_config_setting()
352 365
    value="`_read_environment_setting "${name}"`"
353 366
    if [ $? -ne 0 ]
354 367
    then
355
-      value="`_read_setting "${BOOTSTRAP_DIR}.local/config/${name}" "${name}"`"
368
+      value="`_read_setting "${BOOTSTRAP_DIR}.local/config/${name}"`"
356 369
       if [ $? -ne 0 ]
357 370
       then
358 371
          value="`_read_home_setting "${name}"`"
... ...
@@ -524,24 +537,28 @@ read_sane_config_path_setting()
524 537
 # this is used during copy operations into .auto to already expand variables