Browse code

Improved handling of repository entries with variables. Prefix fails with mulle-bootstrap <action> so the user knows, whos complaining (if running in a script). -i flag for fetch and update

Nat! authored on 20/10/2016 23:43:05
Showing 18 changed files
... ...
@@ -1,3 +1,41 @@
1
+2.3
2
+===
3
+The main new feature of 2.3 is support for working with different repositories.
4
+E.g. I host releases on GitHub on a branch "release", which are accessed via
5
+https://, but when I develop I use Mulle KybernetiK on branch "master".
6
+
7
+The "trick" is to use parameterized branches and urls like so:
8
+
9
+```
10
+$ cat .bootstrap/repositories
11
+${MULLE_REPOSITORIES}/mulle-c11;;${MULLE_C11_BRANCH:-release}
12
+$ cat .bootstrap/MULLE_REPOSITORIES
13
+https://github.com/mulle-nat
14
+```
15
+
16
+This works for the release part. Locally though in the non-committed
17
+`.bootstrap.local`:
18
+
19
+```
20
+$ cat MULLE_REPOSITORIES
21
+nat@mulle-kybernetik.com:/scm/public_git/repositories
22
+$ cat MULLE_C11_BRANCH
23
+master
24
+```
25
+
26
+Changes:
27
+
28
+* clarified the use of options vs. flags some more. e.g. git GITFLAGS command GITOPTIONS.
29
+* update will now also refresh
30
+* start version checking bootstrap contents
31
+* -f flag will now also try to checkout branches, that are checked out
32
+incorrectly
33
+* fetch gains -i option, to ignore "wrongly" checked out repositories
34
+* fails are prefixed with the command, that caused the failure now
35
+* use unexpanded URLs for dependency matches and store those into .bootstrap.auto
36
+* mulle-bootstrap now picks up URL changes and corrects them in fetched
37
+repositiories, but that does not per se force an update.
38
+
1 39
 2.2.1
2 40
 ===
3 41
 
... ...
@@ -28,8 +28,12 @@
28 28
 #   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 29
 #   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 30
 #   POSSIBILITY OF SUCH DAMAGE.
31
+MULLE_BOOTSTRAP_VERSION_MAJOR=2
32
+MULLE_BOOTSTRAP_VERSION_MINOR=3
33
+MULLE_BOOTSTRAP_VERSION_PATCH=0
31 34
 
32
-MULLE_BOOTSTRAP_VERSION="2.2.1"
35
+MULLE_BOOTSTRAP_VERSION="${MULLE_BOOTSTRAP_VERSION_MAJOR}.${MULLE_BOOTSTRAP_VERSION_MINOR}.${MULLE_BOOTSTRAP_VERSION_PATCH}"
36
+MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap"
33 37
 
34 38
 #
35 39
 # This is the main user interface to mulle-bootstrap
... ...
@@ -49,6 +53,7 @@ usage: mulle-bootstrap [flags] [command] [options]
49 49
  Flags:
50 50
    -a -y     : default answer to questions (scripts wont be checked)
51 51
                -a (clone preferred) -y (local copy/symlink preferred)
52
+   -f        : force operation
52 53
    -n        : do nothing creative or destructive
53 54
    -v        : -v to be more verbose (-vv or -vvv for more verbosity)
54 55
 
... ...
@@ -106,7 +111,6 @@ bootstrap_nomagic_main()
106 106
 {
107 107
    local command
108 108
 
109
-
110 109
    command="$1"
111 110
    shift
112 111
 
... ...
@@ -130,6 +134,7 @@ bootstrap_nomagic_main()
130 130
 
131 131
    if fetch_needed
132 132
    then
133
+      MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap fetch"
133 134
       if [ -z "${DONT_RECURSE}" ]
134 135
       then
135 136
          fetch_main "$@" || exit 1
... ...
@@ -142,6 +147,7 @@ bootstrap_nomagic_main()
142 142
 
143 143
    if build_needed
144 144
    then
145
+      MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap build"
145 146
       build_main "$@" || exit 1
146 147
    fi
147 148
 
... ...
@@ -185,6 +191,8 @@ bootstrap_main()
185 185
 
186 186
    trap trap_fail INT
187 187
 
188
+   source_environment
189
+
188 190
    #
189 191
    # simple option handling
190 192
    #
... ...
@@ -242,7 +250,7 @@ bootstrap_main()
242 242
          -t|--trace)
243 243
             MULLE_BOOTSTRAP_TRACE="1848"
244 244
             COPYMOVEFLAGS="-v"
245
-            GITFLAGS="${GITFLAGS} -v"
245
+            GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
246 246
          ;;
247 247
 
248 248
          -V|--verbose-build)
... ...
@@ -252,25 +260,25 @@ bootstrap_main()
252 252
          -v|--verbose)
253 253
             MULLE_BOOTSTRAP_TRACE="VERBOSE"
254 254
             COPYMOVEFLAGS="-v"
255
-            GITFLAGS="${GITFLAGS} -v"
255
+            GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
256 256
          ;;
257 257
 
258 258
          -vv|--very-verbose)
259 259
             MULLE_BOOTSTRAP_TRACE="FLUFF"
260 260
             COPYMOVEFLAGS="-v"
261
-            GITFLAGS="${GITFLAGS} -v"
261
+            GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
262 262
          ;;
263 263
 
264 264
          -vvv|--very-verbose-with-settings)
265 265
             MULLE_BOOTSTRAP_TRACE="TRACE"
266 266
             COPYMOVEFLAGS="-v"
267
-            GITFLAGS="${GITFLAGS} -v"
267
+            GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
268 268
          ;;
269 269
 
270 270
          -s|--silent)
271 271
             MULLE_BOOTSTRAP_TRACE=
272 272
             MULLE_BOOTSTRAP_TERSE="YES"
273
-            GITFLAGS="${GITFLAGS} -q"
273
+            GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
274 274
          ;;
275 275
 
276 276
          -h|--help)
... ...
@@ -278,7 +286,7 @@ bootstrap_main()
278 278
          ;;
279 279
 
280 280
          -*)
281
-            log_error "unknown option \"$1\""
281
+            log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown flag \"$1\""
282 282
             usage
283 283
          ;;
284 284
 
... ...
@@ -341,6 +349,10 @@ bootstrap_main()
341 341
       log_trace "Dry run is active."
342 342
    fi
343 343
 
344
+   # source in environment now
345
+
346
+   local_environment_main
347
+
344 348
    #
345 349
    # some commands only run when we have a .bootstrap folder
346 350
    #
... ...
@@ -374,7 +386,7 @@ bootstrap_main()
374 374
    if [ "${MULLE_BOOTSTRAP_NEEDS_REFRESH}" = "YES" ] || refresh_needed
375 375
    then
376 376
       case "${command}" in
377
-         bootstrap|nomagic|fetch)
377
+         bootstrap|nomagic|fetch|update)
378 378
             MULLE_BOOTSTRAP_WILL_FETCH="YES"
379 379
             . mulle-bootstrap-refresh.sh
380 380
             refresh_main || exit 1
... ...
@@ -391,7 +403,7 @@ bootstrap_main()
391 391
             refresh_main refresh_if_bare || exit 1
392 392
          ;;
393 393
 
394
-         update|refresh)
394
+         refresh)
395 395
            . mulle-bootstrap-refresh.sh
396 396
 
397 397
            # 4 laters
... ...
@@ -407,41 +419,49 @@ bootstrap_main()
407 407
       build)
408 408
          . mulle-bootstrap-build.sh
409 409
 
410
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap build"
410 411
          build_main "$@" || exit 1
411 412
       ;;
412 413
 
413 414
       clean)
414 415
          . mulle-bootstrap-clean.sh
415 416
 
417
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap clean"
416 418
          clean_main "$@" || exit 1
417 419
       ;;
418 420
 
419 421
       config)
420 422
          . mulle-bootstrap-settings.sh
423
+
424
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap config"
421 425
          config_main "$@" || exit 1
422 426
       ;;
423 427
 
424 428
       dist)
425 429
          . mulle-bootstrap-clean.sh
426 430
 
431
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap clean"
427 432
          clean_main "dist" || exit 1
428 433
       ;;
429 434
 
430 435
       fetch)
431 436
          . mulle-bootstrap-fetch.sh
432 437
 
438
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap fetch"
433 439
          DONT_ASK_AFTER_WARNING=YES fetch_main "$@" || exit 1
434 440
       ;;
435 441
 
436 442
       init)
437 443
          . mulle-bootstrap-init.sh
438 444
 
445
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap init"
439 446
          init_main "$@" || exit 1
440 447
       ;;
441 448
 
442 449
       install)
443 450
          . mulle-bootstrap-install.sh
444 451
 
452
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap install"
445 453
          install_main "$@" || exit 1
446 454
       ;;
447 455
 
... ...
@@ -453,33 +473,39 @@ bootstrap_main()
453 453
       refresh)
454 454
          [ -z "${MULLE_BOOTSTRAP_REFRESH_SH}" ] && . mulle-bootstrap-refresh.sh
455 455
 
456
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap refresh"
456 457
          refresh_main "$@" || exit 1
457 458
       ;;
458 459
 
459 460
       update|pull)
460 461
          . mulle-bootstrap-fetch.sh
461 462
 
463
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap update"
462 464
          update_main "$@" || exit 1
463 465
 
464 466
          [ -z "${MULLE_BOOTSTRAP_REFRESH_SH}" ] && . mulle-bootstrap-refresh.sh
467
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap refresh"
465 468
          refresh_main || exit 1
466 469
       ;;
467 470
 
468 471
       setup-xcode|xcode)
469 472
          . mulle-bootstrap-xcode.sh
470 473
 
474
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap xcode"
471 475
          xcode_main "$@" || exit 1
472 476
       ;;
473 477
 
474 478
       tag)
475 479
          . mulle-bootstrap-tag.sh
476 480
 
481
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap tag"
477 482
          tag_main "$@" || exit 1
478 483
       ;;
479 484
 
480 485
       git)
481 486
          . mulle-bootstrap-scm.sh
482 487
 
488
+         MULLE_BOOTSTRAP_FAIL_PREFIX="mulle-bootstrap git"
483 489
          git_main "$@" || exit 1
484 490
       ;;
485 491
 
... ...
@@ -488,7 +514,7 @@ bootstrap_main()
488 488
       ;;
489 489
 
490 490
       *)
491
-         log_error "Unknown command \"${command}\""
491
+         log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown command \"${command}\""
492 492
          usage
493 493
       ;;
494 494
    esac
... ...
@@ -59,6 +59,8 @@ find_library_in_directories()
59 59
    local directory
60 60
    local path
61 61
 
62
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
63
+
62 64
    IFS="
63 65
 "
64 66
    for directory in ${directories}
... ...
@@ -290,7 +292,7 @@ ${SEARCH_PATH}"
290 290
          ;;
291 291
 
292 292
          -*)
293
-            echo "unknown option $1" >&2
293
+            echo "mulle-mingw-dumpdef.sh: Unknown option $1" >&2
294 294
             usage
295 295
          ;;
296 296
 
... ...
@@ -50,6 +50,8 @@ bootstrap_auto_update_merge()
50 50
    local match
51 51
    local i
52 52
 
53
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
54
+
53 55
    IFS="
54 56
 "
55 57
    for i in `ls -1 "${directory}/.bootstrap"`
... ...
@@ -213,6 +215,8 @@ bootstrap_auto_create()
213 213
 {
214 214
    log_verbose "Creating .bootstrap.auto from .bootstrap and .bootstrap.local"
215 215
 
216
+   assert_mulle_bootstrap_version
217
+
216 218
    mkdir_if_missing "${BOOTSTRAP_SUBDIR}.auto"
217 219
 
218 220
    if dir_has_files "${BOOTSTRAP_SUBDIR}.local"
... ...
@@ -228,6 +232,7 @@ bootstrap_auto_create()
228 228
    local file
229 229
    local name
230 230
 
231
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
231 232
    IFS="
232 233
 "
233 234
    for file in `ls -1 "${BOOTSTRAP_SUBDIR}"`
... ...
@@ -256,9 +261,10 @@ bootstrap_auto_create()
256 256
 
257 257
 auto_update_initialize()
258 258
 {
259
-    log_fluff ":auto_update_initialize:"
259
+   log_fluff ":auto_update_initialize:"
260 260
 
261
-  NON_MERGABLE_SETTINGS='embedded_repositories
261
+   NON_MERGABLE_SETTINGS='embedded_repositories
262
+version
262 263
 '
263 264
    [ -z "${MULLE_BOOTSTRAP_FUNCTIONS_SH}" ] && . mulle-bootstrap-functions.sh
264 265
 }
... ...
@@ -882,6 +882,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
882 882
 
883 883
 
884 884
       # cmake separator
885
+      [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
885 886
       IFS=";"
886 887
       for path in ${native_includelines}
887 888
       do
... ...
@@ -2185,7 +2186,7 @@ build_clones()
2185 2185
             then
2186 2186
                :
2187 2187
             else
2188
-               fail "unknown repo ${name}"
2188
+               fail "Unknown repo ${name}"
2189 2189
             fi
2190 2190
          fi
2191 2191
       done
... ...
@@ -2242,6 +2243,8 @@ build_main()
2242 2242
 
2243 2243
    [ -z "${MULLE_BOOTSTRAP_BUILD_ENVIRONMENT_SH}" ] && . mulle-bootstrap-build-environment.sh
2244 2244
 
2245
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
2246
+
2245 2247
    #
2246 2248
    # it is useful, that fetch understands build options and
2247 2249
    # ignores them
... ...
@@ -2277,17 +2280,13 @@ build_main()
2277 2277
             CONFIGURATIONS="`printf "%s" "$1" | tr ',' '\012'`"
2278 2278
             ;;
2279 2279
 
2280
-         # fetch options
2281
-         -cs|--check-usr-local-include|-nr|--no-recursion|-e|--embedded-only|-u|--update-symlinks)
2282
-            if [ -z "${MULLE_BOOTSTRAP_DID_FETCH}" ]
2283
-            then
2284
-               log_error "unknown option $1"
2285
-               ${USAGE}
2286
-            fi
2280
+         # fetch options, are just ignored
2281
+         -i|--ignore-branch|-fc|--force-checkout|-cs|--check-usr-local-include|-nr|--no-recursion|-e|--embedded-only|-u|--update-symlinks)
2282
+            :
2287 2283
          ;;
2288 2284
 
2289 2285
          -*)
2290
-            log_error "unknown option $1"
2286
+            log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown build option $1"
2291 2287
             build_usage
2292 2288
          ;;
2293 2289
 
... ...
@@ -51,11 +51,7 @@ ${ADDICTION_SUBDIR}
51 51
 .bootstrap.auto"`"
52 52
    EMBEDDED="`embedded_repository_directories_from_repos`"
53 53
 
54
-   if [ ! -z "$EMBEDDED" ]
55
-   then
56
-      DIST_CLEANABLE_SUBDIRS="${DIST_CLEANABLE_SUBDIRS}
57
-${EMBEDDED}"
58
-   fi
54
+   DIST_CLEANABLE_SUBDIRS="`add_line "${EMBEDDED}" "${DIST_CLEANABLE_SUBDIRS}"`"
59 55
 }
60 56
 
61 57
 
... ...
@@ -319,6 +315,8 @@ clean_main()
319 319
    [ -z "${MULLE_BOOTSTRAP_SETTINGS_SH}" ] && . mulle-bootstrap-settings.sh
320 320
    [ -z "${MULLE_BOOTSTRAP_REPOSITORIES_SH}" ] && . mulle-bootstrap-repositories.sh
321 321
 
322
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
323
+
322 324
    COMMAND=
323 325
 
324 326
    while [ $# -ne 0 ]
... ...
@@ -329,7 +327,7 @@ clean_main()
329 329
          ;;
330 330
 
331 331
          -*)
332
-            log_error "unknown option $1"
332
+            log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown clean option $1"
333 333
             COMMAND=help
334 334
          ;;
335 335
 
... ...
@@ -33,58 +33,6 @@
33 33
 MULLE_BOOTSTRAP_DEPENDENY_RESOLVE_SH="included"
34 34
 
35 35
 
36
-_dependency_resolve()
37
-{
38
-   local map
39
-   local name
40
-
41
-   map="$1"
42
-   name="$2"
43
-
44
-   if [ "$MULLE_BOOTSTRAP_TRACE_SETTINGS" = "YES" -o "$MULLE_BOOTSTRAP_TRACE_MERGE" = "YES"  ]
45
-   then
46
-      log_trace2 "resolve ${name}"
47
-   fi
48
-
49
-   local escaped_dependencies
50
-   local dependencies
51
-
52
-   escaped_dependencies="`assoc_array_get "${map}" "${name}"`"
53
-   dependencies="`unescape_linefeeds "${escaped_dependencies}"`"
54
-
55
-   UNRESOLVED_DEPENDENCIES="`array_add "${UNRESOLVED_DEPENDENCIES}" "${name}"`"
56
-
57
-   local sub_name
58
-   #local insert
59
-
60
-   #insert="`array_count "${RESOLVED_DEPENDENCIES}"`"
61
-
62
-   IFS="
63
-"
64
-   for sub_name in ${dependencies}
65
-   do
66
-      IFS="${DEFAULT_IFS}"
67
-
68
-      if array_contains "${RESOLVED_DEPENDENCIES}" "${sub_name}"
69
-      then
70
-         continue
71
-      fi
72
-
73
-      if array_contains "${UNRESOLVED_DEPENDENCIES}" "${sub_name}"
74
-      then
75
-         fail "circular dependency ${sub_name} and ${name}"
76
-      fi
77
-
78
-      _dependency_resolve "${map}" "${sub_name}"
79
-   done
80
-
81
-   IFS="${DEFAULT_IFS}"
82
-
83
-   UNRESOLVED_DEPENDENCIES="`array_remove "${UNRESOLVED_DEPENDENCIES}" "${name}"`"
84
-   RESOLVED_DEPENDENCIES="`array_add "${RESOLVED_DEPENDENCIES}" "${name}"`"
85
-}
86
-
87
-
88 36
 dependency_add()
89 37
 {
90 38
    local map
... ...
@@ -144,6 +92,58 @@ dependency_add_array()
144 144
 }
145 145
 
146 146
 
147
+_dependency_resolve()
148
+{
149
+   local map
150
+   local name
151
+
152
+   map="$1"
153
+   name="$2"
154
+
155
+   if [ "$MULLE_BOOTSTRAP_TRACE_SETTINGS" = "YES" -o "$MULLE_BOOTSTRAP_TRACE_MERGE" = "YES"  ]
156
+   then
157
+      log_trace2 "resolve ${name}"
158
+   fi
159
+
160
+   local escaped_dependencies
161
+   local dependencies
162
+
163
+   escaped_dependencies="`assoc_array_get "${map}" "${name}"`"
164
+   dependencies="`unescape_linefeeds "${escaped_dependencies}"`"
165
+
166
+   UNRESOLVED_DEPENDENCIES="`array_add "${UNRESOLVED_DEPENDENCIES}" "${name}"`"
167
+
168
+   local sub_name
169
+   #local insert
170
+
171
+   #insert="`array_count "${RESOLVED_DEPENDENCIES}"`"
172
+
173
+   IFS="
174
+"
175
+   for sub_name in ${dependencies}
176
+   do
177
+      IFS="${DEFAULT_IFS}"
178
+
179
+      if array_contains "${RESOLVED_DEPENDENCIES}" "${sub_name}"
180
+      then
181
+         continue
182
+      fi
183
+
184
+      if array_contains "${UNRESOLVED_DEPENDENCIES}" "${sub_name}"
185
+      then
186
+         fail "circular dependency ${sub_name} and ${name}"
187
+      fi
188
+
189
+      _dependency_resolve "${map}" "${sub_name}"
190
+   done
191
+
192
+   IFS="${DEFAULT_IFS}"
193
+
194
+   UNRESOLVED_DEPENDENCIES="`array_remove "${UNRESOLVED_DEPENDENCIES}" "${name}"`"
195
+   RESOLVED_DEPENDENCIES="`array_add "${RESOLVED_DEPENDENCIES}" "${name}"`"
196
+}
197
+
198
+
147 199
 dependency_resolve()
148 200
 {
149 201
    local map
... ...
@@ -47,6 +47,7 @@ usage:
47 47
    Options
48 48
       -cs   :  check /usr/local for duplicates
49 49
       -e    :  fetch embedded repositories only
50
+      -i    :  ignore wrongly checked out branches
50 51
       -nr   :  ignore .bootstrap folders of fetched repositories
51 52
       -u    :  try to update symlinked folders as well (not recommended)
52 53
 
... ...
@@ -74,6 +75,8 @@ install_taps()
74 74
 
75 75
    log_fluff "Looking for taps"
76 76
 
77
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
78
+
77 79
    taps=`read_fetch_setting "taps" | sort | sort -u`
78 80
    if [ "${taps}" != "" ]
79 81
    then
... ...
@@ -223,6 +226,7 @@ check_tars()
223 223
    tarballs="`read_fetch_setting "tarballs" | sort | sort -u`"
224 224
    if [ "${tarballs}" != "" ]
225 225
    then
226
+      [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
226 227
       IFS="
227 228
 "
228 229
       for tar in ${tarballs}
... ...
@@ -288,9 +292,10 @@ link_command()
288 288
          local name
289 289
 
290 290
          name="`basename -- "${dst}"`"
291
-         log_warning "tag ${tag} will be ignored, due to symlink" >&2
292
-         log_warning "if you want to checkout this tag do:" >&2
293
-         log_warning "${C_RESET}${C_BOLD}(cd .repos/${name}; git checkout ${GITFLAGS} \"${tag}\" )${C_WARNING}" >&2
291
+         log_warning "The intended tag ${C_RESET_BOLD}${tag}${C_WARNING} will be ignored, because"
292
+         log_warning "the repository is symlinked."
293
+         log_warning "If you want to checkout this tag do:"
294
+         log_warning "${C_RESET_BOLD}(cd .repos/${name}; git checkout ${GITOPTIONS} \"${tag}\" )${C_WARNING}"
294 295
       fi
295 296
    fi
296 297
 
... ...
@@ -465,7 +470,7 @@ checkout()
465 465
          ;;
466 466
 
467 467
       *)
468
-         fail "unknown scm system ${scm}"
468
+         fail "Unknown scm system ${scm}"
469 469
          ;;
470 470
    esac
471 471
 
... ...
@@ -540,16 +545,42 @@ checkout()
540 540
          ;;
541 541
       esac
542 542
 
543
-      local scmflags
543
+      local options
544 544
 
545
-      scmflags="`read_repo_setting "${name}" "checkout" "${scmflagsdefault}"`"
546
-      "${operation}" "${src}" "${dstdir}" "${branch}" "${tag}" "${scmflags}"
545
+      options="`read_repo_setting "${name}" "checkout" "${scmflagsdefault}"`"
546
+      "${operation}" "${src}" "${dstdir}" "${branch}" "${tag}" "${options}"
547 547
 
548 548
       warn_scripts_main "${dstdir}/.bootstrap" "${dstdir}" || fail "Ok, aborted"  #sic
549 549
    fi
550 550
 }
551 551
 
552 552
 
553
+ensure_clone_url_is_correct()
554
+{
555
+   local dstdir
556
+   local url
557
+
558
+   dstdir="$1"
559
+   url="$2"
560
+
561
+   local remote
562
+   local actual
563
+
564
+   remote="`git_get_default_remote "${dstdir}"`"
565
+   if [ -z "${remote}" ]
566
+   then
567
+      fail "Could not figure out a remote for \"${dstdir}\""
568
+   fi
569
+
570
+   actual="`git_get_url "${dstdir}" "${remote}"`"
571
+   if [ "${actual}" != "${url}" ]
572
+   then
573
+      log_verbose "URL change for $remote in \"${dstdir}\" from $actual to $url"
574
+      git_set_url "${dstdir}" "${remote}" "${url}"
575
+   fi
576
+}
577
+
578
+
553 579
 ensure_clone_branch_is_correct()
554 580
 {
555 581
    local dstdir
... ...
@@ -560,16 +591,25 @@ ensure_clone_branch_is_correct()
560 560
 
561 561
    local actual
562 562
 
563
-   if [ ! -z "${branch}" ]
563
+   if [ ! -z "${branch}" -a -z "${MULLE_BOOTSTRAP_IGNORE_BRANCH}" ]
564 564
    then
565 565
       actual="`git_get_branch "${dstdir}"`"
566 566
       if [ "${actual}" != "${branch}" ]
567 567
       then
568
-         fail "Repository \"${dstdir}\" checked-out branch is \"${actual}\".
568
+         if [ "${MULLE_BOOTSTRAP_DIRTY_HARRY}" = "NO" ] # abuse force flag
569
+         then
570
+            git_checkout_tag "${dstdir}" "${branch}"
571
+            actual="`git_get_branch "${dstdir}"`"
572
+         fi
573
+
574
+         if [ "${actual}" != "${branch}" ]
575
+         then
576
+            fail "Repository \"${dstdir}\" checked-out branch is \"${actual}\".
569 577
 But \"${branch}\" is specified.
570 578
 Suggested fix:
571 579
    mulle-bootstrap clean dist
572 580
    mulle-bootstrap"
581
+         fi
573 582
       fi
574 583
    fi
575 584
 }
... ...
@@ -622,6 +662,7 @@ checkout_repository()
622 622
 
623 623
    if [ -e "${dstdir}" ]
624 624
    then
625
+      ensure_clone_url_is_correct "${dstdir}" "${url}"
625 626
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
626 627
 
627 628
       log_fluff "Repository \"${dstdir}\" already exists"
... ...
@@ -630,6 +671,8 @@ checkout_repository()
630 630
       then
631 631
          log_info "Restoring ${name} from graveyard"
632 632
          exekutor mv "${CLONESFETCH_SUBDIR}/.graveyard/${name}" "${CLONESFETCH_SUBDIR}" || fail "move failed"
633
+
634
+         ensure_clone_url_is_correct "${dstdir}" "${url}"
633 635
          ensure_clone_branch_is_correct "${dstdir}" "${branch}"
634 636
       else
635 637
          checkout "$@"
... ...
@@ -728,6 +771,8 @@ clone_repositories()
728 728
    local scm
729 729
    local tag
730 730
 
731
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
732
+
731 733
    stop=0
732 734
    while [ $stop -eq 0 ]
733 735
    do
... ...
@@ -744,7 +789,7 @@ clone_repositories()
744 744
          do
745 745
             IFS="${DEFAULT_IFS}"
746 746
 
747
-            clone="`expanded_setting "${clone}"`"
747
+            clone="`expanded_variables "${clone}"`"
748 748
 
749 749
             # avoid superflous updates
750 750
             match="`echo "${fetched}" | grep -x "${clone}"`"
... ...
@@ -764,6 +809,7 @@ ${clone}"
764 764
                fi
765 765
             fi
766 766
          done
767
+
767 768
          IFS="${DEFAULT_IFS}"
768 769
 
769 770
       fi
... ...
@@ -820,7 +866,7 @@ update()
820 820
          operation="svn_update"
821 821
          ;;
822 822
       *)
823
-         fail "unknown scm system ${scm}"
823
+         fail "Unknown scm system ${scm}"
824 824
          ;;
825 825
    esac
826 826
 
... ...
@@ -850,6 +896,7 @@ update()
850 850
       fetch__run_repo_settings_script "${name}" "${dstdir}" "post-update" "$@"
851 851
    else
852 852
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
853
+
853 854
       log_info "Repository ${C_MAGENTA}${C_BOLD}${name}${C_INFO} exists and is symlinked, so not updated."
854 855
 
855 856
       rval=1
... ...
@@ -913,6 +960,7 @@ update_repository()
913 913
       fi
914 914
    fi
915 915
 
916
+   ensure_clone_url_is_correct "${dstdir}" "${url}"
916 917
    ensure_clone_branch_is_correct "${dstdir}" "${branch}"
917 918
    [ $rval -eq 0 -o $rval -eq 2 ]
918 919
    return $?
... ...
@@ -952,11 +1000,13 @@ update_repositories()
952 952
 
953 953
    if [ $# -ne 0 ]
954 954
    then
955
+      [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
955 956
       IFS="
956 957
 "
957 958
       for name in "$@"
958 959
       do
959 960
          IFS="${DEFAULT_IFS}"
961
+
960 962
          create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
961 963
             update_repository "${name}" "${CLONESFETCH_SUBDIR}/${name}"
962 964
          remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
... ...
@@ -967,6 +1017,7 @@ update_repositories()
967 967
       for name in "$@"
968 968
       do
969 969
          IFS="${DEFAULT_IFS}"
970
+
970 971
          create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
971 972
             did_update_repository "${name}" "${CLONESFETCH_SUBDIR}/${name}"
972 973
          remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
... ...
@@ -989,6 +1040,7 @@ update_repositories()
989 989
    local updated
990 990
 
991 991
    updated=""
992
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
992 993
 
993 994
    stop=0
994 995
    while [ $stop -eq 0 ]
... ...
@@ -1006,7 +1058,7 @@ update_repositories()
1006 1006
          do
1007 1007
             IFS="${DEFAULT_IFS}"
1008 1008
 
1009
-            clone="`expanded_setting "${clone}"`"
1009
+            clone="`expanded_variables "${clone}"`"
1010 1010
 
1011 1011
             # avoid superflous updates
1012 1012
             match="`echo "${updated}" | grep -x "${clone}"`"
... ...
@@ -1188,6 +1240,8 @@ clone_embedded_repository()
1188 1188
          esac
1189 1189
 
1190 1190
          exekutor mv "${CLONESFETCH_SUBDIR}/.embedded/.graveyard/${name}" "${dstdir}" || fail "move failed"
1191
+
1192
+         ensure_clone_url_is_correct "${dstdir}" "${url}"
1191 1193
          ensure_clone_branch_is_correct "${dstdir}" "${branch}"
1192 1194
       else
1193 1195
          #
... ...
@@ -1213,6 +1267,7 @@ clone_embedded_repository()
1213 1213
       fi
1214 1214
 
1215 1215
    else
1216
+      ensure_clone_url_is_correct "${dstdir}" "${url}"
1216 1217
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
1217 1218
 
1218 1219
       log_fluff "Repository \"${dstdir}\" already exists"
... ...
@@ -1237,6 +1292,7 @@ clone_embedded_repositories()
1237 1237
    local clone
1238 1238
 
1239 1239
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="YES"
1240
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
1240 1241
 
1241 1242
    clones="`read_fetch_setting "embedded_repositories"`"
1242 1243
    if [ ! -z "${clones}" ]
... ...
@@ -1278,6 +1334,7 @@ update_embedded_repositories()
1278 1278
    local dstdir
1279 1279
 
1280 1280
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="YES"
1281
+   [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
1281 1282
 
1282 1283
    clones="`read_fetch_setting "embedded_repositories"`"
1283 1284
    clones="`echo "${clones}" | sed '1!G;h;$!d'`"  # reverse lines
... ...
@@ -1339,6 +1396,10 @@ _common_main()
1339 1339
             EMBEDDED_ONLY="YES"
1340 1340
          ;;
1341 1341
 
1342
+         -i|--ignore-branch)
1343
+            MULLE_BOOTSTRAP_IGNORE_BRANCH="YES"
1344
+         ;;
1345
+
1342 1346
          -u|--update-symlinks)
1343 1347
             MULLE_BOOTSTRAP_UPDATE_SYMLINKS="YES"
1344 1348
          ;;
... ...
@@ -1347,7 +1408,7 @@ _common_main()
1347 1347
          -K|--clean|-k|--no-clean)
1348 1348
             if [ -z "${MULLE_BOOTSTRAP_WILL_BUILD}" ]
1349 1349
             then
1350
-               log_error "unknown option $1"
1350
+               log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown fetch option $1"
1351 1351
                ${USAGE}
1352 1352
             fi
1353 1353
          ;;
... ...
@@ -1356,20 +1417,20 @@ _common_main()
1356 1356
          -j|--cores|-c|--configuration)
1357 1357
             if [ -z "${MULLE_BOOTSTRAP_WILL_BUILD}" ]
1358 1358
             then
1359
-               log_error "unknown option $1"
1359
+               log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown fetch option $1"
1360 1360
                ${USAGE}
1361 1361
             fi
1362 1362
 
1363 1363
             if [ $# -eq 1 ]
1364 1364
             then
1365
-               log_error "missing parameter to option $1"
1365
+               log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Missing parameter to fetch option $1"
1366 1366
                ${USAGE}
1367 1367
             fi
1368 1368
             shift
1369 1369
          ;;
1370 1370
 
1371 1371
          -*)
1372
-            log_error "unknown option $1"
1372
+            log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown fetch option $1"
1373 1373
             ${USAGE}
1374 1374
          ;;
1375 1375
 
... ...
@@ -201,28 +201,6 @@ is_yes()
201 201
 }
202 202
 
203 203
 
204
-concat()
205
-{
206
-   local i
207
-   local s
208
-
209
-   for i in "$@"
210
-   do
211
-      if [ "${i}" != "" ]
212
-      then
213
-         if [ "${s}" != "" ]
214
-         then
215
-            s="${s} ${i}"
216
-         else
217
-            s="${i}"
218
-         fi
219
-      fi
220
-   done
221
-
222
-   echo "${s}"
223
-}
224
-
225
-
226 204
 add_cmake_path()
227 205
 {
228 206
    local line
... ...
@@ -277,7 +255,6 @@ add_line()
277 277
    then
278 278
       echo "${line}"
279 279
    else
280
-
281 280
       echo "${lines}
282 281
 ${line}"
283 282
    fi
... ...
@@ -1101,8 +1078,6 @@ write_protect_directory()
1101 1101
 # ####################################################################
1102 1102
 functions_initialize()
1103 1103
 {
1104
-   DEFAULT_IFS="${IFS}"
1105
-
1106 1104
    [ -z "${MULLE_BOOTSTRAP_LOGGING_SH}" ] && . mulle-bootstrap-logging.sh
1107 1105
    [ -z "${MULLE_BOOTSTRAP_ARRAY_SH}" ] && . mulle-bootstrap-array.sh
1108 1106
 
... ...
@@ -78,7 +78,7 @@ init_main()
78 78
          ;;
79 79
 
80 80
          -*)
81
-            log_error "unknown option $1"
81
+            log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown init option $1"
82 82
             ${USAGE}
83 83
 
84 84
          ;;
... ...
@@ -114,6 +114,11 @@ init_main()
114 114
    log_fluff "Create \"${BOOTSTRAP_SUBDIR}\""
115 115
    mkdir_if_missing "${BOOTSTRAP_SUBDIR}"
116 116
 
117
+   redirect_exekutor "${BOOTSTRAP_SUBDIR}/version" cat <<EOF
118
+# required mulle-bootstrap version
119
+${MULLE_BOOTSTRAP_VERSION_MAJOR}.0.0
120
+EOF
121
+
117 122
    if [ "${CREATE_DEFAULT_FILES}" = "YES" ]
118 123
    then
119 124
       log_fluff "Create default files"
... ...
@@ -31,7 +31,6 @@
31 31
 #
32 32
 MULLE_BOOTSTRAP_LOCAL_ENVIRONMENT_SH="included"
33 33
 
34
-
35 34
 # returns 0 if said yes
36 35
 user_say_yes()
37 36
 {
... ...
@@ -162,8 +161,218 @@ refresh_needed()
162 162
 }
163 163
 
164 164
 
165
+#
166
+# version must be <= min_major.min_minor
167
+#
168
+check_version()
169
+{
170
+   local version
171
+   local min_major
172
+   local min_minor
173
+
174
+   version="$1"
175
+   min_major="$2"
176
+   min_minor="$3"
177
+
178
+   local major
179
+   local minor
180
+
181
+   if [ -z "${version}" ]
182
+   then
183
+      return 0
184
+   fi
185
+
186
+   major="`echo "${version}" | head -1 | cut -d. -f1`"
187
+   if [ "${major}" -lt "${min_major}" ]
188
+   then
189
+      return 0
190
+   fi
191
+
192
+   if [ "${major}" -ne "${min_major}" ]
193
+   then
194
+      return 1
195
+   fi
196
+
197
+   minor="`echo "${version}" | head -1 | cut -d. -f2`"
198
+   [ "${minor}" -le "${min_minor}" ]
199
+}
200
+
201
+
202
+assert_mulle_bootstrap_version()
203
+{
204
+   local version
205
+
206
+   # has to be read before .auto is setup
207
+   version="`_read_setting "${BOOTSTRAP_SUBDIR}/version"`"
208
+   if check_version "$version" "${MULLE_BOOTSTRAP_VERSION_MAJOR}" "${MULLE_BOOTSTRAP_VERSION_MINOR}"
209
+   then
210
+      return
211
+   fi
212
+
213
+   fail "This ${BOOTSTRAP_SUBDIR} requires mulle-bootstrap version ${version} at least, you have ${MULLE_BOOTSTRAP_VERSION}"
214
+}
215
+
216
+
217
+#
218
+# expands ${setting} and ${setting:-foo}
219
+#
220
+_expanded_variables()
221
+{
222
+   local string
223
+
224
+   string="$1"
225
+
226
+   local key
227
+   local value
228
+   local prefix
229
+   local suffix
230
+   local next
231
+   local default
232
+   local tmp
233
+
234
+
235
+   key="`echo "${string}" | sed -n 's/^\(.*\)\${\([A-Za-z_][A-Za-z0-9_:-]*\)}\(.*\)$/\2/p'`"
236
+   if [ -z "${key}" ]
237
+   then
238
+      echo "$1"
239
+      return
240
+   fi
241
+
242
+   prefix="`echo "${string}" | sed 's/^\(.*\)\${\([A-Za-z_][A-Za-z0-9_:-]*\)}\(.*\)$/\1/'`"
243
+   suffix="`echo "${string}" | sed 's/^\(.*\)\${\([A-Za-z_][A-Za-z0-9_:-]*\)}\(.*\)$/\3/'`"
244
+
245
+   tmp="`echo "${key}" | sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)[:][-]\(.*\)$/\1/p'`"
246
+   if [ ! -z "${tmp}" ]
247
+   then
248
+      default="`echo "${key}" | sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)[:][-]\(.*\)$/\2/p'`"
249
+      key="${tmp}"
250
+   fi
251
+
252
+   value="`read_fetch_setting "${key}" "${default}"`"
253
+   next="${prefix}${value}${suffix}"
254
+   if [ "${next}" = "${string}" ]
255
+   then
256
+      fail "${string} expands to itself"
257
+   fi
258
+
259
+   _expanded_variables "${next}"
260
+}
261
+
262
+
263
+expanded_variables()
264
+{
265
+   local memo
266
+   local value
267
+
268
+   # a hack ?
269
+
270
+   memo="${MULLE_BOOTSTRAP_SETTINGS_NO_AUTO}"
271
+   MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="NO"
272
+
273
+   value="`_expanded_variables "$1"`"
274
+
275
+   MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="${memo}"
276
+
277
+   if [ "$1" != "${value}" ]
278
+   then
279
+      log_fluff "Expanded \"$1\" to \"${value}\""
280
+   fi
281
+
282
+   echo "$value"
283
+}
284
+
285
+
286
+source_environment_file()
287
+{
288
+   local filename
289
+
290
+   filename="$1"
291
+   if [ ! -r "${filename}" ]
292
+   then
293
+      log_fluff "Environment file ${filename} not found"
294
+      return 1
295
+   fi
296
+
297
+   local lines
298
+   local line
299
+   local key
300
+   local value
301
+
302
+   log_fluff "Environment file ${filename} exists"
303
+
304
+   lines="`egrep -s -v '^#|^[ ]*$' "${filename}"`"
305
+   IFS="
306
+"
307
+   for line in $lines
308
+   do
309
+      IFS="${DEFAULT_IFS}"
310
+
311
+      key="`echo "${line}" | cut -d= -f1`"
312
+      value="`echo "${line}" | cut -d= -f2`"
313
+
314
+      value="`expanded_variables "${value}"`"
315
+      case "${key}" in
316
+         *\`*|*\$*|*\!*)
317
+            fail "Illegal characters in $key of $filename"
318
+         ;;
319
+      esac
320
+      case "${value}" in
321
+         *\`*|*\$*|*\!*)
322
+            fail "Illegal characters in $value of $filename"
323
+         ;;
324
+      esac
325
+      log_verbose "Environment variable $key defined as $value"
326
+
327
+      eval "${key}=${value}; export ${key}"
328
+   done
329
+
330
+   IFS="${DEFAULT_IFS}"
331
+
332
+   return 0
333
+}
334
+
335
+
336
+#
337
+# source environment
338
+#
339
+source_environment()
340
+{
341
+   local flag
342
+
343
+   flag=""
344
+
345
+   if source_environment_file "${HOME}/.mulle-bootstrap/environment"
346
+   then
347
+      flag="${MULLE_BOOTSTRAP_FLUFF}"
348
+   fi
349
+
350
+   if source_environment_file "${BOOTSTRAP_SUBDIR}.auto/environment"
351
+   then
352
+      flag="${MULLE_BOOTSTRAP_FLUFF}"
353
+   else
354
+      if source_environment_file "${BOOTSTRAP_SUBDIR}.local/environment"
355
+      then
356
+         flag="${MULLE_BOOTSTRAP_FLUFF}"
357
+      else
358
+         if source_environment_file "${BOOTSTRAP_SUBDIR}/environment"
359
+         then
360
+            flag="${MULLE_BOOTSTRAP_FLUFF}"
361
+         fi
362
+      fi
363
+   fi
364
+
365
+   if [ "${flag}" = "YES" ]
366
+   then
367
+      log_fluff "Environment:"
368
+      env >&2
369
+   fi
370
+}
371
+
372
+
165 373
 local_environment_initialize()
166 374
 {
375
+   [ -z "${MULLE_BOOTSTRAP_LOGGING_SH}" ] && . mulle-bootstrap-logging.sh
376
+
167 377
    #
168 378
    # read local environment
169 379
    # source this file
... ...
@@ -210,4 +419,12 @@ local_environment_initialize()
210 210
    esac
211 211
 }
212 212
 
213
+
214
+local_environment_main()
215
+{
216
+#  don't do it, so far it's been overkill
217
+#   source_environment
218
+   :
219
+}
220
+
213 221
 local_environment_initialize
... ...
@@ -108,7 +108,7 @@ log_trace2()
108 108
 #
109 109
 fail()
110 110
 {
111
-   log_error "$@"
111
+   log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}:" "$@"
112 112
    if [ ! -z "${MULLE_BOOTSTRAP_PID}" ]
113 113
    then
114 114
       kill -INT "${MULLE_BOOTSTRAP_PID}"  # kill myself (especially, if executing in subshell)
... ...
@@ -128,9 +128,40 @@ internal_fail()
128 128
 }
129 129
 
130 130
 
131
+#
132
+# here because often needed :-/
133
+#
134
+concat()
135
+{
136
+   local i
137
+   local s
138
+
139
+   for i in "$@"
140
+   do
141
+      if [ -z "${i}" ]
142
+      then
143
+         continue
144
+      fi
145
+
146
+      if [ -z "${s}" ]
147
+      then
148
+         s="${i}"
149
+      else
150
+         s="${s} ${i}"
151
+      fi
152
+   done
153
+
154
+   echo "${s}"
155
+}
156
+
157
+
158
+
159
+
131 160
 # Escape sequence and resets, should use tput here instead of ANSI
132 161
 logging_initialize()
133 162
 {
163
+   DEFAULT_IFS="${IFS}" # as early as possible
164
+
134 165
    #
135 166
    # need this for scripts also
136 167
    #
... ...
@@ -54,12 +54,12 @@ refresh_repositories_settings()
54 54
 {
55 55
    local stop
56 56
    local clones
57
-   local clone
58 57
    local stop
59 58
    local refreshed
60 59
    local match
61 60
    local dependency_map
62
-
61
+   local unexpanded
62
+   local unexpanded_url
63 63
 
64 64
    refreshed=""
65 65
    dependency_map=""
... ...
@@ -74,22 +74,20 @@ refresh_repositories_settings()
74 74
       then
75 75
          IFS="
76 76
 "
77
-         for clone in ${clones}
77
+         for unexpanded in ${clones}
78 78
          do
79 79
             IFS="${DEFAULT_IFS}"
80 80
 
81
-            clone="`expanded_setting "${clone}"`"
82
-            # avoid superflous updates
83
-            match="`echo "${refreshed}" | grep -x "${clone}"`"
84
-            # could remove prefixes here https:// http://
85
-
86
-            if [ "${match}" = "${clone}" ]
81
+            match="`echo "${refreshed}" | fgrep -s -x "${unexpanded}"`"
82
+            if [ ! -z "${match}" ]
87 83
             then
88 84
                continue
89 85
             fi
90 86
 
91 87
             refreshed="${refreshed}
92
-${clone}"
88
+${unexpanded}"
89
+
90
+            # avoid superflous updates
93 91
 
94 92
             local branch
95 93
             local dstdir
... ...
@@ -97,7 +95,9 @@ ${clone}"
97 97
             local scm
98 98
             local tag
99 99
             local url
100
+            local clone
100 101
 
102
+            clone="`expanded_variables "${unexpanded}"`"
101 103
             __parse_expanded_clone "${clone}"
102 104
 
103 105
             dstdir="${CLONESFETCH_SUBDIR}/${name}"
... ...
@@ -120,11 +120,12 @@ ${clone}"
120 120
                sub_repos="`_read_setting "${filename}"`"
121 121
                if [ ! -z "${sub_repos}" ]
122 122
                then
123
-                  dependency_map="`dependency_add "${dependency_map}" "__ROOT__" "${url}"`"
124
-                  dependency_map="`dependency_add_array "${dependency_map}" "${url}" "${sub_repos}"`"
123
+#                  unexpanded_url="`url_from_clone "${unexpanded}"`"
124
+                  dependency_map="`dependency_add "${dependency_map}" "__ROOT__" "${unexpanded}"`"
125
+                  dependency_map="`dependency_add_array "${dependency_map}" "${unexpanded}" "${sub_repos}"`"
125 126
                   if [ "$MULLE_BOOTSTRAP_TRACE_SETTINGS" = "YES" -o "$MULLE_BOOTSTRAP_TRACE_MERGE" = "YES"  ]
126 127
                   then
127
-                     log_trace2 "add \"${sub_repos}\" for ${url} to ${dependency_map}"
128
+                     log_trace2 "add \"${sub_repos}\" for ${unexpanded} to ${dependency_map}"
128 129
                   fi
129 130
                fi
130 131
             else
... ...
@@ -326,7 +326,7 @@ __parse_clone()
326 326
 {
327 327
    local clone
328 328
 
329
-   clone="`expanded_setting "${1}"`"
329
+   clone="`expanded_variables "${1}"`"
330 330
 
331 331
    __parse_expanded_clone "${clone}"
332 332
 }
... ...
@@ -347,7 +347,7 @@ __parse_embedded_clone()
347 347
 {
348 348
    local clone
349 349
 
350
-   clone="`expanded_setting "${1}"`"
350
+   clone="`expanded_variables "${1}"`"
351 351
 
352 352
    __parse_expanded_clone "${clone}"
353 353
 
... ...
@@ -41,6 +41,73 @@ git_is_bare_repository()
41 41
 }
42 42
 
43 43
 
44
+git_get_url()
45
+{
46
+   local remote
47
+   remote="$2"
48
+
49
+   ( cd "$1" ; git remote get-url "${remote}" )
50
+}
51
+
52
+
53
+git_set_url()
54
+{
55
+   local remote
56
+   local url
57
+
58
+   remote="$2"
59
+   url="$3"
60
+
61
+   (
62
+      cd "$1" ;
63
+      git remote set-url "${remote}" "${url}" ;
64
+      git fetch "${remote}" # prefetch to get new branches
65
+   )
66
+}
67
+
68
+
69
+#
70
+# prefer origin over others, probably could be smarter
71
+# by passing in the desired branch and figuring more
72
+# stuff out
73
+#
74
+git_get_default_remote()
75
+{
76
+   local i
77
+   local match
78
+
79
+   match=""
80
+   IFS="
81
+"
82
+   for i in `( cd "$1" ; git remote)`
83
+   do
84
+      case "$i" in
85
+         origin)
86
+            match="$i"
87
+            break
88
+         ;;
89
+
90
+         *)
91
+            if [ -z "${match}" ]
92
+            then
93
+               match="$i"
94
+            fi
95
+         ;;
96
+      esac
97
+   done
98
+
99
+   IFS="${DEFAULT_IFS}"
100
+
101
+   echo "$match"
102
+}
103
+
104
+
105
+git_has_branch()
106
+{
107
+   ( cd "$1" ; git branch | cut -c3- | fgrep -q -s -x "$2" > /dev/null )
108
+}
109
+
110
+
44 111
 git_get_branch()
45 112
 {
46 113
    ( cd "$1" ; git rev-parse --abbrev-ref HEAD 2> /dev/null )
... ...
@@ -55,13 +122,16 @@ git_checkout_tag()
55 55
    dst="$1"
56 56
    tag="$2"
57 57
 
58
-   local flags
58
+   [ -z "${dst}" ] && internal_fail "dst is empty"
59
+   [ -z "${tag}" ] && internal_fail "tag is empty"
60
+
61
+   local options
59 62
 
60 63
    # checkout don't know -v
61
-   flags="${GITFLAGS}"
62
-   if [ "${flags}" = "-v" ]
64
+   options="${GITOPTIONS}"
65
+   if [ "${options}" = "-v" ]
63 66
    then
64
-      flags=""
67
+      options=""
65 68
    fi
66 69
 
67 70
    local branch
... ...
@@ -71,13 +141,12 @@ git_checkout_tag()
71 71
    if [ "${branch}" != "${tag}" ]
72 72
    then
73 73
       log_info "Checking out version ${C_WHITE}${C_BOLD}${tag}${C_INFO} of ${C_MAGENTA}${C_BOLD}${dst}${C_INFO} ..."
74
-      ( exekutor cd "${dst}" ; exekutor git checkout ${flags} "${tag}" )
74
+      ( exekutor cd "${dst}" ; exekutor git ${GITFLAGS} checkout ${options} "${tag}" )
75 75
 
76 76
       if [ $? -ne 0 ]
77 77
       then
78 78
          log_error "Checkout failed, moving ${C_CYAN}${C_BOLD}${dst}${C_ERROR} to ${C_CYAN}${C_BOLD}${dst}.failed${C_ERROR}"
79 79
          log_error "You need to fix this manually and then move it back."
80
-         log_info "Hint: check ${BOOTSTRAP_SUBDIR}/`basename -- "${dst}"`/TAG" >&2
81 80
 
82 81
          rmdir_safer "${dst}.failed"
83 82
          exekutor mv "${dst}" "${dst}.failed"
... ...
@@ -95,28 +164,29 @@ git_clone()
95 95
    local dst
96 96
    local branch
97 97
    local tag
98
-   local flags
98
+   local options
99 99
 
100 100
    src="$1"
101 101
    dst="$2"
102 102
    branch="$3"
103 103
    tag="$4"
104
-   flags="$5"
104
+   options="$5"
105 105
 
106 106
    [ ! -z "${src}" ] || internal_fail "src is empty"
107 107
    [ ! -z "${dst}" ] || internal_fail "dst is empty"
108
+   [ -z "${DEFAULT_IFS}" ] && internal_internal_fail "IFS fail"
108 109
 
109 110
    if [ ! -z "${branch}" ]
110 111
    then
111 112
       log_info "Cloning branch ${C_RESET_BOLD}$branch${C_INFO} of ${C_MAGENTA}${C_BOLD}${src}${C_INFO} ..."
112
-      flags="${flags} -b ${branch}"
113
+      options="`concat "${options}" "-b ${branch}"`"
113 114
    else
114 115
       log_info "Cloning ${C_MAGENTA}${C_BOLD}${src}${C_INFO} ..."
115 116
    fi
116 117
 
117
-   exekutor git clone ${flags} ${GITFLAGS} "${src}" "${dst}" || fail "git clone of \"${src}\" into \"${dst}\" failed"
118
+   exekutor git ${GITFLAGS} clone ${options} ${GITOPTIONS} -- "${src}" "${dst}" || fail "git clone of \"${src}\" into \"${dst}\" failed"
118 119
 
119
-   if [ "${tag}" != "" ]
120
+   if [ ! -z "${tag}" ]
120 121
    then
121 122
       git_checkout_tag "${dst}" "${tag}"
122 123
    fi
... ...
@@ -128,20 +198,20 @@ git_pull()
128 128
    local dst
129 129
    local branch
130 130
    local tag
131
-   local flags
131
+   local options
132 132
 
133 133
    dst="$1"
134 134
    branch="$2"
135 135
    tag="$3"
136
-   tag="$4"
136
+   options="$4"
137 137
 
138 138
    [ ! -z "$dst" ] || internal_fail "dst is empty"
139 139