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 87
 **The changes should be harmless, but to be safe
86 88
 `mulle-bootstrap dist clean` your projects**
87 89
 
88
-
89 90
 This version has some additions, that enable a more flexible use of
90 91
 embedded repositories to "compose" source trees. Up till 2.1 embedded
91 92
 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 108
 }
108 109
 
109 110
 
111
+define_local_keyvalue()
112
+{
113
+   local keyvalue
114
+
115
+   keyvalue="$1"
116
+
117
+   if [ -z "${keyvalue}" ]
118
+   then
119
+      fail "Missing key, directly after -D"
120
+      usage
121
+   fi
122
+
123
+   [ -z "${MULLE_BOOTSTRAP_FUNCTIONS_SH}" ] && . mulle-bootstrap-functions.sh
124
+
125
+   local key
126
+   local value
127
+
128
+   key="`echo "${keyvalue}" | cut -d= -f1`"
129
+   if [ -z "${key}" ]
130
+   then
131
+      key="${keyvalue}"
132
+      value="YES"
133
+   else
134
+      value="`echo "${keyvalue}" | cut -d= -f2-`"
135
+   fi
136
+
137
+   local path
138
+
139
+   path="${BOOTSTRAP_SUBDIR}.local/${key}"
140
+   mkdir_if_missing "`dirname -- "${path}"`"
141
+   redirect_exekutor "${path}" echo "# commandline argument -D${keyvalue}
142
+${value}"
143
+}
144
+
145
+
110 146
 bootstrap_nomagic_main()
111 147
 {
112 148
    local command
... ...
@@ -249,10 +285,6 @@ bootstrap_main()
249 285
             GITOPTIONS="`concat "${GITOPTIONS}" "-v"`"
250 286
          ;;
251 287
 
252
-         -V|--verbose-build)
253
-            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
254
-         ;;
255
-
256 288
          -v|--verbose)
257 289
             MULLE_BOOTSTRAP_TRACE="VERBOSE"
258 290
             COPYMOVEFLAGS="-v"
... ...
@@ -281,6 +313,15 @@ bootstrap_main()
281 313
             usage
282 314
          ;;
283 315
 
316
+         -D*)  # just like C
317
+            # define key values (by putting them into .bootstrap.local)
318
+            define_local_keyvalue "`echo "$1" | sed s'/^-D[ ]*//'`"
319
+         ;;
320
+
321
+         -V|--verbose-build)
322
+            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
323
+         ;;
324
+
284 325
          -*)
285 326
             log_error "${MULLE_BOOTSTRAP_FAIL_PREFIX}: Unknown flag \"$1\""
286 327
             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 693
       fi
693 694
    fi
694 695
 
696
+   #
697
+   # If we symlinked the repositiory, we don't embed
698
+   # repos into it, unless the user is really crazy
699
+   #
695 700
    if [ "${COMMAND}" = "fetch" -a "${DONT_RECURSE}" = "" ]
696 701
    then
697
-      ROOT_BOOTSTRAP_SUBDIR="${BOOTSTRAP_SUBDIR}"
702
+      if [ ! -L "${dstdir}" -o "${MULLE_BOOTSTRAP_UPDATE_SYMLINKS}" = "YES" ]
703
+      then
704
+         ROOT_BOOTSTRAP_SUBDIR="${BOOTSTRAP_SUBDIR}"
698 705
 
699
-      BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
700
-      clone_embedded_repositories "${dstdir}/"
701
-      BOOTSTRAP_SUBDIR="${ROOT_BOOTSTRAP_SUBDIR}"
706
+         BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
707
+         clone_embedded_repositories "${dstdir}/"
708
+         BOOTSTRAP_SUBDIR="${ROOT_BOOTSTRAP_SUBDIR}"
709
+      fi
702 710
    fi
703 711
 
704 712
    if [ $run_script -eq 0 ]
... ...
@@ -795,17 +803,20 @@ clone_repositories()
795 803
             IFS="${DEFAULT_IFS}"
796 804
 
797 805
             clone="`expanded_variables "${clone}"`"
806
+            __parse_expanded_clone "${clone}"
798 807
 
799
-            # avoid superflous updates
800
-            match="`echo "${fetched}" | grep -x "${clone}"`"
808
+            #
809
+            # avoid superflous updates, match by "canonical name"
810
+            # this has the advantage, that https://foo/a.git and
811
+            # git:foo.git match
812
+            #
813
+            match="`echo "${fetched}" | fgrep -s -x "${name}"`"
801 814
             # could remove prefixes here https:// http://
802 815
 
803
-            if [ "${match}" != "${clone}" ]
816
+            if [ "${match}" != "${name}" ]
804 817
             then
805 818
                fetched="${fetched}
806
-${clone}"
807
-
808
-               __parse_expanded_clone "${clone}"
819
+${name}"
809 820
 
810 821
                if clone_repository "${name}" "${url}" "${branch}" "${scm}"
811 822
                then
... ...
@@ -1065,19 +1076,19 @@ update_repositories()
1065 1076
          do
1066 1077
             IFS="${DEFAULT_IFS}"
1067 1078
 
1068
-            clone="`expanded_variables "${clone}"`"
1079
+            __parse_clone "${clone}"
1069 1080
 
1081
+            #
1070 1082
             # avoid superflous updates
1071
-            match="`echo "${updated}" | grep -x "${clone}"`"
1072
-
1073
-            if [ "${match}" = "${clone}" ]
1083
+            # match by name
1084
+            #
1085
+            match="`echo "${updated}" | fgrep -s -x "${name}"`"
1086
+            if [ "${match}" = "${name}" ]
1074 1087
             then
1075 1088
                continue
1076 1089
             fi
1077
-
1078 1090
             updated="${updated}
1079
-${clone}"
1080
-            __parse_expanded_clone "${clone}"
1091
+${name}"
1081 1092
 
1082 1093
             dstdir="${CLONESFETCH_SUBDIR}/${name}"
1083 1094
 
... ...
@@ -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 581
 
576 582
          __parse_embedded_clone "${clone}"
577 583
 
578
-         dstprefix="${CLONESFETCH_SUBDIR}/${subdir}/"
579
-
580
-         if [ ! -L "${dstprefix}" ]
584
+         if [ ! -L "${CLONESFETCH_SUBDIR}/${subdir}" ]
581 585
          then
586
+            dstprefix="${CLONESFETCH_SUBDIR}/${subdir}/"
582 587
             previous_bootstrap="${BOOTSTRAP_SUBDIR}"
583 588
             previous_clones="${CLONESFETCH_SUBDIR}"
584 589
             BOOTSTRAP_SUBDIR="${dstprefix}.bootstrap"
... ...
@@ -589,7 +594,7 @@ refresh_deeply_embedded_repositories()
589 594
             BOOTSTRAP_SUBDIR="${previous_bootstrap}"
590 595
             CLONESFETCH_SUBDIR="${previous_clones}"
591 596
          else
592
-            log_warn  "Don't refresh embedded repositories of symlinked \"${name}\""
597
+            log_fluff "Don't refresh embedded repositories of symlinked \"${name}\""
593 598
          fi
594 599
       done
595 600
       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 299
    scm="`scm_from_clone "${clone}"`"
304 300
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
305 301
 
306
-
307 302
    case "${name}" in
308 303
       /*|~*|..*|.*)
309
-         fail "Destination name \"${name}\" of repository ${name} looks fishy"
304
+         fail "Destination \"${name}\" of ${1} looks fishy"
310 305
       ;;
311 306
    esac
312 307
 }
... ...
@@ -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 50
 git_get_url()
50 51
 {
51 52
    local remote
53
+
52 54
    remote="$2"
53 55
 
54 56
    ( cd "$1" ; git remote get-url "${remote}" )
55 57
new file mode 100755
... ...
@@ -0,0 +1,35 @@
1
+#! /bin/sh
2
+
3
+. mulle-bootstrap-functions.sh
4
+. mulle-bootstrap-local-environment.sh
5
+
6
+
7
+run_test()
8
+{
9
+  expect="$1"
10
+  shift
11
+
12
+  result="`eval "$@"`"
13
+
14
+  [ "${result}" != "${expect}" ] && fail "test:" "$@" "failed with \"${result}\", expected \"${expect}\""
15
+}
16
+
17
+
18
+test_expand()
19
+{
20
+  FOO="foo"
21
+
22
+  run_test "foo" expanded_variables '${FOO}'
23
+  run_test "foo" expanded_variables '${FOO:-bar}'
24
+
25
+  run_test "foofoo" expanded_variables '${FOO}${FOO}'
26
+
27
+  run_test "" expanded_variables '${BAR}'
28
+  run_test "foo" expanded_variables '${BAR:-foo}'
29
+
30
+  # obscure but OK
31
+  run_test "-bar" expanded_variables '${FOO+-bar}'
32
+}
33
+
34
+
35
+test_expand
0 36
new file mode 100755
... ...
@@ -0,0 +1,111 @@
1
+#! /bin/sh
2
+
3
+# test doesn't work on MINGW
4
+case "`uname`" in
5
+   MINGW*)
6
+      exit 0
7
+   ;;
8
+esac
9
+
10
+
11
+create_demo_repo()
12
+{
13
+   local name
14
+
15
+   name="$1"
16
+
17
+   set -e
18
+      mkdir "${name}"
19
+      cd "${name}"
20
+         echo "# ${name}" > README.md
21
+         git init
22
+         git add README.md
23
+         git commit -m "Merciful Release" README.md
24
+      cd ..
25
+   set +e
26
+}
27
+
28
+fail()
29
+{
30
+   echo "$@" >&2
31
+   exit 1
32
+}
33
+
34
+
35
+##
36
+## Setup test environment
37
+##
38
+
39
+
40
+rm -rf a b c  2> /dev/null
41
+
42
+create_demo_repo a
43
+create_demo_repo b
44
+create_demo_repo c
45
+
46
+# b embeds a
47
+(
48
+   cd b;
49
+   mkdir .bootstrap ;
50
+   echo "../a;src/a" > .bootstrap/embedded_repositories ;
51
+   git add .bootstrap/embedded_repositories ;
52
+   git commit -m "embedded added"
53
+)
54
+
55
+# c depends on b
56
+(
57
+   cd c ;
58
+   mkdir .bootstrap ;
59
+   echo "../b" > .bootstrap/repositories ;
60
+   git add .bootstrap/repositories ;
61
+   git commit -m "repository added"
62
+)
63
+
64
+
65
+##
66
+## Now test
67
+##
68
+echo "--| 1 |--------------------------------"
69
+(
70
+   cd c ;
71
+   mulle-bootstrap -y fetch  ;  # use symlink
72
+
73
+   [ ! -L .repos/b ]     && fail "failed to symlink b" ;
74
+   [ -d .repos/b/src/a ] && fail "superzealously embedded a" ;
75
+   :
76
+) || exit 1
77
+
78
+#
79
+# Make embedded repository appear
80
+#
81
+echo "--| 2 |--------------------------------"
82
+(
83
+   cd b ;
84
+   mulle-bootstrap -y fetch  ;  # can't use symlink here
85
+
86
+   [ ! -d src/a ] && fail "failed to embed a" ;
87
+   [ -L src/a ]   && fail "mistakenly embedded a as a symlink" ;
88
+   :
89
+) || exit 1
90
+
91
+
92
+#
93
+# now move embedded repository (c should not touch it)
94
+#
95
+echo "--| 3 |--------------------------------"
96
+(
97
+   cd b ;
98
+   echo "../a;a" > .bootstrap/embedded_repositories
99
+)
100
+
101
+(
102
+   cd c ;
103
+   mulle-bootstrap -y fetch  ;  # use symlink
104
+
105
+   [ ! -L .repos/b ]     && fail "failed to symlink b" ;
106
+   [ ! -d .repos/b/src/a ] && fail "superzealously removed a" ;
107
+   [ -d .repos/b/a ]     && fail "superzealously added a" ;
108
+   :
109
+) || exit 1
110
+
111
+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
 }