Browse code

Unprotect directories before trying to erase them. Fix y/n answering. Allow autoanswer with -a. Automatically update .gitignore with stuff I want ignored. Redirect build output into logfiles, since the cruft is annoying now.

Nat! authored on 13-10-2015 12:22:36
Showing 11 changed files
... ...
@@ -4,3 +4,4 @@ build/
4 4
 .repos/
5 5
 .bootstrap.auto/
6 6
 dependencies/
7
+.bootstrap.local/
... ...
@@ -114,6 +114,10 @@ mkdir -p  ".bootstrap/settings" 2> /dev/null
114 114
 cp myconfig.xcconfig > .bootstrap/settings/xcconfig
115 115
 ```
116 116
 
117
+### I changed something in .bootstrap but it nothing happens ?
118
+
119
+This can happen, when you  a .bootstrap.auto was created. The easy solution
120
+is to say `mulle-bootstrap clean dist`.
117 121
 
118 122
 ### My Xcode project's headers do not show up ?
119 123
 
... ...
@@ -153,3 +157,5 @@ MULLE_BOOTSTRAP_TRACE_SETTINGS        | traces settings accesses
153 157
 
154 158
 
155 159
 
160
+
161
+
... ...
@@ -1,3 +1,15 @@
1
+0.8
2
+===
3
+   Added dist shortcut, because I always like to type "dist-clean".
4
+   Allow upper-case user input for yes/no questions.
5
+   Write protect dependencies folder, because I have a tendency to edit
6
+   the headers.
7
+   Automatically append boring directories to .gitignore after fetch.
8
+   Inverted script default answer, because it pains me. Also it's not
9
+   useful when using -a to just "breeze" through.
10
+   Redirect build logs to "build/.repos/.logs", because especially
11
+   xcodebuild is just too verbose.
12
+
1 13
 0.7.1
2 14
 ===
3 15
    Fixed an internal error, when using mulle-bootstrap update.
... ...
@@ -29,7 +29,7 @@
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 31
 
32
-VERSION=0.7.1
32
+VERSION=0.8
33 33
 
34 34
 #
35 35
 # This is the main user interface to mulle-bootstrap
... ...
@@ -43,9 +43,16 @@ export PATH
43 43
 #
44 44
 # simple option handling
45 45
 #
46
+if [ "$1" = "-a" ] # silent
47
+then
48
+   MULLE_BOOTSTRAP_ANSWER="NO"
49
+   export MULLE_BOOTSTRAP_ANSWER
50
+   shift
51
+fi
52
+
46 53
 if [ "$1" = "-n" ]
47 54
 then
48
-   MULLE_BOOTSTRAP_DRY_RUN=YES
55
+   MULLE_BOOTSTRAP_DRY_RUN="YES"
49 56
    export MULLE_BOOTSTRAP_DRY_RUN
50 57
    shift
51 58
 fi
... ...
@@ -54,7 +61,7 @@ if [ "$1" = "-v" ]
54 61
 then
55 62
    if [ -z "${MULLE_BOOTSTRAP_TRACE}" ]
56 63
    then
57
-      MULLE_BOOTSTRAP_TRACE=VERBOSE
64
+      MULLE_BOOTSTRAP_TRACE="VERBOSE"
58 65
       export MULLE_BOOTSTRAP_TRACE
59 66
    fi
60 67
    GITFLAGS="-v"
... ...
@@ -65,7 +72,7 @@ else
65 72
    then
66 73
       if [ -z "${MULLE_BOOTSTRAP_TRACE}" ]
67 74
       then
68
-         MULLE_BOOTSTRAP_TRACE=ALL
75
+         MULLE_BOOTSTRAP_TRACE="ALL"
69 76
          export MULLE_BOOTSTRAP_TRACE
70 77
       fi
71 78
       GITFLAGS="-v"
... ...
@@ -75,7 +82,7 @@ else
75 82
       if [ "$1" = "-s" ] # silent
76 83
       then
77 84
          MULLE_BOOTSTRAP_TRACE=
78
-         MULLE_BOOTSTRAP_TERSE=YES
85
+         MULLE_BOOTSTRAP_TERSE="YES"
79 86
          export MULLE_BOOTSTRAP_TERSE
80 87
          GITFLAGS="-q"
81 88
          export GITFLAGS
... ...
@@ -88,12 +95,13 @@ fi
88 95
 usage()
89 96
 {
90 97
    cat <<EOF
91
-usage: mulle-bootstrap [-n][-v|-s] [command] [--help]
98
+usage: mulle-bootstrap [-n][-v|-s][-a] [command] [--help]
92 99
        version ${VERSION}
93 100
 
94 101
  Specify the -h or --help option after each command to get more help.
95 102
 
96 103
  Flags (-n must be first, if present)
104
+   -a        : always chose default answer to questions
97 105
    -n        : do nothing creative or destructive
98 106
    -v        : be more verbose (-V even more verbose)
99 107
    -s        : be more terse
... ...
@@ -148,7 +156,7 @@ bootstrap()
148 156
       . install.sh "$@"
149 157
       export MULLE_BOOTSTRAP=mulle-bootstrap
150 158
    else
151
-      warn_scripts "${BOOTSTRAP_SUBDIR}"  || exit 1
159
+      warn_scripts "${BOOTSTRAP_SUBDIR}"  || fail "Ok, aborted."
152 160
    fi
153 161
 
154 162
    if [ "${DONT_RECURSE}" = "" ]
... ...
@@ -187,6 +195,10 @@ main()
187 195
          mulle-bootstrap-clean.sh "$@" || exit 1
188 196
          ;;
189 197
 
198
+      dist-clean)
199
+         mulle-bootstrap-clean.sh "dist"  || exit 1
200
+         ;;
201
+
190 202
       fetch)
191 203
          mulle-bootstrap-fetch.sh "$@" || exit 1
192 204
          ;;
... ...
@@ -91,9 +91,10 @@ dispense_headers()
91 91
          exekutor find -x "${src}" ! -path "${src}" -depth 1 \( -type f -o -type l \) -print0 | \
92 92
             exekutor xargs -0 -J % mv -v -n % "${dst}"
93 93
          [ $? -eq 0 ]  || exit 1
94
+
94 95
          rmdir_safer "${src}"
95 96
       else
96
-         log_fluff "But threre are none"
97
+         log_fluff "But there are none"
97 98
       fi
98 99
    else
99 100
       log_fluff "But it doesn't exist"
... ...
@@ -344,6 +345,17 @@ create_dummy_dirs_against_warnings()
344 345
 }
345 346
 
346 347
 
348
+
349
+build_fail()
350
+{
351
+   printf "${C_RED}"
352
+   grep -A5 "error:" "${1}" >&2
353
+   printf "${C_RESET}"
354
+
355
+   fail "$2 failed"
356
+}
357
+
358
+
347 359
 #
348 360
 # remove old builddir, create a new one
349 361
 # depending on configuration cmake with flags
... ...
@@ -387,6 +399,13 @@ ${C_MAGENTA}${name}${C_INFO} for SDK ${C_MAGENTA}${sdk}${C_INFO} ..."
387 399
 
388 400
    create_dummy_dirs_against_warnings "${builddir}" "${configuration}" "${suffix}" "${relative}"
389 401
 
402
+   local logfile
403
+
404
+   mkdir_if_missing "${BUILDLOG_SUBDIR}"
405
+   logfile="${BUILDLOG_SUBDIR}/${name}"
406
+
407
+   log_info "Logs in \"${logfile}.cmake\" and \"${logfile}.make\""
408
+
390 409
    owd="${PWD}"
391 410
    mkdir_if_missing "${builddir}"
392 411
    exekutor cd "${builddir}" || fail "failed to enter ${builddir}"
... ...
@@ -396,6 +415,8 @@ ${C_MAGENTA}${name}${C_INFO} for SDK ${C_MAGENTA}${sdk}${C_INFO} ..."
396 415
       #
397 416
       set -f
398 417
 
418
+      logfile="${owd}/${logfile}"
419
+
399 420
       exekutor cmake "-DCMAKE_BUILD_TYPE=${mapped}" \
400 421
 "-DCMAKE_INSTALL_PREFIX:PATH=${owd}/${BUILD_DEPENDENCY_SUBDIR}/usr/local"  \
401 422
 "-DCMAKE_C_FLAGS=\
... ...
@@ -421,9 +442,9 @@ ${sdk}" \
421 442
 -F${relative}/${REFERENCE_DEPENDENCY_SUBDIR}/${FRAMEWORK_DIR_NAME} \
422 443
 ${other_ldflags} \
423 444
 ${sdk}" \
424
-"${relative}/${srcdir}" 1>&2  || fail "cmake failed for ${srcdir}" 1
445
+"${relative}/${srcdir}" > "${logfile}.cmake" || build_fail "${logfile}.cmake" "cmake"
425 446
 
426
-      exekutor make all install 1>&2 || fail "make install failed for ${srcdir}" 1
447
+      exekutor make all install > "${logfile}.make" || build_fail "${logfile}.make" "make"
427 448
 
428 449
       set +f
429 450
 
... ...
@@ -477,12 +498,21 @@ ${C_MAGENTA}${name}${C_INFO} for SDK ${C_MAGENTA}${sdk}${C_INFO} ..."
477 498
 
478 499
    create_dummy_dirs_against_warnings "${builddir}" "${configuration}" "${suffix}" "${relative}"
479 500
 
501
+   local logfile
502
+
503
+   mkdir_if_missing "${BUILDLOG_SUBDIR}"
504
+   logfile="${BUILDLOG_SUBDIR}/${name}"
505
+
506
+   log_info "Logs in \"${logfile}.configure\" and \"${logfile}.make\""
507
+
480 508
    owd="${PWD}"
481 509
    mkdir_if_missing "${builddir}"
482 510
    exekutor cd "${builddir}" || fail "failed to enter ${builddir}"
483 511
 
484 512
        set -f
485 513
 
514
+      logfile="${owd}/${logfile}"
515
+
486 516
       # use absolute paths for configure, safer (and easier to read IMO)
487 517
       CFLAGS="\
488 518
 -I${owd}/${REFERENCE_DEPENDENCY_SUBDIR}/${HEADER_DIR_NAME} \
... ...
@@ -507,9 +537,9 @@ ${sdk}" \
507 537
 -L${owd}/${REFERENCE_DEPENDENCY_SUBDIR}/${LIBRARY_DIR_NAME} \
508 538
 ${other_ldflags} \
509 539
 ${sdk}" \
510
-      exekutor "${owd}/${srcdir}/configure" --prefix "${owd}/${BUILD_DEPENDENCY_SUBDIR}/usr/local" 1>&2  || exit 1
540
+      exekutor "${owd}/${srcdir}/configure" --prefix "${owd}/${BUILD_DEPENDENCY_SUBDIR}/usr/local" > "${logfile}.configure" || build_fail "${logfile}.configure" "configure"
511 541
 
512
-      exekutor make all install 1>&2 || exit 1
542
+      exekutor make all install > "${logfile}.make" || build_fail "${logfile}.make" "make"
513 543
 
514 544
       set +f
515 545
 
... ...
@@ -648,6 +678,7 @@ combined_escaped_search_path()
648 678
 }
649 679
 
650 680
 
681
+
651 682
 build_xcodebuild()
652 683
 {
653 684
    local configuration
... ...
@@ -685,16 +716,16 @@ build_xcodebuild()
685 716
    info=""
686 717
    if [ ! -z "${targetname}" ]
687 718
    then
688
-      info="Target ${C_MAGENTA}${targetname}${C_FLUFF}"
719
+      info="Target ${C_MAGENTA}${targetname}${C_INFO}"
689 720
    fi
690 721
 
691 722
    if [ ! -z "${schemename}" ]
692 723
    then
693
-      info="Scheme ${C_MAGENTA}${schemename}${C_FLUFF}"
724
+      info="Scheme ${C_MAGENTA}${schemename}${C_INFO}"
694 725
    fi
695 726
 
696
-   log_info "Do a xcodebuild ${C_MAGENTA}${configuration}${C_FLUFF} of \
697
-${C_MAGENTA}${name}${C_FLUFF} for SDK ${C_MAGENTA}${sdk}${C_FLUFF} \
727
+   log_info "Do a xcodebuild ${C_MAGENTA}${configuration}${C_INFO} of \
728
+${C_MAGENTA}${name}${C_INFO} for SDK ${C_MAGENTA}${sdk}${C_INFO} \
698 729
 ${info} ..."
699 730
 
700 731
    local projectname
... ...
@@ -799,33 +830,43 @@ ${info} ..."
799 830
    default="/include/${name}/private"
800 831
    private_headers="`fixup_header_path "PRIVATE_HEADERS_FOLDER_PATH" "xcode_private_headers" "${name}" "${default}" ${arguments}`"
801 832
 
833
+
834
+   local logfile
835
+
836
+   mkdir_if_missing "${BUILDLOG_SUBDIR}"
837
+   logfile="${BUILDLOG_SUBDIR}/${name}"
838
+
839
+   log_info "Log in \"${logfile}.xcodebuild\""
840
+
841
+   set -f
842
+
843
+   arguments=""
844
+   if [ ! -z "${projectname}" ]
845
+   then
846
+      arguments="${arguments} -project \"${projectname}\""
847
+   fi
848
+   if [ ! -z "${sdk}" ]
849
+   then
850
+      arguments="${arguments} -sdk \"${sdk}\""
851
+   fi
852
+   if [ ! -z "${schemename}" ]
853
+   then
854
+      arguments="${arguments} -scheme \"${schemename}\""
855
+   fi
856
+   if [ ! -z "${targetname}" ]
857
+   then
858
+      arguments="${arguments} -target \"${targetname}\""
859
+   fi
860
+   if [ ! -z "${mapped}" ]
861
+   then
862
+      arguments="${arguments} -configuration \"${mapped}\""
863
+   fi
864
+
802 865
    owd=`pwd`
803 866
    cd "${srcdir}" || exit 1
804 867
 
805
-      set -f
806
-
807
-      arguments=""
808
-      if [ ! -z "${projectname}" ]
809
-      then
810
-         arguments="${arguments} -project \"${projectname}\""
811
-      fi
812
-      if [ ! -z "${sdk}" ]
813
-      then
814
-         arguments="${arguments} -sdk \"${sdk}\""
815
-      fi
816
-      if [ ! -z "${schemename}" ]
817
-      then
818
-         arguments="${arguments} -scheme \"${schemename}\""
819
-      fi
820
-      if [ ! -z "${targetname}" ]
821
-      then
822
-         arguments="${arguments} -target \"${targetname}\""
823
-      fi
824
-      if [ ! -z "${mapped}" ]
825
-      then
826
-         arguments="${arguments} -configuration \"${mapped}\""
827
-      fi
828 868
 
869
+      logfile="${owd}/${logfile}"
829 870
 
830 871
       # manually point xcode to our headers and libs
831 872
       # this is like manually doing xcode-setup
... ...
@@ -893,7 +934,6 @@ ${info} ..."
893 934
          arguments="${arguments} PRIVATE_HEADERS_FOLDER_PATH='${private_headers}'"
894 935
       fi
895 936
 
896
-
897 937
       # if it doesn't install, probably SKIP_INSTALL is set
898 938
       cmdline="\"${xcodebuild}\" \"${command}\" ${arguments} \
899 939
 ARCHS='\${ARCHS_STANDARD_32_64_BIT}' \
... ...
@@ -907,7 +947,7 @@ HEADER_SEARCH_PATHS='${dependencies_header_search_path}' \
907 947
 LIBRARY_SEARCH_PATHS='${dependencies_lib_search_path}' \
908 948
 FRAMEWORK_SEARCH_PATHS='${dependencies_framework_search_path}'"
909 949
 
910
-      eval_exekutor "${cmdline}" 1>&2 || exit 1
950
+      eval_exekutor "${cmdline}" > "${logfile}.xcodebuild" || build_fail "${logfile}.xcodebuild" "xcodebuild"
911 951
 
912 952
       set +f
913 953
 
... ...
@@ -1324,6 +1364,15 @@ main()
1324 1364
    fi
1325 1365
 
1326 1366
    build_clones "$@"
1367
+
1368
+   if [ $# -eq 0 ]
1369
+   then
1370
+      if [ "${clean}" = "YES" ]
1371
+      then
1372
+         log_info "Write-protecting \"${DEPENDENCY_SUBDIR}\" to avoid spurious header edits"
1373
+         chmod -R a-w "${DEPENDENCY_SUBDIR}"
1374
+      fi
1375
+   fi
1327 1376
 }
1328 1377
 
1329 1378
 main "$@"
... ...
@@ -91,9 +91,9 @@ clean_asserted_folder()
91 91
 {
92 92
    if [ -d "$1" ]
93 93
    then
94
-      assert_sane_subdir_path "$1"
95 94
       log_info "Deleting \"$1\""
96
-      exekutor rm -rf "$1"
95
+
96
+      rmdir_safer "$1"
97 97
    else
98 98
       log_fluff "\"$1\" doesn't exist"
99 99
    fi
... ...
@@ -377,7 +377,7 @@ git_clone()
377 377
    [ -z "$src" ] && internal_fail "src is empty"
378 378
    [ -z "$dst" ] && internal_fail "dst is empty"
379 379
 
380
-   log_info "Cloning ${C_WHITE}${src}${C_INFO} ..."
380
+   log_info "Cloning ${C_MAGENTA}${src}${C_INFO} ..."
381 381
    exekutor git clone ${GITFLAGS} "${src}" "${dst}" || fail "git clone of \"${src}\" into \"${dst}\" failed"
382 382
 
383 383
    if [ "${tag}" != "" ]
... ...
@@ -688,7 +688,7 @@ Use it ?"
688 688
       esac
689 689
 
690 690
       "${operation}" "${srcname}" "${dstname}" "${tag}"
691
-       warn_scripts "${dstname}/.bootstrap" "${dstname}" || exit 1 # sic
691
+       warn_scripts "${dstname}/.bootstrap" "${dstname}" || fail "Ok, aborted"  #sic
692 692
    fi
693 693
 }
694 694
 
... ...
@@ -931,6 +931,18 @@ update_repositories()
931 931
 }
932 932
 
933 933
 
934
+
935
+append_dir_to_gitignore_if_needed()
936
+{
937
+   grep -s -x "$1/" .gitignore > /dev/null 2>&1
938
+   if [ $? -ne 0 ]
939
+   then
940
+      echo "$1/" >> .gitignore || fail "Couldn't append to .gitignore"
941
+      log_info "Added ${C_MAGENTA}$1/${C_INFO} to ${C_CYAN}.gitignore${C_INFO}"
942
+   fi
943
+}
944
+
945
+
934 946
 main()
935 947
 {
936 948
    log_fluff "::: fetch :::"
... ...
@@ -961,6 +973,17 @@ main()
961 973
    # Run prepare scripts if present
962 974
    #
963 975
    run_fetch_settings_script "post-${COMMAND}" "%@"
976
+
977
+   if read_yes_no_config_setting "update_gitignore" "YES"
978
+   then
979
+      if [ -d .git ]
980
+      then
981
+         append_dir_to_gitignore_if_needed "${BOOTSTRAP_SUBDIR}.auto"
982
+         append_dir_to_gitignore_if_needed "${BOOTSTRAP_SUBDIR}.local"
983
+         append_dir_to_gitignore_if_needed "${DEPENDENCY_SUBDIR}"
984
+         append_dir_to_gitignore_if_needed "${CLONES_SUBDIR}"
985
+      fi
986
+   fi
964 987
 }
965 988
 
966 989
 main "$@"
... ...
@@ -356,6 +356,7 @@ rmdir_safer()
356 356
    if [ -d "$1" ]
357 357
    then
358 358
       assert_sane_path "$1"
359
+      exekutor chmod -R u+w "$1" || fail "Failed to make $1 writable"
359 360
       exekutor rm -rf "$1" || fail "failed to remove ${1}"
360 361
    fi
361 362
 }
... ...
@@ -365,14 +366,15 @@ user_say_yes()
365 366
 {
366 367
   local  x
367 368
 
368
-  x="nix"
369
-  while [ "$x" != "y" -a "$x" != "n" -a "$x" != "" ]
369
+  x=`read_config_setting "answer" "ASK"`
370
+  while [ "$x" != "Y" -a "$x" != "YES" -a  "$x" != "N"  -a  "$x" != "NO"  -a "$x" != "" ]
370 371
   do
371 372
      echo "${C_YELLOW}$* (${C_WHITE}y${C_YELLOW}/${C_GREEN}N${C_YELLOW})${C_RESET}" >&2
372 373
      read x
374
+     x=`echo "${x}" | tr '[:lower:]' '[:upper:]'`
373 375
   done
374 376
 
375
-  [ "$x" = "y" ]
377
+  [ "$x" = "Y" -o "$x" = "YES" ]
376 378
   return $?
377 379
 }
378 380
 
... ...
@@ -73,6 +73,7 @@ fi
73 73
 CLONES_SUBDIR=`read_sane_config_path_setting "repos_foldername" ".repos"`
74 74
 CLONESBUILD_SUBDIR=`read_sane_config_path_setting "build_foldername" "build/.repos"`
75 75
 DEPENDENCY_SUBDIR=`read_sane_config_path_setting "output_foldername" "dependencies"`
76
+BUILDLOG_SUBDIR=`read_sane_config_path_setting "build_log_foldername" "${CLONESBUILD_SUBDIR}/.logs"`
76 77
 
77 78
 
78 79
 if [ "${CLONES_FETCH_SUBDIR}" = "" ]
... ...
@@ -99,6 +100,7 @@ fi
99 100
 [ -z "${BOOTSTRAP_SUBDIR}" ]     && internal_fail "variable BOOTSTRAP_SUBDIR is empty"
100 101
 [ -z "${CLONES_SUBDIR}" ]        && internal_fail "variable CLONES_SUBDIR is empty"
101 102
 [ -z "${CLONESBUILD_SUBDIR}" ]   && internal_fail "variable CLONESBUILD_SUBDIR is empty"
103
+[ -z "${BUILDLOG_SUBDIR}" ]      && internal_fail "variable BUILDLOG_SUBDIR is empty"
102 104
 [ -z "${DEPENDENCY_SUBDIR}" ]    && internal_fail "variable DEPENDENCY_SUBDIR is empty"
103 105
 [ -z "${CLONES_RELATIVE}" ]      && internal_fail "variable CLONES_RELATIVE is empty"
104 106
 [ -z "${CLONESBUILD_RELATIVE}" ] && internal_fail "CLONESBUILD_RELATIVE is empty"
... ...
@@ -117,6 +119,7 @@ FRAMEWORK_DIR_NAME="`read_config_setting "framework_dir_name" "Frameworks"`"
117 119
 export CLONES_SUBDIR
118 120
 export CLONES_FETCH_SUBDIR
119 121
 export CLONESBUILD_SUBDIR
122
+export BUILDLOG_SUBDIR
120 123
 export DEPENDENCY_SUBDIR
121 124
 export HEADER_DIR_NAME
122 125
 export LIBRARY_DIR_NAME
... ...
@@ -460,6 +460,15 @@ read_yes_no_build_setting()
460 460
 }
461 461
 
462 462
 
463
+read_yes_no_config_setting()
464
+{
465
+   local value
466
+
467
+   value=`read_config_setting "$1" "$2"`
468
+   is_yes "$value" "$1"
469
+}
470
+
471
+
463 472
 
464 473
 read_sane_config_path_setting()
465 474
 {
... ...
@@ -53,15 +53,15 @@ private_user_say_yes()
53 53
 {
54 54
   local  x
55 55
 
56
-  x="nix"
57
-  while [ "$x" != "y" -a "$x" != "n" -a "$x" != "" ]
56
+  x=`read_config_setting "answer" "ASK"`
57
+  while [ "$x" != "Y" -a "$x" != "YES" -a "$x" != "N" -a "$x" != "NO" -a "$x" != "" ]
58 58
   do
59 59
      echo "${C_YELLOW}$* (${C_WHITE}y${C_YELLOW}/${C_GREEN}N${C_YELLOW})${C_RESET}" >&2
60 60
      read x
61
+     x=`echo "${x}" | tr '[:lower:]' '[:upper:]'`
61 62
   done
62 63
 
63
-  [ "$x" = "y" ]
64
-  return $?
64
+  [ "$x" = "Y" -o "$x" = "YES" ]
65 65
 }
66 66
 
67 67
 
... ...
@@ -116,8 +116,15 @@ warn_scripts()
116 116
    if [ "$phases" != "" -o "$scripts" != "" ]
117 117
    then
118 118
       private_user_say_yes "You should probably inspect them before continuing.
119
-Ready to proceed ?"
120
-      return $?
119
+Abort now ?"
120
+      if [ $? -eq 0 ]
121
+      then
122
+          log_error "The bootstrap is in an inconsistent state. It would be good
123
+to run
124
+        ${C_WHITE}mulle-bootstrap clean dist${C_ERROR}
125
+now."
126
+          return 1
127
+      fi
121 128
    fi
122 129
 }
123 130