Skip to content

Commit 88eb3bf

Browse files
authored
Merge pull request #84 from DannyBen/add/completions
Add bash completions generator
2 parents 79fdb4a + 7ec6748 commit 88eb3bf

File tree

36 files changed

+1402
-6
lines changed

36 files changed

+1402
-6
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
LC_ALL: en_US.UTF-8 # consistent sort order
1414

1515
strategy:
16-
matrix: { ruby: ['2.4', '2.5', '2.6', '2.7', '3.0'] }
16+
matrix: { ruby: ['2.7', '3.0'] }
1717

1818
steps:
1919
- name: Checkout code

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Create beautiful bash scripts from simple YAML configuration
3131
- [Flag options](#flag-options)
3232
- [Environment Variable options](#environment-variable-options)
3333
- [Extensible Scripts](#extensible-scripts)
34+
- [Bash Completions](#bash-completions)
3435
- [Real World Examples](#real-world-examples)
3536
- [Contributing / Support](#contributing--support)
3637

@@ -75,13 +76,15 @@ Bahsly is responsible for:
7576
- Optional or required **option flags** (with or without flag arguments).
7677
- **Commands** (and subcommands).
7778
- Standard flags (like **--help** and **--version**).
79+
- Preventing your script from running unless the command line is valid.
7880
- Providing you with a place to input your code for each of the functions
7981
your tool performs, and merging it back to the final script.
8082
- Providing you with additional (optional) framework-style, standard
8183
library functions:
8284
- **Color output**.
8385
- **Config file management** (INI format).
8486
- **YAML parsing**.
87+
- **Bash completions**.
8588
- and more.
8689

8790

@@ -198,6 +201,7 @@ command and subcommands (under the `commands` definition).
198201
`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.
199202
`args` | Specify the array of [positional arguments](#argument-options) this script needs.
200203
`flags` | Specify the array of option [flags](#flag-options) this script needs.
204+
`completions` | Specify an array of additional completion suggestions when used in conjunction with `bashly add comp`. See [Bash Completions](#bash-completions).
201205
`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`.
202206
`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.
203207
`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.
@@ -326,6 +330,71 @@ The generated script will execute `git status`.
326330
See the [extensible-delegate example](examples/extensible-delegate).
327331

328332

333+
## Bash Completions
334+
335+
Bashly comes with built-in bash completions generator, provided by the
336+
[completely][completely] gem.
337+
338+
By running any of the `bashly add comp` commands, you can add this
339+
functionality to your script in one of three ways:
340+
341+
- `bashly add comp function` - creates a function in your `./src/lib` directory
342+
that echoes a completion script. You can then call this function from any
343+
command (for example `yourcli completions`) and your users will be able to
344+
install the completions by running `eval "$(yourcli completions)"`.
345+
- `bashly add comp script` - creates a standalone completion script that can be
346+
sourced or copies to the system's bash completions directory.
347+
- `bashly add comp yaml` - creates the "raw data" YAML file. This is intended
348+
mainly for development purposes.
349+
350+
The bash completions generation is completely automatic, and you will have to
351+
rerun the `bashly add comp *` command whenever you change your `bashly.yml`
352+
script.
353+
354+
In addition to suggesting subcommands and flags, you can instruct bashly to
355+
also suggest files, directories, users and more. To do this, add another option
356+
in your `bashly.yml` on the command you wish to alter:
357+
358+
```yaml
359+
# bashly.yml
360+
commands:
361+
- name: upload
362+
help: Upload a file
363+
completions: [directory, user]
364+
365+
```
366+
367+
Valid completion additions are:
368+
369+
| Keyword | Meaning
370+
|-------------|---------------------
371+
| `alias` | Alias names
372+
| `arrayvar` | Array variable names
373+
| `binding` | Readline key binding names
374+
| `builtin` | Names of shell builtin commands
375+
| `command` | Command names
376+
| `directory` | Directory names
377+
| `disabled` | Names of disabled shell builtins
378+
| `enabled` | Names of enabled shell builtins
379+
| `export` | Names of exported shell variables
380+
| `file` | File names
381+
| `function` | Names of shell functions
382+
| `group` | Group names
383+
| `helptopic` | Help topics as accepted by the help builtin
384+
| `hostname` | Hostnames, as taken from the file specified by the HOSTFILE shell variable
385+
| `job` | Job names
386+
| `keyword` | Shell reserved words
387+
| `running` | Names of running jobs
388+
| `service` | Service names
389+
| `signal` | Signal names
390+
| `stopped` | Names of stopped jobs
391+
| `user` | User names
392+
| `variable` | Names of all shell variables
393+
394+
Note that these are taken from the [Programmable Completion Builtin][compgen],
395+
and will simply be added using the `compgen -A action` command.
396+
397+
329398
## Real World Examples
330399

331400
- [Rush][rush] - a Personal Package Manager
@@ -344,3 +413,5 @@ to contribute, feel free to [open an issue][issues].
344413
[rush]: https://github.com/DannyBen/rush-cli
345414
[alf]: https://github.com/DannyBen/alf
346415
[git-changelog]: https://github.com/DannyBen/git-changelog
416+
[completely]: https://github.com/DannyBen/completely
417+
[compgen]: https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html

bashly.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
1515
s.executables = ['bashly']
1616
s.homepage = 'https://github.com/dannyben/bashly'
1717
s.license = 'MIT'
18-
s.required_ruby_version = ">= 2.3.0"
18+
s.required_ruby_version = ">= 2.7.0"
1919

2020
s.add_runtime_dependency 'colsole', '~> 0.6'
21+
s.add_runtime_dependency 'completely', '~> 0.1', '>= 0.1.2'
2122
s.add_runtime_dependency 'mister_bin', '~> 0.7'
2223
s.add_runtime_dependency 'requires', '~> 0.1'
2324
end

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ Each of these examples demonstrates one aspect or feature of bashly.
4242
- [config-ini](config-ini#readme) - using the config (INI) functions
4343
- [colors](colors#readme) - using the color print feature
4444
- [yaml](yaml#readme) - using the YAML reading functions
45+
- [completions](completions#readme) - adding bash completion functionality

examples/completions/README.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Bash Completions Example
2+
3+
Demonstrates how to build a script that supports bash completions.
4+
5+
This example was generated with:
6+
7+
$ bashly init
8+
$ bashly add comp function
9+
$ bashly generate
10+
11+
-----
12+
13+
## `bashly.yml`
14+
15+
```yaml
16+
name: cli
17+
help: Sample application with bash completions
18+
version: 0.1.0
19+
20+
commands:
21+
- name: completions
22+
help: |-
23+
Generate bash completions
24+
Usage: eval "\$(cli completions)"
25+
26+
- name: download
27+
short: d
28+
help: Download a file
29+
completions: [file]
30+
31+
args:
32+
- name: source
33+
required: true
34+
help: URL to download from
35+
- name: target
36+
help: "Target filename (default: same as source)"
37+
38+
flags:
39+
- long: --force
40+
short: -f
41+
help: Overwrite existing files
42+
43+
examples:
44+
- cli download example.com
45+
- cli download example.com ./output -f
46+
47+
environment_variables:
48+
- name: default_target_location
49+
help: Set the default location to download to
50+
51+
- name: upload
52+
short: u
53+
help: Upload a file
54+
completions: [directory, user]
55+
args:
56+
- name: source
57+
required: true
58+
help: File to upload
59+
60+
flags:
61+
- long: --user
62+
short: -u
63+
arg: user
64+
help: Username to use for logging in
65+
required: true
66+
- long: --password
67+
short: -p
68+
arg: password
69+
help: Password to use for logging in
70+
```
71+
72+
## Generated script output
73+
74+
### `$ ./cli`
75+
76+
```shell
77+
cli - Sample application with bash completions
78+
79+
Usage:
80+
cli [command]
81+
cli [command] --help | -h
82+
cli --version | -v
83+
84+
Commands:
85+
completions Generate bash completions
86+
download Download a file
87+
upload Upload a file
88+
89+
90+
91+
```
92+
93+
### `$ ./cli -h`
94+
95+
```shell
96+
cli - Sample application with bash completions
97+
98+
Usage:
99+
cli [command]
100+
cli [command] --help | -h
101+
cli --version | -v
102+
103+
Commands:
104+
completions Generate bash completions
105+
download Download a file
106+
upload Upload a file
107+
108+
Options:
109+
--help, -h
110+
Show this help
111+
112+
--version, -v
113+
Show version number
114+
115+
116+
117+
```
118+
119+
### `$ ./cli completions -h`
120+
121+
```shell
122+
cli completions
123+
124+
Generate bash completions
125+
Usage: eval "$(cli completions)"
126+
127+
Usage:
128+
cli completions
129+
cli completions --help | -h
130+
131+
Options:
132+
--help, -h
133+
Show this help
134+
135+
136+
137+
```
138+
139+
### `$ ./cli completions`
140+
141+
```shell
142+
#!/usr/bin/env bash
143+
144+
# This bash completions script was generated by
145+
# completely (https://github.com/dannyben/completely)
146+
# Modifying it manually is not recommended
147+
_cli_completions() {
148+
local cur=${COMP_WORDS[COMP_CWORD]}
149+
150+
case "$COMP_LINE" in
151+
'cli completions'*) COMPREPLY=($(compgen -W "--help -h" -- "$cur")) ;;
152+
'cli download'*) COMPREPLY=($(compgen -A file -W "--force --help -f -h" -- "$cur")) ;;
153+
'cli upload'*) COMPREPLY=($(compgen -A directory -A user -W "--help --password --user -h -p -u" -- "$cur")) ;;
154+
'cli'*) COMPREPLY=($(compgen -W "--help --version -h -v completions download upload" -- "$cur")) ;;
155+
esac
156+
}
157+
158+
complete -F _cli_completions cli
159+
160+
161+
```
162+
163+
164+

0 commit comments

Comments
 (0)