Browse code

Make global config happening. Add missing files.

Nat! authored on 21/03/2017 17:17:58
Showing 12 changed files
... ...
@@ -1,7 +1,11 @@
1 1
 #! /bin/sh
2 2
 
3
+TAP="${1:-software}"
4
+[ $# -ne 0 ] && shift
5
+BRANCH="${1:-release}"
6
+[ $# -ne 0 ] && shift
3 7
 TAG="${1:-`./mulle-bootstrap version`}"
4
-
8
+[ $# -ne 0 ] && shift
5 9
 
6 10
 . src/mulle-bootstrap-logging.sh
7 11
 
... ...
@@ -19,34 +23,41 @@ git_must_be_clean()
19 19
    fi
20 20
 
21 21
    clean=`git status -s --untracked-files=no`
22
-   if [ "${clean}" != "" ]
22
+   if [ ! -z "${clean}" ]
23 23
    then
24 24
       fail "repository \"${name}\" is tainted"
25 25
    fi
26 26
 }
27 27
 
28 28
 
29
+[ -d "../homebrew-$TAP" ] || fail "tap $TAP is invalid"
30
+
29 31
 git_must_be_clean
30 32
 
31
-branch="`git rev-parse --abbrev-ref HEAD`"
33
+devbranch="`git rev-parse --abbrev-ref HEAD`"
34
+
35
+(
36
+   git checkout "${BRANCH}"    &&
37
+   git rebase "${devbranch}"   &&
38
+   git push public "${BRANCH}"
39
+) || exit 1
32 40
 
33
-git checkout release
34
-git rebase "${branch}"
35
-git push public release
36 41
 
37 42
 # seperate step, as it's tedious to remove tag when
38 43
 # previous push fails
39 44
 
40
-git tag "${TAG}"
41
-git push public release --tags
42
-git push github release --tags
45
+(
46
+   git tag "${TAG}"                    &&
47
+   git push public "${BRANCH}" --tags  &&
48
+   git push github "${BRANCH}" --tags
49
+) || exit 1
50
+
43 51
 
44
-./bin/generate-brew-formula.sh  > ../homebrew-software/mulle-bootstrap.rb
52
+./bin/generate-brew-formula.sh  > ../homebrew-$TAP/mulle-bootstrap.rb
45 53
 (
46
-	cd ../homebrew-software ; \
54
+	cd ../homebrew-$TAP ; \
47 55
  	git commit -m "${TAG} release of mulle-bootstrap" mulle-bootstrap.rb ; \
48 56
  	git push origin master
49 57
 )
50 58
 
51
-git checkout "${branch}"
52
-
59
+git checkout "${devbranch}"
53 60
new file mode 100755
... ...
@@ -0,0 +1,383 @@
0
+#! /bin/sh
1
+#
2
+#   Copyright (c) 2017 Nat! - Mulle kybernetiK
3
+#   All rights reserved.
4
+#
5
+#   Redistribution and use in source and binary forms, with or without
6
+#   modification, are permitted provided that the following conditions are met:
7
+#
8
+#   Redistributions of source code must retain the above copyright notice, this
9
+#   list of conditions and the following disclaimer.
10
+#
11
+#   Redistributions in binary form must reproduce the above copyright notice,
12
+#   this list of conditions and the following disclaimer in the documentation
13
+#   and/or other materials provided with the distribution.
14
+#
15
+#   Neither the name of Mulle kybernetiK nor the names of its contributors
16
+#   may be used to endorse or promote products derived from this software
17
+#   without specific prior written permission.
18
+#
19
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+#   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+#   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+#   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+#   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+#   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+#   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+#   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+#   POSSIBILITY OF SUCH DAMAGE.
30
+MULLE_EXECUTABLE_VERSION_MAJOR=3
31
+MULLE_EXECUTABLE_VERSION_MINOR=0
32
+MULLE_EXECUTABLE_VERSION_PATCH=0
33
+
34
+MULLE_EXECUTABLE_VERSION="${MULLE_EXECUTABLE_VERSION_MAJOR}.${MULLE_EXECUTABLE_VERSION_MINOR}.${MULLE_EXECUTABLE_VERSION_PATCH}"
35
+
36
+#
37
+# This is the main user interface to mulle-bootstrap
38
+# sorta like git
39
+#
40
+
41
+trap_fail()
42
+{
43
+   exit 1
44
+}
45
+
46
+
47
+mulle_brew_usage()
48
+{
49
+   cat <<EOF
50
+usage: mulle-brew [flags] [command] [options]
51
+ Flags:
52
+   -n        : do nothing creative or destructive
53
+   -v        : -v to be more verbose (-vv or -vvv for more verbosity)
54
+EOF
55
+
56
+   bootstrap_technical_option_usage
57
+
58
+   cat <<EOF
59
+
60
+ Commands:
61
+   install   : fetches brews
62
+   update    : update brew
63
+   upgrade   : upgrade brew fomulae
64
+   init      : initializes a bootstrap project
65
+
66
+ Options are command specific. Use mulle-brew <command> -h for help.
67
+EOF
68
+
69
+   if [ "${UNAME}" = 'darwin' ]
70
+   then
71
+      cat <<EOF
72
+   xcode     : setup xcodeproj settings
73
+EOF
74
+   fi
75
+
76
+   exit 1
77
+}
78
+
79
+
80
+bootstrap_libexec_path()
81
+{
82
+   local exedir
83
+   local exedirpath
84
+   local prefix
85
+   local libexecpath
86
+
87
+   exedir="`dirname "$1"`"
88
+   exedirpath="`( cd "${exedir}" ; pwd -P )`" || fail "failed to get pwd"
89
+   prefix="`dirname "${exedirpath}"`"
90
+   libexecpath="${prefix}/libexec/mulle-bootstrap"
91
+
92
+   if [ ! -x "${libexecpath}/mulle-bootstrap-functions.sh" ]
93
+   then
94
+      libexecpath="${exedirpath}/src"
95
+   fi
96
+
97
+   if [ -x "${libexecpath}/mulle-bootstrap-functions.sh" ]
98
+   then
99
+      echo "${libexecpath}"
100
+   fi
101
+}
102
+
103
+
104
+bootstrap_init()
105
+{
106
+   local libexecpath
107
+
108
+   libexecpath="`bootstrap_libexec_path "$0"`"
109
+   if [ -z "${libexecpath}" ]
110
+   then
111
+      echo "could not find libexec for mulle-bootstrap" >&2
112
+      exit 1
113
+   fi
114
+
115
+   #
116
+   # shell export commands with minimal
117
+   # trap setup
118
+   #
119
+   case "${1}" in
120
+      library-path)
121
+         echo "${libexecpath}"
122
+         exit 0
123
+      ;;
124
+
125
+      version)
126
+         echo "${MULLE_EXECUTABLE_VERSION}"
127
+         exit 0
128
+      ;;
129
+   esac
130
+
131
+
132
+   PATH="${libexecpath}:$PATH"
133
+   export PATH
134
+
135
+   if [ ! -z "${MULLE_BOOTSTRAP_LIBEXEC_TRACE}" ]
136
+   then
137
+      echo "PATH=$PATH" >&2
138
+   fi
139
+
140
+   #  set -e # more pain then gain in the end
141
+   #  set -u # doesn't work with my style
142
+
143
+   # now include this first to get
144
+   # logging and UNAME
145
+
146
+   . mulle-bootstrap-logging.sh
147
+   . mulle-bootstrap-local-environment.sh || fail "not loaded"
148
+
149
+   trap trap_fail INT
150
+
151
+   # source_environment
152
+}
153
+
154
+
155
+brew_main()
156
+{
157
+   local command
158
+   local ps4string
159
+
160
+   # technical flags
161
+   local MULLE_FLAG_EXECUTOR_DRY_RUN="NO"
162
+   local MULLE_FLAG_LOG_CACHE="NO"
163
+   local MULLE_FLAG_LOG_DEBUG="NO"
164
+   local MULLE_FLAG_LOG_EXECUTOR="NO"
165
+   local MULLE_FLAG_LOG_EXECUTOR="NO"
166
+   local MULLE_FLAG_LOG_FLUFF="NO"
167
+   local MULLE_FLAG_LOG_SCRIPTS="NO"
168
+   local MULLE_FLAG_LOG_SETTINGS="NO"
169
+   local MULLE_FLAG_LOG_VERBOSE="NO"
170
+   local MULLE_FLAG_MERGE_LOG="NO"
171
+   local MULLE_TRACE_PATHS_FLIP_X="NO"
172
+   local MULLE_TRACE_POSTPONE="NO"
173
+   local MULLE_TRACE_RESOLVER_FLIP_X="NO"
174
+   local MULLE_TRACE_SETTINGS_FLIP_X="NO"
175
+
176
+   #
177
+   # simple option handling
178
+   #
179
+   while [ $# -ne 0 ]
180
+   do
181
+      if bootstrap_technical_flags "$1"
182
+      then
183
+         shift
184
+         continue
185
+      fi
186
+
187
+      case "$1" in
188
+         -h|--help)
189
+            mulle_brew_usage
190
+         ;;
191
+
192
+         -*)
193
+            log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}: Unknown option \"$1\""
194
+            mulle_brew_usage
195
+         ;;
196
+
197
+         *)
198
+            break
199
+         ;;
200
+      esac
201
+
202
+      shift
203
+   done
204
+
205
+   bootstrap_setup_trace "${MULLE_TRACE}"
206
+
207
+   if [ "${MULLE_FLAG_EXECUTOR_DRY_RUN}" = "YES" ]
208
+   then
209
+      log_trace "Dry run is active."
210
+   fi
211
+
212
+   # source in environment now
213
+
214
+   local_environment_main
215
+
216
+   #
217
+   # some commands only run when we have a .bootstrap folder
218
+   #
219
+   command="${1:-install}"
220
+   [ $# -eq 0 ] || shift
221
+
222
+   if [ ! -d "${BOOTSTRAP_DIR}" -a ! -d "${BOOTSTRAP_DIR}.local" ]
223
+   then
224
+      case "$1" in
225
+         -h|--help)
226
+         ;;
227
+
228
+         *)
229
+            case "${command}" in
230
+               dist|clean|dist-clean|install|upgrade|update|setup-xcode|xcode)
231
+                  fail "There is no ${BOOTSTRAP_DIR} or ${BOOTSTRAP_DIR}.local folder here ($PWD), can't continue"
232
+               ;;
233
+            esac
234
+         ;;
235
+      esac
236
+   else
237
+      if bootstrap_should_defer_to_master "$@"
238
+      then
239
+         return 1
240
+      fi
241
+   fi
242
+
243
+   MULLE_EXECUTABLE_FAIL_PREFIX="${MULLE_EXECUTABLE} ${command}"
244
+   MULLE_EXECUTABLE_OPTIONS="$@"
245
+
246
+   case "${command}" in
247
+      build)
248
+         . mulle-bootstrap-build.sh
249
+
250
+         build_main "$@" || exit 1
251
+      ;;
252
+
253
+      clean)
254
+         . mulle-bootstrap-clean.sh
255
+
256
+         clean_main "$@" || exit 1
257
+      ;;
258
+
259
+      config)
260
+         . mulle-bootstrap-settings.sh
261
+
262
+         config_main "$@" || exit 1
263
+      ;;
264
+
265
+      dist)
266
+         . mulle-bootstrap-clean.sh
267
+
268
+         clean_main "dist" || exit 1
269
+      ;;
270
+
271
+      defer)
272
+         . mulle-bootstrap-defer.sh
273
+
274
+         defer_main "$@" || exit 1
275
+      ;;
276
+
277
+      emancipate)
278
+         . mulle-bootstrap-defer.sh
279
+
280
+         emancipate_main "$@" || exit 1
281
+      ;;
282
+
283
+      flags)
284
+         . mulle-bootstrap-flags.sh
285
+
286
+         flags_main "$@" || exit 1
287
+      ;;
288
+
289
+      help)
290
+         mulle_brew_usage "$@" || exit 1
291
+      ;;
292
+
293
+      init)
294
+         . mulle-bootstrap-init.sh
295
+
296
+         init_main "$@" || exit 1
297
+      ;;
298
+
299
+      install|fetch)
300
+         . mulle-bootstrap-brew.sh
301
+
302
+         brew_install_main "$@" || exit 1
303
+      ;;
304
+
305
+      library-path)
306
+         echo "$PATH" | tr ':' '\012' | head -1
307
+         return 0
308
+      ;;
309
+
310
+      setting)
311
+         . mulle-bootstrap-settings.sh
312
+
313
+         setting_main "$@" || exit 1
314
+      ;;
315
+
316
+      show)
317
+         . mulle-bootstrap-show.sh
318
+
319
+         show_main "$@" || exit 1
320
+      ;;
321
+
322
+      uname)
323
+         echo "${UNAME}"
324
+         exit 0
325
+      ;;
326
+
327
+      update)
328
+         . mulle-bootstrap-brew.sh
329
+
330
+         brew_update_main "$@" || exit 1
331
+      ;;
332
+
333
+      upgrade)
334
+         . mulle-bootstrap-brew.sh
335
+
336
+         brew_upgrade_main "$@" || exit 1
337
+      ;;
338
+
339
+      version)
340
+         echo "${MULLE_EXECUTABLE_VERSION}"
341
+         return 0
342
+      ;;
343
+
344
+      xcode|setup-xcode)
345
+         . mulle-bootstrap-xcode.sh
346
+
347
+         MULLE_EXECUTABLE_FAIL_PREFIX="mulle-bootstrap xcode"
348
+         xcode_main "$@" || exit 1
349
+      ;;
350
+
351
+      *)
352
+         log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}: Unknown command \"${command}\""
353
+         mulle_bootstrap_usage
354
+      ;;
355
+   esac
356
+}
357
+
358
+#
359
+# service both names
360
+#
361
+MULLE_EXECUTABLE="`basename -- "$0"`"
362
+MULLE_ARGUMENTS="$@"
363
+MULLE_EXECUTABLE_FAIL_PREFIX="${MULLE_EXECUTABLE}"
364
+MULLE_EXECUTABLE_PID="$$"
365
+export MULLE_EXECUTABLE_PID
366
+
367
+
368
+bootstrap_init "$@" # needs params
369
+
370
+main()
371
+{
372
+   if ! brew_main "$@"
373
+   then
374
+      # just do it again, but cd has been set differently
375
+      main "$@" # is array
376
+      exit $?
377
+   fi
378
+}
379
+
380
+main "$@"
381
+
382
+trap - TERM EXIT
... ...
@@ -94,14 +94,14 @@ _bootstrap_auto_copy()
94 94
          ;;
95 95
 
96 96
          repositories)
97
-            _bootstrap_merge_repository_files "${filepath}" "${dstfilepath}" "NO"
97
+            merge_repository_files "${filepath}" "${dstfilepath}" "NO"
98 98
          ;;
99 99
 
100 100
          embedded_repositories)
101 101
             (
102 102
                STASHES_DEFAULT_DIR=""
103 103
                STASHES_ROOT_DIR=""
104
-               _bootstrap_merge_repository_files "${filepath}" "${dstfilepath}" "NO"
104
+               merge_repository_files "${filepath}" "${dstfilepath}" "NO"
105 105
             )
106 106
          ;;
107 107
 
... ...
@@ -138,6 +138,21 @@ _bootstrap_auto_copy()
138 138
 }
139 139
 
140 140
 
141
+_bootstrap_create_required_if_needed()
142
+{
143
+   dst="$1"
144
+
145
+   #
146
+   # if there is no required file add all names from repositories
147
+   # which ought to have been expanded already
148
+   #
149
+   if [ ! -f "${dst}/required" -a -f "${dst}/repositories" ]
150
+   then
151
+      redirect_exekutor "${dst}/required" names_from_repository_file "${dst}/repositories"
152
+   fi
153
+}
154
+
155
+
141 156
 #
142 157
 # This function is called initially to setup .bootstrap.auto before
143 158
 # doing anything else. It is clear that .bootstrap.auto does not exist
... ...
@@ -175,6 +190,8 @@ _bootstrap_auto_create()
175 175
    then
176 176
       _bootstrap_auto_copy "${dst}" "${src}" "NO"
177 177
    fi
178
+
179
+   _bootstrap_create_required_if_needed "${dst}"
178 180
 }
179 181
 
180 182
 
... ...
@@ -211,25 +228,6 @@ _bootstrap_merge_expanded_settings_in_front()
211 211
 }
212 212
 
213 213
 
214
-_bootstrap_merge_repository_files()
215
-{
216
-   local srcfile="$1"
217
-   local dstfile="$2"
218
-   local delete_dstdir="${3:-NO}"
219
-
220
-   log_fluff "Copying expanded \"repositories\" from \"${srcfile}\""
221
-
222
-   local contents
223
-   local additions
224
-
225
-   contents="`cat "${dstfile}" 2> /dev/null || :`"
226
-   additions="`read_repository_file "${srcfile}" "${delete_dstdir}"`" || fail "read"
227
-   additions="`echo "${additions}"| sed 's/;*$//'`"
228
-   additions="`merge_repository_contents "${contents}" "${additions}"`"
229
-
230
-   redirect_exekutor "${dstfile}" echo "${additions}"
231
-}
232
-
233 214
 
234 215
 #
235 216
 # prepend new contents to old contents
... ...
@@ -280,7 +278,7 @@ _bootstrap_auto_merge_root_settings()
280 280
          ;;
281 281
 
282 282
          "repositories")
283
-            _bootstrap_merge_repository_files "${srcfile}" "${dstfile}" "YES"
283
+            merge_repository_files "${srcfile}" "${dstfile}" "YES"
284 284
             continue
285 285
          ;;
286 286
       esac
... ...
@@ -308,11 +306,10 @@ _bootstrap_auto_merge_root_settings()
308 308
       fi
309 309
    done
310 310
 
311
-   IFS="${DEFAULT_IFS}"
311
+   _bootstrap_create_required_if_needed "${dst}"
312 312
 }
313 313
 
314 314
 
315
-
316 315
 _bootstrap_auto_special_copy()
317 316
 {
318 317
    local key="$1"; shift
... ...
@@ -339,7 +336,7 @@ _bootstrap_auto_special_copy()
339 339
    (
340 340
       STASHES_DEFAULT_DIR=""
341 341
       STASHES_ROOT_DIR="${directory}"
342
-      _bootstrap_merge_repository_files "${filepath}" "${dstfilepath}" "NO"
342
+      merge_repository_files "${filepath}" "${dstfilepath}" "NO"
343 343
    )
344 344
 }
345 345
 
... ...
@@ -536,6 +533,7 @@ bootstrap_auto_final()
536 536
    fi
537 537
 
538 538
    order=""
539
+   missing="`read_setting "${REPOS_DIR}/.missing"`"
539 540
 
540 541
    IFS="
541 542
 "
... ...
@@ -544,7 +542,14 @@ bootstrap_auto_final()
544 544
       IFS="${DEFAULT_IFS}"
545 545
 
546 546
       parse_clone "${clone}"
547
-      order="`add_line "${order}" "${name}"`"
547
+
548
+      #
549
+      # don't build optional missing stuff
550
+      #
551
+      if ! echo "${missing}" | fgrep -s -x -q "${name}"
552
+      then
553
+         order="`add_line "${order}" "${name}"`"
554
+      fi
548 555
    done
549 556
 
550 557
    IFS="${DEFAULT_IFS}"
... ...
@@ -404,13 +404,11 @@ build_fail()
404 404
 
405 405
 build_log_name()
406 406
 {
407
-   local tool
408
-   local name
407
+   local tool="$1"; shift
408
+   local name="$1"; shift
409 409
 
410
-   tool="$1"
411
-   [ $# -eq 0 ] || shift
412
-   name="$1"
413
-   [ $# -eq 0 ] || shift
410
+   [ -z "${tool}" ] && internal_fail "tool missing"
411
+   [ -z "${name}" ] && internal_fail "name missing"
414 412
 
415 413
    local logfile
416 414
 
... ...
@@ -1032,7 +1030,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
1032 1032
 
1033 1033
       logging_redirect_eval_exekutor "${logfile1}" "'${CMAKE}'" \
1034 1034
 -G "'${CMAKE_GENERATOR}'" \
1035
-"-DMULLE_EXECUTABLE_VERSION=${MULLE_EXECUTABLE_VERSION}" \
1035
+"-DMULLE_BOOTSTRAP_VERSION=${MULLE_EXECUTABLE_VERSION}" \
1036 1036
 "-DCMAKE_BUILD_TYPE='${mapped}'" \
1037 1037
 "-DCMAKE_INSTALL_PREFIX:PATH='${prefixbuild}'"  \
1038 1038
 "${sdkparameter}" \
... ...
@@ -1405,7 +1403,9 @@ build_xcodebuild()
1405 1405
 
1406 1406
    enforce_build_sanity "${builddir}"
1407 1407
 
1408
-   toolname=`read_config_setting "xcodebuild" "xcodebuild"`
1408
+   local toolname
1409
+
1410
+   toolname="`read_config_setting "xcodebuild" "xcodebuild"`"
1409 1411
 
1410 1412
    local info
1411 1413
 
... ...
@@ -1473,8 +1473,6 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO}${info} in \
1473 1473
       skip_install="SKIP_INSTALL=NO"
1474 1474
    fi
1475 1475
 
1476
-   local toolname
1477
-
1478 1476
    #
1479 1477
    # xctool needs schemes, these are often autocreated, which xctool cant do
1480 1478
    # xcodebuild can just use a target
... ...
@@ -1482,7 +1480,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO}${info} in \
1482 1482
    #
1483 1483
    if [ "${toolname}" = "xctool"  -a "${schemename}" = ""  ]
1484 1484
    then
1485
-      if [ "$targetname" != "" ]
1485
+      if [ ! -z "$targetname" ]
1486 1486
       then
1487 1487
          schemename="${targetname}"
1488 1488
          targetname=
... ...
@@ -1511,7 +1509,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO}${info} in \
1511 1511
    local owd
1512 1512
    local command
1513 1513
 
1514
-   if [ "$MULLE_FLAG_EXECUTOR_DRY_RUN" != "" ]
1514
+   if [ "${MULLE_FLAG_EXECUTOR_DRY_RUN}" = "YES" ]
1515 1515
    then
1516 1516
       command=-showBuildSettings
1517 1517
    else
... ...
@@ -1910,18 +1908,21 @@ build_with_configuration_sdk_preferences()
1910 1910
                return 0
1911 1911
             else
1912 1912
                [ ! -e "${script}" ] || fail "script ${script} is not executable"
1913
+               log_fluff "There is no build script in \"`build_setting_path "${name}" "bin/build.sh"`\""
1913 1914
             fi
1914 1915
          ;;
1915 1916
 
1916 1917
          xcodebuild)
1917 1918
             if [ ! -z "${XCODEBUILD}" ]
1918 1919
             then
1919
-               project=`(cd "${srcdir}" ; find_xcodeproj "${name}")`
1920
+               project="`(cd "${srcdir}" ; find_xcodeproj "${name}")`"
1920 1921
 
1921
-               if [ ! -z "$project" ]
1922
+               if [ ! -z "${project}" ]
1922 1923
                then
1923 1924
                   build_xcodebuild_schemes_or_target "${configuration}" "${srcdir}" "${builddir}" "${name}" "${sdk}" "${project}"  || exit 1
1924 1925
                   return 0
1926
+               else
1927
+                  log_fluff "There is no Xcode project in \"${srcdir}\""
1925 1928
                fi
1926 1929
             fi
1927 1930
          ;;
... ...
@@ -1941,6 +1942,8 @@ build_with_configuration_sdk_preferences()
1941 1941
                   build_configure "${configuration}" "${srcdir}" "${builddir}" "${name}" "${sdk}"  || exit 1
1942 1942
                   return 0
1943 1943
                fi
1944
+            else
1945
+               log_fluff "There is no configure script in \"${srcdir}\""
1944 1946
             fi
1945 1947
          ;;
1946 1948
 
... ...
@@ -1954,6 +1957,8 @@ build_with_configuration_sdk_preferences()
1954 1954
                   build_cmake "${configuration}" "${srcdir}" "${builddir}" "${name}" "${sdk}"  || exit 1
1955 1955
                   return 0
1956 1956
                fi
1957
+            else
1958
+               log_fluff "There is no CMakeLists.txt file in \"${srcdir}\""
1957 1959
             fi
1958 1960
          ;;
1959 1961
 
... ...
@@ -2125,7 +2130,7 @@ build_if_alive()
2125 2125
          build_wrapper "${name}" "${stashdir}"
2126 2126
 
2127 2127
          # memorize what we build
2128
-         redirect_append_exekutor "${REPOS_DIR}/.build_done" echo "${name}"
2128
+         merge_line_into_file "${REPOS_DIR}/.build_done" "${name}"
2129 2129
 
2130 2130
          BUILT="${name}
2131 2131
 ${BUILT}"
... ...
@@ -2223,7 +2228,7 @@ build_stashes()
2223 2223
 have_tars()
2224 2224
 {
2225 2225
    tarballs=`read_root_setting "tarballs"`
2226
-   [ "${tarballs}" != "" ]
2226
+   [ ! -z "${tarballs}" ]
2227 2227
 }
2228 2228
 
2229 2229
 
... ...
@@ -114,7 +114,7 @@ check_tars()
114 114
    log_fluff "Looking for tarballs"
115 115
 
116 116
    tarballs="`read_root_setting "tarballs" | sort | sort -u`"
117
-   if [ "${tarballs}" != "" ]
117
+   if [ ! -z "${tarballs}" ]
118 118
    then
119 119
       [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
120 120
       IFS="
... ...
@@ -182,7 +182,10 @@ link_command()
182 182
    local absolute
183 183
 
184 184
    absolute="`read_config_setting "absolute_symlinks" "NO"`"
185
-   exekutor create_symlink "${url}" "${stashdir}" "${absolute}"
185
+   if ! exekutor create_symlink "${url}" "${stashdir}" "${absolute}"
186
+   then
187
+      return 1
188
+   fi
186 189
 
187 190
    local branchlabel
188 191
 
... ...
@@ -496,7 +499,7 @@ clone_or_symlink()
496 496
    # and check that the archive is correct
497 497
    #
498 498
    extra="`echo "${scm}" | sed -n 's/^[^?]*\?\(.*\)/\1/p'`"
499
-   if [ ! -z "{extra}" ]
499
+   if [ ! -z "${extra}" ]
500 500
    then
501 501
       log_fluff "Parsed SCM_OPTIONS as \"${extra}\""
502 502
       SCM_OPTIONS="${extra}"
... ...
@@ -567,13 +570,38 @@ clone_or_symlink()
567 567
       ;;
568 568
    esac
569 569
 
570
-   "${operation}" "${reposdir}" \
571
-                  "${name}" \
572
-                  "${url}" \
573
-                  "${branch}" \
574
-                  "${scm}" \
575
-                  "${tag}" \
576
-                  "${stashdir}" || exit 1
570
+   local rval
571
+
572
+   if ! "${operation}" "${reposdir}" \
573
+                       "${name}" \
574
+                       "${url}" \
575
+                       "${branch}" \
576
+                       "${scm}" \
577
+                       "${tag}" \
578
+                       "${stashdir}"
579
+   then
580
+      #
581
+      # check if clone is an optional install component
582
+      # it is if it doesn't show up in "required"
583
+      # required is built by mulle-bootstrap usually
584
+      # you specify optionals, by specifying the required
585
+      # clones and leaving the optional out
586
+      #
587
+      local required
588
+
589
+      required="`read_root_setting "required"`"
590
+      [ -z "${required}" ] && internal_fail "required missing"
591
+
592
+      if ! echo "${required}" | fgrep -s -q -x "${name}" > /dev/null
593
+      then
594
+         log_info "${C_MAGENTA}${C_BOLD}${name}${C_INFO} is missing, but it's not required."
595
+
596
+         merge_line_into_file "${REPOS_DIR}/.missing" "${name}"
597
+         return 1  # means just skip
598
+      fi
599
+
600
+      return  # means exit
601
+   fi
577 602
 
578 603
    if [ "${DONT_WARN_SCRIPTS}" != "YES" ]
579 604
    then
... ...
@@ -1186,6 +1214,10 @@ work_clones()
1186 1186
                         # if we used a symlink, we want to memorize that
1187 1187
                         scm="symlink"
1188 1188
                      ;;
1189
+
1190
+                     3)
1191
+                        exit 1
1192
+                     ;;
1189 1193
                   esac
1190 1194
                ;;
1191 1195
 
... ...
@@ -50,6 +50,8 @@ eval_trace()
50 50
    then
51 51
       local arrow
52 52
 
53
+      [ -z "${MULLE_EXECUTABLE_PID}" ] && internal_fail "MULLE_EXECUTABLE_PID not set"
54
+
53 55
       if [ "${PPID}" -ne "${MULLE_EXECUTABLE_PID}" ]
54 56
       then
55 57
          arrow="=[${PPID}]=>"
... ...
@@ -75,6 +77,8 @@ eval_trace_output()
75 75
    then
76 76
       local arrow
77 77
 
78
+      [ -z "${MULLE_EXECUTABLE_PID}" ] && internal_fail "MULLE_EXECUTABLE_PID not set"
79
+
78 80
       if [ "${PPID}" -ne "${MULLE_EXECUTABLE_PID}" ]
79 81
       then
80 82
          arrow="=[${PPID}]=>"
... ...
@@ -1172,6 +1176,19 @@ _create_file_if_missing()
1172 1172
 }
1173 1173
 
1174 1174
 
1175
+merge_line_into_file()
1176
+{
1177
+  local path="$1"
1178
+  local line="$2"
1179
+
1180
+  if fgrep -s -q -x "${name}" "${path}" 2> /dev/null
1181
+  then
1182
+     return
1183
+  fi
1184
+  redirect_append_exekutor "${path}" echo "${line}"
1185
+}
1186
+
1187
+
1175 1188
 create_file_if_missing()
1176 1189
 {
1177 1190
   _create_file_if_missing "$1" "# intentionally blank file"
... ...
@@ -1301,7 +1318,7 @@ find_xcodeproj()
1301 1301
    #
1302 1302
    # don't go too deep in search
1303 1303
    #
1304
-   for i in `find . -depth 2 -name "*.xcodeproj" -print`
1304
+   for i in `find . -maxdepth 2 -name "*.xcodeproj" -print`
1305 1305
    do
1306 1306
       match=`basename -- "${i}" .xcodeproj`
1307 1307
       if [ "$match" = "$expect" ]
... ...
@@ -1318,7 +1335,7 @@ find_xcodeproj()
1318 1318
       fi
1319 1319
    done
1320 1320
 
1321
-   if [ "$found" != "" ]
1321
+   if [ ! -z "$found" ]
1322 1322
    then
1323 1323
       echo "${found}"
1324 1324
       return 0
... ...
@@ -399,7 +399,7 @@ user_say_yes()
399 399
 
400 400
       if [ -z "${x}" ]
401 401
       then
402
-         x="${MULLE_FLAG_ANSWER}"
402
+         x="NO"
403 403
       fi
404 404
    done
405 405
 }
... ...
@@ -518,9 +518,12 @@ build_needed()
518 518
 
519 519
    [ -z "${REPOS_DIR}" ] && internal_fail "REPOS_DIR undefined"
520 520
 
521
-   if [ ! -f "${REPOS_DIR}/build_done" ]
521
+   local build_done
522
+
523
+   build_done="${REPOS_DIR}/.build_done"
524
+   if [ ! -f "${build_done}" ]
522 525
    then
523
-      log_verbose "Need build because \"${REPOS_DIR}/.build_done\" does not exist."
526
+      log_verbose "Need build because \"${build_done}\" does not exist."
524 527
       return 0
525 528
    fi
526 529
 
... ...
@@ -531,12 +534,12 @@ build_needed()
531 531
    # sort  and unique, because people can redo builds manually
532 532
    # which will add duplicate lines
533 533
    #
534
-   progress="`read_setting "${REPOS_DIR}/.build_done" | sort | sort -u`"
534
+   progress="`read_setting "${build_done}" | sort`"
535 535
    complete="`read_root_setting "build_order" | sort`"
536 536
 
537 537
    if [ "${progress}" != "${complete}" ]
538 538
    then
539
-      log_verbose "Need build because \"${REPOS_DIR}/build_done\" is different to \"build_order\""
539
+      log_verbose "Need build because \"${build_done}\" is different to \"build_order\""
540 540
       return 0
541 541
    fi
542 542
 
... ...
@@ -591,6 +594,23 @@ fetch_needed()
591 591
       fi
592 592
    done
593 593
 
594
+   local minions
595
+
596
+   minions="`read_root_setting "minions"`"
597
+
598
+   IFS="
599
+"
600
+   for stashdir in ${minions}
601
+   do
602
+      IFS="${DEFAULT_IFS}"
603
+
604
+      if [ "${referencefile}" -ot "${stashdir}/${BOOTSTRAP_DIR}" ]
605
+      then
606
+         log_verbose "Need fetch because \"${stashdir}/${BOOTSTRAP_DIR}\" is modified"
607
+         return 0
608
+      fi
609
+   done
610
+
594 611
    IFS="${DEFAULT_IFS}"
595 612
 
596 613
    return 1
... ...
@@ -780,6 +780,8 @@ parse_raw_clone()
780 780
 }
781 781
 
782 782
 
783
+#   # process_raw_clone
784
+#   local name        # name of clone
783 785
 process_raw_clone()
784 786
 {
785 787
    name="`_canonical_clone_name "${url}"`"
... ...
@@ -831,6 +833,40 @@ parse_clone()
831 831
 }
832 832
 
833 833
 
834
+names_from_repository_file()
835
+{
836
+   local filename="$1"
837
+
838
+   local clones
839
+
840
+   local url        # url of clone
841
+   local dstdir
842
+   local name
843
+   local branch
844
+   local scm
845
+   local tag
846
+
847
+   clones="`read_setting "${dst}/repositories"`"
848
+
849
+   IFS="
850
+"
851
+   for clone in ${clones}
852
+   do
853
+      IFS="${DEFAULT_IFS}"
854
+
855
+      parse_raw_clone "${clone}"
856
+      process_raw_clone
857
+
858
+      if [ ! -z "${name}" ]
859
+      then
860
+         echo "${name}"
861
+      fi
862
+   done
863
+
864
+   IFS="${DEFAULT_IFS}"
865
+}
866
+
867
+
834 868
 #
835 869
 # read repository file, properly do expansions
836 870
 # replace branch with override if needed
... ...
@@ -980,6 +1016,29 @@ merge_repository_contents()
980 980
 }
981 981
 
982 982
 
983
+merge_repository_files()
984
+{
985
+   local srcfile="$1"
986
+   local dstfile="$2"
987
+   local delete_dstdir="${3:-NO}"
988
+
989
+   [ -z "${srcfile}" ] && internal_fail "srcfile is empty"
990
+   [ -z "${dstfile}" ] && internal_fail "dstfile is empty"
991
+
992
+   log_fluff "Copying expanded \"repositories\" from \"${srcfile}\""
993
+
994
+   local contents
995
+   local additions
996
+
997
+   contents="`cat "${dstfile}" 2> /dev/null || :`"
998
+   additions="`read_repository_file "${srcfile}" "${delete_dstdir}"`" || fail "read"
999
+   additions="`echo "${additions}"| sed 's/;*$//'`"
1000
+   additions="`merge_repository_contents "${contents}" "${additions}"`"
1001
+
1002
+   redirect_exekutor "${dstfile}" echo "${additions}"
1003
+}
1004
+
1005
+
983 1006
 #
984 1007
 # take a list of repositories
985 1008
 # unique them with another list of repositories by url
... ...
@@ -234,14 +234,20 @@ _git_clone()
234 234
 
235 235
    if [ ! -d "${dstdir}" ]
236 236
    then
237
-      exekutor git ${GITFLAGS} clone ${options} ${GITOPTIONS} -- "${url}" "${dstdir}"  >&2 \
238
-         || fail "git clone of \"${url}\" into \"${dstdir}\" failed"
237
+      if ! exekutor git ${GITFLAGS} clone ${options} ${GITOPTIONS} -- "${url}" "${dstdir}" >&2
238
+      then
239
+         log_error "git clone of \"${url}\" into \"${dstdir}\" failed"
240
+         return 1
241
+      fi
239 242
    fi
240 243
 
241 244
    if [ ! -z "${CLONE_CACHE}" -a "${stashdir}" != "${CLONE_CACHE}" ]
242 245
    then
243
-      exekutor git ${GITFLAGS} clone ${options} ${GITOPTIONS} -- "${dstdir}" "${stashdir}"  >&2 \
244
-      || fail "git clone of \"${dstdir}\" into \"${stashdir}\" failed"
246
+      if ! exekutor git ${GITFLAGS} clone ${options} ${GITOPTIONS} -- "${dstdir}" "${stashdir}"  >&2
247
+      then
248
+         log_error "git clone of \"${dstdir}\" into \"${stashdir}\" failed"
249
+         return 1
250
+      fi
245 251
    fi
246 252
 
247 253
    if [ ! -z "${tag}" ]
... ...
@@ -365,8 +371,11 @@ svn_checkout()
365 365
       fi
366 366
    fi
367 367
 
368
-   exekutor svn checkout ${options} ${SVNOPTIONS} "${url}" "${stashdir}"  >&2 \
369
-     || fail "svn clone of \"${url}\" into \"${stashdir}\" failed"
368
+   if ! exekutor svn checkout ${options} ${SVNOPTIONS} "${url}" "${stashdir}"  >&2
369
+   then
370
+      log_error "svn clone of \"${url}\" into \"${stashdir}\" failed"
371
+      return 1
372
+   fi
370 373
 }
371 374
 
372 375
 
... ...
@@ -721,17 +730,17 @@ tar_unpack()
721 721
    esac
722 722
 
723 723
    rmdir_safer "${name}.tmp"
724
-   tmpdir="`exekutor mktemp -d "${name}.tmp"`" || exit 1
724
+   tmpdir="`exekutor mktemp -d "${name}.tmp"`" || return 1
725 725
    (
726
-      exekutor cd "${tmpdir}" || exit 1
726
+      exekutor cd "${tmpdir}" || return 1
727 727
 
728
-      _tar_download "${download}" || exit 1
728
+      _tar_download "${download}" || return 1
729 729
 
730 730
       case "${url}" in
731 731
          *.zip)
732
-            exekutor unzip "${download}" || exit 1
732
+            exekutor unzip "${download}" || return 1
733 733
             archive="`basename "${download}" .zip`"
734
-            exekutor rm "${download}" || exit 1
734
+            exekutor rm "${download}" || return 1
735 735
          ;;
736 736
       esac
737 737
 
... ...
@@ -758,9 +767,9 @@ tar_unpack()
758 758
 
759 759
       log_verbose "Extracting ${C_MAGENTA}${C_BOLD}${archive}${C_INFO} ..."
760 760
 
761
-      exekutor tar xf ${TAROPTIONS} ${options} "${archive}" || exit 1
762
-      exekutor rm "${archive}" || exit 1
763
-   ) || exit 1
761
+      exekutor tar xf ${TAROPTIONS} ${options} "${archive}" || return 1
762
+      exekutor rm "${archive}"
763
+   ) || return 1
764 764
 
765 765
    _move_stuff "${tmpdir}" "${stashdir}" "${archivename}" "${name}"
766 766
 }
... ...
@@ -788,18 +797,18 @@ zip_unpack()
788 788
    rmdir_safer "${name}.tmp"
789 789
    tmpdir="`exekutor mktemp -d "${name}.tmp"`" || exit 1
790 790
    (
791
-      exekutor cd "${tmpdir}" || exit 1
791
+      exekutor cd "${tmpdir}" || return 1
792 792
 
793 793
       log_info "Downloading ${C_MAGENTA}${C_BOLD}${url}${C_INFO} ..."
794 794
 
795
-      exekutor curl -O -L ${CURLOPTIONS} "${url}" || exit 1
796
-      _validate_download "${download}" "${SCM_OPTIONS}" || exit 1
795
+      exekutor curl -O -L ${CURLOPTIONS} "${url}" || return 1
796
+      _validate_download "${download}" "${SCM_OPTIONS}" || return 1
797 797
 
798 798
       log_verbose "Extracting ${C_MAGENTA}${C_BOLD}${download}${C_INFO} ..."
799 799
 
800
-      exekutor unzip "${download}" || exit 1
801
-      exekutor rm "${download}" || exit 1
802
-   ) || exit 1
800
+      exekutor unzip "${download}" || return 1
801
+      exekutor rm "${download}"
802
+   ) || return 1
803 803
 
804 804
    _move_stuff "${tmpdir}" "${stashdir}" "${archivename}" "${name}"
805 805
 }
... ...
@@ -39,6 +39,7 @@ usage:
39 39
 
40 40
    Options:
41 41
       -d   : delete config setting
42
+      -g   : use ~/.mulle-bootstrap folder instead of .bootstrap-local
42 43
       -l   : list config values
43 44
 
44 45
    Use:
... ...
@@ -231,7 +232,7 @@ _read_setting()
231 231
 {
232 232
    local apath="$1"
233 233
 
234
-   [ ! -z "${apath}" ] || fail "no path given to read_setting"
234
+   [ ! -z "${apath}" ] || internal_fail "no path given to read_setting"
235 235
 
236 236
    local value
237 237
 
... ...
@@ -314,7 +315,7 @@ read_raw_setting()
314 314
 {
315 315
    local key="$1"
316 316
 
317
-   [ $# -ne 1 ]     && internal_fail "parameterization error"
317
+   [ $# -ne 1 ]    && internal_fail "parameterization error"
318 318
    [ -z "${key}" ] && internal_fail "empty key in read_raw_setting"
319 319
 
320 320
    if _read_setting "${BOOTSTRAP_DIR}.local/${key}"
... ...
@@ -324,6 +325,25 @@ read_raw_setting()
324 324
    _read_setting "${BOOTSTRAP_DIR}/${key}"
325 325
 }
326 326
 
327
+
328
+_bootstrap_setting_path()
329
+{
330
+   local key="$1"
331
+
332
+   #
333
+   # to access unmerged data (needed for embedded repos)
334
+   #
335
+   if [ "${MULLE_BOOTSTRAP_SETTINGS_NO_AUTO}" = "YES" ]
336
+   then
337
+      suffix=""
338
+   else
339
+      suffix=".auto"
340
+   fi
341
+
342
+   echo "${BOOTSTRAP_DIR}${suffix}/${key}"
343
+}
344
+
345
+
327 346
 #
328 347
 # this has to be flexible, because fetch and build settings read differently
329 348
 #
... ...
@@ -331,7 +351,7 @@ _read_bootstrap_setting()
331 331
 {
332 332
    local key="$1"
333 333
 
334
-   [ $# -ne 1 ]     && internal_fail "parameterization error"
334
+   [ $# -ne 1 ]    && internal_fail "parameterization error"
335 335
    [ -z "${key}" ] && internal_fail "empty key in _read_bootstrap_setting"
336 336
 
337 337
    local value
... ...
@@ -530,6 +550,15 @@ read_config_setting()
530 530
 }
531 531
 
532 532
 
533
+build_setting_path()
534
+{
535
+   local package="$1"
536
+   local key="$2"
537
+
538
+   _bootstrap_setting_path "${package}.build/${key}"
539
+}
540
+
541
+
533 542
 #
534 543
 # values in "overrides" override those inherited by repositories
535 544
 # values in "settings" are overriden by those inherited by repositories
... ...
@@ -541,15 +570,11 @@ read_build_setting()
541 541
       set +x
542 542
    fi
543 543
 
544
-   local key
545
-   local default
546
-   local package
547
-
548 544
    [ $# -lt 2 -o $# -gt 3 ] && internal_fail "parameterization error"
549 545
 
550
-   package="$1"
551
-   key="$2"
552
-   default="$3"
546
+   local package="$1"
547
+   local key="$2"
548
+   local default="$3"
553 549
 
554 550
    [ -z "${key}" ] && internal_fail "empty parameter in read_config_setting"
555 551
 
... ...
@@ -634,6 +659,8 @@ find_build_setting_file()
634 634
 }
635 635
 
636 636
 
637
+
638
+
637 639
 ####
638 640
 # Functions building on read_ functions
639 641
 #
... ...
@@ -709,6 +736,46 @@ read_expanded_setting()
709 709
 }
710 710
 
711 711
 
712
+# sti
713
+_combine_settings_in_front()
714
+{
715
+   local settings1="$1"
716
+   local settings2="$2"
717
+   local key="$3"
718
+
719
+   local result
720
+
721
+   result="${settings2}"
722
+
723
+   local line
724
+
725
+   # https://stackoverflow.com/questions/742466/how-can-i-reverse-the-order-of-lines-in-a-file/744093#744093
726
+
727
+   IFS="
728
+"
729
+   for line in `echo "${settings1}" | sed -n '1!G;h;$p'`
730
+   do
731
+      result="`echo "${result}" | grep -v -x "${line}"`"
732
+      result="${line}
733
+${result}"
734
+   done
735
+
736
+   IFS="${DEFAULT_IFS}"
737
+
738
+   if [ "$MULLE_FLAG_LOG_SETTINGS" = "YES" -o \
739
+        "$MULLE_FLAG_MERGE_LOG" = "YES"  ]
740
+   then
741
+      log_trace2 "----------------------"
742
+      log_trace2 "Merged settings:      "
743
+      log_trace2 "----------------------"
744
+      log_trace2 "${result}"
745
+      log_trace2 "----------------------"
746
+   fi
747
+   echo "${result}"
748
+}
749
+
750
+
751
+
712 752
 _merge_settings_in_front()
713 753
 {
714 754
    local settings1="$1"
... ...
@@ -908,9 +975,12 @@ _setting_append()
908 908
    filename="${directory}/${key}"
909 909
    before="`_read_setting "${filename}"`"
910 910
 
911
+   # ugliness needed for
912
+   [ -z "${MULLE_BOOTSTRAP_REPOSITORIES_SH}" ] && . mulle-bootstrap-repositories.sh
913
+
911 914
    case "${key}" in
912 915
       embedded_repositories|repositories)
913
-         redirect_exekutor "${filename}" merge_repository_file "${before}" "${value}"
916
+         redirect_exekutor "${filename}" merge_repository_contents "${before}" "${value}"
914 917
       ;;
915 918
 
916 919
       brews|tarballs)
... ...
@@ -960,32 +1030,54 @@ _config_list()
960 960
 
961 961
 _config_read()
962 962
 {
963
-   local key="$1"
964
-
965 963
    read_config_setting "${key}"
966 964
 }
967 965
 
968 966
 
969 967
 _config_append()
970 968
 {
971
-   fail "Not yet implemented"
969
+   internal_fail "Not yet implemented"
972 970
 }
973 971
 
974 972
 
975 973
 _config_write()
976 974
 {
977
-   mkdir_if_missing "${BOOTSTRAP_DIR}.local/config"
975
+   local key="$1"
976
+   local value="$2"
977
+
978
+   local configdir
979
+
980
+   configdir="${BOOTSTRAP_DIR}.local/config"
981
+
982
+   if [ "${OPTION_GLOBAL}" = "YES" ]
983
+   then
984
+      configdir="${HOME}/.mulle-bootstrap"
985
+   fi
986
+
987
+   mkdir_if_missing "${configdir}"
988
+   exekutor echo "${value}" > "${configdir}/${key}"
978 989
 
979
-   exekutor echo "$2" > "${BOOTSTRAP_DIR}.local/config/$1"
980 990
    exekutor touch "${BOOTSTRAP_DIR}.local"
981 991
 }
982 992
 
983 993
 
984 994
 _config_delete()
985 995
 {
986
-   if [ -f "${BOOTSTRAP_DIR}.local/config/$1" ]
996
+   local key="$1"
997
+   local value="$2"
998
+
999
+   local configdir
1000
+
1001
+   configdir="${BOOTSTRAP_DIR}.local/config"
1002
+
1003
+   if [ "${OPTION_GLOBAL}" = "YES" ]
987 1004
    then
988
-      exekutor rm "${BOOTSTRAP_DIR}.local/config/$1"  >&2
1005
+      configdir="${HOME}/.mulle-bootstrap"
1006
+   fi
1007
+
1008
+   if [ -f "${configdir}/$1" ]
1009
+   then
1010
+      exekutor rm "${configdir}/$1"  >&2
989 1011
       exekutor touch "${BOOTSTRAP_DIR}.local"  >&2
990 1012
    fi
991 1013
 }
... ...
@@ -1026,7 +1118,7 @@ _expansion_write()
1026 1026
 
1027 1027
 _expansion_append()
1028 1028
 {
1029
-   fail "Not yet implemented"
1029
+   internal_fail "Not yet implemented"
1030 1030
 }
1031 1031
 
1032 1032
 
... ...
@@ -1043,7 +1135,7 @@ _expansion_delete()
1043 1043
 
1044 1044
 _expansion_list()
1045 1045
 {
1046
-   fail "Not yet implemented"
1046
+   internal_fail "Not yet implemented"
1047 1047
 }
1048 1048
 
1049 1049
 
... ...
@@ -88,7 +88,7 @@ git_must_be_clean()
88 88
    local clean
89 89
 
90 90
    clean=`git status -s`
91
-   if [ "${clean}" != "" ]
91
+   if [ ! -z "${clean}" ]
92 92
    then
93 93
       log_error "Repository \"$name\" is not ready to be tagged yet."
94 94
       if [ "${MULLE_FLAG_LOG_TERSE}" != "YES" ]
95 95
new file mode 100755
... ...
@@ -0,0 +1,136 @@
0
+#! /bin/sh
1
+
2
+clear_test_dirs()
3
+{
4
+   local i
5
+
6
+   for i in "$@"
7
+   do
8
+      if [ -d "$i" ]
9
+      then
10
+         rm -rf "$i"
11
+      fi
12
+   done
13
+}
14
+
15
+
16
+fail()
17
+{
18
+   echo "failed" "$@" >&2
19
+   exit 1
20
+}
21
+
22
+
23
+run_mulle_bootstrap()
24
+{
25
+   echo "####################################" >&2
26
+   echo mulle-bootstrap "$@"  >&2
27
+   echo "####################################" >&2
28
+
29
+   mulle-bootstrap "$@" || fail "mulle-bootstrap failed"
30
+}
31
+
32
+
33
+#
34
+#
35
+#
36
+setup()
37
+{
38
+   [ -d a ] && rm -rf a
39
+   [ -d b ] && rm -rf b
40
+   [ -d c ] && rm -rf c
41
+
42
+   mkdir a
43
+   mkdir b
44
+   mkdir c
45
+
46
+   (
47
+      cd a
48
+
49
+      mkdir -p .bootstrap
50
+      echo "b" > .bootstrap/repositories
51
+
52
+      mkdir -p .bootstrap/b.build/bin
53
+      echo "echo a/.bootstrap/b.build/bin/pre-build.sh >&2" > .bootstrap/b.build/bin/pre-build.sh
54
+      chmod 755 .bootstrap/b.build/bin/pre-build.sh
55
+      # echo "echo a/.bootstrap/b.build/bin/post-build.sh >&2" > .bootstrap/b.build/bin/post-build.sh
56
+      # chmod 755 .bootstrap/b.build/bin/post-build.sh
57
+
58
+      mkdir -p .bootstrap/bin
59
+      echo "echo a/.bootstrap/bin/pre-build.sh >&2" > .bootstrap/bin/pre-build.sh
60
+      chmod 755 .bootstrap/bin/pre-build.sh
61
+      echo "echo a/.bootstrap/bin/post-build.sh >&2" > .bootstrap/bin/post-build.sh
62
+      chmod 755 .bootstrap/bin/post-build.sh
63
+      echo "echo a/.bootstrap/bin/build.sh >&2" > .bootstrap/bin/build.sh
64
+      chmod 755 .bootstrap/bin/build.sh
65
+   )
66
+
67
+   (
68
+      cd b
69
+
70
+      mkdir -p .bootstrap
71
+      echo "c" > .bootstrap/repositories
72
+
73
+      mkdir -p .bootstrap/c.build/bin
74
+      echo "echo b/.bootstrap/c.build/bin/pre-build.sh >&2" > .bootstrap/c.build/bin/pre-build.sh
75
+      chmod 755 .bootstrap/c.build/bin/pre-build.sh
76
+      echo "echo b/.bootstrap/c.build/bin/post-build.sh >&2" > .bootstrap/c.build/bin/post-build.sh
77
+      chmod 755 .bootstrap/c.build/bin/post-build.sh
78
+
79
+      mkdir -p .bootstrap/bin
80
+      echo "echo b/.bootstrap/bin/pre-build.sh >&2" > .bootstrap/bin/pre-build.sh
81
+      chmod 755 .bootstrap/bin/pre-build.sh
82
+      echo "echo b/.bootstrap/bin/post-build.sh >&2" > .bootstrap/bin/post-build.sh
83
+      chmod 755 .bootstrap/bin/post-build.sh
84
+      echo "echo b/.bootstrap/bin/build.sh >&2" > .bootstrap/bin/build.sh
85