Browse Source

Update MKit to v0.0.34

Alois Mahdal 6 years ago
parent
commit
f374b44040

+ 2
- 2
mkit.ini View File

@@ -27,7 +27,7 @@
27 27
     share   = [ENV:PREFIX]/share/imapdomo
28 28
     etc     = /etc/imapdomo
29 29
 
30
-[tokens]
30
+[macros]
31 31
     __IMAPDOMO_CONFIG_USER__    = $HOME/.config/imapdomo
32 32
     __IMAPDOMO_CONFIG_LOCAL__   = [roots:etc]
33 33
     __IMAPDOMO_SHARE__          = [roots:share]
@@ -41,4 +41,4 @@
41 41
     share   = src/main.lua
42 42
     share   = src/common.lua
43 43
 
44
-#mkit version=0.0.24
44
+#mkit version=0.0.34

+ 158
- 95
utils/mkit/include/build.sh View File

@@ -6,7 +6,7 @@ mkit_import ini
6 6
 mkit_import facts
7 7
 
8 8
 
9
-_build1() {
9
+__build1() {
10 10
     #
11 11
     # Process one skeleton $1 of type $3 (or guessed) to path $2
12 12
     #
@@ -14,97 +14,95 @@ _build1() {
14 14
     local dstpath=$2    # destination meaty animal path
15 15
     local ftype=$3      # file/builder type
16 16
     test -n "$dstpath"  || dstpath=${srcpath%.skel}
17
-    test -n "$ftype"    || ftype=$(_guess_ftype "$dstpath")
17
+    test -n "$ftype"    || ftype=$(__guess_ftype "$dstpath")
18 18
     debug_var srcpath dstpath ftype
19
-    <"$srcpath" _build1_ftype "$ftype" >"$dstpath"
20
-    rec_built "$dstpath"
19
+    <"$srcpath" __build1_ftype "$ftype" >"$dstpath"
20
+    __rec_built "$dstpath"
21 21
 }
22 22
 
23
-_build1_ftype() {
23
+__build1_ftype() {
24 24
     #
25 25
     # Build a file of type $1; fom stdin to stdout
26 26
     #
27 27
     local ftype=$1      # file/builder type
28 28
     case $ftype in
29
-        MKIT_COMMON)    _expand_tokens "tokens" ;;
30
-        markdown)       _expand_includes | _expand_tokens "tokens" ;;
31
-        rpmstuff)       _expand_tokens "tokens" "rpmstuff:tokens" ;;
32
-        debstuff)       _expand_tokens "tokens" "debstuff:tokens" ;;
29
+        MKIT_COMMON)    __expand_macros "macros" ;;
30
+        rpmstuff)       __expand_macros "macros" "rpmstuff:macros" ;;
31
+        debstuff)       __expand_macros "macros" "debstuff:macros" ;;
33 32
         *)              die "unknown file type: $ftype" ;;
34 33
     esac
35 34
 }
36 35
 
37
-_expand_includes() {
38
-    #
39
-    # Expand include directives
40
-    #
41
-    # Expand e.g. `<!-- include4: foo.sh -->` to include code of foo.sh
42
-    #
43
-    perl -we '
44
-        use strict;
45
-        my $text;
46
-        while (<>) {
47
-            chomp;
48
-            if (m/<!-- include4: (\S+) -->/) {
49
-                open my $fh, $1 or warn "cannot find: $1";
50
-                my $text = do { local($/); <$fh> };
51
-                close $fh;
52
-                $text =~ s/^(.)/    $1/gm;
53
-                chomp $text;
54
-                print "$text\n";
55
-            } else {
56
-                print "$_\n";
57
-            }
58
-        }
59
-    '
36
+__expand_line() {
37
+    #
38
+    # Expand macro from $MacroMap in single line $1
39
+    #
40
+    # If macro value has multiple lines, repeat original line with
41
+    # different substitution.
42
+    #
43
+    # E.g. if macro value is "foo\nbar" and macro name is __FOO__,
44
+    # line `see: "__FOO__"` will expand to two lines: `see: "foo"`
45
+    # and `see: "bar"`.
46
+    #
47
+    local line=$1   # line to process
48
+    local mname     # macro name
49
+    local mvline    # line of macro value
50
+    local xline     # expanded line
51
+    xline=$line
52
+    for mname in "${!MacroMap[@]}"; do
53
+        if ! test "${line//$mname}" == "$line"; then
54
+            xline=$(
55
+                while IFS= read -r mvline; do
56
+                    echo "${line//$mname/$mvline}"
57
+                done <<<"${MacroMap[$mname]}"
58
+            )
59
+        fi
60
+        line=$xline
61
+    done
62
+    echo "$xline"
63
+    return 1
60 64
 }
61 65
 
62
-_expand_tokens() {
66
+__expand_macros() {
63 67
     #
64
-    # Read stdin, expanding tokens from sections $@
68
+    # Read stdin, expanding macros from sections $@
65 69
     #
66
-    local script        # sed script cache
67
-    local section       # each section to expand tokens from
68
-    local varname       # each token name
69
-    local varvalue      # each token value
70
-    script=$(mktemp --tmpdir mkit-tmp.XXXXXXXXXX)
71
-    {
72
-        for section in "$@"; do
73
-            debug_var section
74
-            ini lskeys "$section" \
75
-              | while read -r varname; do
76
-                    varvalue="$(ini 1value "$section:$varname" | _qfs )"
77
-                    echo "s|$varname|$varvalue|g;"
78
-                    debug_var varname varvalue
79
-                done
70
+    local section       # each section to expand macros from
71
+    local line          # each line on stdin
72
+    local mname         # each macro name
73
+    local -A MacroMap   # macro value map
74
+    MacroMap[__MKIT_PROJ_NAME__]=$(ini 1value project:name)
75
+    MacroMap[__MKIT_PROJ_CODENAME__]=$(ini 1value project:codename)
76
+    MacroMap[__MKIT_PROJ_LICENSE__]=$(ini 1value project:license)
77
+    MacroMap[__MKIT_PROJ_PKGNAME__]=$(ini 1value project:pkgname)
78
+    MacroMap[__MKIT_PROJ_TAGLINE__]=$(ini 1value project:tagline)
79
+    MacroMap[__MKIT_PROJ_MAINTAINER__]=$(ini 1value project:maintainer)
80
+    MacroMap[__MKIT_PROJ_VCS_BROWSER__]=$(ini 1value project:vcs_browser)
81
+    MacroMap[__MKIT_PROJ_GIT_LASTHASH__]=$(__cached git_lasthash)
82
+    MacroMap[__MKIT_PROJ_VERSION__]=$(__cached semver)
83
+    MacroMap[__MKIT_SELF_VERSION__]=$MKIT_VERSION
84
+    for section in "$@"; do
85
+        for mname in $(ini lskeys "$section"); do
86
+            MacroMap[$mname]=$(ini values "$section:$mname")
80 87
         done
81
-        echo "s|__MKIT_PROJ_NAME__|$(ini 1value project:name | _qfs)|g;"
82
-        echo "s|__MKIT_PROJ_CODENAME__|$(ini 1value project:codename | _qfs)|g;"
83
-        echo "s|__MKIT_PROJ_LICENSE__|$(ini 1value project:license | _qfs)|g;"
84
-        echo "s|__MKIT_PROJ_PKGNAME__|$(ini 1value project:pkgname | _qfs)|g;"
85
-        echo "s|__MKIT_PROJ_TAGLINE__|$(ini 1value project:tagline | _qfs)|g;"
86
-        echo "s|__MKIT_PROJ_MAINTAINER__|$(ini 1value project:maintainer | _qfs)|g;"
87
-        echo "s|__MKIT_PROJ_VCS_BROWSER__|$(ini 1value project:vcs_browser | _qfs)|g;"
88
-        echo "s|__MKIT_PROJ_GIT_LASTHASH__|$(git_lasthash | _qfs)|g;"
89
-        echo "s|__MKIT_PROJ_VERSION__|$(semver | _qfs)|g;"
90
-        echo "s|__MKIT_SELF_VERSION__|$MKIT_VERSION|g;"
91
-    } >> "$script"
92
-    sed -f "$script" || die "_expand_tokens failed"
93
-    rm "$script"
94
-}
95
-
96
-_guess_ftype() {
88
+    done
89
+    debug_var MacroMap
90
+    while IFS= read -r line; do
91
+        __expand_line "$line"
92
+    done
93
+}
94
+
95
+__guess_ftype() {
97 96
     #
98 97
     # Guess file type from destination path $1
99 98
     #
100 99
     local dstpath=$1    # destination path
101 100
     case $dstpath in
102
-        *.md) echo markdown    ;;
103 101
         *)    echo MKIT_COMMON ;;
104 102
     esac
105 103
 }
106 104
 
107
-_qfs() {
105
+__qfs() {
108 106
     #
109 107
     # Quote for our sed scipt's RHS
110 108
     #
@@ -114,37 +112,102 @@ _qfs() {
114 112
     '
115 113
 }
116 114
 
115
+__cached() {
116
+    #
117
+    # Cached value $1 of function $1()
118
+    #
119
+    # In order to support git-less builds, some values might be cached
120
+    # in $MKIT_LOCAL.  This function gets file $1 from that cache (cache
121
+    # hit) or re-creates it (cache miss), but prints its body in either
122
+    # case.
123
+    #
124
+    # The command to re-create file is the same as the key (ie. no
125
+    # arguments).
126
+    #
127
+    local name=$1
128
+    __local_get "$name" && return 0
129
+    "$name" | __local_putb "$name"
130
+    __local_get "$name"
131
+}
132
+
133
+__local_putb() {
134
+    #
135
+    # Make file $1 in $MKIT_LOCAL from stdin and mark as built
136
+    #
137
+    local fpath=$1
138
+    __local_put "$fpath" && __rec_built "$MKIT_LOCAL/$fpath"
139
+}
140
+
141
+__local_put() {
142
+    #
143
+    # Make file $1 in $MKIT_LOCAL from stdin
144
+    #
145
+    local fpath="$MKIT_LOCAL/$1"
146
+    { mkdir -p "${fpath%/*}" && cat >"$fpath"; } \
147
+     || die "cannot write to local cache: $fpath"
148
+}
149
+
150
+__local_get() {
151
+    #
152
+    # Read file $1 in $MKIT_LOCAL
153
+    #
154
+    local fpath="$MKIT_LOCAL/$1"
155
+    cat "$fpath" 2>/dev/null
156
+}
157
+
158
+__rec_built() {
159
+    #
160
+    # Record file $1 for deletion on `clean`
161
+    #
162
+    local file=$1
163
+    mkdir -p "$MKIT_LOCAL"
164
+    echo "$file" >> "$MKIT_LOCAL/built.lst"
165
+}
166
+
167
+_mkit_data() {
168
+    #
169
+    # Build sampler showing all macro values
170
+    #
171
+    local macro
172
+    local section
173
+    local sections
174
+    sections=()
175
+    ini lskeys macros | grep -q . && sections=(macros)
176
+    sections+=( $(ini lssect | grep ':macros$') )
177
+    {
178
+        echo "(builtin):"
179
+        echo "  x_MKIT_PROJ_NAME__ => '__MKIT_PROJ_NAME__'"
180
+        echo "  x_MKIT_PROJ_CODENAME__ => '__MKIT_PROJ_CODENAME__'"
181
+        echo "  x_MKIT_PROJ_LICENSE__ => '__MKIT_PROJ_LICENSE__'"
182
+        echo "  x_MKIT_PROJ_PKGNAME__ => '__MKIT_PROJ_PKGNAME__'"
183
+        echo "  x_MKIT_PROJ_TAGLINE__ => '__MKIT_PROJ_TAGLINE__'"
184
+        echo "  x_MKIT_PROJ_MAINTAINER__ => '__MKIT_PROJ_MAINTAINER__'"
185
+        echo "  x_MKIT_PROJ_VCS_BROWSER__ => '__MKIT_PROJ_VCS_BROWSER__'"
186
+        echo "  x_MKIT_PROJ_GIT_LASTHASH__ => '__MKIT_PROJ_GIT_LASTHASH__'"
187
+        echo "  x_MKIT_PROJ_VERSION__ => '__MKIT_PROJ_VERSION__'"
188
+        echo "  x_MKIT_SELF_VERSION__ => '__MKIT_SELF_VERSION__'"
189
+        for section in "${sections[@]}"; do
190
+            echo "$section:"
191
+            for macro in $(ini lskeys "$section"); do
192
+                echo "  x${macro:1} => '$macro'"
193
+            done
194
+        done
195
+    } \
196
+      | __expand_macros "MKIT_BUILTIN" "${sections[@]}" \
197
+      | sed '/^  x/ s|x|_|'
198
+}
199
+
117 200
 build() {
118 201
     #
119 202
     # Add meat to all skeletons
120 203
     #
121 204
     local srcpath   # each source path
122
-    semver >/dev/null
123 205
     find . -type f -name '*.skel' \
124 206
      | while read -r srcpath; do
125
-           _build1 "$srcpath"
207
+           __build1 "$srcpath"
126 208
        done
127 209
 }
128 210
 
129
-build_manpages() {
130
-    #
131
-    # Build manpages using ronn
132
-    #
133
-    local manfile   # each manual file listed in '[files:man]'
134
-    local mdfile    # each source markdown file
135
-    if command -v ronn >/dev/null; then
136
-        ini lskeys "files:man" \
137
-          | while read -r manfile; do
138
-                mdfile="$manfile.md"
139
-                ronn -r "$mdfile"
140
-                rec_built "$manfile"
141
-            done
142
-    else
143
-        echo "ronn is not installed"
144
-        return 1
145
-    fi
146
-}
147
-
148 211
 clean() {
149 212
     #
150 213
     # Clean up tree after building
@@ -166,14 +229,14 @@ debstuff() {
166 229
     local debian_skel   # 'debian' folder skeleton
167 230
     local dfsrc         # each source file from ^^
168 231
     local dftgt         # each built packaging file
169
-    version=$(semver)
232
+    version=$(__cached semver)
170 233
 
171 234
     # tarball - we should already have by means of 'dist'
172 235
     #
173 236
     mv "${MKIT_PROJ_PKGNAME}-$version.tar.gz" \
174 237
        "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz" \
175 238
      || die "could not rename tarball"
176
-    rec_built "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz"
239
+    __rec_built "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz"
177 240
 
178 241
     # read content of each mandatory file from debian_skel
179 242
     #
@@ -185,16 +248,16 @@ debstuff() {
185 248
       | while read -r dfsrc; do
186 249
             dftgt="debian/${dfsrc#$debian_skel}"
187 250
             mkdir -p "$(dirname "$dftgt")"
188
-            _build1 "$dfsrc" "$dftgt" debstuff
251
+            __build1 "$dfsrc" "$dftgt" debstuff
189 252
         done
190
-    rec_built debian
253
+    __rec_built debian
191 254
 }
192 255
 
193 256
 dist() {
194 257
     #
195 258
     # Create distributable tarball
196 259
     #
197
-    #FIXME: lacking Makefile skills, we do this step twice fot
260
+    #FIXME: lacking Makefile skills, we do this step twice for
198 261
     #       rpmstuff, hence -f hack for gzip
199 262
     #
200 263
     local version           # tarball version
@@ -205,12 +268,12 @@ dist() {
205 268
     git_lasthash=$(git_lasthash)
206 269
     mkdir -p "$dirname"
207 270
     ini values "dist:tarball" | xargs -I DIST_ITEM cp -R DIST_ITEM "$dirname"
208
-    update_version "$version" "$dirname/mkit.ini"
209 271
     mkdir -p "$dirname/.mkit"
272
+    echo -n "$version" > "$dirname/.mkit/semver"
210 273
     echo -n "$git_lasthash" > "$dirname/.mkit/git_lasthash"
211 274
     tar -cf "$dirname.tar" "$dirname"
212 275
     gzip -f "$dirname.tar"      # see above FIXME
213
-    rec_built "$dirname.tar.gz"
276
+    __rec_built "$dirname.tar.gz"
214 277
     rm -rf "$dirname"
215 278
 }
216 279
 
@@ -223,5 +286,5 @@ rpmstuff() {
223 286
     specsrc="$(ini 1value "dist:rpmstuff")"
224 287
     test -n "$specsrc" || die "dist:rpmstuff not specified"
225 288
     test -f "$specsrc" || die "specfile template not found: $specsrc"
226
-    _build1 "$specsrc" "$specname" rpmstuff
289
+    __build1 "$specsrc" "$specname" rpmstuff
227 290
 }

+ 13
- 12
utils/mkit/include/deploy.sh View File

@@ -4,11 +4,11 @@
4 4
 
5 5
 mkit_import ini
6 6
 
7
-_deploy_item() {
7
+__deploy_item() {
8 8
     #
9 9
     # Deploy item and make it look like wanted
10 10
     #
11
-    # usage: _deploy_item src dst [mode]
11
+    # usage: __deploy_item src dst [mode]
12 12
     #
13 13
     # Both src and dst must be names of actual items[1],
14 14
     # whereas dst must not exist.  On update, dst is
@@ -37,14 +37,15 @@ _deploy_item() {
37 37
                 [[ $item =~ .skel$ ]] \
38 38
                  && grep -q "${item%.skel}" "$MKIT_LOCAL/built.lst" \
39 39
                  && continue
40
-                _deploy_item "$item" "$dst${item#$src}" "$mode"
40
+                __deploy_item "$item" "$dst${item#$src}" "$mode"
41 41
             done
42 42
     else
43
-        _maybe install -DTvm "$mode" "$src" "$dst"
43
+        test "$mode" == "SRC" && mode=$(stat -c "%a" "$src")
44
+        __maybe install -DTvm "$mode" "$src" "$dst"
44 45
     fi
45 46
 }
46 47
 
47
-_get_dst() {
48
+__get_dst() {
48 49
     #
49 50
     # Find out target path for src file $2 of group $1
50 51
     #
@@ -52,10 +53,10 @@ _get_dst() {
52 53
     local src=$2        # each source
53 54
     local dst=$3        # alternative destination name
54 55
     test -n "$dst" || dst=${src##*/}
55
-    echo "$(_get_root "$grp")/$dst"
56
+    echo "$(__get_root "$grp")/$dst"
56 57
 }
57 58
 
58
-_get_root() {
59
+__get_root() {
59 60
     #
60 61
     # Find out target root for group $1
61 62
     #
@@ -72,7 +73,7 @@ _get_root() {
72 73
     esac
73 74
 }
74 75
 
75
-_maybe() {
76
+__maybe() {
76 77
     #
77 78
     # Call the deploy command $1 $@ unless in dry mode
78 79
     #
@@ -101,8 +102,8 @@ install() {
101 102
             mode=$(ini 1value "modes:$group")
102 103
             ini values "files:$group" \
103 104
               | while read -r src dst; do
104
-                    dst=$(_get_dst "$group" "$src" "$dst")
105
-                    _deploy_item "$src" "$dst" "$mode"
105
+                    dst=$(__get_dst "$group" "$src" "$dst")
106
+                    __deploy_item "$src" "$dst" "$mode"
106 107
                 done
107 108
         done
108 109
     test -f "$MKIT_LOCAL/autoclean" && clean
@@ -122,8 +123,8 @@ uninstall() {
122 123
       | while read -r group; do
123 124
             ini values "files:$group" \
124 125
               | while read -r src dst; do
125
-                    dst=$(_get_dst "$group" "$src" "$dst")
126
-                    _maybe rm -vrf "$dst"
126
+                    dst=$(__get_dst "$group" "$src" "$dst")
127
+                    __maybe rm -vrf "$dst"
127 128
                 done
128 129
         done
129 130
 }

+ 66
- 63
utils/mkit/include/facts.sh View File

@@ -54,6 +54,9 @@ git_fact() {
54 54
         latest_sha)
55 55
             git log -1 --pretty=format:%h HEAD
56 56
             ;;
57
+        latest_cdate)
58
+            git log -1 --format=%cd --date=unix HEAD
59
+            ;;
57 60
         *)
58 61
             warn "unknown git fact asked: $fact_name"
59 62
             ;;
@@ -85,100 +88,100 @@ git_lasthash() {
85 88
     #
86 89
     # Show last commit hash (with .dirty suffix if needed)
87 90
     #
88
-    # If outside git repo, get it from .mkit/git_lasthash, which
89
-    # should have been put there by dist target.  (I.e., this won't
90
-    # work if you got outside the git repo in other way than dist
91
-    # target, but that's actually expected.)
91
+    # We can't do it outside git repo (or without git) but we should
92
+    # not be asked to; targets that don't require git should make use
93
+    # of cache built by dist target.
92 94
     #
93 95
     local last_hash     # last commit hash
94
-    if git_present; then    # we are in git repo
95
-        last_hash=$(git rev-parse HEAD)
96
-        echo -n "$last_hash"
97
-        git_bool dirty && echo -n ".dirty"
98
-    else    # we are outside (eg. distributor's build dir')
99
-        grep . .mkit/git_lasthash || {
100
-            echo UNKNOWN
101
-            warn "malformed source, could not determine git hash"
102
-        }
103
-    fi
96
+    git_present || {
97
+        echo UNKNOWN_HASH
98
+        warn "no git present; could not determine last hash"
99
+        return 3
100
+    }
101
+    last_hash=$(git rev-parse HEAD)
102
+    echo -n "$last_hash"
103
+    git_bool dirty && echo -n ".dirty"
104 104
 }
105 105
 
106 106
 semver() {
107 107
     #
108
-    # Build semver version string with build metadata
108
+    # Build proper SemVer version string
109 109
     #
110 110
     # Build version string from available info using following
111 111
     # logic:
112 112
     #
113
-    #  1. use project.version (from mkit.ini)
114
-    #  2. if we are in git, override the version with last tag
115
-    #  3. if set, add project:prerl (from mkit.ini) as pre-release ID
113
+    #  1. Use version from last git tag (or mkit.ini if there is no
114
+    #     tag, which is possible on new project)
115
+    #  2. if set, add project:prerl (from mkit.ini) as pre-release ID
116 116
     #     (afer dash)
117
-    #  4. if we are at a later commit than the last tag, add branch
117
+    #  3. if we are at a later commit than the last tag, add branch
118 118
     #     name and commit sha1 to build metadata (after plus sign)
119
-    #  5. if the tree is "dirty", i.e. has uncommited changes,
119
+    #  4. if the tree is "dirty", i.e. has uncommited changes,
120 120
     #     add "dirty" to build metadata
121 121
     #
122 122
     # The version is compatible with SemVer 2.0.0.
123 123
     #
124 124
     # Examples:
125 125
     #
126
-    #     myprog v1.0.7                         # all clear
127
-    #     myprog v1.0.7-alpha                   # mkit.ini: project:prerl="alpha"
128
-    #     myprog v1.0.7-alpha+g1aef811.master   # ^^ + some commits after
129
-    #     myprog v1.0.7-alpha+gf14fc4f.api2     # ^^ + on a feature branch
130
-    #     myprog v1.0.7-alpha+gf14fc4f.api2.dirty  # ^^ + tree edited
131
-    #     myprog v1.0.7-alpha+dirty             # tag OK but tree edited
132
-    #     myprog v1.0.7+dirty                   # ^^ but no pre-release id
126
+    #     foo v1.0.7                            # all clear; proper release
127
+    #     foo v1.0.7-beta                       # mkit.ini: project:prerl="beta"
128
+    #     foo v1.0.7-beta+g1aef811.master       # ^^ + some commits after
129
+    #     foo v1.0.7-beta+gf14fc4f.api2         # ^^ + on a feature branch
130
+    #     foo v1.0.7-beta+gf14fc4f.api2.dirty   # ^^ + tree edited
131
+    #     foo v1.0.7-beta+dirty                 # tag OK but tree edited
132
+    #     foo v1.0.7+dirty                      # ^^ but no pre-release id
133 133
     #
134 134
     # Note that versions with "dirty" should be perceived as kind of
135 135
     # dangerous outside developer's own machine.  Versions with sha1 are
136 136
     # safer but must not be released.
137 137
     #
138
-    # I have considered decorating the git commit refs to make them
139
-    # sort of sortable (e.g. "r1.g1aef811"), but on second thought,
140
-    # I don't think it's good idea to give *any* semantics to meta-data
141
-    # at all.  First, there is no rule that r1<r2<r3; a commit can be
142
-    # removing what other just added and one change can be split to
143
-    # multiple commits.  Also, the whole thing breaks anyway once you
144
-    # rebase your branch (no, it's not a sin).  The sole purpose of
145
-    # meta-data is to *identify* the code, and provide safe path back
146
-    # to tree; commit refs are already perfect for that.
147
-    #
148 138
     # FIXME:  Using project:prerl for release IDs may not be compatible with
149 139
     #         release strategy implemented in release.sh
150 140
     #
151
-    local version       # version string (final result)
152
-    local prerl         # pre-release keyword (from mkit.ini, eg. 'alpha')
141
+    local xyz           # base version string
142
+    local prerl         # pre-release keyword (from mkit.ini, eg. 'beta')
153 143
     local latest_tag    # latest git tag
154 144
     local commit        # commit indicator (CURRENT_BRANCH.gHASH)
155
-    local dirty         # 0 if dirty, 1 if clean
145
+    local dirty=F       # F if dirty, T if clean
146
+    local btime         # timestamp or nothing (see $MKIT_TTAG)
156 147
     local suffix        # version suffix
157
-    local_get semver && return 0
158
-    version=$(ini 1value project:version)
159 148
     prerl=$(ini 1value project:prerl)
149
+    case $MKIT_TTAG in
150
+        none)   btime= ;;
151
+        btime)  btime=$(date -u +%Y%m%d%H%M%S) ;;
152
+        ctime)  btime=$(date -d @"$(git_fact latest_cdate)" -u +%Y%m%d%H%M%S) ;;
153
+    esac
160 154
     grep ":" <<<"$prerl" \
161 155
      && warn "colon in project:prerl may corrupt version data: $prerl"
162
-    if git_present;
163
-    then    # we are in git repo... so we can get smart
164
-        latest_tag=$(git_fact latest_tag)
165
-        if ! git describe --tags --exact-match HEAD >&/dev/null;
166
-        then    # we are at a later commit than the last tag
167
-            commit="$(git_fact current_branch).g$(git_fact latest_sha)"
168
-        fi
169
-        git_bool dirty; dirty=$?
170
-        test -n "$latest_tag" && version=${latest_tag:1}
171
-        case "$dirty:$commit" in
172
-            1:)  suffix=""               ;;
173
-            0:)  suffix="+dirty"         ;;
174
-            1:*) suffix="+$commit"       ;;
175
-            0:*) suffix="+$commit.dirty" ;;
176
-            *)   suffix=MKIT_BUG
177
-                 warn "MKIT_BUG: bad dirt/commit detection" ;;
178
-        esac
179
-        test -n "$prerl" && suffix="-$prerl$suffix"
180
-        version="$version$suffix"
156
+    git_present || {
157
+        echo UNKNOWN_VERSION
158
+        warn "no git present; could not determine SemVer"
159
+        return 3
160
+    }
161
+    latest_tag=$(git_fact latest_tag)
162
+    case $latest_tag in
163
+        v*) xyz=${latest_tag:1} ;;
164
+        "") warn "no tags, using base version from mkit.ini (ok for new project)"
165
+            xyz=$(ini 1value project:version) ;;
166
+        *)  warn "bad form of last tag, using base version from mkit.ini: tag is '$latest_tag'"
167
+            xyz=$(ini 1value project:version) ;;
168
+    esac
169
+    if ! git describe --tags --exact-match HEAD >&/dev/null;
170
+    then    # we are at a later commit than the last tag
171
+        commit="$(git_fact current_branch).g$(git_fact latest_sha)"
181 172
     fi
182
-    local_putb semver <<<"$version"
183
-    echo "$version"
173
+    git_bool dirty && dirty=T
174
+    case "$dirty:$btime:$commit" in
175
+        F:*:)   suffix=""                       ;;
176
+        T::)    suffix="+dirty"                 ;;
177
+        T:*:)   suffix="+t$btime.dirty"           ;;
178
+        F::*)   suffix="+$commit"               ;;
179
+        F:*:*)  suffix="+t$btime.$commit"         ;;
180
+        T::*)   suffix="+$commit.dirty"         ;;
181
+        T:*:*)  suffix="+t$btime.$commit.dirty"   ;;
182
+        *)      suffix=MKIT_BUG
183
+                warn "MKIT_BUG: bad dirt/commit detection" ;;
184
+    esac
185
+    test -n "$prerl" && suffix="-$prerl$suffix"
186
+    echo "$xyz$suffix"
184 187
 }

+ 53
- 21
utils/mkit/include/ini.sh View File

@@ -2,7 +2,7 @@
2 2
 # MKit - simple install helper
3 3
 # See LICENSE file for copyright and license details.
4 4
 
5
-_ini_cat() {
5
+__ini_cat() {
6 6
     #
7 7
     # A no-op for text stream
8 8
     #
@@ -12,7 +12,7 @@ _ini_cat() {
12 12
     done
13 13
 }
14 14
 
15
-_ini_expand() {
15
+__ini_expand() {
16 16
     #
17 17
     # Expand reference value (prefix only)
18 18
     #
@@ -30,20 +30,26 @@ _ini_expand() {
30 30
     done
31 31
 }
32 32
 
33
-_ini_grepkey() {
33
+__ini_grepcmt() {
34
+    #
35
+    # Remove comments from INI file on stdin
36
+    #
37
+    grep -v '^[[:space:]]*#'
38
+}
39
+
40
+__ini_grepkey() {
34 41
     #
35 42
     # Read key from a section
36 43
     #
37 44
     local wnt=$1    # wanted key
38 45
     grep '.' \
39
-      | grep -v '\s*#' \
40 46
       | sed -e 's/ *= */=/; s/ +$//; s/^//;' \
41 47
       | grep -e "^$wnt=" \
42 48
       | cut -d= -f2- \
43
-      | _ini_maybe_expand
49
+      | __ini_maybe_expand
44 50
 }
45 51
 
46
-_ini_greppath() {
52
+__ini_greppath() {
47 53
     #
48 54
     # Read key from the right section
49 55
     #
@@ -62,10 +68,10 @@ _ini_greppath() {
62 68
          && echo "$override" \
63 69
          && return
64 70
     fi
65
-    _ini_grepsec "$wntsec" | _ini_grepkey "$wntkey"
71
+    __ini_grepsec "$wntsec" | __ini_grepkey "$wntkey"
66 72
 }
67 73
 
68
-_ini_grepsec() {
74
+__ini_grepsec() {
69 75
     #
70 76
     # Read one INI section
71 77
     #
@@ -73,7 +79,6 @@ _ini_grepsec() {
73 79
     local ok=false      # are we in the section?
74 80
     local line          # each input line
75 81
     grep '.' \
76
-      | grep -v '\s*#' \
77 82
       | while read -r line; do
78 83
             case "$line" in
79 84
                 \[$wnt\]) ok=true;  continue ;;
@@ -85,25 +90,51 @@ _ini_grepsec() {
85 90
       | sed -e 's/ *= */=/; s/ +$//; s/^//;'
86 91
 }
87 92
 
88
-_ini_lskeys() {
93
+__ini_lskeys() {
89 94
     #
90 95
     # List keys from a section
91 96
     #
92 97
     local sct=$1    # section of interest
93
-    _ini_grepsec "$sct" | cut -d= -f1 | awk '!x[$0]++'
98
+    __ini_grepsec "$sct" | cut -d= -f1 | awk '!x[$0]++'
99
+}
100
+
101
+__ini_lssect() {
102
+    #
103
+    # List all section names
104
+    #
105
+    local arg=$1    # unused argument
106
+    grep -x '\[.*\]' | sed 's/^.//; s/.$//'
94 107
 }
95 108
 
96
-_ini_maybe_expand() {
109
+__ini_maybe_expand() {
97 110
     #
98 111
     # Decide whether or not to expand
99 112
     #
100 113
     if test "$MKIT_INI_EXPAND" -gt 0; then
101
-        MKIT_INI_EXPAND=$(( --MKIT_INI_EXPAND )) _ini_expand
114
+        MKIT_INI_EXPAND=$(( --MKIT_INI_EXPAND )) __ini_expand
102 115
     else
103
-        _ini_cat
116
+        __ini_cat
104 117
     fi
105 118
 }
106 119
 
120
+__ini_body() {
121
+    #
122
+    # Produce mkit.ini body including INCLUDE
123
+    #
124
+    # Note: recursive includes are not supported.
125
+    #
126
+    local inc                       # file to include
127
+    local incre='\[INCLUDE:.*\]'    # include directive regex
128
+    local iline                     # include directive line
129
+    if iline=$(grep -m1 -x "$incre" "$MKIT_INI"); then
130
+        inc=${iline#*:}; inc=${inc%]}
131
+        grep -vx "$incre" "$inc"
132
+        grep -vx "$incre" "$MKIT_INI"
133
+    else
134
+        cat "$MKIT_INI"
135
+    fi | __ini_grepcmt
136
+}
137
+
107 138
 ini() {
108 139
     #
109 140
     # do ini operation
@@ -111,20 +142,21 @@ ini() {
111 142
     local op=$1             # operator
112 143
     local arg=$2            # argument
113 144
     local fn                # internal function implementing $op
114
-    local limit=_ini_cat    # limiting internal function
145
+    local limit=__ini_cat    # limiting internal function
115 146
     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" ;;
147
+        lskeys) fn=__ini_lskeys   ;;
148
+        lssect) fn=__ini_lssect   ;;
149
+        sec)    fn=__ini_grepsec  ;;
150
+        values) fn=__ini_greppath ;;
151
+        1value) fn=__ini_greppath; limit="tail -1" ;;
120 152
         *)      die "incorrect use of \`ini()\`"
121 153
     esac
122
-    <"$MKIT_INI" $fn "$arg" | $limit
154
+    __ini_body | $fn "$arg" | $limit
123 155
 }
124 156
 
125 157
 update_version() {
126 158
     #
127
-    # Change project.version in mkit.ini at path $2 to version $1
159
+    # Change project:version in mkit.ini at path $2 to value $1
128 160
     #
129 161
     local version=$1    # new version
130 162
     local inifile=$2    # mkit.ini path

+ 12
- 46
utils/mkit/include/mkit.sh View File

@@ -30,12 +30,12 @@ mkit_import deploy
30 30
 mkit_import release
31 31
 mkit_import ini
32 32
 
33
-_valid_targets() {
33
+__valid_targets() {
34 34
     #
35 35
     # List valid routes
36 36
     #
37
+    echo _mkit_data
37 38
     echo build
38
-    echo build_manpages
39 39
     echo clean
40 40
     echo debstuff
41 41
     echo dist
@@ -66,17 +66,17 @@ debug_var() {
66 66
     #
67 67
     $MKIT_DEBUG || return 0
68 68
     local __mkit_debug_var_name__       # variable name to debug
69
+    local decl                          # declare string
69 70
     for __mkit_debug_var_name__ in "$@"; do
70 71
         {
71
-            echo -n "MKIT_DEBUG: ${FUNCNAME[1]}():"
72
-            echo -n " $__mkit_debug_var_name__"
73
-            echo -n "='${!__mkit_debug_var_name__}'"
74
-            echo
72
+            decl=$(declare -p "$__mkit_debug_var_name__")
73
+            decl=${decl#declare ?? }
74
+            echo "MKIT_DEBUG: ${FUNCNAME[1]}(): $decl"
75 75
         } >&2
76 76
     done
77 77
 }
78 78
 
79
-_compver() {
79
+__compver() {
80 80
     #
81 81
     # True if version $1 matches our version
82 82
     #
@@ -103,7 +103,7 @@ _compver() {
103 103
     return 0
104 104
 }
105 105
 
106
-_chkiniversion() {
106
+__chkiniversion() {
107 107
     #
108 108
     # Check if ini version is supported
109 109
     #
@@ -121,35 +121,10 @@ _chkiniversion() {
121 121
     test -n "$ver_line" \
122 122
      || die "version mark ('#mkit version=x.y.z') not found in: $MKIT_INI"
123 123
     their_ver="$(tr -d '[:blank:]v' <<<"${ver_line##*=}")"
124
-    _compver "$their_ver" \
124
+    __compver "$their_ver" \
125 125
      || die "bad mkit.ini version: $their_ver does not match $MKIT_VERSION"
126 126
 }
127 127
 
128
-local_putb() {
129
-    #
130
-    # Make file $1 in $MKIT_LOCAL from stdin and mark as built
131
-    #
132
-    local fpath=$1
133
-    local_put "$fpath" && rec_built "$MKIT_LOCAL/$fpath"
134
-}
135
-
136
-local_put() {
137
-    #
138
-    # Make file $1 in $MKIT_LOCAL from stdin
139
-    #
140
-    local fpath="$MKIT_LOCAL/$1"
141
-    { mkdir -p "${fpath%/*}" && cat >"$fpath"; } \
142
-     || die "cannot write to local cache: $fpath"
143
-}
144
-
145
-local_get() {
146
-    #
147
-    # Read file $1 in $MKIT_LOCAL
148
-    #
149
-    local fpath="$MKIT_LOCAL/$1"
150
-    cat "$fpath" 2>/dev/null
151
-}
152
-
153 128
 mkit_init() {
154 129
     #
155 130
     # Do basic initialization
@@ -160,30 +135,21 @@ mkit_init() {
160 135
     #shellcheck disable=SC2034
161 136
     MKIT_PROJ_PKGNAME=$(ini 1value "project:pkgname")
162 137
     test -f "$MKIT_INI" || die "cannot find mkit.ini: $MKIT_INI"
163
-    _chkiniversion
164
-}
165
-
166
-rec_built() {
167
-    #
168
-    # Record file $1 for deletion on `clean`
169
-    #
170
-    local file=$1
171
-    mkdir -p "$MKIT_LOCAL"
172
-    echo "$file" >> "$MKIT_LOCAL/built.lst"
138
+    __chkiniversion
173 139
 }
174 140
 
175 141
 route() {
176 142
     #
177 143
     # Call correct function based on $1
178 144
     #
179
-    if _valid_targets | grep -qwx "^$1"; then
145
+    if __valid_targets | grep -qwx "^$1"; then
180 146
         "$1"
181 147
     else
182 148
         {
183 149
             echo "usage: $(basename "$0") TARGET"
184 150
             echo
185 151
             echo "valid targets:"
186
-            _valid_targets | sed 's/^/    /'
152
+            __valid_targets | sed 's/^/    /'
187 153
         } >&2
188 154
     fi
189 155
 }

+ 33
- 29
utils/mkit/include/release.sh View File

@@ -5,7 +5,7 @@
5 5
 mkit_import ini
6 6
 mkit_import facts
7 7
 
8
-_bump_version() {
8
+__bump_version() {
9 9
     #
10 10
     # Bump version on stdin by level $1 (x, y or z)
11 11
     #
@@ -30,7 +30,7 @@ _bump_version() {
30 30
     echo "$new"
31 31
 }
32 32
 
33
-_relck() {
33
+__relck() {
34 34
     #
35 35
     # Die if blocking condition $1 is detected
36 36
     #
@@ -68,7 +68,7 @@ _relck() {
68 68
              && die "WIP commit since $(git_fact latest_tag)"
69 69
             ;;
70 70
         ini_version)
71
-            oracle=$(git_fact latest_version | _bump_version "$rlevel")
71
+            oracle=$(git_fact latest_version | __bump_version "$rlevel")
72 72
             ini 1value project:version  \
73 73
               | grep -qFx "$oracle" \
74 74
              || die "new version not in mkit.ini: $oracle"
@@ -79,7 +79,7 @@ _relck() {
79 79
     esac
80 80
 }
81 81
 
82
-_release() {
82
+__release() {
83 83
     #
84 84
     # Prepare release
85 85
     #
@@ -94,19 +94,19 @@ _release() {
94 94
     local relsrc        # release source branch (if any)
95 95
     local reldst        # release destination branch (if any)
96 96
 
97
-    _relck git_present
98
-    _relck at_relsrc
99
-    _relck not_dirty
100
-    _relck tags_ok
101
-    _relck vbump_hot
102
-    _relck no_wip
103
-    _relck ini_version
97
+    __relck git_present
98
+    __relck at_relsrc
99
+    __relck not_dirty
100
+    __relck tags_ok
101
+    __relck vbump_hot
102
+    __relck no_wip
103
+    __relck ini_version
104 104
 
105
-    newtag=$(git_fact latest_version | _bump_version "$rlevel" | git_ver2tag )
105
+    newtag=$(git_fact latest_version | __bump_version "$rlevel" | git_ver2tag )
106 106
     set -e
107 107
     debug_var newtag
108 108
     $MKIT_DRY && return
109
-    git tag -m "$(_release_msg)" "$newtag"
109
+    git tag -m "$(__release_msg)" "$newtag"
110 110
 
111 111
     relsrc=$(ini 1value project:relsrc)
112 112
     reldst=$(ini 1value project:reldst)
@@ -116,7 +116,7 @@ _release() {
116 116
     fi
117 117
 }
118 118
 
119
-_release_msg() {
119
+__release_msg() {
120 120
     #
121 121
     # Generate message for annotated tag
122 122
     #
@@ -133,7 +133,7 @@ _release_msg() {
133 133
       | tail -n +3
134 134
 }
135 135
 
136
-_vbump() {
136
+__vbump() {
137 137
     #
138 138
     # Do version bump at level $1
139 139
     #
@@ -142,17 +142,21 @@ _vbump() {
142 142
     #
143 143
     local rlevel=$1     # bump level (x, y or z)
144 144
     local nextver       # version after the bump
145
-    _relck git_present
146
-    _relck at_relsrc
147
-    _relck not_dirty
148
-    nextver=$(ini 1value project:version | _bump_version "$rlevel")
145
+    local cache         # cache for the message
146
+    __relck git_present
147
+    __relck at_relsrc
148
+    __relck not_dirty
149
+    nextver=$(ini 1value project:version | __bump_version "$rlevel")
149 150
     debug_var nextver
150 151
     $MKIT_DRY && return
151 152
     update_version "$nextver" mkit.ini \
152 153
       || die "failed to update version in mkit.ini"
153 154
     git add mkit.ini \
154 155
       || die "failed to add mkit.ini to the index"
155
-    git commit -e -m "$(_vbump_gitmsg)"
156
+    cache=$(mktemp -t "mkit._vbump_gitmsg.XXXXXXXX")
157
+    _vbump_gitmsg > "$cache"
158
+    git commit -e -F "$cache"   # note: reading from stdin will break vim
159
+    rm "$cache"
156 160
 }
157 161
 
158 162
 _vbump_gitmsg() {
@@ -165,7 +169,7 @@ _vbump_gitmsg() {
165 169
     echo ""
166 170
     git_fact reldiff \
167 171
       | sed '
168
-            s/^[a-f0-9]\{7\} / *  &/; t PATHS
172
+            s/^[a-f0-9]\{7\} /\n *  &/; t PATHS
169 173
             s/^/        /
170 174
             :PATHS
171 175
         '
@@ -175,54 +179,54 @@ release() {
175 179
     #
176 180
     # Perform release on Z level
177 181
     #
178
-    _release z
182
+    __release z
179 183
 }
180 184
 
181 185
 release_x() {
182 186
     #
183 187
     # Perform release on X level
184 188
     #
185
-    _release x
189
+    __release x
186 190
 }
187 191
 
188 192
 release_y() {
189 193
     #
190 194
     # Perform release on Y level
191 195
     #
192
-    _release y
196
+    __release y
193 197
 }
194 198
 
195 199
 release_z() {
196 200
     #
197 201
     # Perform release on Z level
198 202
     #
199
-    _release z
203
+    __release z
200 204
 }
201 205
 
202 206
 vbump() {
203 207
     #
204 208
     # Perform version bump on Z level
205 209
     #
206
-    _vbump z
210
+    __vbump z
207 211
 }
208 212
 
209 213
 vbump_x() {
210 214
     #
211 215
     # Perform version bump on X level
212 216
     #
213
-    _vbump x
217
+    __vbump x
214 218
 }
215 219
 
216 220
 vbump_y() {
217 221
     #
218 222
     # Perform version bump on Y level
219 223
     #
220
-    _vbump y
224
+    __vbump y
221 225
 }
222 226
 
223 227
 vbump_z() {
224 228
     #
225 229
     # Perform version bump on Z level
226 230
     #
227
-    _vbump z
231
+    __vbump z
228 232
 }

+ 30
- 2
utils/mkit/include/vars.sh View File

@@ -51,11 +51,39 @@ MKIT_LOCAL=${MKIT_LOCAL:-.mkit}
51 51
 #
52 52
 # Package name
53 53
 #
54
-# Used as base for tarball and in some default tokens.
54
+# Used as base for tarball and in some default macros.
55 55
 #
56 56
 MKIT_PROJ_PKGNAME=""
57 57
 
58
+#
59
+# Add time-based ordinal tag to SemVer build data?
60
+#
61
+# Can be 'none', 'ctime' or 'btime'.
62
+#
63
+# If 'ctime', devel builds have also timestamp-based tag in format of
64
+# `t%Y%m%d%H%M%S`, that is, a small character 't' followed by timestamp
65
+# without non-digit characters.  The timestamps are in UTC, ie. timezones
66
+# need not apply.  'btime' has the same format, except that it's derived
67
+# from build time, while 'ctime' is from last commit's commit date.
68
+#
69
+# This helps with deploying development builds where packaging system
70
+# is not SemVer-compliant and makes it hard to install arbitrary version.
71
+# For example, old yum version (as of RHEL-6) will not let you install
72
+# version that it deems older than is installed, making it hard to
73
+# continually upgrade during active development.  While packaging
74
+# systems have their own rukes (and SemVer says both versions should be
75
+# considered same) this tag will make it more likely to "win" the build
76
+# you made later.
77
+#
78
+# Note that this does not affect clean builds (ie. builds from clean
79
+# repo with HEAD corresponding to latest version tag.).
80
+#
81
+# Also note that 'btime' makes the version non-deterministic: merely
82
+# initiating the build a second later will result in different version.
83
+#
84
+MKIT_TTAG=${MKIT_TTAG:-ctime}
85
+
58 86
 #
59 87
 # This MKit version
60 88
 #
61
-MKIT_VERSION=0.0.25
89
+MKIT_VERSION=0.0.34

+ 19
- 19
utils/mkit/mkit.mk View File

@@ -5,52 +5,52 @@ export MKIT_DIR
5 5
 
6 6
 all: build
7 7
 
8
-build:
9
-	@$(MKIT_DIR)/make build
8
+_mkit_data:
9
+	@"$(MKIT_DIR)"/make _mkit_data
10 10
 
11
-manpages: build
12
-	@$(MKIT_DIR)/make build_manpages
11
+build:
12
+	@"$(MKIT_DIR)"/make build
13 13
 
14 14
 clean:
15
-	@$(MKIT_DIR)/make clean
15
+	@"$(MKIT_DIR)"/make clean
16 16
 
17 17
 debstuff: dist
18
-	@$(MKIT_DIR)/make debstuff
18
+	@"$(MKIT_DIR)"/make debstuff
19 19
 
20 20
 dist: clean
21
-	@$(MKIT_DIR)/make dist
21
+	@"$(MKIT_DIR)"/make dist
22 22
 
23 23
 rpmstuff: dist
24
-	@$(MKIT_DIR)/make rpmstuff
24
+	@"$(MKIT_DIR)"/make rpmstuff
25 25
 
26 26
 install: all
27
-	@$(MKIT_DIR)/make install
27
+	@"$(MKIT_DIR)"/make install
28 28
 
29 29
 release:
30
-	@$(MKIT_DIR)/make release
30
+	@"$(MKIT_DIR)"/make release
31 31
 
32 32
 release_x:
33
-	@$(MKIT_DIR)/make release_x
33
+	@"$(MKIT_DIR)"/make release_x
34 34
 
35 35
 release_y:
36
-	@$(MKIT_DIR)/make release_y
36
+	@"$(MKIT_DIR)"/make release_y
37 37
 
38 38
 release_z:
39
-	@$(MKIT_DIR)/make release_z
39
+	@"$(MKIT_DIR)"/make release_z
40 40
 
41 41
 uninstall:
42
-	@$(MKIT_DIR)/make uninstall
42
+	@"$(MKIT_DIR)"/make uninstall
43 43
 
44 44
 vbump:
45
-	@$(MKIT_DIR)/make vbump
45
+	@"$(MKIT_DIR)"/make vbump
46 46
 
47 47
 vbump_x:
48
-	@$(MKIT_DIR)/make vbump_x
48
+	@"$(MKIT_DIR)"/make vbump_x
49 49
 
50 50
 vbump_y:
51
-	@$(MKIT_DIR)/make vbump_y
51
+	@"$(MKIT_DIR)"/make vbump_y
52 52
 
53 53
 vbump_z:
54
-	@$(MKIT_DIR)/make vbump_z
54
+	@"$(MKIT_DIR)"/make vbump_z
55 55
 
56
-.PHONY: all clean dist rpmstuff install uninstall release release_x release_y release_z vbump vbump_x vbump_y vbump_z
56
+.PHONY: all _mkit_data clean dist rpmstuff install uninstall release release_x release_y release_z vbump vbump_x vbump_y vbump_z

+ 86
- 69
utils/mkit/stub View File

@@ -58,7 +58,6 @@ deploy() {
58 58
             echo "$any_name"
59 59
             tr -c '=\n' '=' <<<"$any_name"
60 60
             echo ''
61
-            echo ''
62 61
             if test -n "$Tagline"; then
63 62
                 echo "$Tagline"
64 63
             else
@@ -68,72 +67,84 @@ deploy() {
68 67
 
69 68
         */mkit.ini|mkit.ini)
70 69
             echo "[project]"
71
-            echo "    version     = $Version"
72
-            test -n "$Codename"     && echo "    codename    = $Codename"
73
-            test -n "$NiceName"     && echo "    name        = $NiceName"
74
-            test -n "$Tagline"      && echo "    tagline     = $Tagline"
75
-            test -n "$PackageName"  && echo "    pkgname     = $PackageName"
76
-            test -n "$Maintainer"   && echo "    maintainer  = $Maintainer"
77
-            test -n "$VcsBrowser"   && echo "    vcs_browser = $VcsBrowser"
78
-            test -n "$RelSrc"       && echo "    relsrc      = $RelSrc"
79
-            test -n "$RelDst"       && echo "    reldst      = $RelDst"
70
+            {
71
+                echo "version = $Version"
72
+                test -n "$Codename"     && echo "codename    = $Codename"
73
+                test -n "$NiceName"     && echo "name        = $NiceName"
74
+                test -n "$Tagline"      && echo "tagline     = $Tagline"
75
+                test -n "$PackageName"  && echo "pkgname     = $PackageName"
76
+                test -n "$Maintainer"   && echo "maintainer  = $Maintainer"
77
+                test -n "$VcsBrowser"   && echo "vcs_browser = $VcsBrowser"
78
+                test -n "$RelSrc"       && echo "relsrc      = $RelSrc"
79
+                test -n "$RelDst"       && echo "reldst      = $RelDst"
80
+            } | reformat_section
80 81
             if updating; then
81 82
                 remake_section dist
82 83
                 remake_section ENV
83 84
                 remake_section roots
84
-                remake_section tokens
85
+                remake_section macros
85 86
                 remake_section modes
86 87
                 remake_section files
87 88
             else
88 89
                 echo ""
89 90
                 echo "[dist]"
90
-                $MkLicense  && echo "    tarball = LICENSE.md"
91
-                $MkMakefile && echo "    tarball = Makefile"
92
-                $MkReadme   && echo "    tarball = README.md"
93
-                echo "    tarball = mkit.ini"
94
-                $MkPackaging && echo "    tarball = packaging"
95
-                echo "    tarball = src"
96
-                echo "    tarball = tests"
97
-                echo "    tarball = utils"
98
-                $MkPackaging && echo "    rpmstuff = packaging/template.spec"
99
-                $MkPackaging && echo "    debstuff = packaging/debian"
91
+                {
92
+                    $MkLicense  && echo "tarball = LICENSE.md"
93
+                    $MkMakefile && echo "tarball = Makefile"
94
+                    $MkReadme   && echo "tarball = README.md"
95
+                    echo "tarball = mkit.ini"
96
+                    $MkPackaging && echo "tarball = packaging"
97
+                    echo "tarball = src"
98
+                    echo "tarball = tests"
99
+                    echo "tarball = utils"
100
+                    $MkPackaging && echo "rpmstuff = packaging/template.spec"
101
+                    $MkPackaging && echo "debstuff = packaging/debian"
102
+                } | reformat_section
100 103
                 echo ""
101 104
                 echo "[ENV]"
102
-                echo "    PREFIX = /usr/local"
105
+                {
106
+                    echo "    PREFIX = /usr/local"
107
+                } | reformat_section
103 108
                 echo ""
104 109
                 echo "[roots]"
105
-                echo "    bin     = [ENV:PREFIX]/bin"
106
-                echo "    doc     = [ENV:PREFIX]/share/doc/$PackageName"
110
+                {
111
+                    echo "bin = [ENV:PREFIX]/bin"
112
+                    echo "doc = [ENV:PREFIX]/share/doc/$PackageName"
113
+                } | reformat_section
107 114
                 echo ""
108
-                echo "[tokens]"
109
-                echo "    __${PackageName^^}_FOO__ = Barr.."
115
+                echo "[macros]"
116
+                {
117
+                    echo "__${PackageName^^}_FOO__ = Barr.."
118
+                } | reformat_section
110 119
                 echo ""
111 120
                 echo "[modes]"
112
-                echo "    bin     = 755"
113
-                echo "    doc     = 644"
121
+                {
122
+                    echo "bin = 755"
123
+                    echo "doc = 644"
124
+                } | reformat_section
114 125
                 echo ""
115 126
                 echo "[files]"
116
-                echo "    bin      = src/$PackageName"
117
-                $MkLicense && echo "    doc      = LICENSE.md"
118
-                $MkReadme  && echo "    doc      = README.md"
127
+                {
128
+                    echo "bin = src/$PackageName"
129
+                    $MkLicense && echo "doc = LICENSE.md"
130
+                    $MkReadme  && echo "doc = README.md"
131
+                } | reformat_section
119 132
             fi
120 133
             echo ""
121 134
             echo "#mkit version=$MKIT_VERSION"
122 135
             ;;
123 136
 
124 137
         packaging/template.spec)
125
-            echo 'Name:		__MKIT_PROJ_PKGNAME__'
126
-            echo 'Version:	__MKIT_PROJ_VERSION__'
127
-            echo 'Release:	1%{?dist}'
128
-            echo 'Summary:	__MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
129
-            echo ''
130
-            $MkLicense && echo "License:	$License"
131
-            echo 'Source0:	%{name}-%{version}.tar.gz'
132
-            echo ''
133
-            echo 'BuildArch:	noarch'
134
-            echo 'BuildRequires:	coreutils git'
135
-            echo 'Requires:	MKIT_STUB_REQUIRES'
138
+            echo 'Name:       __MKIT_PROJ_PKGNAME__'
139
+            echo 'Version:    __MKIT_PROJ_VERSION__'
140
+            echo 'Release:    1%{?dist}'
141
+            echo 'Summary:    __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
142
+            test -n "$VcsBrowser" && echo 'URL:        __MKIT_PROJ_VCS_BROWSER__'
143
+            $MkLicense && echo "License:    $License"
144
+            echo 'Source0:    %{name}-%{version}.tar.gz'
145
+            echo 'BuildArch:  noarch'
136 146
             echo ''
147
+            echo 'Requires: MKIT_STUB_REQUIRES'
137 148
             echo '%description'
138 149
             echo 'MKIT_STUB_DESCRIPTION'
139 150
             echo ''
@@ -165,7 +176,8 @@ deploy() {
165 176
             echo 'Section: misc'
166 177
             echo 'Priority: extra'
167 178
             echo 'Standards-Version: 3.9.2'
168
-            echo 'Build-Depends: debhelper (>= 9)'
179
+            echo 'Build-Depends:'
180
+            echo ' debhelper (>= 9),'
169 181
             echo ''
170 182
             echo 'Package: __MKIT_PROJ_PKGNAME__'
171 183
             echo 'Architecture: all'
@@ -198,17 +210,13 @@ deploy() {
198 210
             echo 'override_dh_auto_install:'
199 211
             echo ''
200 212
             echo '	make install PREFIX=/usr DESTDIR=debian/tmp'
201
-            echo ''
202
-            echo 'override_dh_usrlocal:'
203
-            echo ''
204
-            echo '	@true'
205 213
             ;;
206 214
 
207 215
         packaging/debian/source/format)
208 216
             echo '3.0 (quilt)'
209 217
             ;;
210 218
 
211
-        packaging/debian/*.install)
219
+        packaging/debian/install)
212 220
             echo MKIT_STUB_FILELIST
213 221
             ;;
214 222
 
@@ -237,7 +245,6 @@ deploy() {
237 245
             echo "everything, so few things still need to be done manually."
238 246
             echo "This document will guide you throught the rest of the"
239 247
             echo "process."
240
-
241 248
             echo ""
242 249
             echo ""
243 250
             echo "Structure"
@@ -251,7 +258,7 @@ deploy() {
251 258
             echo "    machine should be uder 'src'."
252 259
             echo ""
253 260
             echo "    Note that during build time, files named ending with"
254
-            echo "    '.skel' are subject to token expansion, see mkit.ini"
261
+            echo "    '.skel' are subject to macro expansion, see mkit.ini"
255 262
             echo "    section below for details."
256 263
             echo ""
257 264
             echo " *  *notes* directory - here you shall store notes"
@@ -272,7 +279,7 @@ deploy() {
272 279
             echo " *  *packaging* directory contains templates that enable"
273 280
             echo "    MKit create raw stuffs used to create DEB or RPM"
274 281
             echo "    packages.  Similar to '.skel' files in 'src', all files"
275
-            echo "    here are automatically considered for token expansion,"
282
+            echo "    here are automatically considered for macro expansion,"
276 283
             echo "    no matter how they are named (see mkit.ini section"
277 284
             echo "    below)."
278 285
             echo ""
@@ -285,7 +292,6 @@ deploy() {
285 292
             echo "    idea!), be prepared that you will need to follow their"
286 293
             echo "    guidelines.  This will most probably mean huge changes"
287 294
             echo "    to these packages or even changes to your workflow."
288
-
289 295
             echo ""
290 296
             echo ""
291 297
             echo "Placeholders"
@@ -318,9 +324,9 @@ deploy() {
318 324
             echo "     *  \`MKIT_STUB_FILELIST\` - List of full paths to"
319 325
             echo "        your files after installation."
320 326
             echo ""
321
-            echo "        Note that in case of debian/package.install files,"
322
-            echo "        PREFIX based paths (eg. /usr/bin) in this file should"
323
-            echo "        should be as if PREFIX was /usr."
327
+            echo "        Note that in case of debian/install files, PREFIX"
328
+            echo "        based paths (eg. /usr/bin) in this file should be as"
329
+            echo "        if PREFIX was /usr."
324 330
             echo ""
325 331
             echo "        In case of Fedora-based distro, you should make use"
326 332
             echo "        of RPM macros:"
@@ -349,7 +355,6 @@ deploy() {
349 355
             echo "    Typical example of a role is e.g. 'bin' for commands"
350 356
             echo "    (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
351 357
             echo "    for documents or 'lib' for libraries."
352
-
353 358
             echo ""
354 359
             echo " 2. Next, in \`[roots]\` section, you have to set target"
355 360
             echo "    root directory for each role.  However, in order to"
@@ -358,7 +363,6 @@ deploy() {
358 363
             echo "    environment variable.  For this reason, most paths"
359 364
             echo "    need to start with \`[ENV:PREFIX]\`."
360 365
             echo ""
361
-
362 366
             echo " 3. \`[files]\` section is where you assign actual files"
363 367
             echo "    from your repository to their final paths.  The format"
364 368
             echo "    is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
@@ -373,22 +377,19 @@ deploy() {
373 377
             echo "    individually, if in your repo you have a directory with"
374 378
             echo "    100 files of the same role, you can add just path to the"
375 379
             echo "    directory itself."
376
-
377 380
             echo ""
378 381
             echo " 4. If some roles require special permissions on your files,"
379 382
             echo "    \`[modes]\` section is your friend.  Permissions here"
380 383
             echo "    should be in UNIX octal format."
381
-
382 384
             echo ""
383
-            echo " 5. Next, \`[tokens]\` section allows you to define own"
385
+            echo " 5. Next, \`[macros]\` section allows you to define own"
384 386
             echo "    placeholders that will be replaced when your scripts are"
385 387
             echo "    built.  Each file in 'src' directory that is named with"
386 388
             echo "    '.skel' suffix, and each file from 'packaging' directory"
387
-            echo "    (no matter its name), can contain one or more of tokens"
388
-            echo "    defined here, plus range of tokens automatically defined"
389
-            echo "    by MKit.  During build, these tokens are replaced with"
389
+            echo "    (no matter its name), can contain one or more of macros"
390
+            echo "    defined here, plus range of macros automatically defined"
391
+            echo "    by MKit.  During build, these macros are replaced with"
390 392
             echo "    their actual values."
391
-
392 393
             echo ""
393 394
             echo " 6. Less interesting, but important section is \`[dist]\`,"
394 395
             echo "    which lists files in your codebase that will be added"
@@ -396,14 +397,12 @@ deploy() {
396 397
             echo "    above).  Listing directory here will include all its"
397 398
             echo "    contents, and normally it's OK to be very inclusive, so"
398 399
             echo "    most of the time this section should be OK."
399
-
400 400
             echo ""
401 401
             echo " 7. Even less interesting is section \`[ENV]\`.  It is"
402 402
             echo "    special in that it provides *default* value for an"
403 403
             echo "    environment variable.  You almost never need to touch"
404 404
             echo "    this."
405 405
             echo ""
406
-
407 406
             echo " 8. Finally, the most interesting section!  \`[project]\`,"
408 407
             echo "    provides most general information for your project such"
409 408
             echo "    as name and version."
@@ -486,7 +485,7 @@ usage() {
486 485
         echo "    -R            skip creating README.md"
487 486
         echo "    -M            skip creating Makefile"
488 487
         echo "    -P            skip creating packaging templates"
489
-        echo "    -L            list know licenses and exit"
488
+        echo "    -L            list known licenses and exit"
490 489
         echo ""
491 490
         echo "PKGNAME should be packaging-friendly name, ie. consist"
492 491
         echo "only of small letters, numbers, underscore and dash."
@@ -551,9 +550,9 @@ deploy_packaging() {
551 550
     deploy packaging/debian/control
552 551
     deploy packaging/debian/changelog
553 552
     deploy packaging/debian/compat
553
+    deploy packaging/debian/install
554 554
     deploy packaging/debian/rules
555 555
     deploy packaging/debian/source/format
556
-    deploy packaging/debian/"$PackageName".install
557 556
 }
558 557
 
559 558
 init_from_existing() {
@@ -615,7 +614,25 @@ remake_section() {
615 614
                     echo "$key = $value"
616 615
                 done
617 616
         done \
618
-      | column -to' ' \
617
+      | reformat_section
618
+}
619
+
620
+reformat_section() {
621
+    #
622
+    # Re-format "k = v" on stdin as "nice" ini section
623
+    #
624
+    local key
625
+    local eq
626
+    local value
627
+    while read -r key eq value; do
628
+        test "$eq" == "=" || {
629
+            warn "ignoring malformed ini line: $key $eq $value"
630
+            continue
631
+        }
632
+        echo "$key = $value"
633
+    done \
634
+      | sed 's/ *= */=/; s/^ *//; s/ *$//' \
635
+      | column -t -s= -o' = ' \
619 636
       | sed 's/^/    /'
620 637
 }
621 638