Browse Source

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 years ago
parent
commit
bcad50d4f2
5 changed files with 254 additions and 32 deletions
  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 View File

3
 . "$(shellfu-get path)" || exit 3
3
 . "$(shellfu-get path)" || exit 3
4
 
4
 
5
 shellfu import exit
5
 shellfu import exit
6
-shellfu import inigrep
7
 shellfu import pretty
6
 shellfu import pretty
8
 
7
 
9
 #
8
 #
10
 # =====BEGIN BUILT PART=====
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
 SATURNIN_APP_CODENAME="__MKIT_PROJ_CODENAME__"
12
 SATURNIN_APP_CODENAME="__MKIT_PROJ_CODENAME__"
22
 SATURNIN_APP_TAGLINE="__MKIT_PROJ_TAGLINE__"
13
 SATURNIN_APP_TAGLINE="__MKIT_PROJ_TAGLINE__"
23
 SATURNIN_APP_VERSION="__MKIT_PROJ_VERSION__"
14
 SATURNIN_APP_VERSION="__MKIT_PROJ_VERSION__"
26
 SATURNIN_LIBEXEC="__SATURNIN_LIBEXEC__"
17
 SATURNIN_LIBEXEC="__SATURNIN_LIBEXEC__"
27
 SATURNIN_LIBEXEC_PREFIX="__MKIT_PROJ_PKGNAME__-"
18
 SATURNIN_LIBEXEC_PREFIX="__MKIT_PROJ_PKGNAME__-"
28
 SHELLFU_PATH="__SATURNIN_SHELLFU_DIR__"
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
 # =====END BUILT PART=====
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
        SATURNIN_CACHE_HOME
37
        SATURNIN_CACHE_HOME
39
 
38
 
40
 saturnin__main "$@"
39
 saturnin__main "$@"

+ 2
- 2
src/libexec/satcmd-echo View File

2
 
2
 
3
 . "$(shellfu-get path)" || exit 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
 echo -n "$SATCMD_ECHO__PREFIX"
9
 echo -n "$SATCMD_ECHO__PREFIX"
10
 echo "$@"
10
 echo "$@"

+ 233
- 11
src/shellfu/saturnin.sh View File

4
 shellfu import inigrep
4
 shellfu import inigrep
5
 shellfu import pretty
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
 saturnin__get() {
118
 saturnin__get() {
8
     #
119
     #
9
     # Show Saturnin Internal info by key $1 and exit
120
     # Show Saturnin Internal info by key $1 and exit
18
     local key=${1#--saturnin-get-}
129
     local key=${1#--saturnin-get-}
19
     case "$key" in
130
     case "$key" in
20
         shellfu-path)   echo "$SHELLFU_PATH"                ;;
131
         shellfu-path)   echo "$SHELLFU_PATH"                ;;
21
-        inigrep-path)   echo "$SHELLFU_INIGREP_PATH"        ;;
132
+        saturnin-conf-path) echo "$SATURNIN_CONF_PATH"      ;;
22
         app-git-hash)   echo "$SATURNIN_APP_GIT_HASH"       ;;
133
         app-git-hash)   echo "$SATURNIN_APP_GIT_HASH"       ;;
23
         app-version)    echo "$SATURNIN_APP_VERSION"        ;;
134
         app-version)    echo "$SATURNIN_APP_VERSION"        ;;
24
         cache-home)     echo "$SATURNIN_CACHE_HOME"         ;;
135
         cache-home)     echo "$SATURNIN_CACHE_HOME"         ;;
25
         libexec)        echo "$SATURNIN_LIBEXEC"            ;;
136
         libexec)        echo "$SATURNIN_LIBEXEC"            ;;
26
         libexec-prefix) echo "$SATURNIN_LIBEXEC_PREFIX"     ;;
137
         libexec-prefix) echo "$SATURNIN_LIBEXEC_PREFIX"     ;;
27
         *)              warn "unknown devel key: $key"
138
         *)              warn "unknown devel key: $key"
28
-                        exit "$SHELLFU_EXIT_USAGE" ;;
139
+                        exit "$EXIT_USAGE" ;;
29
     esac
140
     esac
30
-    exit "$SHELLFU_EXIT_OK"
141
+    exit "$EXIT_OK"
31
 }
142
 }
32
 
143
 
33
 saturnin__help() {
144
 saturnin__help() {
43
         saturnin__lssc \
154
         saturnin__lssc \
44
           | sed -e 's/^/    /'
155
           | sed -e 's/^/    /'
45
     } | mkhelp -E -f -
156
     } | mkhelp -E -f -
46
-    return "$SHELLFU_EXIT_OK"
157
+    return "$EXIT_OK"
47
 }
158
 }
48
 
159
 
49
 saturnin__lssc() {
160
 saturnin__lssc() {
61
 saturnin__main() {
172
 saturnin__main() {
62
     local subcommand
173
     local subcommand
63
     while true; do case $1 in
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
         --version)      saturnin__version; exit            ;;
177
         --version)      saturnin__version; exit            ;;
67
         --version-semver) saturnin__get app-version ;;
178
         --version-semver) saturnin__get app-version ;;
68
         --saturnin-get-*) saturnin__get "$1" ;;
179
         --saturnin-get-*) saturnin__get "$1" ;;
73
         *)              break;                          ;;
184
         *)              break;                          ;;
74
     esac done
185
     esac done
75
     subcommand="$1"; shift
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
     case "$subcommand" in
188
     case "$subcommand" in
78
-        conf)               inigrep "$@"    ;;
189
+        conf)               saturnin__conf "$@" ;;
79
         help)               saturnin__help ;;
190
         help)               saturnin__help ;;
80
         _ls_subcommands)    saturnin__lssc ;;
191
         _ls_subcommands)    saturnin__lssc ;;
81
         _lsfun)             shellfu-get lsfun ;;
192
         _lsfun)             shellfu-get lsfun ;;
84
     esac
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
 saturnin__runhook() {
227
 saturnin__runhook() {
88
     #
228
     #
89
     # Run custom hook
229
     # Run custom hook
94
         warn "unknown subcommand, ignoring hook: $hname"
234
         warn "unknown subcommand, ignoring hook: $hname"
95
         return 0
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
     debug -v SATURNIN_SUBCOMMAND hook_code hname
238
     debug -v SATURNIN_SUBCOMMAND hook_code hname
99
     bash -n <<<"$hook_code" || {
239
     bash -n <<<"$hook_code" || {
100
         warn "syntax errors, ignoring hook: $hname"
240
         warn "syntax errors, ignoring hook: $hname"
116
     test -x "$binpath" || {
256
     test -x "$binpath" || {
117
         warn "invalid sub-command: $subcommand"
257
         warn "invalid sub-command: $subcommand"
118
         saturnin__help
258
         saturnin__help
119
-        return "$SHELLFU_EXIT_USAGE"
259
+        return "$EXIT_USAGE"
120
     }
260
     }
121
     SATURNIN_SUBCOMMAND="$subcommand" "$binpath" "$@"
261
     SATURNIN_SUBCOMMAND="$subcommand" "$binpath" "$@"
122
 }
262
 }
135
     local maybe_codename=""
275
     local maybe_codename=""
136
     test -n "$SATURNIN_APP_CODENAME" && maybe_codename=" - $SATURNIN_APP_CODENAME"
276
     test -n "$SATURNIN_APP_CODENAME" && maybe_codename=" - $SATURNIN_APP_CODENAME"
137
     echo "$(basename "$0") ($tagline) $SATURNIN_APP_VERSION$maybe_codename"
277
     echo "$(basename "$0") ($tagline) $SATURNIN_APP_VERSION$maybe_codename"
138
-    return "$SHELLFU_EXIT_OK"
278
+    return "$EXIT_OK"
139
 }
279
 }
140
 
280
 
141
 saturnin__wraphook() {
281
 saturnin__wraphook() {
153
     saturnin__runhook post
293
     saturnin__runhook post
154
     return $es
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 View File

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 View File

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