bashly 0.8.6 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6be5a0594215515e99372cba7e1f6b0a6540429299166e9a2f420d14181af207
4
- data.tar.gz: 91498eb6c640f0eb57f68aa974e876a69d624e9830402f10d11f5de874f6684c
3
+ metadata.gz: '09fd56d9f65d2a7859382562739364338cbe7ccf52d2c82ac446f3e9b6a5d118'
4
+ data.tar.gz: 10a648ebf0552b376cca8aa1ff89592670721c089acea84c10ff3aeaacd218e3
5
5
  SHA512:
6
- metadata.gz: f77887a91b45dcba6422d48fc794cd8bc8c50243a6b04df3bd426aa90b837beb53b1a770adf903482a85ad60631c6515f21f6559045aa73475b9321d5432c13e
7
- data.tar.gz: 8c05eba6921abcf365c6ab4df5f8632f7136749274708361dfb6dcf6e5a85b9b55c267d65adadb3ed77677fe9a94293a7259e86789e0a754c3ba461118c9701d
6
+ metadata.gz: 65c59416204a5c3a7da38efad9373ac555e2368fbdd27b47e4e7d3b143abe73f4c22309b0d6f8909b00f70807b9502095ec10728a8f903738e24f300d75e52f7
7
+ data.tar.gz: fe3a5db484a8cf4af117fc43114095acbbfb96c25ed1f63570029981ca175d6d6bd7e89a42cef8bbc2eedeff6aa5df394db6afccfba763d010aa96b75fede166
data/README.md CHANGED
@@ -70,10 +70,12 @@ If you experience any issue, have a question or a suggestion, or if you wish
70
70
  to contribute, feel free to [open an issue][issues] or
71
71
  [start a discussion][discussions].
72
72
 
73
+ Visit the *[How to contribute][contributing]* page for more information.
74
+
73
75
 
74
76
 
75
77
  [issues]: https://github.com/DannyBen/bashly/issues
76
78
  [discussions]: https://github.com/DannyBen/bashly/discussions
77
79
  [docs]: https://bashly.dannyb.co/
78
80
  [examples]: https://github.com/DannyBen/bashly/tree/master/examples#bashly-examples
79
-
81
+ [contributing]: https://github.com/DannyBen/bashly/blob/master/CONTRIBUTING.md#how-to-contribute
@@ -112,7 +112,7 @@ module Bashly
112
112
  assert_hash key, value, Script::Command.option_keys
113
113
 
114
114
  refute value['commands'] && value['args'], "#{key} cannot have both commands and args"
115
- refute value['commands'] && value['flags'], "#{key} cannot have both commands and flags"
115
+ refute value['commands'] && value['catch_all'], "#{key} cannot have both commands and catch_all"
116
116
 
117
117
  assert_string "#{key}.name", value['name']
118
118
  assert_optional_string "#{key}.help", value['help']
@@ -142,6 +142,10 @@ module Bashly
142
142
  assert_uniq "#{key}.flags", value['flags'], 'short'
143
143
  assert_uniq "#{key}.args", value['args'], 'name'
144
144
 
145
+ if value['default']
146
+ assert value['args'], "#{key}.default makes no sense without args"
147
+ end
148
+
145
149
  if value['catch_all'] and value['args']
146
150
  repeatable_arg = value['args'].select { |a| a['repeatable'] }.first&.dig 'name'
147
151
  refute repeatable_arg, "#{key}.catch_all makes no sense with repeatable arg (#{repeatable_arg})"
@@ -177,6 +177,12 @@ module Bashly
177
177
  parents.any? ? (parents + [name]).join(' ') : name
178
178
  end
179
179
 
180
+ # Returns true if this command's flags should be considered as gloal
181
+ # flags, and cascade to subcommands
182
+ def global_flags?
183
+ flags.any? and commands.any?
184
+ end
185
+
180
186
  # Returns the string for the group caption
181
187
  def group_string
182
188
  if group
@@ -186,6 +192,19 @@ module Bashly
186
192
  end
187
193
  end
188
194
 
195
+ # Returns a mode identifier
196
+ def mode
197
+ @mode ||= begin
198
+ if global_flags? then :global_flags
199
+ elsif commands.any? then :commands
200
+ elsif args.any? and flags.any? then :args_and_flags
201
+ elsif args.any? then :args
202
+ elsif flags.any? then :flags
203
+ else :empty
204
+ end
205
+ end
206
+ end
207
+
189
208
  # Returns an array of all parents. For example, the command
190
209
  # "docker container run" will have [docker, container] as its parents
191
210
  def parents
@@ -239,13 +258,23 @@ module Bashly
239
258
  # Returns a constructed string suitable for Usage pattern
240
259
  def usage_string
241
260
  result = [full_name]
242
- result << "[command]" if commands.any?
243
- args.each do |arg|
244
- result << arg.usage_string
261
+
262
+ result.push case mode
263
+ when :global_flags then ["[OPTIONS]", "COMMAND"]
264
+ when :commands then ["COMMAND"]
265
+ when :args_and_flags then usage_string_args + ["[OPTIONS]"]
266
+ when :args then usage_string_args
267
+ when :flags then ["[OPTIONS]"]
268
+ else nil
245
269
  end
246
- result << "[options]" unless flags.empty?
247
- result << catch_all.usage_string if catch_all.enabled?
248
- result.join " "
270
+
271
+ result.push catch_all.usage_string if catch_all.enabled? && commands.empty?
272
+ result.compact.join " "
273
+ end
274
+
275
+ # Returns an array of args usage_string for the command's usage_string
276
+ def usage_string_args
277
+ args.map { |arg| arg.usage_string }
249
278
  end
250
279
 
251
280
  # Returns an array of files to include as is inside the script
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = "0.8.6"
2
+ VERSION = "0.8.7"
3
3
  end
@@ -3,7 +3,7 @@ if validate
3
3
  = view_marker
4
4
 
5
5
  > if [[ -n $(validate_{{ validate }} "$1") ]]; then
6
- > printf "{{ strings[:validation_error] }}\n" "{{ name.upcase }}" "$(validate_{{ validate }} "$1")"
6
+ > printf "{{ strings[:validation_error] }}\n" "{{ name.upcase }}" "$(validate_{{ validate }} "$1")" >&2
7
7
  > exit 1
8
8
  > fi
9
9
  >
@@ -2,7 +2,7 @@ if catch_all.required?
2
2
  = view_marker
3
3
 
4
4
  > if [[ ${#other_args[@]} -eq 0 ]]; then
5
- > printf "{{ strings[:missing_required_argument] % { arg: catch_all.label, usage: usage_string } }}\n"
5
+ > printf "{{ strings[:missing_required_argument] % { arg: catch_all.label, usage: usage_string } }}\n" >&2
6
6
  > exit 1
7
7
  > fi
8
8
  >
@@ -1,7 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > "" )
4
- > {{ function_name }}_usage
4
+ > {{ function_name }}_usage >&2
5
5
  > exit 1
6
6
  > ;;
7
7
  >
@@ -18,7 +18,7 @@ elsif extensible.is_a? String
18
18
  > if [[ -x "$(command -v "{{ extensible }}")" ]]; then
19
19
  > exec {{ extensible }} "$@"
20
20
  > else
21
- > printf "{{ strings[:invalid_command] }}\n" "$action"
21
+ > printf "{{ strings[:invalid_command] }}\n" "$action" >&2
22
22
  > exit 1
23
23
  > fi
24
24
  >
@@ -28,13 +28,13 @@ elsif extensible
28
28
  > shift
29
29
  > exec "{{ function_name }}-$action" "$@"
30
30
  > else
31
- > printf "{{ strings[:invalid_command] }}\n" "$action"
31
+ > printf "{{ strings[:invalid_command] }}\n" "$action" >&2
32
32
  > exit 1
33
33
  > fi
34
34
  >
35
35
 
36
36
  else
37
- > printf "{{ strings[:invalid_command] }}\n" "$action"
37
+ > printf "{{ strings[:invalid_command] }}\n" "$action" >&2
38
38
  > exit 1
39
39
  > ;;
40
40
  >
@@ -3,7 +3,7 @@ if dependencies
3
3
 
4
4
  dependencies.each do |dependency|
5
5
  > if ! [[ -x "$(command -v {{ dependency }})" ]]; then
6
- > printf "{{ strings[:missing_dependency] % { dependency: dependency } }}\n"
6
+ > printf "{{ strings[:missing_dependency] % { dependency: dependency } }}\n" >&2
7
7
  > exit 1
8
8
  > fi
9
9
  end
@@ -0,0 +1,7 @@
1
+ if default_environment_variables.any?
2
+ = view_marker
3
+
4
+ default_environment_variables.each do |env_var|
5
+ > export {{ env_var.name.upcase }}="${<%= env_var.name.upcase %>:-<%= env_var.default %>}"
6
+ end
7
+ end
@@ -1,16 +1,11 @@
1
1
  if default_environment_variables.any? or required_environment_variables.any?
2
2
  = view_marker
3
-
4
- if default_environment_variables.any?
5
- default_environment_variables.each do |env_var|
6
- > export {{ env_var.name.upcase }}="${<%= env_var.name.upcase %>:-<%= env_var.default %>}"
7
- end
8
- end
3
+ = render(:environment_variables_default)
9
4
 
10
5
  if required_environment_variables.any?
11
6
  required_environment_variables.each do |env_var|
12
7
  > if [[ -z "${<%= env_var.name.upcase %>:-}" ]]; then
13
- > printf "{{ strings[:missing_required_environment_variable] % { var: env_var.name.upcase } }}\n"
8
+ > printf "{{ strings[:missing_required_environment_variable] % { var: env_var.name.upcase } }}\n" >&2
14
9
  > exit 1
15
10
  > fi
16
11
  end
@@ -16,5 +16,12 @@ end
16
16
  > exit
17
17
  > ;;
18
18
  >
19
+
20
+ if global_flags?
21
+ flags.each do |flag|
22
+ = flag.render(:case)
23
+ end
24
+ end
25
+
19
26
  > esac
20
27
  >
@@ -6,6 +6,10 @@
6
6
  > {{ Settings.strict ? "set -euo pipefail" : "set -e" }}
7
7
  >
8
8
 
9
+ if root_command?
10
+ = render(:environment_variables_default).indent 2
11
+ end
12
+
9
13
  = load_user_file("initialize.sh", placeholder: false).indent 2
10
14
 
11
15
  > }
@@ -12,12 +12,12 @@ if args.any?
12
12
  end
13
13
 
14
14
  > else
15
- > printf "{{ strings[:invalid_argument] }}\n" "$key"
15
+ > printf "{{ strings[:invalid_argument] }}\n" "$key" >&2
16
16
  > exit 1
17
17
  > fi
18
18
 
19
19
  else
20
- > printf "{{ strings[:invalid_argument] }}\n" "$key"
20
+ > printf "{{ strings[:invalid_argument] }}\n" "$key" >&2
21
21
  > exit 1
22
22
 
23
23
  end
@@ -4,8 +4,10 @@
4
4
  > key="$1"
5
5
  > case "$key" in
6
6
 
7
- flags.each do |flag|
8
- = flag.render(:case).indent 2
7
+ unless global_flags?
8
+ flags.each do |flag|
9
+ = flag.render(:case).indent 2
10
+ end
9
11
  end
10
12
 
11
13
  >
@@ -17,7 +19,7 @@ if catch_all.enabled?
17
19
  > ;;
18
20
 
19
21
  else
20
- > printf "<%= strings[:invalid_flag] %>\n" "$key"
22
+ > printf "<%= strings[:invalid_flag] %>\n" "$key" >&2
21
23
  > exit 1
22
24
  > ;;
23
25
 
@@ -3,7 +3,7 @@ if required_args.any?
3
3
 
4
4
  required_args.each do |arg|
5
5
  > if [[ -z ${args[{{ arg.name }}]+x} ]]; then
6
- > printf "{{ strings[:missing_required_argument] % { arg: arg.name.upcase, usage: usage_string } }}\n"
6
+ > printf "{{ strings[:missing_required_argument] % { arg: arg.name.upcase, usage: usage_string } }}\n" >&2
7
7
  > exit 1
8
8
  > fi
9
9
  end
@@ -3,7 +3,7 @@ if required_flags.any?
3
3
 
4
4
  required_flags.each do |flag|
5
5
  > if [[ -z ${args[{{ flag.long }}]+x} ]]; then
6
- > printf "{{ strings[:missing_required_flag] % { usage: flag.usage_string } }}\n"
6
+ > printf "{{ strings[:missing_required_flag] % { usage: flag.usage_string } }}\n" >&2
7
7
  > exit 1
8
8
  > fi
9
9
  end
@@ -29,7 +29,7 @@ end
29
29
  > printf " {{ usage_string }}\n"
30
30
 
31
31
  if commands.any?
32
- > printf " {{ full_name }} [command] --help{{ " | -h" unless short_flag_exist? "-h" }}\n"
32
+ > printf " {{ full_name }} [COMMAND] --help{{ " | -h" unless short_flag_exist? "-h" }}\n"
33
33
  else
34
34
  > printf " {{ full_name }} --help{{ " | -h" unless short_flag_exist? "-h" }}\n"
35
35
  end
@@ -5,7 +5,7 @@ if filters
5
5
  filters.each do |filter|
6
6
  > filter_error=$(filter_{{ filter }})
7
7
  > if [[ -n $filter_error ]]; then
8
- > echo "$filter_error"
8
+ > echo "$filter_error" >&2
9
9
  > exit 1
10
10
  > fi
11
11
  >
@@ -6,14 +6,14 @@ if whitelisted_args.any? or whitelisted_flags.any?
6
6
  > eval "input_array=(${args[{{ arg.name }}]})"
7
7
  > for i in "${input_array[@]}"; do
8
8
  > if [[ ! $i =~ ^({{ arg.allowed.join '|' }})$ ]]; then
9
- > printf "%s\n" "{{ strings[:disallowed_argument] % { name: arg.name, allowed: arg.allowed.join(', ') } }}"
9
+ > printf "%s\n" "{{ strings[:disallowed_argument] % { name: arg.name, allowed: arg.allowed.join(', ') } }}" >&2
10
10
  > exit 1
11
11
  > fi
12
12
  > done
13
13
 
14
14
  else
15
15
  > if [[ ! ${args[{{ arg.name }}]} =~ ^({{ arg.allowed.join '|' }})$ ]]; then
16
- > printf "%s\n" "{{ strings[:disallowed_argument] % { name: arg.name, allowed: arg.allowed.join(', ') } }}"
16
+ > printf "%s\n" "{{ strings[:disallowed_argument] % { name: arg.name, allowed: arg.allowed.join(', ') } }}" >&2
17
17
  > exit 1
18
18
  > fi
19
19
 
@@ -25,14 +25,14 @@ if whitelisted_args.any? or whitelisted_flags.any?
25
25
  > eval "input_array=(${args[{{ flag.name }}]})"
26
26
  > for i in "${input_array[@]}"; do
27
27
  > if [[ ! $i =~ ^({{ flag.allowed.join '|' }})$ ]]; then
28
- > printf "%s\n" "{{ strings[:disallowed_flag] % { name: flag.name, allowed: flag.allowed.join(', ') } }}"
28
+ > printf "%s\n" "{{ strings[:disallowed_flag] % { name: flag.name, allowed: flag.allowed.join(', ') } }}" >&2
29
29
  > exit 1
30
30
  > fi
31
31
  > done
32
32
 
33
33
  else
34
34
  > if [[ ! ${args[{{ flag.name }}]} =~ ^({{ flag.allowed.join '|' }})$ ]]; then
35
- > printf "%s\n" "{{ strings[:disallowed_flag] % { name: flag.name, allowed: flag.allowed.join(', ') } }}"
35
+ > printf "%s\n" "{{ strings[:disallowed_flag] % { name: flag.name, allowed: flag.allowed.join(', ') } }}" >&2
36
36
  > exit 1
37
37
  > fi
38
38
 
@@ -18,7 +18,7 @@ end
18
18
  > shift
19
19
  > shift
20
20
  > else
21
- > printf "%s\n" "{{ strings[:flag_requires_an_argument] % { name: name, usage: usage_string } }}"
21
+ > printf "%s\n" "{{ strings[:flag_requires_an_argument] % { name: name, usage: usage_string } }}" >&2
22
22
  > exit 1
23
23
  > fi
24
24
  > ;;
@@ -4,7 +4,7 @@ if conflicts
4
4
 
5
5
  if conflicts.count == 1
6
6
  > if [[ -n "${args[{{ conflicts.first }}]:-}" ]]; then
7
- > printf "{{ strings[:conflicting_flags] }}\n" "$key" "{{ conflicts.first }}"
7
+ > printf "{{ strings[:conflicting_flags] }}\n" "$key" "{{ conflicts.first }}" >&2
8
8
  > exit 1
9
9
  > fi
10
10
  >
@@ -12,7 +12,7 @@ if conflicts
12
12
  else
13
13
  > for conflict in {{ conflicts.join ' ' }}; do
14
14
  > if [[ -n "${args[$conflict]:-}" ]]; then
15
- > printf "{{ strings[:conflicting_flags] }}\n" "$key" "$conflict"
15
+ > printf "{{ strings[:conflicting_flags] }}\n" "$key" "$conflict" >&2
16
16
  > exit 1
17
17
  > fi
18
18
  > done
@@ -3,7 +3,7 @@ if validate
3
3
  = view_marker
4
4
 
5
5
  > if [[ -n $(validate_{{ validate }} "$2") ]]; then
6
- > printf "{{ strings[:validation_error] }}\n" "{{ usage_string }}" "$(validate_{{ validate }} "$2")"
6
+ > printf "{{ strings[:validation_error] }}\n" "{{ usage_string }}" "$(validate_{{ validate }} "$2")" >&2
7
7
  > exit 1
8
8
  > fi
9
9
  >
@@ -1,7 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then
4
- > printf "{{ strings[:unsupported_bash_version] }}\n"
4
+ > printf "{{ strings[:unsupported_bash_version] }}\n" >&2
5
5
  > exit 1
6
6
  > fi
7
7
  >
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: 0.8.6
4
+ version: 0.8.7
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: 2022-09-23 00:00:00.000000000 Z
11
+ date: 2022-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: completely
@@ -167,6 +167,7 @@ files:
167
167
  - lib/bashly/views/command/default_root_script.gtx
168
168
  - lib/bashly/views/command/default_script.gtx
169
169
  - lib/bashly/views/command/dependencies_filter.gtx
170
+ - lib/bashly/views/command/environment_variables_default.gtx
170
171
  - lib/bashly/views/command/environment_variables_filter.gtx
171
172
  - lib/bashly/views/command/fixed_flags_filter.gtx
172
173
  - lib/bashly/views/command/footer.gtx