ソースを参照

Update MKit to v0.0.13

Alois Mahdal 8 年 前
コミット
1239f82ee6
共有7 個のファイルを変更した488 個の追加387 個の削除を含む
  1. 119
    183
      utils/mkit/include/build.sh
  2. 29
    24
      utils/mkit/include/deploy.sh
  3. 175
    0
      utils/mkit/include/facts.sh
  4. 40
    19
      utils/mkit/include/ini.sh
  5. 37
    58
      utils/mkit/include/mkit.sh
  6. 87
    102
      utils/mkit/include/release.sh
  7. 1
    1
      utils/mkit/make

+ 119
- 183
utils/mkit/include/build.sh ファイルの表示

@@ -1,21 +1,10 @@
1 1
 #!/bin/bash
2 2
 
3
-. "$MKIT_DIR/include/ini.sh" || die "cannot import ini.sh"
3
+. "$MKIT_DIR/include/ini.sh"   || die "cannot import ini.sh"
4
+. "$MKIT_DIR/include/facts.sh" || die "cannot import facts.sh"
4 5
 
5 6
 
6
-build() {
7
-    #
8
-    # Add meat to all skeletons
9
-    #
10
-    local srcpath
11
-    find src -type f -name '*.skel' \
12
-     | while read srcpath;
13
-       do
14
-           build1 "$srcpath"
15
-       done
16
-}
17
-
18
-build1() {
7
+_build1() {
19 8
     #
20 9
     # Process one skeleton
21 10
     #
@@ -23,14 +12,84 @@ build1() {
23 12
     local dstpath="$2"
24 13
     local ftype="$3"
25 14
     test -n "$dstpath"  || dstpath=${srcpath%.skel}
26
-    test -n "$ftype"    || ftype=$(guess_ftype "$dstpath")
15
+    test -n "$ftype"    || ftype=$(_guess_ftype "$dstpath")
27 16
     debug_var srcpath dstpath ftype
28
-    <"$srcpath" build1_ftype "$ftype" >"$dstpath"
17
+    <"$srcpath" _build1_ftype "$ftype" >"$dstpath"
29 18
     mkdir -p "$MKIT_LOCAL"
30 19
     echo "$dstpath" >> "$MKIT_LOCAL/built.lst"
31 20
 }
32 21
 
33
-guess_ftype() {
22
+_build1_ftype() {
23
+    #
24
+    # Build a file of type $1
25
+    #
26
+    local ftype="$1"
27
+    case $ftype in
28
+        MKIT_COMMON)    _expand_tokens "tokens" ;;
29
+        markdown)       _expand_includes | _expand_tokens "tokens" ;;
30
+        rpmstuff)       _expand_tokens "tokens" "rpmstuff:tokens" ;;
31
+        *)              die "unknown file type: $ftype" ;;
32
+    esac
33
+}
34
+
35
+_expand_includes() {
36
+    #
37
+    # Expand include directives
38
+    #
39
+    # Expand e.g. `<!-- include4: foo.sh -->` to include code of foo.sh
40
+    #
41
+    perl -we '
42
+        use strict;
43
+        my $text;
44
+        while (<>) {
45
+            chomp;
46
+            if (m/<!-- include4: (\S+) -->/) {
47
+                open my $fh, $1 or warn "cannot find: $1";
48
+                my $text = do { local($/); <$fh> };
49
+                close $fh;
50
+                $text =~ s/^(.)/    $1/gm;
51
+                chomp $text;
52
+                print "$text\n";
53
+            } else {
54
+                print "$_\n";
55
+            }
56
+        }
57
+    '
58
+}
59
+
60
+_expand_tokens() {
61
+    #
62
+    # Expand tokens from sections $@
63
+    #
64
+    local script=$(mktemp --tmpdir mkit-tmp.XXXXXXXXXX)
65
+    local section varname varvalue
66
+    {
67
+        for section in "$@";
68
+        do
69
+            debug_var section
70
+            ini lskeys "$section" \
71
+              | while read varname;
72
+                do
73
+                    varvalue="$(ini 1value "$section:$varname" | _qfs )"
74
+                    echo "s|$varname|$varvalue|g;"
75
+                    debug_var varname varvalue
76
+                done
77
+        done
78
+        echo "s|__MKIT_PROJ_NAME__|$(ini 1value project:name | _qfs)|g;"
79
+        echo "s|__MKIT_PROJ_CODENAME__|$(ini 1value project:codename | _qfs)|g;"
80
+        echo "s|__MKIT_PROJ_PKGNAME__|$(ini 1value project:pkgname | _qfs)|g;"
81
+        echo "s|__MKIT_PROJ_TAGLINE__|$(ini 1value project:tagline | _qfs)|g;"
82
+        echo "s|__MKIT_PROJ_MAINTAINER__|$(ini 1value project:maintainer | _qfs)|g;"
83
+        echo "s|__MKIT_PROJ_VCS_BROWSER__|$(ini 1value project:vcs_browser | _qfs)|g;"
84
+        echo "s|__MKIT_PROJ_GIT_LASTHASH__|$(git_lasthash | _qfs)|g;"
85
+        echo "s|__MKIT_PROJ_VERSION__|$(semver | _qfs)|g;"
86
+        echo "s|__MKIT_SELF_VERSION__|$MKIT_VERSION|g;"
87
+    } >> "$script"
88
+    sed -f "$script" || die "_expand_tokens failed"
89
+    rm "$script"
90
+}
91
+
92
+_guess_ftype() {
34 93
     #
35 94
     # Guess file type from destination path $1
36 95
     #
@@ -41,17 +100,26 @@ guess_ftype() {
41 100
     esac
42 101
 }
43 102
 
44
-build1_ftype() {
103
+_qfs() {
45 104
     #
46
-    # Build a file of type $1
105
+    # Quote for our sed scipt's RHS
47 106
     #
48
-    local ftype="$1"
49
-    case $ftype in
50
-        MKIT_COMMON)    expand_variables "vars" ;;
51
-        markdown)       expand_includes | expand_variables "vars" ;;
52
-        rpmstuff)       expand_variables "vars" "rpmstuff:vars" ;;
53
-        *)              die "unknown file type: $ftype" ;;
54
-    esac
107
+    sed '
108
+        s:\\:\\\\:g
109
+        s:|:\\|:g
110
+    '
111
+}
112
+
113
+build() {
114
+    #
115
+    # Add meat to all skeletons
116
+    #
117
+    local srcpath
118
+    find src -type f -name '*.skel' \
119
+     | while read srcpath;
120
+       do
121
+           _build1 "$srcpath"
122
+       done
55 123
 }
56 124
 
57 125
 build_manpages() {
@@ -85,30 +153,11 @@ clean() {
85 153
     true
86 154
 }
87 155
 
88
-dist() {
89
-    #
90
-    # Create distributable tarball
91
-    #
92
-    #FIXME: lacking Makefile skills, we do this step twice fot
93
-    #       rpmstuff, hence -f hack for gzip
94
-    #
95
-    local version=$(get_version)
96
-    local dirname=$MKIT_PROJ_PKGNAME-$version
97
-    mkdir -p "$dirname"
98
-    ini values "lists:dist" | xargs -I DIST_ITEM cp -R DIST_ITEM "$dirname"
99
-    update_version "$version" "$dirname/mkit.ini"
100
-    tar -cf "$dirname.tar" "$dirname"
101
-    gzip -f "$dirname.tar"      # see above FIXME
102
-    mkdir -p "$MKIT_LOCAL"
103
-    echo "$dirname.tar.gz" >> "$MKIT_LOCAL/built.lst"
104
-    rm -rf "$dirname"
105
-}
106
-
107 156
 debstuff() {
108 157
     #
109 158
     # Build Debian stuff (eamed tarball, debian dir)
110 159
     #
111
-    local version="$(get_version)"
160
+    local version="$(semver)"
112 161
 
113 162
     # tarball - we should already have by means of 'dist'
114 163
     #
@@ -129,11 +178,33 @@ debstuff() {
129 178
         do
130 179
             dftgt="debian/${dfsrc#$debian_skel}"
131 180
             mkdir -p "$(dirname "$dftgt")"
132
-            build1 "$dfsrc" "$dftgt"
181
+            _build1 "$dfsrc" "$dftgt"
133 182
         done
134 183
     echo debian >> "$MKIT_LOCAL/built.lst"
135 184
 }
136 185
 
186
+dist() {
187
+    #
188
+    # Create distributable tarball
189
+    #
190
+    #FIXME: lacking Makefile skills, we do this step twice fot
191
+    #       rpmstuff, hence -f hack for gzip
192
+    #
193
+    local version=$(semver)
194
+    local git_lasthash=$(git_lasthash)
195
+    local dirname=$MKIT_PROJ_PKGNAME-$version
196
+    mkdir -p "$dirname"
197
+    ini values "lists:dist" | xargs -I DIST_ITEM cp -R DIST_ITEM "$dirname"
198
+    update_version "$version" "$dirname/mkit.ini"
199
+    mkdir -p "$dirname/.mkit"
200
+    echo -n "$git_lasthash" > "$dirname/.mkit/git_lasthash"
201
+    tar -cf "$dirname.tar" "$dirname"
202
+    gzip -f "$dirname.tar"      # see above FIXME
203
+    mkdir -p "$MKIT_LOCAL"
204
+    echo "$dirname.tar.gz" >> "$MKIT_LOCAL/built.lst"
205
+    rm -rf "$dirname"
206
+}
207
+
137 208
 rpmstuff() {
138 209
     #
139 210
     # Build specfile
@@ -142,140 +213,5 @@ rpmstuff() {
142 213
     local specsrc="$(ini 1value "rpmstuff:spec_skel")"
143 214
     test -n "$specsrc" || die "rpmstuff:spec_skel not specified"
144 215
     test -f "$specsrc" || die "specfile template not found: $specsrc"
145
-    build1 "$specsrc" "$specname"
146
-}
147
-
148
-expand_includes() {
149
-    #
150
-    # Expand include directives
151
-    #
152
-    # Expand e.g. `<!-- include4: foo.sh -->` to include code of foo.sh
153
-    #
154
-    perl -we '
155
-        use strict;
156
-        my $text;
157
-        while (<>) {
158
-            chomp;
159
-            if (m/<!-- include4: (\S+) -->/) {
160
-                open my $fh, $1 or warn "cannot find: $1";
161
-                my $text = do { local($/); <$fh> };
162
-                close $fh;
163
-                $text =~ s/^(.)/    $1/gm;
164
-                chomp $text;
165
-                print "$text\n";
166
-            } else {
167
-                print "$_\n";
168
-            }
169
-        }
170
-    '
171
-}
172
-
173
-expand_variables() {
174
-    #
175
-    # Expand variables from sections $@
176
-    #
177
-    local script=$(mktemp --tmpdir mkit-tmp.XXXXXXXXXX)
178
-    local section varname varvalue
179
-    {
180
-        for section in "$@";
181
-        do
182
-            debug_var section
183
-            ini lskeys "$section" \
184
-              | while read varname;
185
-                do
186
-                    varvalue="$(ini 1value "$section:$varname" | sed -e 's/\$/\\$/' )"
187
-                    echo "s|$varname|$varvalue|;"
188
-                    debug_var varname varvalue
189
-                done
190
-        done
191
-        echo "s|__MKIT_PROJ_CODENAME__|$(ini 1value project:codename)|;"
192
-        echo "s|__MKIT_PROJ_PKGNAME__|$(ini 1value project:pkgname)|;"
193
-        echo "s|__MKIT_PROJ_TAGLINE__|$(ini 1value project:tagline)|;"
194
-        echo "s|__MKIT_PROJ_VERSION__|$(get_version)|;"
195
-        echo "s|__MKIT_SELF_VERSION__|$MKIT_VERSION|;"
196
-    } >> "$script"
197
-    perl -wp "$script" || die "expand_variables failed"
198
-    rm "$script"
199
-}
200
-
201
-get_version() {
202
-    #
203
-    # Build semver version string with build metadata
204
-    #
205
-    # Build version string from available info using following
206
-    # logic:
207
-    #
208
-    #  1. use project.version (from mkit.ini)
209
-    #  2. if we are in git, override the version with last tag
210
-    #  3. if set, add project:prerl (from mkit.ini) as pre-release ID
211
-    #     (afer dash)
212
-    #  4. if we are at a later commit than the last tag, add branch
213
-    #     name and commit sha1 to build metadata (after plus sign)
214
-    #  5. if the tree is "dirty", i.e. has uncommited changes,
215
-    #     add "dirty" to build metadata
216
-    #
217
-    # The version is compatible with SemVer 2.0.0.
218
-    #
219
-    # Examples:
220
-    #
221
-    #     myprog v1.0.7                         # all clear
222
-    #     myprog v1.0.7-alpha                   # mkit.ini: project:prerl="alpha"
223
-    #     myprog v1.0.7-alpha+g1aef811.master   # ^^ + some commits after
224
-    #     myprog v1.0.7-alpha+gf14fc4f.api2     # ^^ + on a feature branch
225
-    #     myprog v1.0.7-alpha+gf14fc4f.api2.dirty  # ^^ + tree edited
226
-    #     myprog v1.0.7-alpha+dirty             # tag OK but tree edited
227
-    #     myprog v1.0.7+dirty                   # ^^ but no pre-release id
228
-    #
229
-    # Note that versions with "dirty" should be perceived as kind of
230
-    # dangerous outside developer's own machine.  Versions with sha1 are
231
-    # safer but must not be released.
232
-    #
233
-    # I have considered decorating the git commit refs to make them
234
-    # sort of sortable (e.g. "r1.g1aef811"), but on second thought,
235
-    # I don't think it's good idea to give *any* semantics to meta-data
236
-    # at all.  First, there is no rule that r1<r2<r3; a commit can be
237
-    # removing what other just added and one change can be split to
238
-    # multiple commits.  Also, the whole thing breaks anyway once you
239
-    # rebase your branch (no, it's not a sin).  The sole purpose of
240
-    # meta-data is to *identify* the code, and provide safe path back
241
-    # to tree; commit refs are already perfect for that.
242
-    #
243
-    # FIXME:  Using project:prerl for release IDs may not be compatible with
244
-    #         release strategy implemented in release.sh
245
-    #
246
-    local version=$(ini 1value project:version)
247
-    local prerl=$(ini 1value project:prerl)
248
-    grep ":" <<<"$prerl" && warn "colon in project:prerl may corrupt version data: $prerl"
249
-    if git rev-parse HEAD >&/dev/null;
250
-    then    # we are in git repo... so we can get smart
251
-        local latest_tag=$(
252
-            git log --format="%D" \
253
-              | sed 's/,/\n/g' \
254
-              | sed 's/^[[:blank:]]*//; ' \
255
-              | grep -E '^tag: v[[:digit:]]+\.' \
256
-              | cut -d' ' -f2 \
257
-              | head -1
258
-        )
259
-        if ! git describe --tags --exact-match HEAD >&/dev/null;
260
-        then    # we are at a later commit than the last tag
261
-            local sha=g$(git log -1 --pretty=format:%h HEAD)
262
-            local curbranch=$(git rev-parse --abbrev-ref HEAD)
263
-            local commit="$curbranch.$sha"
264
-        fi
265
-        if test "$(git diff --shortstat 2>/dev/null)" != "";
266
-        then    # the tree is "dirty", i.e. has been edited
267
-            local dirty=dirty
268
-        fi
269
-        test -n "$latest_tag" && version=${latest_tag:1}
270
-        local suffix=""
271
-        case "$commit:$dirty" in
272
-            :)       suffix=""                ;;
273
-            :dirty)  suffix="+$dirty"         ;;
274
-            *:)      suffix="+$commit"        ;;
275
-            *:dirty) suffix="+$commit.$dirty" ;;
276
-        esac
277
-        test -b "$prerl" && suffix="-$prerl$suffix"
278
-        version="$version$suffix"
279
-    fi
280
-    echo "$version"
216
+    _build1 "$specsrc" "$specname"
281 217
 }

+ 29
- 24
utils/mkit/include/deploy.sh ファイルの表示

@@ -1,24 +1,10 @@
1 1
 #!/bin/bash
2 2
 
3
-_maybe() {
4
-    #
5
-    # Call the deploy command $1 $@ unless in dry mode
6
-    #
7
-    debug "$@"
8
-    local cmd="$1"; shift
9
-    $MKIT_DRY && return
10
-    case "$cmd" in
11
-        cp|rm|rmdir|chmod|mkdir) $cmd "$@" ;;
12
-        install)                 command -p install "$@" ;;
13
-        *)                       die "bad command called";;
14
-    esac
15
-}
16
-
17
-deploy_item() {
3
+_deploy_item() {
18 4
     #
19 5
     # Deploy item and make it look like wanted
20 6
     #
21
-    # usage: deploy_item src dst [mode]
7
+    # usage: _deploy_item src dst [mode]
22 8
     #
23 9
     # Both src and dst must be names of actual items[1],
24 10
     # whereas dst must not exist.  On update, dst is
@@ -54,23 +40,42 @@ deploy_item() {
54 40
     fi
55 41
 }
56 42
 
57
-get_dst() {
43
+_get_dst() {
58 44
     #
59 45
     # Find out target path for src file $2 of group $1
60 46
     #
61 47
     local grp=$1
62 48
     local src=$2
63
-    echo "$(get_root "$grp")/$(ini 1value "files:$grp:$src")"
49
+    echo "$(_get_root "$grp")/$(ini 1value "files:$grp:$src")"
64 50
 }
65 51
 
66
-get_root() {
52
+_get_root() {
67 53
     #
68 54
     # Find out target rooot for group $1
69 55
     #
70 56
     local grp="$1"
71 57
     local root=$(ini 1value "roots:$grp")
72
-    test -n "$root" || die "missing in config.ini: roots:$grp"
73
-    echo "$(ini 1value ENV:DESTDIR)$root"
58
+    local destdir=$(ini 1value ENV:DESTDIR)
59
+    destdir=${destdir%/}
60
+    case $destdir:$root in
61
+        *:)     die "missing in config.ini: roots:$grp" ;;
62
+        :*)     echo "$root" ;;
63
+        *:*)    echo "$destdir/$root" ;;
64
+    esac
65
+}
66
+
67
+_maybe() {
68
+    #
69
+    # Call the deploy command $1 $@ unless in dry mode
70
+    #
71
+    debug "$@"
72
+    local cmd="$1"; shift
73
+    $MKIT_DRY && return
74
+    case "$cmd" in
75
+        cp|rm|rmdir|chmod|mkdir) $cmd "$@" ;;
76
+        install)                 command -p install "$@" ;;
77
+        *)                       die "bad command called";;
78
+    esac
74 79
 }
75 80
 
76 81
 install() {
@@ -85,8 +90,8 @@ install() {
85 90
             ini lskeys "files:$group" \
86 91
               | while read src;
87 92
                 do
88
-                    dst=$(get_dst "$group" "$src")
89
-                    deploy_item "$src" "$dst" "$mode"
93
+                    dst=$(_get_dst "$group" "$src")
94
+                    _deploy_item "$src" "$dst" "$mode"
90 95
                 done
91 96
         done
92 97
     test -f "$MKIT_LOCAL/autoclean" && clean
@@ -104,7 +109,7 @@ uninstall() {
104 109
             ini lskeys "files:$group" \
105 110
               | while read src;
106 111
                 do
107
-                    dst=$(get_dst "$group" "$src")
112
+                    dst=$(_get_dst "$group" "$src")
108 113
                     _maybe rm -vrf "$dst"
109 114
                 done
110 115
         done

+ 175
- 0
utils/mkit/include/facts.sh ファイルの表示

@@ -0,0 +1,175 @@
1
+#!/bin/bash
2
+
3
+. "$MKIT_DIR/include/ini.sh" || die "cannot import ini.sh"
4
+
5
+git_bool() {
6
+    #
7
+    # Get git bool (ie. exit status counts) $1
8
+    #
9
+    local bool_name="$1"
10
+    git_present || warn "can't give bool outside git repo: $bool_name"
11
+    case "$bool_name" in
12
+        dirty_files)
13
+            git diff-files | grep -qm 1 .
14
+            ;;
15
+        dirty_index)
16
+            git diff-index HEAD | grep -qm 1 .
17
+            ;;
18
+        dirty)
19
+            git_bool dirty_files || git_bool dirty_index
20
+            ;;
21
+        *)
22
+            warn "unknown git bool asked: $bool_name"
23
+            return 2
24
+            ;;
25
+    esac
26
+}
27
+
28
+git_fact() {
29
+    #
30
+    # Get git fact $1
31
+    #
32
+    local fact_name="$1"
33
+    git_present || warn "can't give fact outside git repo: $fact_name"
34
+    case "$fact_name" in
35
+        latest_tag)
36
+            git log --format="%D" \
37
+              | sed 's/,/\n/g' \
38
+              | sed 's/^[[:blank:]]*//; ' \
39
+              | grep -E '^tag: v[[:digit:]]+\.' \
40
+              | cut -d' ' -f2 \
41
+              | head -1
42
+            ;;
43
+        latest_version)
44
+            git_fact latest_tag | git_tag2ver
45
+            ;;
46
+        current_branch)
47
+            git rev-parse --abbrev-ref HEAD
48
+            ;;
49
+        reldiff)
50
+            git log --oneline "$(git_fact latest_tag)..HEAD" --name-only
51
+            ;;
52
+        latest_sha)
53
+            git log -1 --pretty=format:%h HEAD
54
+            ;;
55
+        *)
56
+            warn "unknown git fact asked: $fact_name"
57
+            ;;
58
+    esac
59
+}
60
+
61
+git_present() {
62
+    #
63
+    # True if we're in a git repo
64
+    #
65
+    git rev-parse HEAD >&/dev/null
66
+}
67
+
68
+git_tag2ver() {
69
+    #
70
+    # Convert tag to version
71
+    #
72
+    sed s/^v//
73
+}
74
+
75
+git_ver2tag() {
76
+    #
77
+    # Convert version to tag
78
+    #
79
+    sed s/^/v/
80
+}
81
+
82
+git_lasthash() {
83
+    #
84
+    # Show last commit hash (with .dirty suffix if needed)
85
+    #
86
+    # If outside git repo, get it from .mkit/git_lasthash, which
87
+    # should have been put there by dist target.  (I.e., this won't
88
+    # work if you got outside the git repo in other way than dist
89
+    # target, but that's actually expected.)
90
+    #
91
+    if git_present;
92
+    then    # we are in git repo
93
+        local last_hash=$(git rev-parse HEAD)
94
+        echo -n "$last_hash"
95
+        git_bool dirty && echo -n ".dirty"
96
+    else    # we are outside (eg. distributor's build dir')
97
+        grep . .mkit/git_lasthash || {
98
+            echo UNKNOWN
99
+            warn "malformed source, could not determine git hash"
100
+        }
101
+    fi
102
+}
103
+
104
+semver() {
105
+    #
106
+    # Build semver version string with build metadata
107
+    #
108
+    # Build version string from available info using following
109
+    # logic:
110
+    #
111
+    #  1. use project.version (from mkit.ini)
112
+    #  2. if we are in git, override the version with last tag
113
+    #  3. if set, add project:prerl (from mkit.ini) as pre-release ID
114
+    #     (afer dash)
115
+    #  4. if we are at a later commit than the last tag, add branch
116
+    #     name and commit sha1 to build metadata (after plus sign)
117
+    #  5. if the tree is "dirty", i.e. has uncommited changes,
118
+    #     add "dirty" to build metadata
119
+    #
120
+    # The version is compatible with SemVer 2.0.0.
121
+    #
122
+    # Examples:
123
+    #
124
+    #     myprog v1.0.7                         # all clear
125
+    #     myprog v1.0.7-alpha                   # mkit.ini: project:prerl="alpha"
126
+    #     myprog v1.0.7-alpha+g1aef811.master   # ^^ + some commits after
127
+    #     myprog v1.0.7-alpha+gf14fc4f.api2     # ^^ + on a feature branch
128
+    #     myprog v1.0.7-alpha+gf14fc4f.api2.dirty  # ^^ + tree edited
129
+    #     myprog v1.0.7-alpha+dirty             # tag OK but tree edited
130
+    #     myprog v1.0.7+dirty                   # ^^ but no pre-release id
131
+    #
132
+    # Note that versions with "dirty" should be perceived as kind of
133
+    # dangerous outside developer's own machine.  Versions with sha1 are
134
+    # safer but must not be released.
135
+    #
136
+    # I have considered decorating the git commit refs to make them
137
+    # sort of sortable (e.g. "r1.g1aef811"), but on second thought,
138
+    # I don't think it's good idea to give *any* semantics to meta-data
139
+    # at all.  First, there is no rule that r1<r2<r3; a commit can be
140
+    # removing what other just added and one change can be split to
141
+    # multiple commits.  Also, the whole thing breaks anyway once you
142
+    # rebase your branch (no, it's not a sin).  The sole purpose of
143
+    # meta-data is to *identify* the code, and provide safe path back
144
+    # to tree; commit refs are already perfect for that.
145
+    #
146
+    # FIXME:  Using project:prerl for release IDs may not be compatible with
147
+    #         release strategy implemented in release.sh
148
+    #
149
+    local version=$(ini 1value project:version)
150
+    local prerl=$(ini 1value project:prerl)
151
+    grep ":" <<<"$prerl" && warn "colon in project:prerl may corrupt version data: $prerl"
152
+    if git_present;
153
+    then    # we are in git repo... so we can get smart
154
+        local latest_tag=$(git_fact latest_tag)
155
+        if ! git describe --tags --exact-match HEAD >&/dev/null;
156
+        then    # we are at a later commit than the last tag
157
+            local commit="$(git_fact current_branch).g$(git_fact latest_sha)"
158
+        fi
159
+        local dirty=""
160
+        local suffix=""
161
+        git_bool dirty; dirty=$?
162
+        test -n "$latest_tag" && version=${latest_tag:1}
163
+        case "$dirty:$commit" in
164
+            1:)  suffix=""               ;;
165
+            0:)  suffix="+dirty"         ;;
166
+            1:*) suffix="+$commit"       ;;
167
+            0:*) suffix="+$commit.dirty" ;;
168
+            *)   suffix=MKIT_BUG;
169
+                 warn "MKIT_BUG: bad dirt/commit detection" ;;
170
+        esac
171
+        test -n "$prerl" && suffix="-$prerl$suffix"
172
+        version="$version$suffix"
173
+    fi
174
+    echo "$version"
175
+}

+ 40
- 19
utils/mkit/include/ini.sh ファイルの表示

@@ -1,24 +1,5 @@
1 1
 #!/bin/bash
2 2
 
3
-ini() {
4
-    #
5
-    # do ini operation
6
-    #
7
-    local op=$1
8
-    local arg=$2
9
-    local fn
10
-    local limit=_ini_cat
11
-    debug_var op arg
12
-    case $op in
13
-        lskeys) fn=_ini_lskeys   ;;
14
-        sec)    fn=_ini_grepsec  ;;
15
-        values) fn=_ini_greppath ;;
16
-        1value) fn=_ini_greppath; limit="tail -1" ;;
17
-        *)      die "incorrect use of \`ini()\`"
18
-    esac
19
-    <"$MKIT_INI" $fn "$arg" | $limit
20
-}
21
-
22 3
 _ini_cat() {
23 4
     #
24 5
     # A no-op for text stream
@@ -121,3 +102,43 @@ _ini_maybe_expand() {
121 102
         _ini_cat
122 103
     fi
123 104
 }
105
+
106
+ini() {
107
+    #
108
+    # do ini operation
109
+    #
110
+    local op=$1
111
+    local arg=$2
112
+    local fn
113
+    local limit=_ini_cat
114
+    debug_var op arg
115
+    case $op in
116
+        lskeys) fn=_ini_lskeys   ;;
117
+        sec)    fn=_ini_grepsec  ;;
118
+        values) fn=_ini_greppath ;;
119
+        1value) fn=_ini_greppath; limit="tail -1" ;;
120
+        *)      die "incorrect use of \`ini()\`"
121
+    esac
122
+    <"$MKIT_INI" $fn "$arg" | $limit
123
+}
124
+
125
+update_version() {
126
+    #
127
+    # Change project.version in mkit.ini at path $2 to version $1
128
+    #
129
+    local version="$1"
130
+    local inifile="$2"
131
+    local tmp=$(mktemp -t mkit.update_version.XXXXXXXX)
132
+    <"$inifile" perl -e '
133
+        my $hit = 0;
134
+        my $done = 0;
135
+        foreach (<STDIN>) {
136
+            if      ($done) { print; next; }
137
+            elsif   (m/\[project\]/) { $hit++; print; next; }
138
+            elsif   (m/\[/) { $hit = 0; print; next; }
139
+            elsif   ($hit) { s/\bversion\b( *)=( *).*/version$1=$2$ARGV[0]/ and $done++; print; }
140
+            else { print; next; }
141
+        }
142
+    ' "$version" >"$tmp" || die "failed to update version in mkit.ini"
143
+    mv "$tmp" "$inifile"
144
+}

+ 37
- 58
utils/mkit/include/mkit.sh ファイルの表示

@@ -5,6 +5,31 @@
5 5
 . "$MKIT_DIR/include/release.sh" || die "cannot import release.sh"
6 6
 . "$MKIT_DIR/include/ini.sh"    || die "cannot import ini.sh"
7 7
 
8
+MKIT_INI=${MKIT_INI:-mkit.ini}
9
+MKIT_INI_EXPAND=2
10
+MKIT_PROJ_PKGNAME=""
11
+MKIT_DEFAULT_MODE="644"
12
+
13
+_valid_targets() {
14
+    #
15
+    # List valid routes
16
+    #
17
+    echo build
18
+    echo build_manpages
19
+    echo clean
20
+    echo debstuff
21
+    echo dist
22
+    echo install
23
+    echo release_x
24
+    echo release_y
25
+    echo release_z
26
+    echo rpmstuff
27
+    echo uninstall
28
+    echo vbump_x
29
+    echo vbump_y
30
+    echo vbump_z
31
+}
32
+
8 33
 debug() {
9 34
     #
10 35
     # Print debug message
@@ -30,23 +55,6 @@ debug_var() {
30 55
     done
31 56
 }
32 57
 
33
-MKIT_INI=${MKIT_INI:-mkit.ini}
34
-MKIT_INI_EXPAND=2
35
-MKIT_PROJ_NAME=$(ini 1value "project:name")
36
-MKIT_PROJ_PKGNAME=$(ini 1value "project:pkgname")
37
-MKIT_DEFAULT_MODE="644"
38
-
39
-mkit_init() {
40
-    #
41
-    # Do basic initialization
42
-    #
43
-    # Check for ini file and some variables
44
-    #
45
-    test -f "$MKIT_INI" || die "cannot find mkit.ini: $MKIT_INI"
46
-    test -n "$(tr -d '[:space:]' <<<"$MKIT_LOCAL")" \
47
-     || die "MKIT_LOCAL must be non-blank: '$MKIT_LOCAL'"
48
-}
49
-
50 58
 die() {
51 59
     #
52 60
     # Exit with message and non-zero exit status
@@ -55,39 +63,23 @@ die() {
55 63
     exit 4
56 64
 }
57 65
 
58
-warn() {
59
-    #
60
-    # Print warning message
66
+mkit_init() {
61 67
     #
62
-    echo "$@" >&2
63
-}
64
-
65
-update_version() {
68
+    # Do basic initialization
66 69
     #
67
-    # Change project.version in mkit.ini at path $2 to version $1
70
+    # Check for ini file and some variables
68 71
     #
69
-    local version="$1"
70
-    local inifile="$2"
71
-    local tmp=$(mktemp -t mkit.update_version.XXXXXXXX)
72
-    <"$inifile" perl -e '
73
-        my $hit = 0;
74
-        my $done = 0;
75
-        foreach (<STDIN>) {
76
-            if      ($done) { print; next; }
77
-            elsif   (m/\[project\]/) { $hit++; print; next; }
78
-            elsif   (m/\[/) { $hit = 0; print; next; }
79
-            elsif   ($hit) { s/\bversion\b *=.*/version = $ARGV[0]/ and $done++; print; }
80
-            else { print; next; }
81
-        }
82
-    ' "$version" >"$tmp" || die "failed to update version in mkit.ini"
83
-    mv "$tmp" "$inifile"
72
+    MKIT_PROJ_PKGNAME=$(ini 1value "project:pkgname")
73
+    test -f "$MKIT_INI" || die "cannot find mkit.ini: $MKIT_INI"
74
+    test -n "$(tr -d '[:space:]' <<<"$MKIT_LOCAL")" \
75
+     || die "MKIT_LOCAL must be non-blank: '$MKIT_LOCAL'"
84 76
 }
85 77
 
86 78
 route() {
87 79
     #
88 80
     # Call correct function based on $1
89 81
     #
90
-    if valid_targets | grep -qwx "^$1";
82
+    if _valid_targets | grep -qwx "^$1";
91 83
     then
92 84
         "$1"
93 85
     else
@@ -95,27 +87,14 @@ route() {
95 87
             echo "usage: $(basename "$0") TARGET"
96 88
             echo
97 89
             echo "valid targets:"
98
-            valid_targets | sed 's/^/    /'
90
+            _valid_targets | sed 's/^/    /'
99 91
         } >&2
100 92
     fi
101 93
 }
102 94
 
103
-valid_targets() {
95
+warn() {
104 96
     #
105
-    # List valid routes
97
+    # Print warning message
106 98
     #
107
-    echo build
108
-    echo build_manpages
109
-    echo clean
110
-    echo debstuff
111
-    echo dist
112
-    echo install
113
-    echo release_x
114
-    echo release_y
115
-    echo release_z
116
-    echo rpmstuff
117
-    echo uninstall
118
-    echo vbump_x
119
-    echo vbump_y
120
-    echo vbump_z
99
+    echo "$@" >&2
121 100
 }

+ 87
- 102
utils/mkit/include/release.sh ファイルの表示

@@ -1,127 +1,130 @@
1 1
 #!/bin/bash
2 2
 
3
-__die_if() {
3
+. "$MKIT_DIR/include/ini.sh"   || die "cannot import ini.sh"
4
+. "$MKIT_DIR/include/facts.sh" || die "cannot import facts.sh"
5
+
6
+_bump_version() {
7
+    #
8
+    # Bump version on stdin by level $1 (x, y or z)
9
+    #
10
+    local rlevel=$1
11
+    local old
12
+    read -r old
13
+    local oldx=${old%.*.*}
14
+    local oldz=${old#*.*.}
15
+    local tmpy=${old%.*}
16
+    local oldy=${tmpy#*.}
17
+    local new=""
18
+    case $rlevel in
19
+        x) new="$((oldx+1)).0.0"            ;;
20
+        y) new="$oldx.$((oldy+1)).0"        ;;
21
+        z) new="$oldx.$oldy.$((oldz+1))"    ;;
22
+        *) die "invalid release level: $1"  ;;
23
+    esac
24
+    echo "$new"
25
+}
26
+
27
+_relck() {
4 28
     #
5 29
     # Die if blocking condition $1 is detected
6 30
     #
7 31
     local condition="$1"
8 32
     local x
9 33
     case "$condition" in
10
-        nogit)
34
+        git_present)
11 35
             git rev-parse HEAD >&/dev/null\
12 36
              || die "cannot do this outside git repo"
13 37
             ;;
14
-        norelbr)
38
+        at_relsrc)
15 39
             local relsrc=$(ini 1value project:relsrc)
16
-            __git_info curbranch \
40
+            git_fact current_branch \
17 41
               | grep -qFx "$relsrc" \
18 42
              || die "you are not on release source branch: $relsrc"
19 43
             ;;
20
-        dirty)
44
+        not_dirty)
21 45
             git diff --shortstat 2>/dev/null \
22 46
               | grep -q . \
23 47
              && die "tree is dirty: $dirt"
24 48
             ;;
25
-        novertag)
26
-            __git_info lasttag \
49
+        tags_ok)
50
+            git_fact latest_tag \
27 51
               | grep -q . \
28
-             || die "cannot find last tag"
52
+             || die "cannot find latest tag"
29 53
             ;;
30
-        nobump)
54
+        vbump_hot)
31 55
             git diff-tree --no-commit-id --name-only -r HEAD \
32 56
               | grep -qFx mkit.ini \
33 57
              || die "last change must be version bump in mkit.ini"
34 58
             ;;
35
-        wip)
36
-            __git_info reldiff \
59
+        no_wip)
60
+            git_fact reldiff \
37 61
               | grep '^....... WIP ' \
38
-             && die "WIP commit since $(__git_info lasttag)"
62
+             && die "WIP commit since $(git_fact latest_tag)"
39 63
             ;;
40
-        old_c)
41
-            x=$(__ver_info nextver_g)
42
-            __ver_info currver_c \
43
-              | grep -qFx "$x" \
44
-             || die "new version not in mkit.ini: $x"
64
+        ini_version)
65
+            local oracle=$(git_fact latest_version | _bump_version "$rlevel")
66
+            ini 1value project:version  \
67
+              | grep -qFx "$oracle" \
68
+             || die "new version not in mkit.ini: $oracle"
69
+            ;;
70
+        *)
71
+            die "unknown release check: $condition"
45 72
             ;;
46 73
     esac
47 74
 }
48 75
 
49
-__git_info() {
50
-    #
51
-    # Get git info $1
52
-    #
53
-    local info="$1"
54
-    case "$info" in
55
-        lasttag)    git tag | grep ^v | sort -V | tail -n1  ;;
56
-        curbranch)  git rev-parse --abbrev-ref HEAD         ;;
57
-        reldiff)    git log --oneline "$(__git_info lasttag)..HEAD" --name-only ;;
58
-    esac
59
-}
60
-
61
-__ver_info() {
62
-    #
63
-    # Get git info $1
64
-    #
65
-    local info="$1"
66
-    case "$info" in
67
-        lastver_g)  __git_info lasttag | sed s/^v// ;;
68
-        nextver_g)  __make_ver "$level" "$(__ver_info lastver_g)" ;;
69
-        currver_c)  ini 1value project:version ;;
70
-        nextver_c)  __make_ver "$level" "$(__ver_info currver_c)" ;;
71
-    esac
72
-}
73
-
74
-__make_ver() {
75
-    local level=$1
76
-    local old=$2
77
-    local oldx=${old%.*.*}
78
-    local oldz=${old#*.*.}
79
-    local tmpy=${old%.*}
80
-    local oldy=${tmpy#*.}
81
-    case $level in
82
-        x) new="$((oldx+1)).0.0"            ;;
83
-        y) new="$oldx.$((oldy+1)).0"        ;;
84
-        z) new="$oldx.$oldy.$((oldz+1))"    ;;
85
-        *) die "invalid release level: $1"  ;;
86
-    esac
87
-    echo "$new"
88
-}
89
-
90
-__release() {
76
+_release() {
91 77
     #
92 78
     # Prepare release
93 79
     #
94 80
     # Span release routines: make a signed tag, check branch
95 81
     # and update release branch
96 82
     #
97
-    # FIXME: Using project:prerl as build.sh:get_version() does may not be
83
+    # FIXME: Using project:prerl as build.sh:semver() does may not be
98 84
     #        compatible with this release strategy
99 85
     #
100
-    local level=$1
86
+    local rlevel=$1
101 87
     local newtag
102 88
 
103
-    __die_if nogit
104
-    __die_if norelbr
105
-    __die_if dirty
106
-    __die_if novertag
107
-    __die_if nobump
108
-    __die_if wip
109
-    __die_if old_c
89
+    _relck git_present
90
+    _relck at_relsrc
91
+    _relck not_dirty
92
+    _relck tags_ok
93
+    _relck vbump_hot
94
+    _relck no_wip
95
+    _relck ini_version
110 96
 
111
-    newtag=v$(__ver_info nextver_g)
97
+    newtag=$(git_fact latest_version | _bump_version "$rlevel" | git_ver2tag )
112 98
     set -e
113 99
     debug_var newtag
114 100
     $MKIT_DRY && return
115
-    git tag -m "$MKIT_PROJ_NAME $newtag - $CODENAME" "$newtag"
101
+    git tag -m "$(ini 1value project:name) $newtag - $CODENAME" "$newtag"
116 102
     git branch -f "$(ini 1value project:reldst)" "$newtag"
117 103
 }
118 104
 
119
-__git_msg_vbump() {
105
+_vbump() {
106
+    local rlevel="$1"
107
+    local lastver   # current from mkit.ini
108
+    local nextver   # after the bump
109
+    _relck git_present
110
+    _relck at_relsrc
111
+    _relck not_dirty
112
+    nextver=$(ini 1value project:version | _bump_version "$rlevel")
113
+    debug_var lastver nextver
114
+    $MKIT_DRY && return
115
+    update_version "$nextver" mkit.ini \
116
+      || die "failed to update version in mkit.ini"
117
+    git add mkit.ini \
118
+      || die "failed to add mkit.ini to the index"
119
+    git commit -e -m "$(_vbump_gitmsg)"
120
+}
121
+
122
+_vbump_gitmsg() {
120 123
     echo "Bump version"
121 124
     echo ""
122 125
     echo "Overview of changes:"
123 126
     echo ""
124
-    __git_info reldiff \
127
+    git_fact reldiff \
125 128
       | sed '
126 129
             s/^[a-f0-9]\{7\} / *  &/; t PATHS
127 130
             s/^/        /
@@ -129,44 +132,26 @@ __git_msg_vbump() {
129 132
         '
130 133
 }
131 134
 
132
-__vbump() {
133
-    local level="$1"
134
-    local lastver   # current from mkit.ini
135
-    local nextver   # after the bump
136
-    __die_if nogit
137
-    __die_if norelbr
138
-    __die_if dirty
139
-    lastver=$(__ver_info currver_c)
140
-    nextver=$(__ver_info nextver_c)
141
-    debug_var lastver nextver
142
-    $MKIT_DRY && return
143
-    update_version "$nextver" mkit.ini \
144
-      || die "failed to update version in mkit.ini"
145
-    git add mkit.ini \
146
-      || die "failed to add mkit.ini to the index"
147
-    git commit -e -m "$(__git_msg_vbump)"
148
-}
149
-
150
-vbump_x() {
151
-    __vbump x
135
+release_x() {
136
+    _release x
152 137
 }
153 138
 
154
-vbump_y() {
155
-    __vbump y
139
+release_y() {
140
+    _release y
156 141
 }
157 142
 
158
-vbump_z() {
159
-    __vbump z
143
+release_z() {
144
+    _release z
160 145
 }
161 146
 
162
-release_x() {
163
-    __release x
147
+vbump_x() {
148
+    _vbump x
164 149
 }
165 150
 
166
-release_y() {
167
-    __release y
151
+vbump_y() {
152
+    _vbump y
168 153
 }
169 154
 
170
-release_z() {
171
-    __release z
155
+vbump_z() {
156
+    _vbump z
172 157
 }

+ 1
- 1
utils/mkit/make ファイルの表示

@@ -6,7 +6,7 @@ die() {
6 6
     echo "$@" && exit 9
7 7
 }
8 8
 
9
-export MKIT_VERSION=0.0.11
9
+export MKIT_VERSION=0.0.13
10 10
 
11 11
 export MKIT_DIR=${MKIT_DIR:-$(dirname "$0")}
12 12
 export MKIT_LOCAL=${MKIT_LOCAL:-.mkit}