bashly 1.3.3 → 1.3.5

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: 0d80ba9b8ae35371153a3610de0d3d76e64a7a18e3fcc3500c112634b38ec13e
4
- data.tar.gz: 908bd0775b5568471da0fe0b113fcddfefa1d1063ecafdd12019eacae8392e3d
3
+ metadata.gz: 429df4c59ef5a1dc0f1f9e332ab0b32b702fe5b83124c5ab04d784ef7d82bbc2
4
+ data.tar.gz: fdef11f71141111dea60129f9a9b855c669129010f5ec6e046fc0cdfafd9907f
5
5
  SHA512:
6
- metadata.gz: f11a315e7d68230adedb9b73916619b30893871711cb5716f119b53621813eae23ac9c72a76248d13349924343cc3e77834f0b12c3699130309ecd0c0b9b699d
7
- data.tar.gz: 3a19eada91503c3535b47643e18bb43b4c04d5548f5f18aac0195b8b14f3e18fb548f60a81cccf59d76ed714f8684dcdc9eec3a413b73b1e63d71d8c2d4cf875
6
+ metadata.gz: 17dcbf38797ebdd77898a53e09271cf7e0522c53af2f223910edc205f02d6ccd254eb4bcd11307f76656f14edaef253472efe0a9f699b9490f2ed3ef90746c85
7
+ data.tar.gz: 347ec4aebc9be7dcbcaef970db0465edf422b828361d3a37cfaa09337c372a1940a611b24a190af81dbb9857feeb8acc9c2d5662a39eac54df1f4504129c3424
data/README.md CHANGED
@@ -27,6 +27,7 @@ a [docker image](https://hub.docker.com/r/dannyben/bashly).
27
27
 
28
28
  - [Bashly Homepage][docs]
29
29
  - [Examples][examples]
30
+ - [Bashly AI Assistant][gpt]
30
31
 
31
32
  ## How it works
32
33
 
@@ -73,5 +74,6 @@ Visit the *[How to contribute][contributing]* page for more information.
73
74
  [issues]: https://github.com/bashly-framework/bashly/issues
74
75
  [discussions]: https://github.com/bashly-framework/bashly/discussions
75
76
  [docs]: https://bashly.dev/
77
+ [gpt]: https://bashly.dev/chat
76
78
  [examples]: https://github.com/bashly-framework/bashly/tree/master/examples#bashly-examples
77
79
  [contributing]: https://github.com/bashly-framework/bashly/blob/master/CONTRIBUTING.md#how-to-contribute
@@ -51,6 +51,13 @@ module Bashly
51
51
  File.exist? user_file_path(file)
52
52
  end
53
53
 
54
+ # Returns a wrapped, indented and sanitized string
55
+ # Designed to place help and example messages inside bash's 'printf'
56
+ def user_string(text, indent: 0)
57
+ wrap = Settings.word_wrap - indent
58
+ text.wrap(wrap).indent(indent).sanitize_for_print
59
+ end
60
+
54
61
  private
55
62
 
56
63
  def view_path(view)
@@ -35,6 +35,7 @@ module Bashly
35
35
  assert_string "#{key}.label", value['label']
36
36
  assert_optional_string "#{key}.help", value['help']
37
37
  assert_boolean "#{key}.required", value['required']
38
+ assert_boolean "#{key}.catch_help", value['catch_help']
38
39
  end
39
40
 
40
41
  def assert_default_command(key, value)
@@ -33,7 +33,7 @@ class String
33
33
  tr(' ', '/').downcase
34
34
  end
35
35
 
36
- def wrap(length = 80)
36
+ def wrap(length)
37
37
  strip!
38
38
  split("\n").collect! do |line|
39
39
  if line.length > length
@@ -5,7 +5,7 @@
5
5
  ## Note that code here should be wrapped inside bash functions, and it is
6
6
  ## recommended to have a separate file for each function.
7
7
  ##
8
- ## Subdirectories will also be scanned for *.sh, so you have no reason not
8
+ ## Sub-directories will also be scanned for *.sh, so you have no reason not
9
9
  ## to organize your code neatly.
10
10
  ##
11
11
  sample_function() {
@@ -53,10 +53,16 @@ target_dir: .
53
53
  # The path to use for common library files, relative to source_dir
54
54
  lib_dir: lib
55
55
 
56
+ # An array or comma delimited string of additional directories to search for
57
+ # bash functions. Any bash script found in any of these directories
58
+ # (or sub-directories) will be merged into the final script.
59
+ # Note that this is relative to the working directory.
60
+ extra_lib_dirs: ~
61
+
56
62
  # The path to use for command files, relative to source_dir
57
63
  # When set to nil (~), command files will be placed directly under source_dir
58
64
  # When set to any other string, command files will be placed under this
59
- # directory, and each command will get its own subdirectory
65
+ # directory, and each command will get its own sub-directory
60
66
  commands_dir: ~
61
67
 
62
68
  # The extension to use when reading/writing partial script snippets
@@ -78,6 +84,9 @@ strict: false
78
84
  # (every 2 leading spaces will be converted to a tab character)
79
85
  tab_indent: false
80
86
 
87
+ # Set the character width used to wrap help and example messages
88
+ word_wrap: 80
89
+
81
90
  # Choose a post-processor for the generated script:
82
91
  # formatter: internal # Use Bashly’s built-in formatter (removes extra newlines)
83
92
  # formatter: external # Run the external command `shfmt --case-indent --indent 2`
@@ -34,6 +34,7 @@ module Bashly
34
34
  assert_optional_string "#{key}.usage", value['usage']
35
35
  assert_optional_string "#{key}.handler", value['handler']
36
36
  assert_optional_string "#{key}.post_install_message", value['post_install_message']
37
+ assert_boolean "#{key}.skip_src_check", value['skip_src_check']
37
38
 
38
39
  return if value['handler']
39
40
 
@@ -3,7 +3,7 @@ module Bashly
3
3
  class CatchAll
4
4
  class << self
5
5
  def option_keys
6
- @option_keys ||= %i[label help required]
6
+ @option_keys ||= %i[label help required catch_help]
7
7
  end
8
8
 
9
9
  def from_config(config)
@@ -13,7 +13,7 @@ module Bashly
13
13
  when String
14
14
  { label: config }
15
15
  when Hash
16
- { label: config['label'], help: config['help'], required: config['required'] }
16
+ config.transform_keys(&:to_sym).slice(*option_keys)
17
17
  else
18
18
  {}
19
19
  end
@@ -22,11 +22,12 @@ module Bashly
22
22
  end
23
23
  end
24
24
 
25
- def initialize(label: nil, help: nil, required: false, enabled: true)
25
+ def initialize(label: nil, help: nil, required: false, catch_help: false, enabled: true)
26
26
  @label = label
27
27
  @help = help
28
28
  @required = required
29
29
  @enabled = enabled
30
+ @catch_help = catch_help
30
31
  end
31
32
 
32
33
  def enabled?
@@ -45,6 +46,10 @@ module Bashly
45
46
  @required
46
47
  end
47
48
 
49
+ def catch_help?
50
+ @catch_help
51
+ end
52
+
48
53
  def usage_string
49
54
  return nil unless enabled?
50
55
 
@@ -153,7 +153,13 @@ module Bashly
153
153
  # This is meant to provide the user with the ability to add custom
154
154
  # functions
155
155
  def user_lib
156
- @user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
156
+ @user_lib ||= begin
157
+ result = Settings.all_lib_dirs.map do |dir|
158
+ Dir["#{dir}/**/*.#{Settings.partials_extension}"]
159
+ end
160
+
161
+ result.flatten
162
+ end
157
163
  end
158
164
 
159
165
  # Returns a mixed array of Argument and Flag objects that have validations
@@ -16,6 +16,13 @@ module Bashly
16
16
  end
17
17
  end
18
18
 
19
+ # Returns true if there is at least one fixed flag (--version / --help)
20
+ # Root command always has --version and subcommands always have --help
21
+ # except when it is consumed by catch_all
22
+ def fixed_flags?
23
+ root_command? || !catch_all.catch_help?
24
+ end
25
+
19
26
  # Returns true if this command's flags should be considered as gloal
20
27
  # flags, and cascade to subcommands
21
28
  def global_flags?
@@ -15,6 +15,7 @@ module Bashly
15
15
  :enable_inspect_args,
16
16
  :enable_sourcing,
17
17
  :enable_view_markers,
18
+ :extra_lib_dirs,
18
19
  :formatter,
19
20
  :function_names,
20
21
  :lib_dir,
@@ -26,7 +27,8 @@ module Bashly
26
27
  :tab_indent,
27
28
  :target_dir,
28
29
  :usage_colors,
29
- :var_aliases
30
+ :var_aliases,
31
+ :word_wrap
30
32
  )
31
33
 
32
34
  def commands_dir
@@ -107,6 +109,21 @@ module Bashly
107
109
  @lib_dir ||= get :lib_dir
108
110
  end
109
111
 
112
+ def extra_lib_dirs
113
+ @extra_lib_dirs ||= begin
114
+ dirs = get :extra_lib_dirs
115
+ case dirs
116
+ when Array then dirs
117
+ when String then dirs.split(',').map(&:strip)
118
+ else []
119
+ end
120
+ end
121
+ end
122
+
123
+ def all_lib_dirs
124
+ @all_lib_dirs = [full_lib_dir] + extra_lib_dirs
125
+ end
126
+
110
127
  def partials_extension
111
128
  @partials_extension ||= get :partials_extension
112
129
  end
@@ -157,6 +174,10 @@ module Bashly
157
174
  @var_aliases ||= get :var_aliases
158
175
  end
159
176
 
177
+ def word_wrap
178
+ @word_wrap ||= get :word_wrap
179
+ end
180
+
160
181
  private
161
182
 
162
183
  def get(key)
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.3.3'
2
+ VERSION = '1.3.5'
3
3
  end
@@ -1,7 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > printf " %s\n" "{{ label.color(:arg) }}"
4
- > printf "{{ help.wrap(76).indent(4).sanitize_for_print }}\n"
4
+ > printf "{{ user_string help, indent: 4 }}\n"
5
5
 
6
6
  if allowed
7
7
  > printf " %s\n" "{{ strings[:allowed] % { values: allowed.join(', ') } }}"
@@ -3,6 +3,6 @@ if Settings.show_examples_on_error && examples
3
3
 
4
4
  > printf "{{ strings[:examples_caption_on_error] }}\n" >&2
5
5
  examples.each do |example|
6
- > printf "{{ example.wrap(78).indent(2).sanitize_for_print }}\n" >&2
6
+ > printf "{{ user_string example, indent: 2 }}\n" >&2
7
7
  end
8
8
  end
@@ -12,12 +12,14 @@ if root_command?
12
12
  >
13
13
  end
14
14
 
15
- = (short_flag_exist?("-h") ? "--help)" : "--help | -h)").indent(4)
16
- > long_usage=yes
17
- > <%= function_name %>_usage
18
- > exit
19
- > ;;
20
- >
15
+ unless catch_all.catch_help?
16
+ = (short_flag_exist?("-h") ? "--help)" : "--help | -h)").indent(4)
17
+ > long_usage=yes
18
+ > <%= function_name %>_usage
19
+ > exit
20
+ > ;;
21
+ >
22
+ end
21
23
 
22
24
  if global_flags?
23
25
  flags.each do |flag|
@@ -6,8 +6,8 @@
6
6
 
7
7
  if root_command?
8
8
  >
9
- = render(:variables).indent(2)
10
9
  = render(:environment_variables_default).indent 2
10
+ = render(:variables).indent(2)
11
11
  end
12
12
 
13
13
  if user_file_exist?('initialize')
@@ -1,6 +1,8 @@
1
1
  = view_marker
2
2
 
3
3
  > inspect_args() {
4
+ > local k
5
+ >
4
6
  > if ((${#args[@]})); then
5
7
  > readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
6
8
  > echo args:
@@ -17,8 +19,8 @@ if catch_all_used_anywhere?
17
19
  > echo
18
20
  > echo other_args:
19
21
  > echo "- \${other_args[*]} = ${other_args[*]}"
20
- > for i in "${!other_args[@]}"; do
21
- > echo "- \${other_args[$i]} = ${other_args[$i]}"
22
+ > for k in "${!other_args[@]}"; do
23
+ > echo "- \${other_args[$k]} = ${other_args[$k]}"
22
24
  > done
23
25
  > fi
24
26
  >
@@ -1,15 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > if [[ -n "$long_usage" ]]; then
4
- options_caption = strings[:options]
5
- if commands.any? && (public_flags.any? || (flags.any? && Settings.private_reveal_key))
6
- options_caption = strings[:global_options]
7
- end
8
-
9
- > printf "%s\n" "{{ options_caption.color(:caption) }}"
10
- >
11
- = render(:usage_flags).indent 2 if flags.any?
12
- = render(:usage_fixed_flags).indent 2
4
+ = render(:usage_options).indent 2 if flags.any? || fixed_flags?
13
5
  = render(:usage_args).indent 2 if args.any? or catch_all.help
14
6
  = render(:usage_environment_variables).indent 2 if environment_variables.any?
15
7
  = render(:usage_examples).indent 2 if examples
@@ -5,6 +5,8 @@ if root_command?
5
5
  else
6
6
  > {{ function_name }}_parse_requirements() {
7
7
  end
8
+ > local key
9
+ >
8
10
 
9
11
  = render(:fixed_flags_filter).indent 2
10
12
  = render(:environment_variables_filter).indent 2
@@ -9,7 +9,7 @@ else
9
9
  = help_header_override.indent 4
10
10
  else
11
11
  > printf "{{ full_name }}\n\n"
12
- > printf "{{ help.wrap(78).indent(2).sanitize_for_print }}\n\n"
12
+ > printf "{{ user_string help, indent: 2 }}\n\n"
13
13
  end
14
14
  > else
15
15
  > printf "{{ caption_string.sanitize_for_print }}\n\n"
@@ -12,7 +12,7 @@ end
12
12
  if catch_all.help
13
13
  >
14
14
  > echo " {{ catch_all.label }}"
15
- > printf "{{ catch_all.help.wrap(76).indent(4).sanitize_for_print }}\n"
15
+ > printf "{{ user_string catch_all.help, indent: 4 }}\n"
16
16
  > echo
17
17
  end
18
18
 
@@ -3,7 +3,7 @@
3
3
  > printf "%s\n" "{{ strings[:examples].color(:caption) }}"
4
4
 
5
5
  examples.each do |example|
6
- > printf "{{ example.wrap(78).indent(2).sanitize_for_print }}\n"
6
+ > printf "{{ user_string example, indent: 2 }}\n"
7
7
  end
8
8
 
9
9
  > echo
@@ -1,13 +1,15 @@
1
1
  = view_marker
2
2
 
3
- if short_flag_exist?("-h")
4
- > printf " %s\n" "{{ '--help'.color(:flag) }}"
5
- else
6
- > printf " %s\n" "{{ '--help, -h'.color(:flag) }}"
7
- end
3
+ unless catch_all.catch_help?
4
+ if short_flag_exist?("-h")
5
+ > printf " %s\n" "{{ '--help'.color(:flag) }}"
6
+ else
7
+ > printf " %s\n" "{{ '--help, -h'.color(:flag) }}"
8
+ end
8
9
 
9
- > printf " {{ strings[:help_flag_text] }}\n"
10
- > echo
10
+ > printf " {{ strings[:help_flag_text] }}\n"
11
+ > echo
12
+ end
11
13
 
12
14
  if root_command?
13
15
  if short_flag_exist?("-v")
@@ -0,0 +1,11 @@
1
+ = view_marker
2
+
3
+ options_caption = strings[:options]
4
+ if commands.any? && (public_flags.any? || (flags.any? && Settings.private_reveal_key))
5
+ options_caption = strings[:global_options]
6
+ end
7
+
8
+ > printf "%s\n" "{{ options_caption.color(:caption) }}"
9
+ >
10
+ = render(:usage_flags) if flags.any?
11
+ = render(:usage_fixed_flags)
@@ -1,7 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > printf " %s\n" "{{ usage_string(extended: true).color(:environment_variable) }}"
4
- > printf "{{ help.wrap(76).indent(4).sanitize_for_print }}\n"
4
+ > printf "{{ user_string help, indent: 4 }}\n"
5
5
 
6
6
  if allowed
7
7
  > printf " %s\n" "{{ strings[:allowed] % { values: allowed.join(', ') } }}"
@@ -1,7 +1,7 @@
1
1
  = view_marker
2
2
 
3
3
  > printf " %s\n" "{{ usage_string(extended: true).color(:flag) }}"
4
- > printf "{{ help.wrap(76).indent(4).sanitize_for_print }}\n"
4
+ > printf "{{ user_string help, indent: 4 }}\n"
5
5
 
6
6
  if allowed
7
7
  > printf " %s\n" "{{ strings[:allowed] % { values: allowed.join(', ') } }}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bashly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
@@ -314,6 +314,7 @@ files:
314
314
  - lib/bashly/views/command/usage_examples.gtx
315
315
  - lib/bashly/views/command/usage_fixed_flags.gtx
316
316
  - lib/bashly/views/command/usage_flags.gtx
317
+ - lib/bashly/views/command/usage_options.gtx
317
318
  - lib/bashly/views/command/user_filter.gtx
318
319
  - lib/bashly/views/command/user_hooks.gtx
319
320
  - lib/bashly/views/command/user_lib.gtx
@@ -358,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
358
359
  - !ruby/object:Gem::Version
359
360
  version: '0'
360
361
  requirements: []
361
- rubygems_version: 3.6.9
362
+ rubygems_version: 4.0.0
362
363
  specification_version: 4
363
364
  summary: Bash Command Line Tool Generator
364
365
  test_files: []