File tree Expand file tree Collapse file tree 20 files changed +260
-37
lines changed
repeatable-arg-validations
repeatable-flag-validations Expand file tree Collapse file tree 20 files changed +260
-37
lines changed Original file line number Diff line number Diff line change @@ -101,9 +101,10 @@ def commands
101101 end
102102
103103 # Returns a flat array containing all the commands in this tree.
104- # This includes self + children + grandchildres + ...
105- def deep_commands
104+ # This includes children + grandchildren (recursive), and may include self
105+ def deep_commands ( include_self : false )
106106 result = [ ]
107+ result << self if include_self
107108 commands . each do |command |
108109 result << command
109110 if command . commands . any?
@@ -217,6 +218,16 @@ def grouped_commands
217218 result
218219 end
219220
221+ # Returns true if this command, or any subcommand (deep) as any arg or
222+ # flag with arg that is defined as unique
223+ def has_unique_args_or_flags?
224+ deep_commands ( include_self : true ) . each do |command |
225+ return true if command . args . count ( &:unique ) . positive? ||
226+ command . flags . count ( &:unique ) . positive?
227+ end
228+ false
229+ end
230+
220231 # Returns a mode identifier
221232 def mode
222233 @mode ||= if global_flags? then :global_flags
Original file line number Diff line number Diff line change 11= view_marker
22
33condition = "if"
4- args.each do |arg|
4+ args.each_with_index do |arg, index|
5+ if index == 0
6+ > escaped="$(printf '%q' "$1")"
7+ end
58 > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
69 if arg.repeatable
7- > args['{{ arg.name }}']="\"$1\""
8- > shift
10+ > args['{{ arg.name }}']="$escaped"
911 if arg.unique
10- > elif [[ ! "${args['{{ arg.name }}']}" =~ \"$1\" ]]; then
11- > args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
12- > shift
13- > else
14- > shift
12+ > unique_lookup["{{ arg.name }}:$escaped"]=1
13+ end
14+ if arg.unique
15+ > elif [[ -z "${unique_lookup["{{ arg.name }}:$escaped"]:-}" ]]; then
16+ > args['{{ arg.name }}']="${args['{{ arg.name }}']} $escaped"
17+ > unique_lookup["{{ arg.name }}:$escaped"]=1
1518 else
1619 > else
17- > args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
18- > shift
20+ > args['{{ arg.name }}']="${args['{{ arg.name }}']} $escaped"
1921 end
2022
2123 else
22- > args['{{ arg.name }}']=$1
23- > shift
24+ > args['{{ arg.name }}']="$1"
2425
2526 end
2627 condition = "elif"
2728end
2829
2930> fi
30- >
31+ > shift
32+ >
Original file line number Diff line number Diff line change 66> declare -a other_args=()
77> declare -a env_var_names=()
88> declare -a input=()
9+ if has_unique_args_or_flags?
10+ > declare -A unique_lookup=()
11+ end
912> normalize_input "$@"
1013> parse_requirements "${input[@]}"
1114if user_file_exist?('before')
@@ -29,5 +32,3 @@ if user_file_exist?('after')
2932end
3033
3134> }
32-
33-
Original file line number Diff line number Diff line change 33> if [[ -n ${2+x} ]]; then
44
55if repeatable
6+ > escaped="$(printf '%q' "$2")"
67 > if [[ -z ${args['{{ name }}']+x} ]]; then
7- > args['{{ name }}']="\"$2\" "
8+ > args['{{ name }}']="$escaped "
89 if unique
9- > elif [[ ! "${args[' {{ name }}']}" =~ \"$2\ " ]]; then
10+ > elif [[ -z "${unique_lookup[" {{ name }}:${escaped}"]:-} " ]]; then
1011 else
1112 > else
1213 end
13- > args['{{ name }}']="${args['{{ name }}']} \"$2\" "
14+ > args['{{ name }}']="${args['{{ name }}']} $escaped "
1415 > fi
16+ if unique
17+ > unique_lookup["{{ name }}:${escaped}"]=1
18+ end
1519
1620else
1721 > args['{{ name }}']="$2"
2529> exit 1
2630> fi
2731> ;;
28- >
32+ >
Original file line number Diff line number Diff line change 4747 upcase: CONTENT OF FILE1
4848
4949args:
50- - ${args[file]} = " file1"
50+ - ${args[file]} = file1
5151+ ./upcase file1 file2
5252
5353files:
5959 upcase: CONTENT OF FILE2
6060
6161args:
62- - ${args[file]} = " file1" " file2"
62+ - ${args[file]} = file1 file2
6363+ ./upcase file1 file2 file1
6464
6565files:
7171 upcase: CONTENT OF FILE2
7272
7373args:
74- - ${args[file]} = " file1" " file2"
74+ - ${args[file]} = file1 file2
Original file line number Diff line number Diff line change @@ -47,7 +47,7 @@ two three
4747Verbosity level: 3
4848
4949args:
50- - ${args[--data]} = " one" " two three"
50+ - ${args[--data]} = one two\ three
5151- ${args[--path]} = file\ one file-two
5252- ${args[--verbose]} = 3
5353+ ./download -d one --path /bin --path /usr/lib --path /bin
5757Verbosity level: 1
5858
5959args:
60- - ${args[--data]} = " one"
61- - ${args[--path]} = " /bin" " /usr/lib"
60+ - ${args[--data]} = one
61+ - ${args[--path]} = /bin /usr/lib
Original file line number Diff line number Diff line change @@ -11,7 +11,7 @@ args: none
1111# this file is located in 'src/root_command.sh'
1212# you can edit it freely and regenerate (it will not be overwritten)
1313args:
14- - ${args[number]} = "1"
14+ - ${args[number]} = 1
1515+ ./cli 1.1
1616validation error in NUMBER:
1717must be an integer
@@ -22,7 +22,7 @@ must be an integer
2222# this file is located in 'src/root_command.sh'
2323# you can edit it freely and regenerate (it will not be overwritten)
2424args:
25- - ${args[number]} = "1" "2"
25+ - ${args[number]} = 1 2
2626+ ./cli 1.1 2
2727validation error in NUMBER:
2828must be an integer
@@ -32,3 +32,6 @@ must be an integer
3232+ ./cli 1 a
3333validation error in NUMBER:
3434must be an integer
35+ + ./cli 1 'bad"quote'
36+ validation error in NUMBER:
37+ must be an integer
Original file line number Diff line number Diff line change 1+ + bundle exec 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
7+ args: none
8+
9+ + ./cli before 'x x' 'x x' after
10+ args:
11+ - ${args[term]} = before x\ x after
12+ [TERM] --> before
13+ [TERM] --> x x
14+ [TERM] --> after
15+
16+ + ./cli before 'x "x x"' 'x "x x"' after
17+ args:
18+ - ${args[term]} = before x\ \"x\ x\" after
19+ [TERM] --> before
20+ [TERM] --> x "x x"
21+ [TERM] --> after
22+
23+ + ./cli before 'x"x' 'x"x' after
24+ args:
25+ - ${args[term]} = before x\"x after
26+ [TERM] --> before
27+ [TERM] --> x"x
28+ [TERM] --> after
29+
30+ + ./cli -s before -s 'x x' -s 'x x' -s after
31+ args:
32+ - ${args[--search]} = before x\ x after
33+ [--serach] --> before
34+ [--serach] --> x x
35+ [--serach] --> after
36+
37+ + ./cli -s before -s 'x "x x"' -s 'x "x x"' -s after
38+ args:
39+ - ${args[--search]} = before x\ \"x\ x\" after
40+ [--serach] --> before
41+ [--serach] --> x "x x"
42+ [--serach] --> after
43+
44+ + ./cli -s before -s 'x"x' -s 'x"x' -s after
45+ args:
46+ - ${args[--search]} = before x\"x after
47+ [--serach] --> before
48+ [--serach] --> x"x
49+ [--serach] --> after
50+
51+ + ./cli once x once
52+ args:
53+ - ${args[term]} = once x
54+ [TERM] --> once
55+ [TERM] --> x
56+
57+ + ./cli -s once -s x -s once
58+ args:
59+ - ${args[--search]} = once x
60+ [--serach] --> once
61+ [--serach] --> x
62+
Original file line number Diff line number Diff line change @@ -11,7 +11,7 @@ args: none
1111# this file is located in 'src/root_command.sh'
1212# you can edit it freely and regenerate (it will not be overwritten)
1313args:
14- - ${args[--number]} = "1"
14+ - ${args[--number]} = 1
1515+ ./cli --number 1.1
1616validation error in --number, -n NUMBER:
1717must be an integer
@@ -22,7 +22,7 @@ must be an integer
2222# this file is located in 'src/root_command.sh'
2323# you can edit it freely and regenerate (it will not be overwritten)
2424args:
25- - ${args[--number]} = "1" "2"
25+ - ${args[--number]} = 1 2
2626+ ./cli --number 1.1 --number 2
2727validation error in --number, -n NUMBER:
2828must be an integer
@@ -32,3 +32,6 @@ must be an integer
3232+ ./cli --number 1 --number a
3333validation error in --number, -n NUMBER:
3434must be an integer
35+ + ./cli --number 1 --number 'bad"quote'
36+ validation error in --number, -n NUMBER:
37+ must be an integer
Original file line number Diff line number Diff line change @@ -12,15 +12,17 @@ args:
1212# this file is located in 'src/root_command.sh'
1313# you can edit it freely and regenerate (it will not be overwritten)
1414args:
15- - ${args[--protocol]} = " ssh"
15+ - ${args[--protocol]} = ssh
1616+ ./download -p ssh -p ftp
1717# this file is located in 'src/root_command.sh'
1818# you can edit it freely and regenerate (it will not be overwritten)
1919args:
20- - ${args[--protocol]} = " ssh" " ftp"
20+ - ${args[--protocol]} = ssh ftp
2121+ ./download -p sftp -p https
2222--protocol must be one of: ssh, ftp, sftp
2323+ ./download -p http -p ftp
2424--protocol must be one of: ssh, ftp, sftp
2525+ ./download --protocol telnet
2626--protocol must be one of: ssh, ftp, sftp
27+ + ./download --protocol telnet --protocol 'bad"quote'
28+ --protocol must be one of: ssh, ftp, sftp
You can’t perform that action at this time.
0 commit comments