bashly 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7382bd9a007cc8e3c9b4451e7f3fdbccd62bf740f66cc76f24b03c0e6ef1abdd
4
- data.tar.gz: 32b2ee626d40efd3f60bab256b08e486b2322b3ef4d429c1de090f0d849f5982
3
+ metadata.gz: e17bc036331958bd9ff237d93e287c911bc00c85b33628a4b867dd2e69c818fe
4
+ data.tar.gz: 236e3ba5f96e9f89fce4b77d95adf68a3030ef31d3d59a857ad0477aa871b171
5
5
  SHA512:
6
- metadata.gz: 947f2accba281a365338b86580fe9113ca0a4e5286fa206ee3d11e3816514113f9af80417298b24101c63b8fc84cd95fbca4d6d6abf2be32d95c2a122f092050
7
- data.tar.gz: b70e60017a58d0107e44388dfdf228d3089b39d9e1bb3f650c6b4565905b08604f1a400ed4cb4648cc91846298e8e5320d54f45064f5ecc36dfaacb9e609d8bc
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,8 +174,8 @@ module Bashly
157
174
  assert_extensible "#{key}.extensible", value['extensible']
158
175
  assert_dependencies "#{key}.dependencies", value['dependencies']
159
176
 
160
- assert value['name'].match(/^[a-z0-9_-]+$/),
161
- "#{key}.name must only contain lowercase alphanumeric characters, hyphens and underscores"
177
+ assert value['name'].match(/^[a-z0-9_\-.]+$/),
178
+ "#{key}.name must only contain lowercase alphanumeric characters, hyphens, dots and underscores"
162
179
 
163
180
  refute value['name'].start_with?('-'), "#{key}.name must not start with a hyphen"
164
181
 
@@ -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'
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
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-16 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
@@ -258,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
259
  - !ruby/object:Gem::Version
259
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