bashly 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +104 -40
- data/lib/bashly/extensions/string.rb +0 -1
- data/lib/bashly/models/base.rb +3 -0
- data/lib/bashly/models/command.rb +25 -0
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/command/command_fallback.erb +45 -0
- data/lib/bashly/views/command/command_filter.erb +1 -19
- data/lib/bashly/views/command/footer.erb +2 -0
- data/lib/bashly/views/command/inspect_args.erb +9 -0
- data/lib/bashly/views/command/parse_requirements_case.erb +8 -0
- data/lib/bashly/views/command/parse_requirements_while.erb +6 -0
- data/lib/bashly/views/command/run.erb +1 -0
- data/lib/bashly/views/command/usage.erb +2 -1
- data/lib/bashly/views/command/usage_args.erb +8 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca34648c628c4e7fe167d5f5b0d253792e9b4d3c494b253ed68d0127e4935572
|
4
|
+
data.tar.gz: 5247da7780a8424dd0a808ace6d182ed4284597e094122d94a8716bfca8f343b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2145d1f4125d762c3d583f560c4caa9f4b98cfc2500e7e7b9ac977f4284a190a150a26da6e935c4e59c689f5efcd627924a10091cff0d4d91f00c3f60d26b943
|
7
|
+
data.tar.gz: 9df4695f43e4c57371f876de1dee3eab587bb227b7b0ee51d52d1772faf119cbd59cb117f5a1e3cbb06ef49b5796cd02b6fecba685b733aa35c51442fe9baf19
|
data/README.md
CHANGED
@@ -15,6 +15,7 @@ Create beautiful bash scripts from simple YAML configuration
|
|
15
15
|
|
16
16
|
</div>
|
17
17
|
|
18
|
+
|
18
19
|
## Table of Contents
|
19
20
|
|
20
21
|
- [Table of Contents](#table-of-contents)
|
@@ -22,20 +23,20 @@ Create beautiful bash scripts from simple YAML configuration
|
|
22
23
|
- [Prerequisites](#prerequisites)
|
23
24
|
- [What is Bashly](#what-is-bashly)
|
24
25
|
- [Usage](#usage)
|
25
|
-
- [Using the input
|
26
|
+
- [Using the input arguments in your code](#using-the-input-arguments-in-your-code)
|
26
27
|
- [Examples](#examples)
|
27
|
-
- [Sample configuraiton for a script without commands](#sample-configuraiton-for-a-script-without-commands)
|
28
|
-
- [Sample configuraiton for a script with commands](#sample-configuraiton-for-a-script-with-commands)
|
29
28
|
- [Configuration Reference](#configuration-reference)
|
30
29
|
- [Command options](#command-options)
|
31
30
|
- [Argument options](#argument-options)
|
32
31
|
- [Flag options](#flag-options)
|
33
32
|
- [Environment Variable options](#environment-variable-options)
|
33
|
+
- [Extensible Scripts](#extensible-scripts)
|
34
34
|
- [Real World Examples](#real-world-examples)
|
35
35
|
- [Contributing / Support](#contributing--support)
|
36
36
|
|
37
37
|
---
|
38
38
|
|
39
|
+
|
39
40
|
## Installation
|
40
41
|
|
41
42
|
```shell
|
@@ -83,8 +84,17 @@ Bahsly is responsible for:
|
|
83
84
|
- **YAML parsing**.
|
84
85
|
- and more.
|
85
86
|
|
87
|
+
|
86
88
|
## Usage
|
87
89
|
|
90
|
+
The `bashly.yml` file can be set up to generate two types of scripts:
|
91
|
+
|
92
|
+
1. Script with commands (for example, like `docker` or `git`).
|
93
|
+
2. Script without commands (for example, like `ls`)
|
94
|
+
|
95
|
+
This is detected automatically by the contents of the configuration: If it
|
96
|
+
contains a `commands` definition, it will generate a script with commands.
|
97
|
+
|
88
98
|
In an empty directory, create a sample configuration file by running
|
89
99
|
|
90
100
|
```shell
|
@@ -113,7 +123,7 @@ Finally, edit the files in the `src` folder. Each of your script's commands
|
|
113
123
|
get their own file. Once you edit, run `bashly generate` again to merge the
|
114
124
|
content from your functions back into the script.
|
115
125
|
|
116
|
-
### Using the input
|
126
|
+
### Using the input arguments in your code
|
117
127
|
|
118
128
|
In order to access the parsed arguments in any of your partial scripts, you
|
119
129
|
may simply access the `$args` associative array.
|
@@ -152,32 +162,11 @@ $ ./download a --force
|
|
152
162
|
downloading a with --force
|
153
163
|
```
|
154
164
|
|
155
|
-
## Examples
|
156
|
-
|
157
|
-
The `bashly.yml` file can be set up to generate two types of scripts:
|
158
|
-
|
159
|
-
1. Script with commands (for example, like `docker` or `git`).
|
160
|
-
2. Script without commands (for example, like `ls`)
|
161
165
|
|
162
|
-
|
163
|
-
contains a `commands` definition, it will generate a script with commands.
|
164
|
-
|
165
|
-
|
166
|
-
### Sample configuraiton for a script without commands
|
167
|
-
|
168
|
-
- Generate this script by running `bashly generate --minimal`
|
169
|
-
- [See the initial sample bashly.yml file](examples/minimal/src/bashly.yml)
|
170
|
-
- [See the generated bash script](examples/minimal/download)
|
171
|
-
|
172
|
-
### Sample configuraiton for a script with commands
|
173
|
-
|
174
|
-
- Generate this script by running `bashly generate`
|
175
|
-
- [See the initial sample bashly.yml file](examples/commands/src/bashly.yml)
|
176
|
-
- [See the generated bash script](examples/commands/cli)
|
177
|
-
|
178
|
-
|
179
|
-
See the [examples](examples) folder for more examples.
|
166
|
+
## Examples
|
180
167
|
|
168
|
+
The [examples folder](examples#readme) contains many detailed and documented
|
169
|
+
example configuration files, with their output.
|
181
170
|
|
182
171
|
|
183
172
|
## Configuration Reference
|
@@ -193,24 +182,26 @@ The `bashly.yml` configuration file consists of these types:
|
|
193
182
|
|
194
183
|
### Command options
|
195
184
|
|
196
|
-
Unless otherwise specified, these
|
185
|
+
Unless otherwise specified, these definitions can be used for both the root
|
197
186
|
command and subcommands (under the `commands` definition).
|
198
187
|
|
199
|
-
|
200
188
|
Option | Description
|
201
189
|
-----------|-------------
|
202
190
|
`name` | The name of the script or subcommand.
|
203
191
|
`short` | An additional, optional pattern - usually used to denote a one letter variation of the command name. You can add `*` as a suffix, to denote a "starts with" pattern - for example `short: m*`. *Applicable only in subcommands*.
|
204
192
|
`help` | The header text to display when using `--help`. This option can have multiple lines. In this case, the first line will be used as summary wherever appropriate.
|
205
193
|
`version` | The string to display when using `--version`. *Applicable only in the main command*.
|
206
|
-
`default` | Setting this to `
|
194
|
+
`default` | Setting this to `true` on any command, will cause any unrecognized command line to be passed to this command. *Applicable only in subcommands*.
|
195
|
+
`extensible` | Specify that this command can be [externally extended](#extensible-scripts). *Applicable only in the main command*.
|
207
196
|
`examples` | Specify an array of examples to show when using `--help`. Each example can have multiple lines.
|
208
|
-
`environment_variables` | Specify an array of environment variables needed by your script.
|
209
|
-
`commands` | Specify the array of commands. Each command will have its own args and flags. Note: if `commands` is provided, you cannot specify flags or args at the same level.
|
210
|
-
`args` | Specify the array of positional arguments this script needs.
|
211
|
-
`flags` | Specify the array of option flags this script needs.
|
197
|
+
`environment_variables` | Specify an array of [environment variables](#environment-variable-options) needed by your script.
|
198
|
+
`commands` | Specify the array of [commands](#command-options). Each command will have its own args and flags. Note: if `commands` is provided, you cannot specify flags or args at the same level.
|
199
|
+
`args` | Specify the array of [positional arguments](#argument-options) this script needs.
|
200
|
+
`flags` | Specify the array of option [flags](#flag-options) this script needs.
|
201
|
+
`catch_all` | Specify that this command should allow for additional arbitrary arguments or flags. It can be set in one of three ways:<br>- Set to `true` to just enable it.<br>- Set to a string, to use this string in the usage help text.<br>- Set to a hash containing `label` and `help` keys, to show a detailed help for it when running with `--help`.
|
212
202
|
`dependencies` | Specify an array of any required external dependencies (commands). The script execution will be halted with a friendly error unless all dependency commands exist.
|
213
203
|
`group` | In case you have many commands, use this option to specify a caption to display before this command. This option is purely for display purposes, and needs to be specified only for the first command in each group.
|
204
|
+
`footer` | Add a custom message that will be displayed at the end of the `--help` text.
|
214
205
|
|
215
206
|
### Argument options
|
216
207
|
|
@@ -247,9 +238,7 @@ The `-v` and `-h` flags will be used as the short options for `--version` and
|
|
247
238
|
`--help` respectively **only if you are not using them in any of your own
|
248
239
|
flags**.
|
249
240
|
|
250
|
-
### Environment
|
251
|
-
|
252
|
-
The below configuration generates this environment variable usage text:
|
241
|
+
### Environment variable options
|
253
242
|
|
254
243
|
If an environment variable is defined as required (false by default), the
|
255
244
|
execution of the script will be halted with a friendly error if it is not
|
@@ -262,6 +251,81 @@ set.
|
|
262
251
|
`required` | Specify if this variable is required.
|
263
252
|
|
264
253
|
|
254
|
+
## Extensible Scripts
|
255
|
+
|
256
|
+
You may configure your generated bash script to delegate any unknown command
|
257
|
+
to an external executable, by setting the `extensible` option to either `true`,
|
258
|
+
or to a different external command.
|
259
|
+
|
260
|
+
This is similar to how `git` works. When you execute `git whatever`, the `git`
|
261
|
+
command will look for a file named `git-whatever` in the path, and execute it.
|
262
|
+
|
263
|
+
Note that this option cannot be specified together with the `default` option,
|
264
|
+
since both specify a handler for unknown commands.
|
265
|
+
|
266
|
+
Bashly supports two operation modes.
|
267
|
+
|
268
|
+
### Extension Mode (`extensible: true`)
|
269
|
+
|
270
|
+
By setting `extensible` to `true`, a specially named executable will be called
|
271
|
+
when an unknown command is called by the user.
|
272
|
+
|
273
|
+
Given this `bashly.yml` configuration:
|
274
|
+
|
275
|
+
```yaml
|
276
|
+
name: myscript
|
277
|
+
help: Example
|
278
|
+
version: 0.1.0
|
279
|
+
extensible: true
|
280
|
+
|
281
|
+
commands:
|
282
|
+
- name: upload
|
283
|
+
help: Upload a file
|
284
|
+
```
|
285
|
+
|
286
|
+
And this user command:
|
287
|
+
|
288
|
+
```
|
289
|
+
$ myscript something
|
290
|
+
|
291
|
+
```
|
292
|
+
|
293
|
+
The generated script will look for an executable named `myscript-something`
|
294
|
+
in the path. If found, it will be called.
|
295
|
+
|
296
|
+
See the [extensible example](examples/extensible).
|
297
|
+
|
298
|
+
|
299
|
+
### Delegate Mode (`extensible: <executable name>`)
|
300
|
+
|
301
|
+
By setting `extensible` to any string, unknown command calls by the user will
|
302
|
+
be delegated to the executable with that name.
|
303
|
+
|
304
|
+
Given this `bashly.yml` configuration:
|
305
|
+
|
306
|
+
```yaml
|
307
|
+
name: mygit
|
308
|
+
help: Example
|
309
|
+
version: 0.1.0
|
310
|
+
extensible: git
|
311
|
+
|
312
|
+
commands:
|
313
|
+
- name: push
|
314
|
+
help: Push to my repository
|
315
|
+
```
|
316
|
+
|
317
|
+
And this user command:
|
318
|
+
|
319
|
+
```
|
320
|
+
$ mygit status
|
321
|
+
|
322
|
+
```
|
323
|
+
|
324
|
+
The generated script will execute `git status`.
|
325
|
+
|
326
|
+
See the [extensible-delegate example](examples/extensible-delegate).
|
327
|
+
|
328
|
+
|
265
329
|
## Real World Examples
|
266
330
|
|
267
331
|
- [Rush][rush] - a Personal Package Manager
|
@@ -274,9 +338,9 @@ set.
|
|
274
338
|
If you experience any issue, have a question or a suggestion, or if you wish
|
275
339
|
to contribute, feel free to [open an issue][issues].
|
276
340
|
|
341
|
+
|
342
|
+
|
277
343
|
[issues]: https://github.com/DannyBen/bashly/issues
|
278
344
|
[rush]: https://github.com/DannyBen/rush-cli
|
279
345
|
[alf]: https://github.com/DannyBen/alf
|
280
346
|
[git-changelog]: https://github.com/DannyBen/git-changelog
|
281
|
-
|
282
|
-
|
data/lib/bashly/models/base.rb
CHANGED
@@ -28,6 +28,30 @@ module Bashly
|
|
28
28
|
help ? "#{full_name} - #{summary}" : full_name
|
29
29
|
end
|
30
30
|
|
31
|
+
# Returns a label for the catch_all directive
|
32
|
+
def catch_all_label
|
33
|
+
return nil unless catch_all
|
34
|
+
|
35
|
+
if catch_all.is_a? String
|
36
|
+
"#{catch_all.upcase}..."
|
37
|
+
elsif catch_all.is_a?(Hash) and catch_all['label'].is_a?(String)
|
38
|
+
"#{catch_all['label'].upcase}..."
|
39
|
+
else
|
40
|
+
"..."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a used defined help string for the catch_all directive
|
45
|
+
def catch_all_help
|
46
|
+
return nil unless catch_all
|
47
|
+
|
48
|
+
if catch_all.is_a?(Hash) and catch_all['help'].is_a?(String)
|
49
|
+
catch_all['help']
|
50
|
+
else
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
31
55
|
# Returns only the names of the Commands
|
32
56
|
def command_names
|
33
57
|
commands.map &:name
|
@@ -159,6 +183,7 @@ module Bashly
|
|
159
183
|
result << arg.usage_string
|
160
184
|
end
|
161
185
|
result << "[options]" unless flags.empty?
|
186
|
+
result << "[#{catch_all_label}]" if catch_all
|
162
187
|
result.join " "
|
163
188
|
end
|
164
189
|
|
data/lib/bashly/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# :command.command_fallback
|
2
|
+
<%- if default_command -%>
|
3
|
+
"" )
|
4
|
+
<%= function_name %>_usage
|
5
|
+
exit 1
|
6
|
+
;;
|
7
|
+
|
8
|
+
* )
|
9
|
+
action="<%= default_command.name %>"
|
10
|
+
<%= default_command.function_name %>_parse_requirements "$@"
|
11
|
+
shift $#
|
12
|
+
;;
|
13
|
+
<%- elsif extensible.is_a? String -%>
|
14
|
+
"" )
|
15
|
+
<%= function_name %>_usage
|
16
|
+
exit 1
|
17
|
+
;;
|
18
|
+
|
19
|
+
* )
|
20
|
+
if [[ -x "$(command -v "<%= extensible %>")" ]]; then
|
21
|
+
exec <%= extensible %> "$@"
|
22
|
+
else
|
23
|
+
<%= function_name %>_usage
|
24
|
+
exit 1
|
25
|
+
fi
|
26
|
+
<%- elsif extensible -%>
|
27
|
+
"" )
|
28
|
+
<%= function_name %>_usage
|
29
|
+
exit 1
|
30
|
+
;;
|
31
|
+
|
32
|
+
* )
|
33
|
+
if [[ -x "$(command -v "<%= function_name %>-$action")" ]]; then
|
34
|
+
shift
|
35
|
+
exec "<%= function_name %>-$action" "$@"
|
36
|
+
else
|
37
|
+
<%= function_name %>_usage
|
38
|
+
exit 1
|
39
|
+
fi
|
40
|
+
<%- else -%>
|
41
|
+
* )
|
42
|
+
<%= function_name %>_usage
|
43
|
+
exit 1
|
44
|
+
;;
|
45
|
+
<%- end -%>
|
@@ -15,25 +15,7 @@ case $action in
|
|
15
15
|
;;
|
16
16
|
|
17
17
|
<%- end -%>
|
18
|
-
|
19
|
-
"" )
|
20
|
-
<%= function_name %>_usage
|
21
|
-
exit 1
|
22
|
-
;;
|
23
|
-
|
24
|
-
* )
|
25
|
-
action="<%= default_command.name %>"
|
26
|
-
<%= default_command.function_name %>_parse_requirements "$@"
|
27
|
-
shift $#
|
28
|
-
;;
|
29
|
-
|
30
|
-
<%- else -%>
|
31
|
-
* )
|
32
|
-
<%= function_name %>_usage
|
33
|
-
exit 1
|
34
|
-
;;
|
35
|
-
|
36
|
-
<%- end -%>
|
18
|
+
<%= render :command_fallback %>
|
37
19
|
esac
|
38
20
|
<%- else -%>
|
39
21
|
action="<%= action_name %>"
|
@@ -7,4 +7,13 @@ inspect_args() {
|
|
7
7
|
else
|
8
8
|
echo args: none
|
9
9
|
fi
|
10
|
+
|
11
|
+
if (( ${#other_args[@]} )); then
|
12
|
+
echo
|
13
|
+
echo other_args:
|
14
|
+
echo "- \${other_args[*]} = ${other_args[*]}"
|
15
|
+
for i in "${!other_args[@]}"; do
|
16
|
+
echo "- \${other_args[$i]} = ${other_args[$i]}"
|
17
|
+
done
|
18
|
+
fi
|
10
19
|
}
|
@@ -8,9 +8,17 @@
|
|
8
8
|
<%- condition = "elif" -%>
|
9
9
|
<%- end -%>
|
10
10
|
else
|
11
|
+
<%- if catch_all -%>
|
12
|
+
other_args+=("$1")
|
13
|
+
shift
|
14
|
+
<%- else -%>
|
11
15
|
printf "<%= strings[:invalid_argument] %>\n" "$key"
|
12
16
|
exit 1
|
17
|
+
<%- end -%>
|
13
18
|
fi
|
19
|
+
<%- elsif catch_all -%>
|
20
|
+
other_args+=("$1")
|
21
|
+
shift
|
14
22
|
<%- else -%>
|
15
23
|
printf "<%= strings[:invalid_argument] %>\n" "$key"
|
16
24
|
exit 1
|
@@ -8,9 +8,15 @@ while [[ $# -gt 0 ]]; do
|
|
8
8
|
<%- end -%>
|
9
9
|
|
10
10
|
-* )
|
11
|
+
<%- if catch_all -%>
|
12
|
+
other_args+=("$1")
|
13
|
+
shift
|
14
|
+
;;
|
15
|
+
<%- else -%>
|
11
16
|
printf "<%= strings[:invalid_flag] %>\n" "$key"
|
12
17
|
exit 1
|
13
18
|
;;
|
19
|
+
<%- end -%>
|
14
20
|
|
15
21
|
* )
|
16
22
|
<%= render(:parse_requirements_case).indent 4 %>
|
@@ -37,9 +37,10 @@
|
|
37
37
|
printf "<%= strings[:options] %>\n"
|
38
38
|
<%= render(:usage_fixed_flags).indent 4 %>
|
39
39
|
<%= render(:usage_flags).indent 4 if flags.any? %>
|
40
|
-
<%= render(:usage_args).indent 4 if args.any? %>
|
40
|
+
<%= render(:usage_args).indent 4 if args.any? or catch_all_help %>
|
41
41
|
<%= render(:usage_environment_variables).indent 4 if environment_variables.any? %>
|
42
42
|
<%= render(:usage_examples).indent 4 if examples %>
|
43
|
+
<%= render(:footer).indent 4 if footer %>
|
43
44
|
|
44
45
|
fi
|
45
46
|
}
|
@@ -1,6 +1,14 @@
|
|
1
1
|
# :command.usage_args
|
2
2
|
printf "<%= strings[:arguments] %>\n"
|
3
|
+
<%- if args.any? -%>
|
3
4
|
|
4
5
|
<%- args.each do |arg| -%>
|
5
6
|
<%= arg.render(:usage) %>
|
6
7
|
<%- end -%>
|
8
|
+
<%- end -%>
|
9
|
+
<%- if catch_all_help -%>
|
10
|
+
|
11
|
+
echo " <%= catch_all_label %>"
|
12
|
+
printf "<%= catch_all_help.wrap(76).indent(4).sanitize_for_print %>\n"
|
13
|
+
echo
|
14
|
+
<%- end -%>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bashly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Danny Ben Shitrit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/bashly/templates/strings.yml
|
93
93
|
- lib/bashly/version.rb
|
94
94
|
- lib/bashly/views/argument/usage.erb
|
95
|
+
- lib/bashly/views/command/command_fallback.erb
|
95
96
|
- lib/bashly/views/command/command_filter.erb
|
96
97
|
- lib/bashly/views/command/command_functions.erb
|
97
98
|
- lib/bashly/views/command/default_assignments.erb
|
@@ -101,6 +102,7 @@ files:
|
|
101
102
|
- lib/bashly/views/command/dependencies_filter.erb
|
102
103
|
- lib/bashly/views/command/environment_variables_filter.erb
|
103
104
|
- lib/bashly/views/command/fixed_flags_filter.erb
|
105
|
+
- lib/bashly/views/command/footer.erb
|
104
106
|
- lib/bashly/views/command/function.erb
|
105
107
|
- lib/bashly/views/command/initialize.erb
|
106
108
|
- lib/bashly/views/command/inspect_args.erb
|
@@ -146,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
148
|
- !ruby/object:Gem::Version
|
147
149
|
version: '0'
|
148
150
|
requirements: []
|
149
|
-
rubygems_version: 3.2.
|
151
|
+
rubygems_version: 3.2.16
|
150
152
|
signing_key:
|
151
153
|
specification_version: 4
|
152
154
|
summary: Bash Command Line Tool Generator
|