Skip to content

Commit 0c737ff

Browse files
authored
Merge pull request #66 from DannyBen/add/flag-whitelist
Add support for allowed values for flags
2 parents fd629f9 + c396eee commit 0c737ff

File tree

12 files changed

+248
-1
lines changed

12 files changed

+248
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ short form).
238238
`arg` | If the flag requires an argument, specify its name here.
239239
`required` | Specify if this flag is required.
240240
`default` | The value to use in case it is not provided by the user. Implies that this flag is optional, and only makes sense when the flag has an argument.
241+
`allowed` | For flags with an argument, you can limit the allowed values by providing an array.
241242

242243
#### Special handling for -v and -h
243244

examples/allowed-flags/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Allowed Flag Values
2+
==================================================
3+
4+
This example was generated with:
5+
6+
$ bashly init --minimal
7+
$ bashly generate

examples/allowed-flags/login

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#!/usr/bin/env bash
2+
# This script was generated by bashly (https://github.com/DannyBen/bashly)
3+
# Modifying it manually is not recommended
4+
5+
# :command.root_command
6+
root_command() {
7+
# :src/root_command.sh
8+
echo "# this file is located in 'src/root_command.sh'"
9+
echo "# you can edit it freely and regenerate (it will not be overwritten)"
10+
inspect_args
11+
}
12+
13+
# :command.version_command
14+
version_command() {
15+
echo "$version"
16+
}
17+
18+
# :command.usage
19+
login_usage() {
20+
if [[ -n $long_usage ]]; then
21+
printf "login - Sample showing the use of allowed values for a flag (whitelist)\n"
22+
echo
23+
else
24+
printf "login - Sample showing the use of allowed values for a flag (whitelist)\n"
25+
echo
26+
fi
27+
28+
printf "Usage:\n"
29+
printf " login [options]\n"
30+
printf " login --help | -h\n"
31+
printf " login --version | -v\n"
32+
echo
33+
34+
if [[ -n $long_usage ]]; then
35+
printf "Options:\n"
36+
# :command.usage_fixed_flags
37+
echo " --help, -h"
38+
printf " Show this help\n"
39+
echo
40+
echo " --version, -v"
41+
printf " Show version number\n"
42+
echo
43+
# :command.usage_flags
44+
# :flag.usage
45+
echo " --user, -u NAME"
46+
printf " User name\n"
47+
printf " Allowed: user, admin\n"
48+
printf " Default: user\n"
49+
echo
50+
51+
fi
52+
}
53+
54+
# :command.inspect_args
55+
inspect_args() {
56+
readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
57+
if (( ${#args[@]} )); then
58+
echo args:
59+
for k in "${sorted_keys[@]}"; do echo "- \${args[$k]} = ${args[$k]}"; done
60+
else
61+
echo args: none
62+
fi
63+
}
64+
65+
# :command.command_functions
66+
67+
# :command.parse_requirements
68+
parse_requirements() {
69+
# :command.fixed_flag_filter
70+
case "$1" in
71+
--version | -v )
72+
version_command
73+
exit
74+
;;
75+
76+
--help | -h )
77+
long_usage=yes
78+
login_usage
79+
exit 1
80+
;;
81+
82+
esac
83+
# :command.environment_variables_filter
84+
# :command.dependencies_filter
85+
# :command.command_filter
86+
action="root"
87+
# :command.required_args_filter
88+
# :command.required_flags_filter
89+
# :command.parse_requirements_while
90+
while [[ $# -gt 0 ]]; do
91+
key="$1"
92+
case "$key" in
93+
# :flag.case
94+
--user | -u )
95+
if [[ $2 ]]; then
96+
args[--user]="$2"
97+
shift
98+
shift
99+
if [[ ! ${args[--user]} =~ ^(user|admin)$ ]]; then
100+
printf "%s\n" "--user must be one of: user, admin"
101+
exit 1
102+
fi
103+
else
104+
printf "%s\n" "--user requires an argument: --user, -u NAME"
105+
exit 1
106+
fi
107+
;;
108+
109+
110+
-* )
111+
printf "invalid option: %s\n" "$key"
112+
exit 1
113+
;;
114+
115+
* )
116+
# :command.parse_requirements_case
117+
printf "invalid argument: %s\n" "$key"
118+
exit 1
119+
;;
120+
121+
esac
122+
done
123+
# :command.default_assignments
124+
[[ -n ${args[--user]} ]] || args[--user]="user"
125+
}
126+
127+
# :command.initialize
128+
initialize() {
129+
version="0.1.0"
130+
long_usage=''
131+
set -e
132+
133+
# :src/initialize.sh
134+
# Code here runs inside the initialize() function
135+
# Use it for anything that you need to run before any other function, like
136+
# setting environment vairables:
137+
# CONFIG_FILE=settings.ini
138+
#
139+
# Feel free to empty (but not delete) this file.
140+
}
141+
142+
# :command.run
143+
run() {
144+
declare -A args
145+
parse_requirements "$@"
146+
147+
if [[ $action == "root" ]]; then
148+
root_command
149+
fi
150+
}
151+
152+
initialize
153+
run "$@"

examples/allowed-flags/src/bashly.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: login
2+
help: Sample showing the use of allowed values for a flag (whitelist)
3+
version: 0.1.0
4+
5+
flags:
6+
- long: --user
7+
short: -u
8+
arg: NAME
9+
allowed: [user, admin]
10+
default: user
11+
help: "User name"
12+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Code here runs inside the initialize() function
2+
# Use it for anything that you need to run before any other function, like
3+
# setting environment vairables:
4+
# CONFIG_FILE=settings.ini
5+
#
6+
# Feel free to empty (but not delete) this file.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
echo "# this file is located in 'src/root_command.sh'"
2+
echo "# you can edit it freely and regenerate (it will not be overwritten)"
3+
inspect_args

examples/allowed-flags/test.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
3+
rm -f ./src/*.sh
4+
5+
set -x
6+
7+
bashly generate
8+
9+
./login
10+
./login -h
11+
./login -v
12+
./login --user admin
13+
./login --user no-such-user

lib/bashly/models/base.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ class Base
66
attr_reader :options
77

88
OPTION_KEYS = %i[
9+
allowed
910
arg
11+
default
1012
dependencies
1113
description
12-
default
1314
environment_variables
1415
examples
1516
flags

lib/bashly/templates/strings.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ command_shortcut: "Shortcut: %{short}"
1515
default_command_summary: "%{summary} (default)"
1616
required: "(required)"
1717
default: "Default: %{value}"
18+
allowed: "Allowed: %{values}"
1819

1920
# Fixed flags help text
2021
help_flag_text: Show this help
@@ -28,3 +29,4 @@ missing_required_argument: "missing required argument: %{arg}\\nusage: %{usage}"
2829
missing_required_flag: "missing required flag: %{usage}"
2930
missing_required_environment_variable: "missing required environment variable: %{var}"
3031
missing_dependency: "missing dependency: %{dependency}"
32+
disallowed_flag: "%{name} must be one of: %{allowed}"

lib/bashly/views/flag/case.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
args[<%= name %>]="$2"
66
shift
77
shift
8+
<%- if allowed -%>
9+
if [[ ! ${args[<%= name %>]} =~ ^(<%= allowed.join '|' %>)$ ]]; then
10+
printf "%s\n" "<%= strings[:disallowed_flag] % { name: name, allowed: allowed.join(', ') } %>"
11+
exit 1
12+
fi
13+
<%- end -%>
814
else
915
printf "%s\n" "<%= strings[:flag_requires_an_argument] % { name: name, usage: usage_string } %>"
1016
exit 1

0 commit comments

Comments
 (0)