bashly 1.1.3 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bashly/commands/render.rb +1 -1
- data/lib/bashly/concerns/validation_helpers.rb +1 -1
- data/lib/bashly/config_validator.rb +34 -2
- data/lib/bashly/docs/flag.yml +15 -3
- data/lib/bashly/libraries/strings/strings.yml +1 -0
- data/lib/bashly/render_context.rb +1 -1
- data/lib/bashly/script/argument.rb +13 -1
- data/lib/bashly/script/command.rb +5 -0
- data/lib/bashly/script/environment_variable.rb +1 -1
- data/lib/bashly/script/flag.rb +11 -1
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/argument/usage.gtx +5 -1
- data/lib/bashly/views/command/default_assignments.gtx +2 -2
- data/lib/bashly/views/command/environment_variables_filter.gtx +23 -10
- data/lib/bashly/views/command/inspect_args.gtx +14 -2
- data/lib/bashly/views/command/parse_requirements_case_repeatable.gtx +11 -3
- data/lib/bashly/views/command/run.gtx +1 -0
- data/lib/bashly/views/environment_variable/usage.gtx +4 -0
- data/lib/bashly/views/flag/case_arg.gtx +6 -2
- data/lib/bashly/views/flag/usage.gtx +6 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17cea196efbe1bc65a6639258fe902503b75656c6a759ea5434a12d6a53d4529
|
4
|
+
data.tar.gz: 5e86d08e594250889bc351d5d6113bcfc40f8ec04ba39f72a7f19eec8329c7af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ade5312408fc08533dc6992673744920e941e142c09c9f05e58e66a08a6dfccfab100707cee319cb2ec388e60f9a73ae8ff735e8217c8f91820fc5e2e22af886
|
7
|
+
data.tar.gz: cf7f6da0438551ba2a10ed5c224d7ad6ac6b02d8675dca57c8ac01eb465e705a19bd2c3d1812b61b54ab52a433b5ce228b7f3b579e9de24f71c6f512caad1202
|
@@ -4,7 +4,7 @@ require 'tty-markdown'
|
|
4
4
|
module Bashly
|
5
5
|
module Commands
|
6
6
|
class Render < Base
|
7
|
-
help 'Render the bashly data structure using
|
7
|
+
help 'Render the bashly data structure using custom templates'
|
8
8
|
|
9
9
|
usage 'bashly render SOURCE TARGET [--watch --show PATH]'
|
10
10
|
usage 'bashly render SOURCE --about'
|
@@ -91,16 +91,25 @@ module Bashly
|
|
91
91
|
assert_hash key, value, keys: Script::Argument.option_keys
|
92
92
|
assert_string "#{key}.name", value['name']
|
93
93
|
assert_optional_string "#{key}.help", value['help']
|
94
|
-
|
94
|
+
assert_string_or_array "#{key}.default", value['default']
|
95
95
|
assert_optional_string "#{key}.validate", value['validate']
|
96
96
|
assert_boolean "#{key}.required", value['required']
|
97
97
|
assert_boolean "#{key}.repeatable", value['repeatable']
|
98
|
+
assert_boolean "#{key}.unique", value['unique']
|
98
99
|
|
99
100
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
100
101
|
|
101
102
|
refute value['name'].match(/^-/), "#{key}.name must not start with '-'"
|
102
103
|
|
103
104
|
refute value['required'] && value['default'], "#{key} cannot have both nub`required` and nub`default`"
|
105
|
+
|
106
|
+
if value['unique']
|
107
|
+
assert value['repeatable'], "#{key}.unique does not make sense without nub`repeatable`"
|
108
|
+
end
|
109
|
+
|
110
|
+
if value['default'].is_a? Array
|
111
|
+
assert value['repeatable'], "#{key}.default array does not make sense without nub`repeatable`"
|
112
|
+
end
|
104
113
|
end
|
105
114
|
|
106
115
|
def assert_flag(key, value)
|
@@ -113,11 +122,12 @@ module Bashly
|
|
113
122
|
assert_optional_string "#{key}.short", value['short']
|
114
123
|
assert_optional_string "#{key}.help", value['help']
|
115
124
|
assert_optional_string "#{key}.arg", value['arg']
|
116
|
-
|
125
|
+
assert_string_or_array "#{key}.default", value['default']
|
117
126
|
assert_optional_string "#{key}.validate", value['validate']
|
118
127
|
|
119
128
|
assert_boolean "#{key}.private", value['private']
|
120
129
|
assert_boolean "#{key}.repeatable", value['repeatable']
|
130
|
+
assert_boolean "#{key}.unique", value['unique']
|
121
131
|
assert_boolean "#{key}.required", value['required']
|
122
132
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
123
133
|
assert_array "#{key}.conflicts", value['conflicts'], of: :string
|
@@ -140,6 +150,15 @@ module Bashly
|
|
140
150
|
if value['completions']
|
141
151
|
assert value['arg'], "#{key}.completions does not make sense without nub`arg`"
|
142
152
|
end
|
153
|
+
|
154
|
+
if value['unique']
|
155
|
+
assert value['arg'] && value['repeatable'],
|
156
|
+
"#{key}.unique does not make sense without nub`arg` and nub`repeatable`"
|
157
|
+
end
|
158
|
+
|
159
|
+
if value['default'].is_a? Array
|
160
|
+
assert value['repeatable'], "#{key}.default array does not make sense without nub`repeatable`"
|
161
|
+
end
|
143
162
|
end
|
144
163
|
|
145
164
|
def assert_env_var(key, value)
|
@@ -149,6 +168,9 @@ module Bashly
|
|
149
168
|
assert_optional_string "#{key}.default", value['default']
|
150
169
|
assert_boolean "#{key}.required", value['required']
|
151
170
|
assert_boolean "#{key}.private", value['private']
|
171
|
+
assert_array "#{key}.allowed", value['allowed'], of: :string
|
172
|
+
|
173
|
+
refute value['required'] && value['default'], "#{key} cannot have both nub`required` and nub`default`"
|
152
174
|
end
|
153
175
|
|
154
176
|
def assert_command(key, value)
|
@@ -201,6 +223,16 @@ module Bashly
|
|
201
223
|
refute repeatable_arg, "#{key}.catch_all makes no sense with repeatable arg (#{repeatable_arg})"
|
202
224
|
end
|
203
225
|
|
226
|
+
if value['args']
|
227
|
+
repeatable_args = value['args'].count { |a| a['repeatable'] }
|
228
|
+
assert repeatable_args < 2, "#{key}.args cannot have more than one repeatable args"
|
229
|
+
|
230
|
+
if repeatable_args == 1
|
231
|
+
assert value['args'].last['repeatable'],
|
232
|
+
"#{key}.args cannot contain a repeatable arg unless it is the last one"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
204
236
|
if value['expose']
|
205
237
|
assert value['commands'], "#{key}.expose makes no sense without nub`commands`"
|
206
238
|
end
|
data/lib/bashly/docs/flag.yml
CHANGED
@@ -41,9 +41,10 @@ flag.arg:
|
|
41
41
|
url: https://bashly.dannyb.co/configuration/flag/#arg
|
42
42
|
example: |-
|
43
43
|
flags:
|
44
|
-
- long: --
|
45
|
-
short: -
|
46
|
-
|
44
|
+
- long: --user
|
45
|
+
short: -u
|
46
|
+
arg: name
|
47
|
+
help: Specify the user name
|
47
48
|
|
48
49
|
flag.completions:
|
49
50
|
help: Specify a list of additional completion suggestions when used in conjunction with `bashly add completions`. Must be accompanied by `arg`.
|
@@ -161,6 +162,17 @@ flag.short:
|
|
161
162
|
arg: name
|
162
163
|
help: Repository user name
|
163
164
|
|
165
|
+
flag.unique:
|
166
|
+
help: Specify that the arguments provided by this repeatable flag must be unique. When this is set to `true`, non-unique values will be ignored.
|
167
|
+
url: https://bashly.dannyb.co/configuration/flag/#unique
|
168
|
+
example: |-
|
169
|
+
flags:
|
170
|
+
- long: --path
|
171
|
+
arg: location
|
172
|
+
help: Set one or more paths
|
173
|
+
repeatable: true
|
174
|
+
unique: true
|
175
|
+
|
164
176
|
flag.validate:
|
165
177
|
help: Apply custom validation functions. Must be accompanied by `arg`.
|
166
178
|
|
@@ -34,5 +34,6 @@ missing_required_environment_variable: "missing required environment variable: %
|
|
34
34
|
missing_dependency: "missing dependency: %{dependency}"
|
35
35
|
disallowed_flag: "%{name} must be one of: %{allowed}"
|
36
36
|
disallowed_argument: "%{name} must be one of: %{allowed}"
|
37
|
+
disallowed_environment_variable: "%{name} environment variable must be one of: %{allowed}"
|
37
38
|
unsupported_bash_version: "bash version 4 or higher is required"
|
38
39
|
validation_error: "validation error in %s:\\n%s"
|
@@ -1,14 +1,26 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
1
3
|
module Bashly
|
2
4
|
module Script
|
3
5
|
class Argument < Base
|
4
6
|
class << self
|
5
7
|
def option_keys
|
6
8
|
@option_keys ||= %i[
|
7
|
-
allowed default help name repeatable required validate
|
9
|
+
allowed default help name repeatable required unique validate
|
8
10
|
]
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
14
|
+
def default_string
|
15
|
+
if default.is_a?(Array)
|
16
|
+
Shellwords.shelljoin default
|
17
|
+
elsif default.is_a?(String) && repeatable
|
18
|
+
Shellwords.shellescape default
|
19
|
+
else
|
20
|
+
default
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
def usage_string
|
13
25
|
required ? label : "[#{label}]"
|
14
26
|
end
|
@@ -327,6 +327,11 @@ module Bashly
|
|
327
327
|
args.select(&:allowed)
|
328
328
|
end
|
329
329
|
|
330
|
+
# Returns an array of all the environemnt_variables with a whitelist arg
|
331
|
+
def whitelisted_environment_variables
|
332
|
+
environment_variables.select(&:allowed)
|
333
|
+
end
|
334
|
+
|
330
335
|
# Returns an array of all the flags with a whitelist arg
|
331
336
|
def whitelisted_flags
|
332
337
|
flags.select(&:allowed)
|
data/lib/bashly/script/flag.rb
CHANGED
@@ -7,7 +7,7 @@ module Bashly
|
|
7
7
|
def option_keys
|
8
8
|
@option_keys ||= %i[
|
9
9
|
allowed arg completions conflicts default help long repeatable
|
10
|
-
required short validate private
|
10
|
+
required short unique validate private
|
11
11
|
]
|
12
12
|
end
|
13
13
|
end
|
@@ -22,6 +22,16 @@ module Bashly
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def default_string
|
26
|
+
if default.is_a?(Array)
|
27
|
+
Shellwords.shelljoin default
|
28
|
+
elsif default.is_a?(String) && repeatable
|
29
|
+
Shellwords.shellescape default
|
30
|
+
else
|
31
|
+
default
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
25
35
|
def name
|
26
36
|
long || short
|
27
37
|
end
|
data/lib/bashly/version.rb
CHANGED
@@ -8,7 +8,11 @@ if allowed
|
|
8
8
|
end
|
9
9
|
|
10
10
|
if default
|
11
|
-
|
11
|
+
if default.is_a? Array
|
12
|
+
> printf " {{ strings[:default] % { value: default.join(', ') } }}\n"
|
13
|
+
else
|
14
|
+
> printf " {{ strings[:default] % { value: default } }}\n"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
> echo
|
@@ -2,11 +2,11 @@ if default_args.any? or default_flags.any?
|
|
2
2
|
= view_marker
|
3
3
|
|
4
4
|
default_args.each do |arg|
|
5
|
-
> [[ -n ${args['{{ arg.name }}']:-} ]] || args['{{ arg.name }}']="{{ arg.
|
5
|
+
> [[ -n ${args['{{ arg.name }}']:-} ]] || args['{{ arg.name }}']="{{ arg.default_string }}"
|
6
6
|
end
|
7
7
|
|
8
8
|
default_flags.each do |flag|
|
9
|
-
> [[ -n ${args['{{ flag.name }}']:-} ]] || args['{{ flag.name }}']="{{ flag.
|
9
|
+
> [[ -n ${args['{{ flag.name }}']:-} ]] || args['{{ flag.name }}']="{{ flag.default_string }}"
|
10
10
|
end
|
11
11
|
|
12
12
|
>
|
@@ -1,13 +1,26 @@
|
|
1
|
-
if
|
2
|
-
= view_marker
|
1
|
+
if environment_variables.any?
|
2
|
+
= view_marker
|
3
3
|
= render(:environment_variables_default)
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
> if [[ -z "${<%= env_var.name.upcase %>:-}" ]]; then
|
8
|
-
> printf "{{ strings[:missing_required_environment_variable] % { var: env_var.name.upcase } }}\n" >&2
|
9
|
-
> exit 1
|
10
|
-
> fi
|
11
|
-
end
|
5
|
+
environment_variables.each do |env_var|
|
6
|
+
> env_var_names+=("{{ env_var.name.upcase }}")
|
12
7
|
end
|
13
|
-
end
|
8
|
+
end
|
9
|
+
|
10
|
+
if required_environment_variables.any?
|
11
|
+
required_environment_variables.each do |env_var|
|
12
|
+
> if [[ -z "${<%= env_var.name.upcase %>:-}" ]]; then
|
13
|
+
> printf "{{ strings[:missing_required_environment_variable] % { var: env_var.name.upcase } }}\n" >&2
|
14
|
+
> exit 1
|
15
|
+
> fi
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if whitelisted_environment_variables.any?
|
20
|
+
whitelisted_environment_variables.each do |env_var|
|
21
|
+
> if [[ -n "${<%= env_var.name.upcase %>:-}" ]] && [[ ! ${<%= env_var.name.upcase %>:-} =~ ^({{ env_var.allowed.join '|' }})$ ]]; then
|
22
|
+
> printf "%s\n" "{{ strings[:disallowed_environment_variable] % { name: env_var.name.upcase, allowed: env_var.allowed.join(', ') } }}" >&2
|
23
|
+
> exit 1
|
24
|
+
> fi
|
25
|
+
end
|
26
|
+
end
|
@@ -4,7 +4,9 @@
|
|
4
4
|
> if ((${#args[@]})); then
|
5
5
|
> readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
|
6
6
|
> echo args:
|
7
|
-
> for k in "${sorted_keys[@]}"; do
|
7
|
+
> for k in "${sorted_keys[@]}"; do
|
8
|
+
> echo "- \${args[$k]} = ${args[$k]}"
|
9
|
+
> done
|
8
10
|
> else
|
9
11
|
> echo args: none
|
10
12
|
> fi
|
@@ -22,8 +24,18 @@
|
|
22
24
|
> readarray -t sorted_keys < <(printf '%s\n' "${!deps[@]}" | sort)
|
23
25
|
> echo
|
24
26
|
> echo deps:
|
25
|
-
> for k in "${sorted_keys[@]}"; do
|
27
|
+
> for k in "${sorted_keys[@]}"; do
|
28
|
+
> echo "- \${deps[$k]} = ${deps[$k]}"
|
29
|
+
> done
|
26
30
|
> fi
|
27
31
|
>
|
32
|
+
> if ((${#env_var_names[@]})); then
|
33
|
+
> readarray -t sorted_names < <(printf '%s\n' "${env_var_names[@]}" | sort)
|
34
|
+
> echo
|
35
|
+
> echo "environment variables:"
|
36
|
+
> for k in "${sorted_names[@]}"; do
|
37
|
+
> echo "- \$$k = ${!k:-}"
|
38
|
+
> done
|
39
|
+
> fi
|
28
40
|
> }
|
29
41
|
>
|
@@ -7,9 +7,17 @@ args.each do |arg|
|
|
7
7
|
if arg.repeatable
|
8
8
|
> args['{{ arg.name }}']="\"$1\""
|
9
9
|
> shift
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
if arg.unique
|
11
|
+
> elif [[ ! "${args['{{ arg.name }}']}" =~ \"$1\" ]]; then
|
12
|
+
> args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
|
13
|
+
> shift
|
14
|
+
> else
|
15
|
+
> shift
|
16
|
+
else
|
17
|
+
> else
|
18
|
+
> args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
|
19
|
+
> shift
|
20
|
+
end
|
13
21
|
|
14
22
|
else
|
15
23
|
> args['{{ arg.name }}']=$1
|
@@ -3,6 +3,10 @@
|
|
3
3
|
> printf " %s\n" "{{ usage_string(extended: true).color(:environment_variable) }}"
|
4
4
|
> printf "{{ help.wrap(76).indent(4).sanitize_for_print }}\n"
|
5
5
|
|
6
|
+
if allowed
|
7
|
+
> printf " {{ strings[:allowed] % { values: allowed.join(', ') } }}\n"
|
8
|
+
end
|
9
|
+
|
6
10
|
if default
|
7
11
|
> printf " {{ strings[:default] % { value: default } }}\n"
|
8
12
|
end
|
@@ -6,8 +6,12 @@
|
|
6
6
|
if repeatable
|
7
7
|
> if [[ -z ${args['{{ name }}']+x} ]]; then
|
8
8
|
> args['{{ name }}']="\"$2\""
|
9
|
-
|
10
|
-
|
9
|
+
if unique
|
10
|
+
> elif [[ ! "${args['{{ name }}']}" =~ \"$2\" ]]; then
|
11
|
+
else
|
12
|
+
> else
|
13
|
+
end
|
14
|
+
> args['{{ name }}']="${args['{{ name }}']} \"$2\""
|
11
15
|
> fi
|
12
16
|
|
13
17
|
else
|
@@ -4,11 +4,15 @@
|
|
4
4
|
> printf "{{ help.wrap(76).indent(4).sanitize_for_print }}\n"
|
5
5
|
|
6
6
|
if allowed
|
7
|
-
> printf " {{ strings[:allowed] % { values: allowed.join(', ') } }}\n"
|
7
|
+
> printf " {{ strings[:allowed] % { values: allowed.join(', ') } }}\n"
|
8
8
|
end
|
9
9
|
|
10
10
|
if default
|
11
|
-
|
11
|
+
if default.is_a? Array
|
12
|
+
> printf " {{ strings[:default] % { value: default.join(', ') } }}\n"
|
13
|
+
else
|
14
|
+
> printf " {{ strings[:default] % { value: default } }}\n"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
> echo
|
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: 1.1.
|
4
|
+
version: 1.1.5
|
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: 2023-
|
11
|
+
date: 2023-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|