Skip to content

Commit 3a37ef3

Browse files
authored
Merge pull request #483 from DannyBen/add/key-value-example
Add example for parsing `key=value` arguments and `--flag key=value` flags
2 parents 9eee25c + d0bc638 commit 3a37ef3

File tree

11 files changed

+250
-1
lines changed

11 files changed

+250
-1
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
LC_ALL: en_US.UTF-8
1515

1616
strategy:
17-
matrix: { ruby: ['3.0', '3.1', '3.2'] }
17+
matrix: { ruby: ['3.0', '3.1', '3.2', '3.3'] }
1818

1919
steps:
2020
- name: Checkout code

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Each of these examples demonstrates one aspect or feature of bashly.
3737
- [stdin](stdin#readme) - reading input from stdin
3838
- [filters](filters#readme) - preventing commands from running unless custom conditions are met
3939
- [commands-expose](commands-expose#readme) - showing sub-commands in the parent's help
40+
- [key-value-pairs](key-value-pairs#readme) - parsing key=value arguments and flags
4041

4142
## Customization
4243

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cli

examples/key-value-pairs/README.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Key Value Pairs Example
2+
3+
Demonstrates how to implement support for a command line that accepts
4+
`key=value` pairs, either as positional arguments of repeatable flags.
5+
6+
This example was generated with:
7+
8+
```bash
9+
$ bashly init
10+
# ... now edit src/bashly.yml to match the example ...
11+
# ... now create and edit src/lib/extract_params.sh to match the example ...
12+
$ bashly generate
13+
# ... now edit src/root_command.sh ...
14+
$ bashly generate
15+
```
16+
17+
See the [src/root_command.sh](src/root_command.sh) for usage example.
18+
19+
20+
<!-- include: src/root_command.sh src/lib/extract_params.sh -->
21+
22+
-----
23+
24+
## `bashly.yml`
25+
26+
````yaml
27+
name: cli
28+
help: Sample application to demonstrate `key=value` arguments and flags
29+
version: 0.1.0
30+
31+
args:
32+
- name: param
33+
required: true
34+
repeatable: true
35+
unique: true
36+
help: key=value parameters
37+
38+
flags:
39+
- long: --option
40+
short: -o
41+
arg: option
42+
repeatable: true
43+
unique: true
44+
help: key=value parameters
45+
46+
examples:
47+
- cli user=bob [email protected] --option page=2 --option count=20
48+
````
49+
50+
## `src/root_command.sh`
51+
52+
````bash
53+
extract_params "${args[param]}"
54+
55+
echo "Positional Arguments:"
56+
for key in "${!params[@]}"; do
57+
echo "$key => ${params[$key]}"
58+
done
59+
60+
extract_params "${args[--option]}"
61+
62+
echo
63+
echo "Options (--option):"
64+
for key in "${!params[@]}"; do
65+
echo "$key => ${params[$key]}"
66+
done
67+
68+
````
69+
70+
## `src/lib/extract_params.sh`
71+
72+
````bash
73+
## Convert an array of key=value pairs to an associative array.
74+
## Calling this function will populate an associative array named `params`.
75+
function extract_params {
76+
declare -gA params=()
77+
declare -a list=()
78+
local pattern="([^=]+)=(.+)"
79+
eval "list=($*)"
80+
81+
for pair in "${list[@]}"; do
82+
if [[ $pair =~ $pattern ]]; then
83+
key="${BASH_REMATCH[1]}"
84+
value="${BASH_REMATCH[2]}"
85+
params["$key"]="$value"
86+
fi
87+
done
88+
}
89+
````
90+
91+
92+
## Output
93+
94+
### `$ ./cli -h`
95+
96+
````shell
97+
cli - Sample application to demonstrate `key=value` arguments and flags
98+
99+
Usage:
100+
cli PARAM... [OPTIONS]
101+
cli --help | -h
102+
cli --version | -v
103+
104+
Options:
105+
--option, -o OPTION (repeatable)
106+
key=value parameters
107+
108+
--help, -h
109+
Show this help
110+
111+
--version, -v
112+
Show version number
113+
114+
Arguments:
115+
PARAM...
116+
key=value parameters
117+
118+
Examples:
119+
cli user=bob [email protected] --option page=2 --option count=20
120+
121+
122+
123+
````
124+
125+
### `$ ./cli user=bob [email protected] --option page=2 --option count=20`
126+
127+
````shell
128+
Positional Arguments:
129+
130+
user => bob
131+
132+
Options (--option):
133+
count => 20
134+
page => 2
135+
136+
137+
````
138+
139+
140+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: cli
2+
help: Sample application to demonstrate `key=value` arguments and flags
3+
version: 0.1.0
4+
5+
args:
6+
- name: param
7+
required: true
8+
repeatable: true
9+
unique: true
10+
help: key=value parameters
11+
12+
flags:
13+
- long: --option
14+
short: -o
15+
arg: option
16+
repeatable: true
17+
unique: true
18+
help: key=value parameters
19+
20+
examples:
21+
- cli user=bob [email protected] --option page=2 --option count=20
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## Convert an array of key=value pairs to an associative array.
2+
## Calling this function will populate an associative array named `params`.
3+
function extract_params {
4+
declare -gA params=()
5+
declare -a list=()
6+
local pattern="([^=]+)=(.+)"
7+
eval "list=($*)"
8+
9+
for pair in "${list[@]}"; do
10+
if [[ $pair =~ $pattern ]]; then
11+
key="${BASH_REMATCH[1]}"
12+
value="${BASH_REMATCH[2]}"
13+
params["$key"]="$value"
14+
fi
15+
done
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extract_params "${args[param]}"
2+
3+
echo "Positional Arguments:"
4+
for key in "${!params[@]}"; do
5+
echo "$key => ${params[$key]}"
6+
done
7+
8+
extract_params "${args[--option]}"
9+
10+
echo
11+
echo "Options (--option):"
12+
for key in "${!params[@]}"; do
13+
echo "$key => ${params[$key]}"
14+
done

examples/key-value-pairs/test.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
set -x
4+
5+
bashly generate
6+
7+
### Try Me ###
8+
9+
./cli -h
10+
./cli user=bob [email protected] --option page=2 --option count=20
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
+ bashly generate
2+
creating user files in src
3+
skipped src/root_command.sh (exists)
4+
created ./cli
5+
run ./cli --help to test your bash script
6+
+ ./cli -h
7+
cli - Sample application to demonstrate `key=value` arguments and flags
8+
9+
Usage:
10+
cli PARAM... [OPTIONS]
11+
cli --help | -h
12+
cli --version | -v
13+
14+
Options:
15+
--option, -o OPTION (repeatable)
16+
key=value parameters
17+
18+
--help, -h
19+
Show this help
20+
21+
--version, -v
22+
Show version number
23+
24+
Arguments:
25+
PARAM...
26+
key=value parameters
27+
28+
Examples:
29+
cli user=bob [email protected] --option page=2 --option count=20
30+
31+
+ ./cli user=bob [email protected] --option page=2 --option count=20
32+
Positional Arguments:
33+
34+
user => bob
35+
36+
Options (--option):
37+
count => 20
38+
page => 2

support/runfile/shellcheck.runfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ summary 'Run shellcheck on all examples'
33
action do
44
allowed_skips = 3
55
Example.executables.each do |example|
6+
if ENV['EXAMPLE']
7+
next unless example.include? ENV['EXAMPLE']
8+
end
9+
610
if File.exist? example
711
success = system "shellcheck #{example}"
812
color = success ? 'g' : 'r'

0 commit comments

Comments
 (0)