Bladeren bron

Update for Shellfu v0.9.x

The new Shellfu brings some large changes.  Among what touches us
directly:

 *  Most global variables were renamed (removing SHELLFU_* prefix).

 *  inigrep API has been revamped and the file merging/guessing
    feature has been dropped; it now belongs to us.
Alois Mahdal 8 jaren geleden
bovenliggende
commit
bcad50d4f2
5 gewijzigde bestanden met toevoegingen van 254 en 32 verwijderingen
  1. 12
    13
      src/bin/app.skel
  2. 2
    2
      src/libexec/satcmd-echo
  3. 233
    11
      src/shellfu/saturnin.sh
  4. 4
    3
      tests/cli/oracle/usage.stderr
  5. 3
    3
      tests/saturnin-get/TF_RUN

+ 12
- 13
src/bin/app.skel Bestand weergeven

@@ -3,21 +3,12 @@
3 3
 . "$(shellfu-get path)" || exit 3
4 4
 
5 5
 shellfu import exit
6
-shellfu import inigrep
7 6
 shellfu import pretty
8 7
 
9 8
 #
10 9
 # =====BEGIN BUILT PART=====
11 10
 #
12 11
 
13
-SHELLFU_INIGREP_PATH="$(
14
-    inigrep__mkpath \
15
-        __SATURNIN_CONFIG_USER__/ini.d \
16
-        __SATURNIN_CONFIG_USER__ \
17
-        __SATURNIN_CONFIG_LOCAL__ \
18
-        __SATURNIN_SHARE__/ini.d
19
-)"
20
-
21 12
 SATURNIN_APP_CODENAME="__MKIT_PROJ_CODENAME__"
22 13
 SATURNIN_APP_TAGLINE="__MKIT_PROJ_TAGLINE__"
23 14
 SATURNIN_APP_VERSION="__MKIT_PROJ_VERSION__"
@@ -26,15 +17,23 @@ SATURNIN_CACHE_HOME="__SATURNIN_CACHE_HOME__"
26 17
 SATURNIN_LIBEXEC="__SATURNIN_LIBEXEC__"
27 18
 SATURNIN_LIBEXEC_PREFIX="__MKIT_PROJ_PKGNAME__-"
28 19
 SHELLFU_PATH="__SATURNIN_SHELLFU_DIR__"
29
-SHELLFU_PRETTY_USAGE="subcommand"
20
+PRETTY_USAGE="subcommand"
21
+
22
+shellfu import saturnin
23
+
24
+SATURNIN_CONF_PATH="$(
25
+    saturnin__conf_mkpath \
26
+        __SATURNIN_CONFIG_USER__/ini.d \
27
+        __SATURNIN_CONFIG_USER__ \
28
+        __SATURNIN_CONFIG_LOCAL__ \
29
+        __SATURNIN_SHARE__/ini.d
30
+)"
30 31
 
31 32
 #
32 33
 # =====END BUILT PART=====
33 34
 #
34 35
 
35
-shellfu import saturnin
36
-
37
-export SHELLFU_INIGREP_PATH SHELLFU_PATH SHELLFU_PRETTY_USAGE \
36
+export SATURNIN_CONF_PATH SHELLFU_PATH PRETTY_USAGE \
38 37
        SATURNIN_CACHE_HOME
39 38
 
40 39
 saturnin__main "$@"

+ 2
- 2
src/libexec/satcmd-echo Bestand weergeven

@@ -2,9 +2,9 @@
2 2
 
3 3
 . "$(shellfu-get path)" || exit 3
4 4
 
5
-shellfu import inigrep
5
+shellfu import saturnin
6 6
 
7
-SATCMD_ECHO__PREFIX="${SATCMD_ECHO__PREFIX:-$(inigrep -p "echo.prefix")}"
7
+SATCMD_ECHO__PREFIX="${SATCMD_ECHO__PREFIX:-$(saturnin__conf "echo.prefix")}"
8 8
 
9 9
 echo -n "$SATCMD_ECHO__PREFIX"
10 10
 echo "$@"

+ 233
- 11
src/shellfu/saturnin.sh Bestand weergeven

@@ -4,6 +4,117 @@ shellfu import exit
4 4
 shellfu import inigrep
5 5
 shellfu import pretty
6 6
 
7
+#
8
+# Path where saturnin__conf should look for files
9
+#
10
+# If filename does not contain slash, it is looked up in each
11
+# (or all, based on strategy--see saturnin__conf() doc) path in this
12
+# list.  The list is colon-separated and non-dirs as well as
13
+# empty strings are silently ignored.
14
+#
15
+SATURNIN_CONF_PATH="${SATURNIN_CONF_PATH:-}"
16
+
17
+#
18
+# Expected config filename extension (for guessing from path head)
19
+#
20
+# If no filename to read is given, saturnin__conf() will guess
21
+# filename as the path head plus this suffix (e.g. `foo.ini` for
22
+# `saturnin__conf foo.bar.baz`)
23
+#
24
+SATURNIN_CONF_SUFFIX="${SATURNIN_CONF_SUFFIX:-.ini}"
25
+
26
+saturnin__conf() {
27
+    #
28
+    # inigrep smart loader
29
+    #
30
+    # Usage:
31
+    #   saturnin__conf [-j] [inigrep-query] [-- [file]..]
32
+    #
33
+    #
34
+    # File arguments
35
+    # ==============
36
+    #
37
+    # If omitted, *file* argument is inferred by taking part of
38
+    # kpath name before first dot and appending value of
39
+    # `$SATURNIN_CONF_SUFFIX`, (".ini" by default).
40
+    #
41
+    # Each *file* argument is then processed as follows:
42
+    #
43
+    #  *  `-` (single dash) is interpreted as reading from
44
+    #     STDIN.
45
+    #
46
+    #  *  If argument contains slash, it is expanded as a regular
47
+    #     path (relative or absolute).
48
+    #
49
+    #  *  Otherwise, it is taken as filename and searched for
50
+    #     in directories given in `$SATURNIN_CONF_PATH`.  (This can
51
+    #     yield more than one path, which is equivalent as if
52
+    #     all paths were provided.)
53
+    #
54
+    #     Not all files expanded based on `$SATURNIN_CONF_PATH`
55
+    #     are read by default; reading is governed by "merge
56
+    #     strategy": the default strategy "first" reads only
57
+    #     the first existing file.
58
+    #
59
+    #     "join" strategy on the other hand, means that any
60
+    #     files are simply concatenated and prefixed with
61
+    #     comment (visible only in raw mode) containing path
62
+    #     to the file.
63
+    #
64
+    #     This means that if a section is queried that is
65
+    #     present in both files, it is effectively concatenated
66
+    #     as well.
67
+    #
68
+    # Following calls are equivalent
69
+    #
70
+    #     saturnin__conf foo.bar.baz
71
+    #     saturnin__conf foo.bar.baz foo.ini
72
+    #
73
+    # and both result in reading of key *baz* from section *foo.bar*
74
+    # in file *foo.ini*, which is selected from *SATURNIN_CONF_PATH*.
75
+    # Should there be more foo.ini's, the first is selected.
76
+    # Using `-j` switch
77
+    #
78
+    #     saturnin__conf -j foo.bar.baz
79
+    #
80
+    # would cause all foo.ini's on *SATURNIN_CONF_PATH* be
81
+    # concatenated instead.
82
+    #
83
+    local ig_mode               # retrieval mode
84
+    local ig_query              # keypath or section name (when listing keys)
85
+    local ig_limit              # line limit
86
+    local files=()              # file specification
87
+    local Strategy=first        # merge strategy
88
+    while true; do case $1:$2 in
89
+        "":*)   break ;;
90
+        -j:*)   Strategy=join;           shift 1        ;;
91
+        -1:*)   ig_limit=$1;             shift 1        ;;
92
+        -e:*.*) ig_mode=$1; ig_query=$2; shift 2; break ;;
93
+        -r:*.*) ig_mode=$1; ig_query=$2; shift 2; break ;;
94
+        -K:*)   ig_mode=$1; ig_query=$2; shift 2; break ;;
95
+        -S:*)   ig_mode=$1; ig_query=""; shift 1; break ;;
96
+        -P:*)   ig_mode=$1; ig_query=""; shift 1; break ;;
97
+        .*:*)   warn "bad syntax: $*"; return 2 ;;
98
+        *.*:*)  ig_mode=-e; ig_query=$1; shift 1; break ;;
99
+        *)      warn "bad syntax: $*"; return 2 ;;
100
+    esac done
101
+    test -n "$ig_mode" || { warn "could not determine inigrep mode"; return 2; }
102
+    debug -v ig_limit ig_query ig_mode Strategy
103
+    if test -n "$*";
104
+    then
105
+        files=("$@")
106
+    elif test -n "$ig_query";
107
+    then
108
+        files=("${ig_query%%.*}$SATURNIN_CONF_SUFFIX")
109
+    else
110
+        warn "dunno what to load"
111
+        return 2
112
+    fi
113
+    debug -v files
114
+    #shellcheck disable=SC2086
115
+    _saturnin__conf__load "${files[@]}" | inigrep $ig_limit $ig_mode $ig_query
116
+}
117
+
7 118
 saturnin__get() {
8 119
     #
9 120
     # Show Saturnin Internal info by key $1 and exit
@@ -18,16 +129,16 @@ saturnin__get() {
18 129
     local key=${1#--saturnin-get-}
19 130
     case "$key" in
20 131
         shellfu-path)   echo "$SHELLFU_PATH"                ;;
21
-        inigrep-path)   echo "$SHELLFU_INIGREP_PATH"        ;;
132
+        saturnin-conf-path) echo "$SATURNIN_CONF_PATH"      ;;
22 133
         app-git-hash)   echo "$SATURNIN_APP_GIT_HASH"       ;;
23 134
         app-version)    echo "$SATURNIN_APP_VERSION"        ;;
24 135
         cache-home)     echo "$SATURNIN_CACHE_HOME"         ;;
25 136
         libexec)        echo "$SATURNIN_LIBEXEC"            ;;
26 137
         libexec-prefix) echo "$SATURNIN_LIBEXEC_PREFIX"     ;;
27 138
         *)              warn "unknown devel key: $key"
28
-                        exit "$SHELLFU_EXIT_USAGE" ;;
139
+                        exit "$EXIT_USAGE" ;;
29 140
     esac
30
-    exit "$SHELLFU_EXIT_OK"
141
+    exit "$EXIT_OK"
31 142
 }
32 143
 
33 144
 saturnin__help() {
@@ -43,7 +154,7 @@ saturnin__help() {
43 154
         saturnin__lssc \
44 155
           | sed -e 's/^/    /'
45 156
     } | mkhelp -E -f -
46
-    return "$SHELLFU_EXIT_OK"
157
+    return "$EXIT_OK"
47 158
 }
48 159
 
49 160
 saturnin__lssc() {
@@ -61,8 +172,8 @@ saturnin__lssc() {
61 172
 saturnin__main() {
62 173
     local subcommand
63 174
     while true; do case $1 in
64
-        -d|--debug)     export SHELLFU_DEBUG=true; shift   ;;
65
-        -v|--verbose)   export SHELLFU_VERBOSE=true; shift ;;
175
+        -d|--debug)     export PRETTY_DEBUG=true; shift   ;;
176
+        -v|--verbose)   export PRETTY_VERBOSE=true; shift ;;
66 177
         --version)      saturnin__version; exit            ;;
67 178
         --version-semver) saturnin__get app-version ;;
68 179
         --saturnin-get-*) saturnin__get "$1" ;;
@@ -73,9 +184,9 @@ saturnin__main() {
73 184
         *)              break;                          ;;
74 185
     esac done
75 186
     subcommand="$1"; shift
76
-    debug -v SHELLFU_PATH SATURNIN_LIBEXEC SHELLFU_INIGREP_PATH
187
+    debug -v SHELLFU_PATH SATURNIN_LIBEXEC SATURNIN_CONF_PATH
77 188
     case "$subcommand" in
78
-        conf)               inigrep "$@"    ;;
189
+        conf)               saturnin__conf "$@" ;;
79 190
         help)               saturnin__help ;;
80 191
         _ls_subcommands)    saturnin__lssc ;;
81 192
         _lsfun)             shellfu-get lsfun ;;
@@ -84,6 +195,35 @@ saturnin__main() {
84 195
     esac
85 196
 }
86 197
 
198
+saturnin__conf_mkpath() {
199
+    #
200
+    # Assemble SATURNIN_CONF_PATH from locations $@
201
+    #
202
+    # For each location, print colon-delimited list of
203
+    # directories.  If location ends with "/ini.d", list of
204
+    # subfolders, sorted by C locale is printed--this allows
205
+    # for modular configuration.  Otherwise the location
206
+    # is printed.  Non-existent or non-directory locations
207
+    # are silently ignored.
208
+    #
209
+    local location      # one location argument
210
+    local path          # one path listed
211
+    for location in "$@";
212
+    do
213
+        test -d "$location" || continue
214
+        case "$location" in
215
+            */ini.d)    # modular location--sort subfolders
216
+                find -L "$location" -mindepth 1 -maxdepth 1 -type d \
217
+                  | LC_ALL=C sort
218
+                ;;
219
+            *)
220
+                echo "$location"
221
+                ;;
222
+        esac
223
+    done \
224
+      | _saturnin__nl2colon
225
+}
226
+
87 227
 saturnin__runhook() {
88 228
     #
89 229
     # Run custom hook
@@ -94,7 +234,7 @@ saturnin__runhook() {
94 234
         warn "unknown subcommand, ignoring hook: $hname"
95 235
         return 0
96 236
     }
97
-    hook_code="$(inigrep -j -p "hook.$SATURNIN_SUBCOMMAND.$hname")"
237
+    hook_code="$(saturnin__conf -j "hook.$SATURNIN_SUBCOMMAND.$hname")"
98 238
     debug -v SATURNIN_SUBCOMMAND hook_code hname
99 239
     bash -n <<<"$hook_code" || {
100 240
         warn "syntax errors, ignoring hook: $hname"
@@ -116,7 +256,7 @@ saturnin__runsc() {
116 256
     test -x "$binpath" || {
117 257
         warn "invalid sub-command: $subcommand"
118 258
         saturnin__help
119
-        return "$SHELLFU_EXIT_USAGE"
259
+        return "$EXIT_USAGE"
120 260
     }
121 261
     SATURNIN_SUBCOMMAND="$subcommand" "$binpath" "$@"
122 262
 }
@@ -135,7 +275,7 @@ saturnin__version() {
135 275
     local maybe_codename=""
136 276
     test -n "$SATURNIN_APP_CODENAME" && maybe_codename=" - $SATURNIN_APP_CODENAME"
137 277
     echo "$(basename "$0") ($tagline) $SATURNIN_APP_VERSION$maybe_codename"
138
-    return "$SHELLFU_EXIT_OK"
278
+    return "$EXIT_OK"
139 279
 }
140 280
 
141 281
 saturnin__wraphook() {
@@ -153,3 +293,85 @@ saturnin__wraphook() {
153 293
     saturnin__runhook post
154 294
     return $es
155 295
 }
296
+
297
+
298
+#          #                           that what you see below this line #
299
+# INTERNAL # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
300
+#          #                        use in your code to anger the divine #
301
+
302
+_saturnin__conf__merge() {
303
+    #
304
+    # Take paths and applying merge strategy, load file(s)
305
+    #
306
+    local path
307
+    while read -r path;
308
+    do
309
+        test -f "$path" || continue
310
+        case $Strategy in
311
+            first)
312
+                debug "winner: $path"
313
+                cat "$path"
314
+                cat >/dev/null  # throw away rest of paths
315
+                ;;
316
+            join)
317
+                echo "# file: ${path/$HOME/~}"
318
+                cat "$path" 2>/dev/null
319
+                ;;
320
+        esac
321
+    done
322
+}
323
+
324
+_saturnin__conf__load() {
325
+    #
326
+    # Print contents of files specified in $@
327
+    #
328
+    # Each argument means possible file candidate.  If candidate
329
+    # contains slash, it's treated as file path and is printed
330
+    # directly.  If it's single dash, standard input is copied.
331
+    #
332
+    # In all other cases, filename is searched in all elements
333
+    # of SATURNIN_CONF_PATH; output then depends on chosen $Strategy:
334
+    # with 'first' strategy, first existing file is printed, with
335
+    # 'join' strategy. all existing files are printed.
336
+    #
337
+    local arg trydir trypath
338
+    for arg in "$@";
339
+    do
340
+        case $arg in
341
+            -|*/*)      # stdin, or path (with slash)
342
+                cat "$arg"
343
+            ;;
344
+        *)              # name given, find all its incarnations
345
+            debug -v SATURNIN_CONF_PATH
346
+            echos "$SATURNIN_CONF_PATH" \
347
+              | tr ':' '\n' \
348
+              | while read -r trydir;
349
+                do
350
+                    test -n "$trydir" || continue
351
+                    trypath="$trydir/$arg"
352
+                    echos "$trypath"
353
+                done \
354
+              |  _saturnin__conf__merge
355
+            ;;
356
+        esac
357
+    done
358
+    true
359
+}
360
+
361
+_saturnin__nl2colon() {
362
+    #
363
+    # Convert newline-based list of paths to colon:based:list
364
+    #
365
+    # Empty paths must not be included in the resulting list,
366
+    # so we need to drop them and also get the colons right.
367
+    #
368
+    local idx=0     # current item index (zero-based)
369
+    local path
370
+    while read -r path;
371
+    do
372
+        test -z "$path" && continue
373
+        test $idx -gt 0 && echo -n ':'
374
+        echo -n "$path"
375
+        ((idx++))
376
+    done
377
+}

+ 4
- 3
tests/cli/oracle/usage.stderr Bestand weergeven

@@ -1,3 +1,4 @@
1
-usage: satcmd [-d|-v] command [args...]
2
-usage: satcmd help
3
-usage: satcmd --version
1
+usage:
2
+  satcmd [-d|-v] command [args...]
3
+  satcmd help
4
+  satcmd --version

+ 3
- 3
tests/saturnin-get/TF_RUN Bestand weergeven

@@ -10,7 +10,7 @@ tf_enum_subtests() {
10 10
     echo unknown_none
11 11
     echo unknown_same
12 12
     echo shellfu_path
13
-    echo inigrep_path
13
+    echo saturnin_conf_path
14 14
     echo app_version
15 15
     echo cache_home
16 16
     echo libexec
@@ -25,7 +25,7 @@ ckfuzzy() {
25 25
     cat > "$out"
26 26
     case "$name" in
27 27
         shellfu_path)   grep -q '^/usr/'                  ;;
28
-        inigrep_path)   grep -q '^/usr/'                  ;;
28
+        saturnin_conf_path)  tr : '\n' | grep -q '^/usr/' ;;
29 29
         app_version)    grep -q '[0-9]'                   ;;
30 30
         cache_home)     grep -qx '/home/.*/.cache/satcmd' ;;
31 31
         libexec)        grep -q '^/usr/'                  ;;
@@ -49,7 +49,7 @@ tf_do_subtest() {
49 49
         unknown_none)   tf_testflt -n "$name" -E "$o_err" -S 2 satcmd --saturnin-get-                ;;
50 50
         unknown_same)   tf_testflt -n "$name" -E "$o_err" -S 2 satcmd --saturnin-get---saturnin-get  ;;
51 51
         shellfu_path)   satcmd --saturnin-get-shellfu-path    | ckfuzzy ;;
52
-        inigrep_path)   satcmd --saturnin-get-inigrep-path    | ckfuzzy ;;
52
+        saturnin_conf_path)   satcmd --saturnin-get-saturnin-conf-path | ckfuzzy ;;
53 53
         app_version)    satcmd --saturnin-get-app-version     | ckfuzzy ;;
54 54
         cache_home)     satcmd --saturnin-get-cache-home      | ckfuzzy ;;
55 55
         libexec)        satcmd --saturnin-get-libexec         | ckfuzzy ;;