bashly 1.0.0.rc1 → 1.0.1

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: b23af9b1533c906c685ef6f62620bb32b55fb45599e354e85548e800d7ecf832
4
- data.tar.gz: e65e8f10fefd0b2945c9c31459ee427b9688a5d8565880ddbce3021d2b8b1c6a
3
+ metadata.gz: e17bc036331958bd9ff237d93e287c911bc00c85b33628a4b867dd2e69c818fe
4
+ data.tar.gz: 236e3ba5f96e9f89fce4b77d95adf68a3030ef31d3d59a857ad0477aa871b171
5
5
  SHA512:
6
- metadata.gz: 4c82c7e9a804e2d95d1a4179aaf96948c7f9e8150f64ace8d8b87b990a5157f22def814289f2aebb82869fafdd38fb03fc3aeec4fc752ff836c37efe0e53e389
7
- data.tar.gz: b82bc5d7be814046b42fc959238f3a455d3f1f9c17fa0d2a5e1a3cd2e516db64db33ed9d62afcdfef8368f33a7c3b5a4b65ac58bd9d3aa308aacc1130e9983de
6
+ metadata.gz: 55f3361b37d963fcd33ad97b9204ce201517b9249522e4d4fb501c4502e8ba31ef5049c629d6bf5e82d85854ca64de1435f2604a01e12913ba5a56de346994ee
7
+ data.tar.gz: 23832fbbfbbaec41862b61eeb75ef0a34598db175192d09c3f1ea738bf1bd81aa11d855df7a6ba9ec8461a5daa0de835bc9343cb56e72e8867f5d7a15492f8d7
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align='center'>
2
- <img src='logo.svg' width=280>
2
+ <img src='support/img/bashly-logo.svg' width=280>
3
3
 
4
4
  # Bashly - Bash CLI Framework and Generator
5
5
 
@@ -13,7 +13,7 @@ Create feature-rich bash scripts using simple YAML configuration
13
13
 
14
14
  ---
15
15
 
16
- ![demo](demo/cast.gif)
16
+ ![demo](support/demo/cast.gif)
17
17
 
18
18
  </div>
19
19
 
@@ -27,6 +27,11 @@ usually handled by a framework in any other programming language.
27
27
  It is available both as a [ruby gem](https://rubygems.org/gems/bashly) and as
28
28
  a [docker image](https://hub.docker.com/r/dannyben/bashly).
29
29
 
30
+ ## Bashly is Sponsored By
31
+
32
+ <a href="https://rhodecode.com/"><img src='support/img/RhodeCode-logo.png' width=280></a>
33
+
34
+
30
35
  ## Documentation
31
36
 
32
37
  - [Bashly Homepage][docs]
@@ -64,7 +69,7 @@ Bashly is responsible for:
64
69
  - **Bash completions**.
65
70
  - and more.
66
71
 
67
- ## Contributing / Support
72
+ ## Contributing / Support
68
73
 
69
74
  If you experience any issue, have a question or a suggestion, or if you wish
70
75
  to contribute, feel free to [open an issue][issues] or
@@ -35,19 +35,13 @@ module Bashly
35
35
  end
36
36
  end
37
37
 
38
- def assert_hash(key, value, keys: nil, of: nil)
38
+ def assert_hash(key, value, keys: nil)
39
39
  assert value.is_a?(Hash), "#{key} must be a hash"
40
40
 
41
- if keys
42
- invalid_keys = value.keys.map(&:to_sym) - keys
43
- assert invalid_keys.empty?, "#{key} contains invalid options: #{invalid_keys.join ', '}"
44
- end
45
-
46
- return unless of
41
+ return unless keys
47
42
 
48
- value.each do |k, v|
49
- send "assert_#{of}".to_sym, "#{key}.#{k}", v
50
- end
43
+ invalid_keys = value.keys.map(&:to_sym) - keys
44
+ assert invalid_keys.empty?, "#{key} contains invalid options: #{invalid_keys.join ', '}"
51
45
  end
52
46
 
53
47
  def assert_uniq(key, value, array_keys)
@@ -50,13 +50,30 @@ module Bashly
50
50
  when Array
51
51
  assert_array key, value, of: :string
52
52
  when Hash
53
- assert_hash key, value, of: :string
53
+ assert_dependencies_hash key, value
54
54
  else
55
55
  assert [Array, Hash].include?(value.class),
56
56
  "#{key} must be an array or a hash"
57
57
  end
58
58
  end
59
59
 
60
+ def assert_dependencies_hash(key, value)
61
+ value.each do |k, v|
62
+ assert_dependency "#{key}.#{k}", v
63
+ end
64
+ end
65
+
66
+ def assert_dependency(key, value)
67
+ assert [String, Hash, NilClass].include?(value.class),
68
+ "#{key} must be a string, a hash or nil"
69
+
70
+ return unless value.is_a? Hash
71
+
72
+ assert_hash key, value, keys: Script::Dependency.option_keys
73
+ assert_string_or_array "#{key}.command", value['command']
74
+ assert_optional_string "#{key}.help", value['help']
75
+ end
76
+
60
77
  def assert_extensible(key, value)
61
78
  return unless value
62
79
 
@@ -157,6 +174,11 @@ module Bashly
157
174
  assert_extensible "#{key}.extensible", value['extensible']
158
175
  assert_dependencies "#{key}.dependencies", value['dependencies']
159
176
 
177
+ assert value['name'].match(/^[a-z0-9_\-.]+$/),
178
+ "#{key}.name must only contain lowercase alphanumeric characters, hyphens, dots and underscores"
179
+
180
+ refute value['name'].start_with?('-'), "#{key}.name must not start with a hyphen"
181
+
160
182
  assert_array "#{key}.args", value['args'], of: :arg
161
183
  assert_array "#{key}.flags", value['flags'], of: :flag
162
184
  assert_array "#{key}.commands", value['commands'], of: :command
@@ -113,10 +113,18 @@ command.dependencies:
113
113
  - docker
114
114
  - curl
115
115
 
116
- # Hash syntax, to provide additional help message
116
+ # Simple hash syntax, to provide additional (optional) help message
117
117
  dependencies:
118
118
  docker: see https://docker.com for installation instructions
119
119
  git: "install by running: sudo apt install git"
120
+ ruby:
121
+
122
+ # Explicit hash syntax, to provide additional help message and
123
+ # look for "one of" a given list of dependencies
124
+ dependencies:
125
+ http_client:
126
+ command: [curl, wget]
127
+ help: Run 'sudo apt install curl' or 'sudo apt install wget'
120
128
 
121
129
  command.environment_variables:
122
130
  help: Define a list of environment variables. See `environment_variable` for reference.
@@ -12,16 +12,20 @@
12
12
  # The path containing the bashly source files
13
13
  source_dir: src
14
14
 
15
- # Tha path to bashly.yml
15
+ # The path to bashly.yml
16
16
  config_path: "%{source_dir}/bashly.yml"
17
17
 
18
18
  # The path to use for creating the bash script
19
19
  target_dir: .
20
20
 
21
- # The path to use for upgrading library files, relative to the source dir
21
+ # The path to use for common library files, relative to the source dir
22
22
  lib_dir: lib
23
23
 
24
- # When true, enable bash strict mode (set -euo pipefail)
24
+ # Configure the bash options that will be added to the initialize function:
25
+ # strict: true Bash strict mode (set -euo pipefail)
26
+ # strict: false Only exit on errors (set -e)
27
+ # strict: '' Do not add any 'set' directive
28
+ # strict: <string> Add any other custom 'set' directive
25
29
  strict: false
26
30
 
27
31
  # When true, the generated script will use tab indentation instead of spaces
@@ -33,11 +37,11 @@ tab_indent: false
33
37
  compact_short_flags: true
34
38
 
35
39
  # Set to 'production' or 'development':
36
- # - production generate a smaller script, without file markers
37
- # - development generate with file markers
40
+ # env: production Generate a smaller script, without file markers
41
+ # env: development Generate with file markers
38
42
  env: development
39
43
 
40
- # The extension to use when reading/writing partial script snippets.
44
+ # The extension to use when reading/writing partial script snippets
41
45
  partials_extension: sh
42
46
 
43
47
  # Display various usage elements in color by providing the name of the color
@@ -53,6 +53,7 @@ module Bashly
53
53
  help.empty? ? full_name : "#{full_name} - #{summary}"
54
54
  end
55
55
 
56
+ # Returns an object representing the catch_all configuration
56
57
  def catch_all
57
58
  @catch_all ||= CatchAll.from_config options['catch_all']
58
59
  end
@@ -133,7 +134,16 @@ module Bashly
133
134
  flags.select(&:default)
134
135
  end
135
136
 
136
- # Returns an array of EnvironmentVariables
137
+ # Returns an array of Dependency objects
138
+ def dependencies
139
+ return [] unless options['dependencies']
140
+
141
+ @dependencies ||= options['dependencies'].map do |key, value|
142
+ Dependency.from_config key, value
143
+ end
144
+ end
145
+
146
+ # Returns an array of EnvironmentVariable objects
137
147
  def environment_variables
138
148
  return [] unless options['environment_variables']
139
149
 
@@ -0,0 +1,42 @@
1
+ module Bashly
2
+ module Script
3
+ class Dependency
4
+ attr_reader :label, :commands, :help
5
+
6
+ class << self
7
+ def option_keys
8
+ @option_keys ||= %i[command help]
9
+ end
10
+
11
+ def from_config(key, value)
12
+ options = case value
13
+ when nil
14
+ { label: key, commands: key }
15
+ when String
16
+ { label: key, commands: key, help: value }
17
+ when Hash
18
+ { label: key, commands: value['command'], help: value['help'] }
19
+ else
20
+ {}
21
+ end
22
+
23
+ new(**options)
24
+ end
25
+ end
26
+
27
+ def initialize(label: nil, commands: nil, help: nil)
28
+ @label = label
29
+ @commands = commands.is_a?(String) ? [commands] : commands
30
+ @help = help&.empty? ? nil : help
31
+ end
32
+
33
+ def multi?
34
+ @multi ||= commands.size > 1
35
+ end
36
+
37
+ def name
38
+ @name ||= multi? ? "#{label} (#{commands.join '/'})" : label
39
+ end
40
+ end
41
+ end
42
+ end
@@ -55,6 +55,16 @@ module Bashly
55
55
  @strict ||= get :strict
56
56
  end
57
57
 
58
+ def strict_string
59
+ if Settings.strict.is_a? String
60
+ Settings.strict
61
+ elsif Settings.strict
62
+ 'set -euo pipefail'
63
+ else
64
+ 'set -e'
65
+ end
66
+ end
67
+
58
68
  def tab_indent
59
69
  @tab_indent ||= get :tab_indent
60
70
  end
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.0.0.rc1'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -1,11 +1,13 @@
1
1
  if dependencies
2
2
  = view_marker
3
3
 
4
- dependencies.each do |dependency, message|
5
- > if ! command -v {{ dependency }} >/dev/null 2>&1; then
6
- > printf "{{ strings[:missing_dependency] % { dependency: dependency } }}\n" >&2
7
- if message and !message.empty?
8
- > printf "%s\n" "{{ message }}" >&2
4
+ dependencies.each do |dependency|
5
+ > if command -v {{ dependency.commands.join(' ') }} >/dev/null 2>&1; then
6
+ > deps['{{ dependency.label }}']="$(command -v {{ dependency.commands.join(' ') }} | head -n1)"
7
+ > else
8
+ > printf "{{ strings[:missing_dependency] % { dependency: dependency.name } }}\n" >&2
9
+ if dependency.help
10
+ > printf "%s\n" "{{ dependency.help }}" >&2
9
11
  end
10
12
  > exit 1
11
13
  > fi
@@ -3,7 +3,7 @@
3
3
  > initialize() {
4
4
  > version="<%= version %>"
5
5
  > long_usage=''
6
- > {{ Settings.strict ? "set -euo pipefail" : "set -e" }}
6
+ > {{ Settings.strict_string }}
7
7
  >
8
8
 
9
9
  if root_command?
@@ -1,8 +1,8 @@
1
1
  = view_marker
2
2
 
3
3
  > inspect_args() {
4
- > readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
5
4
  > if ((${#args[@]})); then
5
+ > readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort)
6
6
  > echo args:
7
7
  > for k in "${sorted_keys[@]}"; do echo "- \${args[$k]} = ${args[$k]}"; done
8
8
  > else
@@ -17,5 +17,13 @@
17
17
  > echo "- \${other_args[$i]} = ${other_args[$i]}"
18
18
  > done
19
19
  > fi
20
+ >
21
+ > if ((${#deps[@]})); then
22
+ > readarray -t sorted_keys < <(printf '%s\n' "${!deps[@]}" | sort)
23
+ > echo
24
+ > echo deps:
25
+ > for k in "${sorted_keys[@]}"; do echo "- \${deps[$k]} = ${deps[$k]}"; done
26
+ > fi
27
+ >
20
28
  > }
21
29
  >
@@ -2,6 +2,7 @@
2
2
 
3
3
  > run() {
4
4
  > declare -A args=()
5
+ > declare -A deps=()
5
6
  > declare -a other_args=()
6
7
  > declare -a input=()
7
8
  > normalize_input "$@"
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.0.0.rc1
4
+ version: 1.0.1
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-02-12 00:00:00.000000000 Z
11
+ date: 2023-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -174,6 +174,7 @@ files:
174
174
  - lib/bashly/script/base.rb
175
175
  - lib/bashly/script/catch_all.rb
176
176
  - lib/bashly/script/command.rb
177
+ - lib/bashly/script/dependency.rb
177
178
  - lib/bashly/script/environment_variable.rb
178
179
  - lib/bashly/script/flag.rb
179
180
  - lib/bashly/script/wrapper.rb
@@ -254,11 +255,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
254
255
  version: 2.7.0
255
256
  required_rubygems_version: !ruby/object:Gem::Requirement
256
257
  requirements:
257
- - - ">"
258
+ - - ">="
258
259
  - !ruby/object:Gem::Version
259
- version: 1.3.1
260
+ version: '0'
260
261
  requirements: []
261
- rubygems_version: 3.4.6
262
+ rubygems_version: 3.4.7
262
263
  signing_key:
263
264
  specification_version: 4
264
265
  summary: Bash Command Line Tool Generator