Browse Source

Update MKit to v0.0.34

Alois Mahdal 6 years ago
parent
commit
2e64b13cd0
7 changed files with 261 additions and 174 deletions
  1. 2
    2
      mkit.ini
  2. 122
    46
      utils/mkit/include/build.sh
  3. 66
    63
      utils/mkit/include/facts.sh
  4. 26
    3
      utils/mkit/include/ini.sh
  5. 4
    38
      utils/mkit/include/mkit.sh
  6. 30
    2
      utils/mkit/include/vars.sh
  7. 11
    20
      utils/mkit/stub

+ 2
- 2
mkit.ini View File

35
     etc_bc  = /etc/bash_completion.d
35
     etc_bc  = /etc/bash_completion.d
36
     sfincb  = [ENV:PREFIX]/share/shellfu/include-bash
36
     sfincb  = [ENV:PREFIX]/share/shellfu/include-bash
37
 
37
 
38
-[tokens]
38
+[macros]
39
     __SATURNIN_DATA_HOME__    = [ENV:XDG_DATA_HOME]/saturnin-demo
39
     __SATURNIN_DATA_HOME__    = [ENV:XDG_DATA_HOME]/saturnin-demo
40
     __SATURNIN_CACHE_HOME__   = [ENV:XDG_CACHE_HOME]/saturnin-demo
40
     __SATURNIN_CACHE_HOME__   = [ENV:XDG_CACHE_HOME]/saturnin-demo
41
     __SATURNIN_CONFIG_HOME__  = [ENV:XDG_CONFIG_HOME]/saturnin-demo
41
     __SATURNIN_CONFIG_HOME__  = [ENV:XDG_CONFIG_HOME]/saturnin-demo
58
     share   = src/help
58
     share   = src/help
59
     share   = src/ini.d
59
     share   = src/ini.d
60
 
60
 
61
-#mkit version=0.0.24
61
+#mkit version=0.0.34

+ 122
- 46
utils/mkit/include/build.sh View File

17
     test -n "$ftype"    || ftype=$(__guess_ftype "$dstpath")
17
     test -n "$ftype"    || ftype=$(__guess_ftype "$dstpath")
18
     debug_var srcpath dstpath ftype
18
     debug_var srcpath dstpath ftype
19
     <"$srcpath" __build1_ftype "$ftype" >"$dstpath"
19
     <"$srcpath" __build1_ftype "$ftype" >"$dstpath"
20
-    rec_built "$dstpath"
20
+    __rec_built "$dstpath"
21
 }
21
 }
22
 
22
 
23
 __build1_ftype() {
23
 __build1_ftype() {
26
     #
26
     #
27
     local ftype=$1      # file/builder type
27
     local ftype=$1      # file/builder type
28
     case $ftype in
28
     case $ftype in
29
-        MKIT_COMMON)    __expand_tokens "tokens" ;;
30
-        rpmstuff)       __expand_tokens "tokens" "rpmstuff:tokens" ;;
31
-        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" ;;
32
         *)              die "unknown file type: $ftype" ;;
32
         *)              die "unknown file type: $ftype" ;;
33
     esac
33
     esac
34
 }
34
 }
35
 
35
 
36
-__expand_tokens() {
36
+__expand_line() {
37
     #
37
     #
38
-    # Read stdin, expanding tokens from sections $@
38
+    # Expand macro from $MacroMap in single line $1
39
     #
39
     #
40
-    local script        # sed script cache
41
-    local section       # each section to expand tokens from
42
-    local varname       # each token name
43
-    local varvalue      # each token value
44
-    script=$(mktemp --tmpdir mkit-tmp.XXXXXXXXXX)
45
-    {
46
-        for section in "$@"; do
47
-            debug_var section
48
-            ini lskeys "$section" \
49
-              | while read -r varname; do
50
-                    varvalue="$(ini 1value "$section:$varname" | __qfs )"
51
-                    echo "s|$varname|$varvalue|g;"
52
-                    debug_var varname varvalue
53
-                done
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
64
+}
65
+
66
+__expand_macros() {
67
+    #
68
+    # Read stdin, expanding macros from sections $@
69
+    #
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")
54
         done
87
         done
55
-        echo "s|__MKIT_PROJ_NAME__|$(ini 1value project:name | __qfs)|g;"
56
-        echo "s|__MKIT_PROJ_CODENAME__|$(ini 1value project:codename | __qfs)|g;"
57
-        echo "s|__MKIT_PROJ_LICENSE__|$(ini 1value project:license | __qfs)|g;"
58
-        echo "s|__MKIT_PROJ_PKGNAME__|$(ini 1value project:pkgname | __qfs)|g;"
59
-        echo "s|__MKIT_PROJ_TAGLINE__|$(ini 1value project:tagline | __qfs)|g;"
60
-        echo "s|__MKIT_PROJ_MAINTAINER__|$(ini 1value project:maintainer | __qfs)|g;"
61
-        echo "s|__MKIT_PROJ_VCS_BROWSER__|$(ini 1value project:vcs_browser | __qfs)|g;"
62
-        echo "s|__MKIT_PROJ_GIT_LASTHASH__|$(git_lasthash | __qfs)|g;"
63
-        echo "s|__MKIT_PROJ_VERSION__|$(semver | __qfs)|g;"
64
-        echo "s|__MKIT_SELF_VERSION__|$MKIT_VERSION|g;"
65
-    } >> "$script"
66
-    sed -f "$script" || die "__expand_tokens failed"
67
-    rm "$script"
88
+    done
89
+    debug_var MacroMap
90
+    while IFS= read -r line; do
91
+        __expand_line "$line"
92
+    done
68
 }
93
 }
69
 
94
 
70
 __guess_ftype() {
95
 __guess_ftype() {
87
     '
112
     '
88
 }
113
 }
89
 
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
+
90
 _mkit_data() {
167
 _mkit_data() {
91
     #
168
     #
92
-    # Build sampler showing all token values
169
+    # Build sampler showing all macro values
93
     #
170
     #
94
-    local token
171
+    local macro
95
     local section
172
     local section
96
     local sections
173
     local sections
97
     sections=()
174
     sections=()
98
-    ini lskeys tokens | grep -q . && sections=(tokens)
99
-    sections+=( $(ini lssect | grep ':tokens$') )
175
+    ini lskeys macros | grep -q . && sections=(macros)
176
+    sections+=( $(ini lssect | grep ':macros$') )
100
     {
177
     {
101
         echo "(builtin):"
178
         echo "(builtin):"
102
         echo "  x_MKIT_PROJ_NAME__ => '__MKIT_PROJ_NAME__'"
179
         echo "  x_MKIT_PROJ_NAME__ => '__MKIT_PROJ_NAME__'"
111
         echo "  x_MKIT_SELF_VERSION__ => '__MKIT_SELF_VERSION__'"
188
         echo "  x_MKIT_SELF_VERSION__ => '__MKIT_SELF_VERSION__'"
112
         for section in "${sections[@]}"; do
189
         for section in "${sections[@]}"; do
113
             echo "$section:"
190
             echo "$section:"
114
-            for token in $(ini lskeys "$section"); do
115
-                echo "  x${token:1} => '$token'"
191
+            for macro in $(ini lskeys "$section"); do
192
+                echo "  x${macro:1} => '$macro'"
116
             done
193
             done
117
         done
194
         done
118
     } \
195
     } \
119
-      | __expand_tokens "MKIT_BUILTIN" "${sections[@]}" \
196
+      | __expand_macros "MKIT_BUILTIN" "${sections[@]}" \
120
       | sed '/^  x/ s|x|_|'
197
       | sed '/^  x/ s|x|_|'
121
 }
198
 }
122
 
199
 
125
     # Add meat to all skeletons
202
     # Add meat to all skeletons
126
     #
203
     #
127
     local srcpath   # each source path
204
     local srcpath   # each source path
128
-    semver >/dev/null
129
     find . -type f -name '*.skel' \
205
     find . -type f -name '*.skel' \
130
      | while read -r srcpath; do
206
      | while read -r srcpath; do
131
            __build1 "$srcpath"
207
            __build1 "$srcpath"
153
     local debian_skel   # 'debian' folder skeleton
229
     local debian_skel   # 'debian' folder skeleton
154
     local dfsrc         # each source file from ^^
230
     local dfsrc         # each source file from ^^
155
     local dftgt         # each built packaging file
231
     local dftgt         # each built packaging file
156
-    version=$(semver)
232
+    version=$(__cached semver)
157
 
233
 
158
     # tarball - we should already have by means of 'dist'
234
     # tarball - we should already have by means of 'dist'
159
     #
235
     #
160
     mv "${MKIT_PROJ_PKGNAME}-$version.tar.gz" \
236
     mv "${MKIT_PROJ_PKGNAME}-$version.tar.gz" \
161
        "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz" \
237
        "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz" \
162
      || die "could not rename tarball"
238
      || die "could not rename tarball"
163
-    rec_built "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz"
239
+    __rec_built "${MKIT_PROJ_PKGNAME}_$version.orig.tar.gz"
164
 
240
 
165
     # read content of each mandatory file from debian_skel
241
     # read content of each mandatory file from debian_skel
166
     #
242
     #
174
             mkdir -p "$(dirname "$dftgt")"
250
             mkdir -p "$(dirname "$dftgt")"
175
             __build1 "$dfsrc" "$dftgt" debstuff
251
             __build1 "$dfsrc" "$dftgt" debstuff
176
         done
252
         done
177
-    rec_built debian
253
+    __rec_built debian
178
 }
254
 }
179
 
255
 
180
 dist() {
256
 dist() {
192
     git_lasthash=$(git_lasthash)
268
     git_lasthash=$(git_lasthash)
193
     mkdir -p "$dirname"
269
     mkdir -p "$dirname"
194
     ini values "dist:tarball" | xargs -I DIST_ITEM cp -R DIST_ITEM "$dirname"
270
     ini values "dist:tarball" | xargs -I DIST_ITEM cp -R DIST_ITEM "$dirname"
195
-    update_version "$version" "$dirname/mkit.ini"
196
     mkdir -p "$dirname/.mkit"
271
     mkdir -p "$dirname/.mkit"
272
+    echo -n "$version" > "$dirname/.mkit/semver"
197
     echo -n "$git_lasthash" > "$dirname/.mkit/git_lasthash"
273
     echo -n "$git_lasthash" > "$dirname/.mkit/git_lasthash"
198
     tar -cf "$dirname.tar" "$dirname"
274
     tar -cf "$dirname.tar" "$dirname"
199
     gzip -f "$dirname.tar"      # see above FIXME
275
     gzip -f "$dirname.tar"      # see above FIXME
200
-    rec_built "$dirname.tar.gz"
276
+    __rec_built "$dirname.tar.gz"
201
     rm -rf "$dirname"
277
     rm -rf "$dirname"
202
 }
278
 }
203
 
279
 

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

54
         latest_sha)
54
         latest_sha)
55
             git log -1 --pretty=format:%h HEAD
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
             warn "unknown git fact asked: $fact_name"
61
             warn "unknown git fact asked: $fact_name"
59
             ;;
62
             ;;
85
     #
88
     #
86
     # Show last commit hash (with .dirty suffix if needed)
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
     local last_hash     # last commit hash
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
 semver() {
106
 semver() {
107
     #
107
     #
108
-    # Build semver version string with build metadata
108
+    # Build proper SemVer version string
109
     #
109
     #
110
     # Build version string from available info using following
110
     # Build version string from available info using following
111
     # logic:
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
     #     (afer dash)
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
     #     name and commit sha1 to build metadata (after plus sign)
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
     #     add "dirty" to build metadata
120
     #     add "dirty" to build metadata
121
     #
121
     #
122
     # The version is compatible with SemVer 2.0.0.
122
     # The version is compatible with SemVer 2.0.0.
123
     #
123
     #
124
     # Examples:
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
     # Note that versions with "dirty" should be perceived as kind of
134
     # Note that versions with "dirty" should be perceived as kind of
135
     # dangerous outside developer's own machine.  Versions with sha1 are
135
     # dangerous outside developer's own machine.  Versions with sha1 are
136
     # safer but must not be released.
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
     # FIXME:  Using project:prerl for release IDs may not be compatible with
138
     # FIXME:  Using project:prerl for release IDs may not be compatible with
149
     #         release strategy implemented in release.sh
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
     local latest_tag    # latest git tag
143
     local latest_tag    # latest git tag
154
     local commit        # commit indicator (CURRENT_BRANCH.gHASH)
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
     local suffix        # version suffix
147
     local suffix        # version suffix
157
-    local_get semver && return 0
158
-    version=$(ini 1value project:version)
159
     prerl=$(ini 1value project:prerl)
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
     grep ":" <<<"$prerl" \
154
     grep ":" <<<"$prerl" \
161
      && warn "colon in project:prerl may corrupt version data: $prerl"
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
     fi
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
 }

+ 26
- 3
utils/mkit/include/ini.sh View File

30
     done
30
     done
31
 }
31
 }
32
 
32
 
33
+__ini_grepcmt() {
34
+    #
35
+    # Remove comments from INI file on stdin
36
+    #
37
+    grep -v '^[[:space:]]*#'
38
+}
39
+
33
 __ini_grepkey() {
40
 __ini_grepkey() {
34
     #
41
     #
35
     # Read key from a section
42
     # Read key from a section
36
     #
43
     #
37
     local wnt=$1    # wanted key
44
     local wnt=$1    # wanted key
38
     grep '.' \
45
     grep '.' \
39
-      | grep -v '\s*#' \
40
       | sed -e 's/ *= */=/; s/ +$//; s/^//;' \
46
       | sed -e 's/ *= */=/; s/ +$//; s/^//;' \
41
       | grep -e "^$wnt=" \
47
       | grep -e "^$wnt=" \
42
       | cut -d= -f2- \
48
       | cut -d= -f2- \
73
     local ok=false      # are we in the section?
79
     local ok=false      # are we in the section?
74
     local line          # each input line
80
     local line          # each input line
75
     grep '.' \
81
     grep '.' \
76
-      | grep -v '\s*#' \
77
       | while read -r line; do
82
       | while read -r line; do
78
             case "$line" in
83
             case "$line" in
79
                 \[$wnt\]) ok=true;  continue ;;
84
                 \[$wnt\]) ok=true;  continue ;;
112
     fi
117
     fi
113
 }
118
 }
114
 
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
+
115
 ini() {
138
 ini() {
116
     #
139
     #
117
     # do ini operation
140
     # do ini operation
128
         1value) fn=__ini_greppath; limit="tail -1" ;;
151
         1value) fn=__ini_greppath; limit="tail -1" ;;
129
         *)      die "incorrect use of \`ini()\`"
152
         *)      die "incorrect use of \`ini()\`"
130
     esac
153
     esac
131
-    <"$MKIT_INI" $fn "$arg" | $limit
154
+    __ini_body | $fn "$arg" | $limit
132
 }
155
 }
133
 
156
 
134
 update_version() {
157
 update_version() {

+ 4
- 38
utils/mkit/include/mkit.sh View File

66
     #
66
     #
67
     $MKIT_DEBUG || return 0
67
     $MKIT_DEBUG || return 0
68
     local __mkit_debug_var_name__       # variable name to debug
68
     local __mkit_debug_var_name__       # variable name to debug
69
+    local decl                          # declare string
69
     for __mkit_debug_var_name__ in "$@"; do
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
         } >&2
75
         } >&2
76
     done
76
     done
77
 }
77
 }
125
      || die "bad mkit.ini version: $their_ver does not match $MKIT_VERSION"
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
 mkit_init() {
128
 mkit_init() {
154
     #
129
     #
155
     # Do basic initialization
130
     # Do basic initialization
163
     __chkiniversion
138
     __chkiniversion
164
 }
139
 }
165
 
140
 
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"
173
-}
174
-
175
 route() {
141
 route() {
176
     #
142
     #
177
     # Call correct function based on $1
143
     # Call correct function based on $1

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

51
 #
51
 #
52
 # Package name
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
 MKIT_PROJ_PKGNAME=""
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
 # This MKit version
87
 # This MKit version
60
 #
88
 #
61
-MKIT_VERSION=0.0.28
89
+MKIT_VERSION=0.0.34

+ 11
- 20
utils/mkit/stub View File

82
                 remake_section dist
82
                 remake_section dist
83
                 remake_section ENV
83
                 remake_section ENV
84
                 remake_section roots
84
                 remake_section roots
85
-                remake_section tokens
85
+                remake_section macros
86
                 remake_section modes
86
                 remake_section modes
87
                 remake_section files
87
                 remake_section files
88
             else
88
             else
112
                     echo "doc = [ENV:PREFIX]/share/doc/$PackageName"
112
                     echo "doc = [ENV:PREFIX]/share/doc/$PackageName"
113
                 } | reformat_section
113
                 } | reformat_section
114
                 echo ""
114
                 echo ""
115
-                echo "[tokens]"
115
+                echo "[macros]"
116
                 {
116
                 {
117
                     echo "__${PackageName^^}_FOO__ = Barr.."
117
                     echo "__${PackageName^^}_FOO__ = Barr.."
118
                 } | reformat_section
118
                 } | reformat_section
141
             echo 'Summary:    __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
141
             echo 'Summary:    __MKIT_PROJ_NAME__ - __MKIT_PROJ_TAGLINE__'
142
             test -n "$VcsBrowser" && echo 'URL:        __MKIT_PROJ_VCS_BROWSER__'
142
             test -n "$VcsBrowser" && echo 'URL:        __MKIT_PROJ_VCS_BROWSER__'
143
             $MkLicense && echo "License:    $License"
143
             $MkLicense && echo "License:    $License"
144
-            echo ''
145
             echo 'Source0:    %{name}-%{version}.tar.gz'
144
             echo 'Source0:    %{name}-%{version}.tar.gz'
146
             echo 'BuildArch:  noarch'
145
             echo 'BuildArch:  noarch'
147
             echo ''
146
             echo ''
177
             echo 'Section: misc'
176
             echo 'Section: misc'
178
             echo 'Priority: extra'
177
             echo 'Priority: extra'
179
             echo 'Standards-Version: 3.9.2'
178
             echo 'Standards-Version: 3.9.2'
180
-            echo 'Build-Depends: debhelper (>= 9)'
179
+            echo 'Build-Depends:'
180
+            echo ' debhelper (>= 9),'
181
             echo ''
181
             echo ''
182
             echo 'Package: __MKIT_PROJ_PKGNAME__'
182
             echo 'Package: __MKIT_PROJ_PKGNAME__'
183
             echo 'Architecture: all'
183
             echo 'Architecture: all'
245
             echo "everything, so few things still need to be done manually."
245
             echo "everything, so few things still need to be done manually."
246
             echo "This document will guide you throught the rest of the"
246
             echo "This document will guide you throught the rest of the"
247
             echo "process."
247
             echo "process."
248
-
249
             echo ""
248
             echo ""
250
             echo ""
249
             echo ""
251
             echo "Structure"
250
             echo "Structure"
259
             echo "    machine should be uder 'src'."
258
             echo "    machine should be uder 'src'."
260
             echo ""
259
             echo ""
261
             echo "    Note that during build time, files named ending with"
260
             echo "    Note that during build time, files named ending with"
262
-            echo "    '.skel' are subject to token expansion, see mkit.ini"
261
+            echo "    '.skel' are subject to macro expansion, see mkit.ini"
263
             echo "    section below for details."
262
             echo "    section below for details."
264
             echo ""
263
             echo ""
265
             echo " *  *notes* directory - here you shall store notes"
264
             echo " *  *notes* directory - here you shall store notes"
280
             echo " *  *packaging* directory contains templates that enable"
279
             echo " *  *packaging* directory contains templates that enable"
281
             echo "    MKit create raw stuffs used to create DEB or RPM"
280
             echo "    MKit create raw stuffs used to create DEB or RPM"
282
             echo "    packages.  Similar to '.skel' files in 'src', all files"
281
             echo "    packages.  Similar to '.skel' files in 'src', all files"
283
-            echo "    here are automatically considered for token expansion,"
282
+            echo "    here are automatically considered for macro expansion,"
284
             echo "    no matter how they are named (see mkit.ini section"
283
             echo "    no matter how they are named (see mkit.ini section"
285
             echo "    below)."
284
             echo "    below)."
286
             echo ""
285
             echo ""
293
             echo "    idea!), be prepared that you will need to follow their"
292
             echo "    idea!), be prepared that you will need to follow their"
294
             echo "    guidelines.  This will most probably mean huge changes"
293
             echo "    guidelines.  This will most probably mean huge changes"
295
             echo "    to these packages or even changes to your workflow."
294
             echo "    to these packages or even changes to your workflow."
296
-
297
             echo ""
295
             echo ""
298
             echo ""
296
             echo ""
299
             echo "Placeholders"
297
             echo "Placeholders"
357
             echo "    Typical example of a role is e.g. 'bin' for commands"
355
             echo "    Typical example of a role is e.g. 'bin' for commands"
358
             echo "    (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
356
             echo "    (normally under '/usr/bin' or '/usr/local/bin'), 'doc'"
359
             echo "    for documents or 'lib' for libraries."
357
             echo "    for documents or 'lib' for libraries."
360
-
361
             echo ""
358
             echo ""
362
             echo " 2. Next, in \`[roots]\` section, you have to set target"
359
             echo " 2. Next, in \`[roots]\` section, you have to set target"
363
             echo "    root directory for each role.  However, in order to"
360
             echo "    root directory for each role.  However, in order to"
366
             echo "    environment variable.  For this reason, most paths"
363
             echo "    environment variable.  For this reason, most paths"
367
             echo "    need to start with \`[ENV:PREFIX]\`."
364
             echo "    need to start with \`[ENV:PREFIX]\`."
368
             echo ""
365
             echo ""
369
-
370
             echo " 3. \`[files]\` section is where you assign actual files"
366
             echo " 3. \`[files]\` section is where you assign actual files"
371
             echo "    from your repository to their final paths.  The format"
367
             echo "    from your repository to their final paths.  The format"
372
             echo "    is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
368
             echo "    is \`ROLE = REPOPATH [RENAMED]\`, where ROLE is file's"
381
             echo "    individually, if in your repo you have a directory with"
377
             echo "    individually, if in your repo you have a directory with"
382
             echo "    100 files of the same role, you can add just path to the"
378
             echo "    100 files of the same role, you can add just path to the"
383
             echo "    directory itself."
379
             echo "    directory itself."
384
-
385
             echo ""
380
             echo ""
386
             echo " 4. If some roles require special permissions on your files,"
381
             echo " 4. If some roles require special permissions on your files,"
387
             echo "    \`[modes]\` section is your friend.  Permissions here"
382
             echo "    \`[modes]\` section is your friend.  Permissions here"
388
             echo "    should be in UNIX octal format."
383
             echo "    should be in UNIX octal format."
389
-
390
             echo ""
384
             echo ""
391
-            echo " 5. Next, \`[tokens]\` section allows you to define own"
385
+            echo " 5. Next, \`[macros]\` section allows you to define own"
392
             echo "    placeholders that will be replaced when your scripts are"
386
             echo "    placeholders that will be replaced when your scripts are"
393
             echo "    built.  Each file in 'src' directory that is named with"
387
             echo "    built.  Each file in 'src' directory that is named with"
394
             echo "    '.skel' suffix, and each file from 'packaging' directory"
388
             echo "    '.skel' suffix, and each file from 'packaging' directory"
395
-            echo "    (no matter its name), can contain one or more of tokens"
396
-            echo "    defined here, plus range of tokens automatically defined"
397
-            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"
398
             echo "    their actual values."
392
             echo "    their actual values."
399
-
400
             echo ""
393
             echo ""
401
             echo " 6. Less interesting, but important section is \`[dist]\`,"
394
             echo " 6. Less interesting, but important section is \`[dist]\`,"
402
             echo "    which lists files in your codebase that will be added"
395
             echo "    which lists files in your codebase that will be added"
404
             echo "    above).  Listing directory here will include all its"
397
             echo "    above).  Listing directory here will include all its"
405
             echo "    contents, and normally it's OK to be very inclusive, so"
398
             echo "    contents, and normally it's OK to be very inclusive, so"
406
             echo "    most of the time this section should be OK."
399
             echo "    most of the time this section should be OK."
407
-
408
             echo ""
400
             echo ""
409
             echo " 7. Even less interesting is section \`[ENV]\`.  It is"
401
             echo " 7. Even less interesting is section \`[ENV]\`.  It is"
410
             echo "    special in that it provides *default* value for an"
402
             echo "    special in that it provides *default* value for an"
411
             echo "    environment variable.  You almost never need to touch"
403
             echo "    environment variable.  You almost never need to touch"
412
             echo "    this."
404
             echo "    this."
413
             echo ""
405
             echo ""
414
-
415
             echo " 8. Finally, the most interesting section!  \`[project]\`,"
406
             echo " 8. Finally, the most interesting section!  \`[project]\`,"
416
             echo "    provides most general information for your project such"
407
             echo "    provides most general information for your project such"
417
             echo "    as name and version."
408
             echo "    as name and version."
494
         echo "    -R            skip creating README.md"
485
         echo "    -R            skip creating README.md"
495
         echo "    -M            skip creating Makefile"
486
         echo "    -M            skip creating Makefile"
496
         echo "    -P            skip creating packaging templates"
487
         echo "    -P            skip creating packaging templates"
497
-        echo "    -L            list know licenses and exit"
488
+        echo "    -L            list known licenses and exit"
498
         echo ""
489
         echo ""
499
         echo "PKGNAME should be packaging-friendly name, ie. consist"
490
         echo "PKGNAME should be packaging-friendly name, ie. consist"
500
         echo "only of small letters, numbers, underscore and dash."
491
         echo "only of small letters, numbers, underscore and dash."