Browse code

Add a test. Fix a function Add new -DKEY=VALUE flag to mulle-bootstrap.

Nat! authored on 26/10/2016 11:59:44
Showing 13 changed files
... ...
@@ -33,13 +33,15 @@ edit is less than a second after the last refresh run. Death of the hidden -fr f
33 33
 * -f flag will now also try to checkout branches, that are checked out
34 34
 incorrectly
35 35
 * fetch gains -i option, to ignore "wrongly" checked out repositories
36
-* fails are prefixed with the command, that caused the failure now
36
+* fails are prefixed with the command, that caused the failure
37 37
 * use unexpanded URLs for dependency matches and store those into .bootstrap.auto
38 38
 * mulle-bootstrap now picks up URL changes and corrects them in fetched
39 39
 repositiories, but that does not per se force an update.
40 40
 * try to detect changes in .bootstrap better
41 41
 * improved retrieval of settings for embedded repositories
42 42
 * improved dependency code
43
+* some more checks, that embedded repositories do not clobber symlinked content
44
+* added -D bootstrap flag to create .bootstrap.local definition files. Convenient for specifiying alternate URLs for example.
43 45
 
44 46
 
45 47
 2.2.1
... ...
@@ -85,7 +87,6 @@ works
85 85
 **The changes should be harmless, but to be safe
86 86
 `mulle-bootstrap dist clean` your projects**
87 87
 
88
-
89 88
 This version has some additions, that enable a more flexible use of
90 89
 embedded repositories to "compose" source trees. Up till 2.1 embedded
91 90
 repositories were always placed into the project root. Now you can
... ...
@@ -56,6 +56,7 @@ usage: mulle-bootstrap [flags] [command] [options]
56 56
    -f        : force operation
57 57
    -n        : do nothing creative or destructive
58 58
    -v        : -v to be more verbose (-vv or -vvv for more verbosity)
59
+   -DKEY=VAL : define local key/value C style
59 60
 
60 61
  Commands:
61 62
    bootstrap : does fetch and build recursively [default]
... ...
@@ -107,6 +108,41 @@ Well, do ya, punk?"
107 107
 }
108 108
 
109 109
 
110
+define_local_keyvalue()
111
+{
112
+   local keyvalue
113
+
114
+   keyvalue="$1"
115
+
116
+   if [ -z "${keyvalue}" ]
117
+   then
118
+      fail "Missing key, directly after -D"
119
+      usage
120
+   fi
121
+
122
+   [ -z "${MULLE_BOOTSTRAP_FUNCTIONS_SH}" ] && . mulle-bootstrap-functions.sh
123
+
124
+   local key
125
+   local value
126
+
127
+   key="`echo "${keyvalue}" | cut -d= -f1`"
128
+   if [ -z "${key}" ]
129
+   then
130
+      key="${keyvalue}"
131
+      value="YES"
132
+   else
133
+      value="`echo "${keyvalue}" | cut -d= -f2-`"
134
+   fi
135
+
136
+   local path
137
+
138
+   path="${BOOTSTRAP_SUBDIR}.local/${key}"
139
+   mkdir_if_missing "`dirname -- "${path}"`"
140
+   redirect_exekutor "${path}" echo "# commandline argument -D${keyvalue}
141
+${value}"
142
+}
143
+
144
+
110 145
 bootstrap_nomagic_main()
111 146
 {
112 147
    local command
... ...
@@ -249,10 +285,6 @@ bootstrap_main()
249 249
             GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
250 250
          ;;
251 251
 
252
-         -V|--verbose-build)
253
-            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
254
-         ;;
255
-
256 252
          -v|--verbose)
257 253
             MULLE_BOOTSTRAP_TRACE="VERBOSE"
258 254
             COPYMOVEFLAGS="-v"
... ...
@@ -281,6 +313,15 @@ bootstrap_main()
281 281
             usage
282 282
          ;;
283 283
 
284
+         -D*)  # just like C
285
+            # define key values (by putting them into .bootstrap.local)
286
+            define_local_keyvalue "`echo "$1" | sed s'/^-D[ ]*//'`"
287
+         ;;
288
+
289
+         -V|--verbose-build)
290
+            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
291
+         ;;
292
+
284 293
          -*)
285 294
             log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown flag \"$1\""
286 295
             usage
... ...
@@ -74,7 +74,7 @@ bootstrap_auto_update_merge()
74 74
          continue
75 75
       fi
76 76
 
77
-      match="`echo "${NON_MERGABLE_SETTINGS}" | fgrep -x "${settingname}"`"
77
+      match="`echo "${NON_MERGABLE_SETTINGS}" | fgrep -s -x "${settingname}"`"
78 78
       if [ ! -z "${match}" ]
79 79
       then
80 80
          log_fluff "Setting \"${settingname}\" is not mergable"
... ...
@@ -308,6 +308,7 @@ ask_symlink_it()
308 308
    local  clone
309 309
 
310 310
    clone="$1"
311
+
311 312
    if [ ! -d "${clone}" ]
312 313
    then
313 314
       fail "You need to check out ${clone} yourself, as it's not there."
... ...
@@ -692,13 +693,20 @@ checkout_repository()
692 692
       fi
693 693
    fi
694 694
 
695
+   #
696
+   # If we symlinked the repositiory, we don't embed
697
+   # repos into it, unless the user is really crazy
698
+   #
695 699
    if [ "${COMMAND}" = "fetch" -a "${DONT_RECURSE}" = "" ]
696 700
    then
697
-      ROOT_BOOTSTRAP_SUBDIR="${BOOTSTRAP_SUBDIR}"
701
+      if [ ! -L "${dstdir}" -o "${MULLE_BOOTSTRAP_UPDATE_SYMLINKS}" = "YES" ]
702
+      then
703
+         ROOT_BOOTSTRAP_SUBDIR="${BOOTSTRAP_SUBDIR}"
698 704
 
699
-      BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
700
-      clone_embedded_repositories "${dstdir}/"
701
-      BOOTSTRAP_SUBDIR="${ROOT_BOOTSTRAP_SUBDIR}"
705
+         BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
706
+         clone_embedded_repositories "${dstdir}/"
707
+         BOOTSTRAP_SUBDIR="${ROOT_BOOTSTRAP_SUBDIR}"
708
+      fi
702 709
    fi
703 710
 
704 711
    if [ $run_script -eq 0 ]
... ...
@@ -795,17 +803,20 @@ clone_repositories()
795 795
             IFS="${DEFAULT_IFS}"
796 796
 
797 797
             clone="`expanded_variables "${clone}"`"
798
+            __parse_expanded_clone "${clone}"
798 799
 
799
-            # avoid superflous updates
800
-            match="`echo "${fetched}" | grep -x "${clone}"`"
800
+            #
801
+            # avoid superflous updates, match by "canonical name"
802
+            # this has the advantage, that https://foo/a.git and
803
+            # git:foo.git match
804
+            #
805
+            match="`echo "${fetched}" | fgrep -s -x "${name}"`"
801 806
             # could remove prefixes here https:// http://
802 807
 
803
-            if [ "${match}" != "${clone}" ]
808
+            if [ "${match}" != "${name}" ]
804 809
             then
805 810
                fetched="${fetched}
806
-${clone}"
807
-
808
-               __parse_expanded_clone "${clone}"
811
+${name}"
809 812
 
810 813
                if clone_repository "${name}" "${url}" "${branch}" "${scm}"
811 814
                then
... ...
@@ -1065,19 +1076,19 @@ update_repositories()
1065 1065
          do
1066 1066
             IFS="${DEFAULT_IFS}"
1067 1067
 
1068
-            clone="`expanded_variables "${clone}"`"
1068
+            __parse_clone "${clone}"
1069 1069
 
1070
+            #
1070 1071
             # avoid superflous updates
1071
-            match="`echo "${updated}" | grep -x "${clone}"`"
1072
-
1073
-            if [ "${match}" = "${clone}" ]
1072
+            # match by name
1073
+            #
1074
+            match="`echo "${updated}" | fgrep -s -x "${name}"`"
1075
+            if [ "${match}" = "${name}" ]
1074 1076
             then
1075 1077
                continue
1076 1078
             fi
1077
-
1078 1079
             updated="${updated}
1079
-${clone}"
1080
-            __parse_expanded_clone "${clone}"
1080
+${name}"
1081 1081
 
1082 1082
             dstdir="${CLONESFETCH_SUBDIR}/${name}"
1083 1083
 
... ...
@@ -297,6 +297,11 @@ expand_environment_variables()
297 297
        prefix="`echo "${string}" | sed 's/^\(.*\)\${\([A-Za-z_][A-Za-z0-9_:-]*\)}\(.*\)$/\1/'`"
298 298
        suffix="`echo "${string}" | sed 's/^\(.*\)\${\([A-Za-z_][A-Za-z0-9_:-]*\)}\(.*\)$/\3/'`"
299 299
        value="`eval echo \$\{${key}\}`"
300
+       if [ -z "${value}" ]
301
+       then
302
+          log_verbose "${key} expanded to empty string ($1)"
303
+       fi
304
+
300 305
        next="${prefix}${value}${suffix}"
301 306
        if [ "${next}" != "${string}" ]
302 307
        then
... ...
@@ -155,8 +155,6 @@ concat()
155 155
 }
156 156
 
157 157
 
158
-
159
-
160 158
 # Escape sequence and resets, should use tput here instead of ANSI
161 159
 logging_initialize()
162 160
 {
... ...
@@ -401,7 +401,13 @@ bury_embedded_zombies()
401 401
             dstdir="`embedded_repository_subdir_from_file "${i}" "${CLONESFETCH_SUBDIR}/.embedded"`"
402 402
             dstdir="${dstprefix}${dstdir}"
403 403
 
404
-            if [ -d "${dstdir}" -o -L "${dstdir}" ]
404
+            if [ -L "${dstdir}" -a "${MULLE_BOOTSTRAP_UPDATE_SYMLINKS}" != "YES" ]
405
+            then
406
+               log_fluff "${dstdir} is symlinked, so ignored"
407
+               continue
408
+            fi
409
+
410
+            if [ -d "${dstdir}" ]
405 411
             then
406 412
                name="`basename -- "${i}"`"
407 413
 
... ...
@@ -575,10 +581,9 @@ refresh_deeply_embedded_repositories()
575 575
 
576 576
          __parse_embedded_clone "${clone}"
577 577
 
578
-         dstprefix="${CLONESFETCH_SUBDIR}/${subdir}/"
579
-
580
-         if [ ! -L "${dstprefix}" ]
578
+         if [ ! -L "${CLONESFETCH_SUBDIR}/${subdir}" ]
581 579
          then
580
+            dstprefix="${CLONESFETCH_SUBDIR}/${subdir}/"
582 581
             previous_bootstrap="${BOOTSTRAP_SUBDIR}"
583 582
             previous_clones="${CLONESFETCH_SUBDIR}"
584 583
             BOOTSTRAP_SUBDIR="${dstprefix}.bootstrap"
... ...
@@ -589,7 +594,7 @@ refresh_deeply_embedded_repositories()
589 589
             BOOTSTRAP_SUBDIR="${previous_bootstrap}"
590 590
             CLONESFETCH_SUBDIR="${previous_clones}"
591 591
          else
592
-            log_warn  "Don't refresh embedded repositories of symlinked \"${name}\""
592
+            log_fluff "Don't refresh embedded repositories of symlinked \"${name}\""
593 593
          fi
594 594
       done
595 595
       IFS="${DEFAULT_IFS}"
... ...
@@ -44,16 +44,12 @@ MULLE_BOOTSTRAP_REPOSITORIES_SH="included"
44 44
 # https://www./foo.git
45 45
 # host:foo
46 46
 #
47
-
48 47
 canonical_clone_name()
49 48
 {
50 49
    local  url
51 50
 
52 51
    url="$1"
53
-
54
-
55 52
    # cut off scheme part
56
-
57 53
    case "$url" in
58 54
       *:*)
59 55
          url="`echo "$@" | sed 's/^\(.*\):\(.*\)/\2/'`"
... ...
@@ -303,10 +299,9 @@ __parse_expanded_clone()
303 303
    scm="`scm_from_clone "${clone}"`"
304 304
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
305 305
 
306
-
307 306
    case "${name}" in
308 307
       /*|~*|..*|.*)
309
-         fail "Destination name \"${name}\" of repository ${name} looks fishy"
308
+         fail "Destination \"${name}\" of ${1} looks fishy"
310 309
       ;;
311 310
    esac
312 311
 }
... ...
@@ -30,9 +30,10 @@
30 30
 #
31 31
 MULLE_BOOTSTRAP_SCM_SH="included"
32 32
 
33
+
33 34
 git_is_repository()
34 35
 {
35
-   [ -d "${dstdir}.git" ] || [ -d  "${dstdir}/refs" -a  -f "${dstdir}/HEAD" ]
36
+   [ -d "${1}.git" ] || [ -d  "${1}/refs" -a  -f "${1}/HEAD" ]
36 37
 }
37 38
 
38 39
 
... ...
@@ -49,6 +50,7 @@ git_is_bare_repository()
49 49
 git_get_url()
50 50
 {
51 51
    local remote
52
+
52 53
    remote="$2"
53 54
 
54 55
    ( cd "$1" ; git remote get-url "${remote}" )
55 56
new file mode 100755
... ...
@@ -0,0 +1,35 @@
0
+#! /bin/sh
1
+
2
+. mulle-bootstrap-functions.sh
3
+. mulle-bootstrap-local-environment.sh
4
+
5
+
6
+run_test()
7
+{
8
+  expect="$1"
9
+  shift
10
+
11
+  result="`eval "$@"`"
12
+
13
+  [ "${result}" != "${expect}" ] && fail "test:" "$@" "failed with \"${result}\", expected \"${expect}\""
14
+}
15
+
16
+
17
+test_expand()
18
+{
19
+  FOO="foo"
20
+
21
+  run_test "foo" expanded_variables '${FOO}'
22
+  run_test "foo" expanded_variables '${FOO:-bar}'
23
+
24
+  run_test "foofoo" expanded_variables '${FOO}${FOO}'
25
+
26
+  run_test "" expanded_variables '${BAR}'
27
+  run_test "foo" expanded_variables '${BAR:-foo}'
28
+
29
+  # obscure but OK
30
+  run_test "-bar" expanded_variables '${FOO+-bar}'
31
+}
32
+
33
+
34
+test_expand
0 35
new file mode 100755
... ...
@@ -0,0 +1,111 @@
0
+#! /bin/sh
1
+
2
+# test doesn't work on MINGW
3
+case "`uname`" in
4
+   MINGW*)
5
+      exit 0
6
+   ;;
7
+esac
8
+
9
+
10
+create_demo_repo()
11
+{
12
+   local name
13
+
14
+   name="$1"
15
+
16
+   set -e
17
+      mkdir "${name}"
18
+      cd "${name}"
19
+         echo "# ${name}" > README.md
20
+         git init
21
+         git add README.md
22
+         git commit -m "Merciful Release" README.md
23
+      cd ..
24
+   set +e
25
+}
26
+
27
+fail()
28
+{
29
+   echo "$@" >&2
30
+   exit 1
31
+}
32
+
33
+
34
+##
35
+## Setup test environment
36
+##
37
+
38
+
39
+rm -rf a b c  2> /dev/null
40
+
41
+create_demo_repo a
42
+create_demo_repo b
43
+create_demo_repo c
44
+
45
+# b embeds a
46
+(
47
+   cd b;
48
+   mkdir .bootstrap ;
49
+   echo "../a;src/a" > .bootstrap/embedded_repositories ;
50
+   git add .bootstrap/embedded_repositories ;
51
+   git commit -m "embedded added"
52
+)
53
+
54
+# c depends on b
55
+(
56
+   cd c ;
57
+   mkdir .bootstrap ;
58
+   echo "../b" > .bootstrap/repositories ;
59
+   git add .bootstrap/repositories ;
60
+   git commit -m "repository added"
61
+)
62
+
63
+
64
+##
65
+## Now test
66
+##
67
+echo "--| 1 |--------------------------------"
68
+(
69
+   cd c ;
70
+   mulle-bootstrap -y fetch  ;  # use symlink
71
+
72
+   [ ! -L .repos/b ]     && fail "failed to symlink b" ;
73
+   [ -d .repos/b/src/a ] && fail "superzealously embedded a" ;
74
+   :
75
+) || exit 1
76
+
77
+#
78
+# Make embedded repository appear
79
+#
80
+echo "--| 2 |--------------------------------"
81
+(
82
+   cd b ;
83
+   mulle-bootstrap -y fetch  ;  # can't use symlink here
84
+
85
+   [ ! -d src/a ] && fail "failed to embed a" ;
86
+   [ -L src/a ]   && fail "mistakenly embedded a as a symlink" ;
87
+   :
88
+) || exit 1
89
+
90
+
91
+#
92
+# now move embedded repository (c should not touch it)
93
+#
94
+echo "--| 3 |--------------------------------"
95
+(
96
+   cd b ;
97
+   echo "../a;a" > .bootstrap/embedded_repositories
98
+)
99
+
100
+(
101
+   cd c ;
102
+   mulle-bootstrap -y fetch  ;  # use symlink
103
+
104
+   [ ! -L .repos/b ]     && fail "failed to symlink b" ;
105
+   [ ! -d .repos/b/src/a ] && fail "superzealously removed a" ;
106
+   [ -d .repos/b/a ]     && fail "superzealously added a" ;
107
+   :
108
+) || exit 1
109
+
110
+echo "--| PASS |-----------------------------"
... ...
@@ -18,7 +18,7 @@ setup()
18 18
       echo "# a" > README.md
19 19
       git init
20 20
       git add README.md
21
-      git commit -m "Mercyful Release"
21
+      git commit -m "Merciful Release"
22 22
       cd ..
23 23
 
24 24
    cd b
... ...
@@ -27,7 +27,7 @@ setup()
27 27
       echo "# b" > README.md
28 28
       git init
29 29
       git add README.md .bootstrap/embedded_repositories
30
-      git commit -m "Mercyful Release"
30
+      git commit -m "Merciful Release"
31 31
       cd ..
32 32
 
33 33
 
... ...
@@ -37,7 +37,7 @@ setup()
37 37
       echo "# c" > README.md
38 38
       git init
39 39
       git add README.md .bootstrap/embedded_repositories
40
-      git commit -m "Mercyful Release"
40
+      git commit -m "Merciful Release"
41 41
       cd ..
42 42
 
43 43
    cd d
... ...
@@ -46,7 +46,7 @@ setup()
46 46
       echo "# d" > README.md
47 47
       git init
48 48
       git add README.md .bootstrap/repositories
49
-      git commit -m "Mercyful Release"
49
+      git commit -m "Merciful Release"
50 50
       cd ..
51 51
 
52 52
 }
... ...
@@ -12,7 +12,7 @@ create_demo_repo()
12 12
    echo "# ${name}" > README.md
13 13
    git init
14 14
    git add README.md
15
-   git commit -m "Mercyful Release" README.md
15
+   git commit -m "Merciful Release" README.md
16 16
    cd ..
17 17
    set +e
18 18
 }