bashly 1.1.6 → 1.1.8

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: 412b8737b7f30c9851116b020bafbb220bb001fcf148d4baf3bc383a32ad3e0d
4
- data.tar.gz: 0b4595b01191d2899f50ab7d74f6f7f9d0ec4901f17daebf57304d197b8e8ccd
3
+ metadata.gz: d11d229ff42dc84aa910ee8292e145b63641c5520315583e92d5aa0747e6e578
4
+ data.tar.gz: 61a2ddcb970af41f7a086da0a75d0452a637e3fe650569e2768f1a0eefe49849
5
5
  SHA512:
6
- metadata.gz: 9af37fd9a1a5883e8c05ff88d3fd1de2b0689586e9717072b17e15dcb55a9c8f228e963e2131aa8828a1fd1d12a51c8373bdf28f650f8e13369dcf84bec3a68a
7
- data.tar.gz: 51a9db127eb74ebbe7e3d55aa8fb6e7f17479c587e632061d62330503103dbed7ca7c405f01d3090036459aaf5a529960156c66d6248849f936aff5be0bcd6d7
6
+ metadata.gz: b9ffdaa7a7a862b11d932e6533d4b7e1b1e76407292bbaf5ca8afdc192249b0f51ea504adfc459e37b712074291ef612fc5b29965700043676bc94709062e696
7
+ data.tar.gz: 629b81b7ef43fa64523a465968828d74192fbd17440e9f20f724a6ef040ebe0c805bed339f899ca6047f53043c29d88537829075bd60be2f752a69e09eaaee55
data/README.md CHANGED
@@ -27,15 +27,6 @@ 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
- <table>
33
- <tr>
34
- <td><a href="https://rhodecode.com/"><img src='support/img/RhodeCode-logo.png' width=240></a></td>
35
- </tr>
36
- </table>
37
-
38
-
39
30
  ## Documentation
40
31
 
41
32
  - [Bashly Homepage][docs]
@@ -0,0 +1,45 @@
1
+ module Bashly
2
+ # A helper class, used by the `Array#indent` extension.
3
+ # It will return the array of strings with all strings prefixed by `indentation`
4
+ # unless the line is within a heredoc block.
5
+ class IndentationHelper
6
+ attr_reader :marker, :indentation
7
+
8
+ def initialize(indentation)
9
+ @indentation = indentation
10
+ @marker = nil
11
+ end
12
+
13
+ def indent(line)
14
+ if inside_heredoc?
15
+ reset_marker if heredoc_closed?(line)
16
+ line
17
+ else
18
+ set_heredoc_state(line)
19
+ "#{indentation}#{line}"
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def reset_marker
26
+ @marker = nil
27
+ end
28
+
29
+ def inside_heredoc?
30
+ !!marker
31
+ end
32
+
33
+ def set_heredoc_state(line)
34
+ @marker = extract_heredoc_marker(line)
35
+ end
36
+
37
+ def extract_heredoc_marker(line)
38
+ line =~ /<<-?\s*(\w+)/ ? $1 : nil
39
+ end
40
+
41
+ def heredoc_closed?(line)
42
+ inside_heredoc? && /^#{marker}\n?$/.match?(line)
43
+ end
44
+ end
45
+ end
@@ -1,9 +1,13 @@
1
+ require 'bashly/concerns/indentation_helper'
2
+
1
3
  class Array
2
4
  def indent(offset)
3
5
  return self unless offset.positive?
4
6
 
5
7
  indentation = ' ' * offset
6
- map { |line| "#{indentation}#{line}" }
8
+ indenter = Bashly::IndentationHelper.new indentation
9
+
10
+ map { |line| indenter.indent line }
7
11
  end
8
12
 
9
13
  def nonuniq
@@ -1,7 +1,10 @@
1
- # approvals.bash v0.4.0
1
+ # approvals.bash v0.5.0
2
2
  #
3
3
  # Interactive approval testing for Bash.
4
4
  # https://github.com/DannyBen/approvals.bash
5
+ #
6
+ # shellcheck disable=SC2059
7
+ # Disabling SC2059 (quoted format string) because we use dynamic format strings
5
8
  approve() {
6
9
  local expected approval approval_file actual cmd
7
10
  approvals_dir=${APPROVALS_DIR:=approvals}
@@ -9,8 +12,8 @@ approve() {
9
12
  cmd=$1
10
13
  last_exit_code=0
11
14
  actual=$(eval "$cmd" 2>&1) || last_exit_code=$?
12
- if [[ "$allow_diff_regex" ]]; then
13
- actual=$(echo "$actual" | sed "s/$allow_diff_regex/*/g")
15
+ if [[ -v allow_diff_regex && "$allow_diff_regex" ]]; then
16
+ actual=$(echo "$actual" | sed -E "s/$allow_diff_regex/*/g")
14
17
  unset allow_diff_regex
15
18
  fi
16
19
  approval=$(printf "%b" "$cmd" | tr -s -c "[:alnum:]" _)
@@ -21,9 +24,9 @@ approve() {
21
24
  if [[ -f "$approval_file" ]]; then
22
25
  expected=$(cat "$approval_file")
23
26
  else
24
- echo "--- [$(blue "new: $cmd")] ---"
27
+ printf -- "$new_diff_string\n" "$cmd"
25
28
  printf "%b\n" "$actual"
26
- echo "--- [$(blue "new: $cmd")] ---"
29
+ printf -- "$new_diff_string\n" "$cmd"
27
30
  expected="$actual"
28
31
  user_approval "$cmd" "$actual" "$approval_file"
29
32
  return
@@ -32,9 +35,9 @@ approve() {
32
35
  if [[ "$(printf "%b" "$actual")" = "$(printf "%b" "$expected")" ]]; then
33
36
  pass "$cmd"
34
37
  else
35
- echo "--- [$(blue "diff: $cmd")] ---"
38
+ printf -- "$changed_diff_string\n" "$cmd"
36
39
  $diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n") | tail -n +4
37
- echo "--- [$(blue "diff: $cmd")] ---"
40
+ printf -- "$changed_diff_string\n" "$cmd"
38
41
  user_approval "$cmd" "$actual" "$approval_file"
39
42
  fi
40
43
  }
@@ -44,22 +47,20 @@ allow_diff() {
44
47
  }
45
48
 
46
49
  describe() {
47
- echo
48
- blue "= $*"
50
+ printf "$describe_string\n" "$*"
49
51
  }
50
52
 
51
53
  context() {
52
- echo
53
- magenta "= $*"
54
+ printf "$context_string\n" "$*"
54
55
  }
55
56
 
56
57
  fail() {
57
- red " FAILED: $*"
58
+ printf "$fail_string\n" "$*"
58
59
  exit 1
59
60
  }
60
61
 
61
62
  pass() {
62
- green " approved: $*"
63
+ printf "$pass_string\n" "$*"
63
64
  return 0
64
65
  }
65
66
 
@@ -67,15 +68,17 @@ expect_exit_code() {
67
68
  if [[ $last_exit_code == "$1" ]]; then
68
69
  pass "exit $last_exit_code"
69
70
  else
70
- fail "Expected exit code $1, got $last_exit_code"
71
+ fail "expected exit code $1, got $last_exit_code"
71
72
  fi
72
73
  }
73
74
 
74
- red() { printf "\e[31m%b\e[0m\n" "$*"; }
75
- green() { printf "\e[32m%b\e[0m\n" "$*"; }
75
+ bold() { printf "\e[1m%b\e[0m\n" "$*"; }
76
76
  blue() { printf "\e[34m%b\e[0m\n" "$*"; }
77
- magenta() { printf "\e[35m%b\e[0m\n" "$*"; }
78
77
  cyan() { printf "\e[36m%b\e[0m\n" "$*"; }
78
+ green() { printf "\e[32m%b\e[0m\n" "$*"; }
79
+ magenta() { printf "\e[35m%b\e[0m\n" "$*"; }
80
+ red() { printf "\e[31m%b\e[0m\n" "$*"; }
81
+ yellow() { printf "\e[33m%b\e[0m\n" "$*"; }
79
82
 
80
83
  # Private
81
84
 
@@ -89,9 +92,9 @@ user_approval() {
89
92
  fi
90
93
 
91
94
  echo
92
- printf "[A]pprove? \n"
95
+ printf "$approval_string"
93
96
  response=$(bash -c "read -n 1 key; echo \$key")
94
- printf "\r"
97
+ printf "\b%.s" $(seq 1 $((${#approval_string} + 1)))
95
98
  if [[ $response =~ [Aa] ]]; then
96
99
  printf "%b\n" "$actual" >"$approval_file"
97
100
  pass "$cmd"
@@ -103,21 +106,32 @@ user_approval() {
103
106
  onexit() {
104
107
  exitcode=$?
105
108
  if [[ "$exitcode" == 0 ]]; then
106
- green "\nFinished successfully"
109
+ printf "$exit_success_string\n" "$0"
107
110
  else
108
- red "\nFinished with failures"
111
+ printf "$exit_failed_string\n" "$0"
109
112
  fi
113
+ echo
110
114
  exit $exitcode
111
115
  }
112
116
 
113
117
  onerror() {
114
- fail "Caller: $(caller)"
118
+ fail "caller: $(caller)"
115
119
  }
116
120
 
117
121
  set -e
118
122
  trap 'onexit' EXIT
119
123
  trap 'onerror' ERR
120
124
 
125
+ describe_string="$(blue ▌ describe) %s"
126
+ context_string="$(magenta ▌ context) %s"
127
+ fail_string=" $(red FAILED) %s"
128
+ pass_string=" $(green approved) %s"
129
+ exit_success_string="$(green ▌ exit) $(bold %s finished successfully)"
130
+ exit_failed_string="$(red ▌ exit) $(bold %s finished with errors)"
131
+ new_diff_string="────┤ $(yellow new): $(bold %s)) ├────"
132
+ changed_diff_string="────┤ $(cyan changed): $(bold %s)) ├────"
133
+ approval_string="[A]pprove? "
134
+
121
135
  if diff --help | grep -- --color >/dev/null 2>&1; then
122
136
  diff_cmd="diff --unified --color=always"
123
137
  else
@@ -1,41 +1,43 @@
1
- module ComposeRefinements
2
- refine Hash do
3
- def compose(keyword = 'import')
4
- result = {}
5
- each do |k, v|
6
- if k.to_s == keyword
7
- sub = safe_load_yaml(v).compose keyword
8
- if sub.is_a? Array
9
- result = sub
1
+ module Bashly
2
+ module ComposeRefinements
3
+ refine Hash do
4
+ def compose(keyword = 'import')
5
+ result = {}
6
+ each do |k, v|
7
+ if k.to_s == keyword
8
+ sub = safe_load_yaml(v).compose keyword
9
+ if sub.is_a? Array
10
+ result = sub
11
+ else
12
+ result.merge! sub
13
+ end
14
+ elsif v.respond_to? :compose
15
+ result[k] = v.compose keyword
10
16
  else
11
- result.merge! sub
17
+ result[k] = v
12
18
  end
13
- elsif v.respond_to? :compose
14
- result[k] = v.compose keyword
15
- else
16
- result[k] = v
17
19
  end
20
+ result
18
21
  end
19
- result
20
- end
21
22
 
22
- def safe_load_yaml(path)
23
- loaded = YAML.load_erb_file path
24
- return loaded if loaded.is_a?(Array) || loaded.is_a?(Hash)
23
+ def safe_load_yaml(path)
24
+ loaded = YAML.load_erb_file path
25
+ return loaded if loaded.is_a?(Array) || loaded.is_a?(Hash)
25
26
 
26
- raise Bashly::ConfigurationError, "Cannot find a valid YAML in g`#{path}`"
27
- rescue Errno::ENOENT
28
- raise Bashly::ConfigurationError, "Cannot find import file g`#{path}`"
27
+ raise Bashly::ConfigurationError, "Cannot find a valid YAML in g`#{path}`"
28
+ rescue Errno::ENOENT
29
+ raise Bashly::ConfigurationError, "Cannot find import file g`#{path}`"
30
+ end
29
31
  end
30
- end
31
32
 
32
- refine Array do
33
- def compose(keyword = 'import')
34
- map do |x|
35
- if x.respond_to? :compose
36
- x.compose keyword
37
- else
38
- x
33
+ refine Array do
34
+ def compose(keyword = 'import')
35
+ map do |x|
36
+ if x.respond_to? :compose
37
+ x.compose keyword
38
+ else
39
+ x
40
+ end
39
41
  end
40
42
  end
41
43
  end
@@ -322,12 +322,17 @@ module Bashly
322
322
  @user_lib ||= Dir["#{Settings.full_lib_dir}/**/*.#{Settings.partials_extension}"]
323
323
  end
324
324
 
325
+ # Returns a mixed array of Argument and Flag objects that have validations
326
+ def validatables
327
+ @validatables ||= args.select(&:validate) + flags.select(&:validate)
328
+ end
329
+
325
330
  # Returns an array of all the args with a whitelist
326
331
  def whitelisted_args
327
332
  args.select(&:allowed)
328
333
  end
329
334
 
330
- # Returns an array of all the environemnt_variables with a whitelist arg
335
+ # Returns an array of all the environment_variables with a whitelist arg
331
336
  def whitelisted_environment_variables
332
337
  environment_variables.select(&:allowed)
333
338
  end
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.1.6'
2
+ VERSION = '1.1.8'
3
3
  end
@@ -1,4 +1,4 @@
1
- # View Tempaltes
1
+ # View Templates
2
2
 
3
3
  These are [GTX](https://github.com/dannyben/gtx) templates.
4
4
 
@@ -1,11 +1,22 @@
1
1
  if validate
2
+ = view_marker
2
3
 
3
- = view_marker
4
-
5
- > if [[ -n $(validate_{{ validate }} "$1") ]]; then
6
- > printf "{{ strings[:validation_error] }}\n" "{{ name.upcase }}" "$(validate_{{ validate }} "$1")" >&2
7
- > exit 1
8
- > fi
9
- >
4
+ if repeatable
5
+ > if [[ -v args['{{ name }}'] ]]; then
6
+ > eval "values=(${args['{{ name }}']})"
7
+ > for value in "${values[@]}"; do
8
+ > if [[ -n $(validate_{{ validate }} "$value") ]]; then
9
+ > printf "{{ strings[:validation_error] }}\n" "{{ name.upcase }}" "$(validate_{{ validate }} "$value")" >&2
10
+ > exit 1
11
+ > fi
12
+ > done
13
+ > fi
14
+ else
15
+ > if [[ -v args['{{ name }}'] && -n $(validate_{{ validate }} "${args['{{ name }}']:-}") ]]; then
16
+ > printf "{{ strings[:validation_error] }}\n" "{{ name.upcase }}" "$(validate_{{ validate }} "${args['{{ name }}']:-}")" >&2
17
+ > exit 1
18
+ > fi
19
+ >
20
+ end
10
21
 
11
22
  end
@@ -27,3 +27,4 @@ end
27
27
  > shift
28
28
  > done
29
29
  > }
30
+ >
@@ -15,6 +15,7 @@ end
15
15
  = render(:required_flags_filter).indent 2
16
16
  = render(:catch_all_filter).indent 2
17
17
  = render(:default_assignments).indent 2
18
+ = render(:validations).indent 2
18
19
  = render(:whitelist_filter).indent 2
19
20
  = render(:user_filter).indent 2
20
21
 
@@ -4,7 +4,6 @@ if args.any?
4
4
  condition = "if"
5
5
  args.each do |arg|
6
6
  > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
7
- = arg.render(:validations).indent 2
8
7
  > args['{{ arg.name }}']=$1
9
8
  > shift
10
9
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  condition = "if"
4
4
  args.each do |arg|
5
- = arg.render(:validations)
6
5
  > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
7
6
  if arg.repeatable
8
7
  > args['{{ arg.name }}']="\"$1\""
@@ -4,7 +4,6 @@ if args.any?
4
4
  condition = "if"
5
5
  args.each do |arg|
6
6
  > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
7
- > {{ arg.render(:validations).indent 2 }}
8
7
  > args['{{ arg.name }}']=$1
9
8
  > shift
10
9
 
@@ -0,0 +1,7 @@
1
+ if validatables.any?
2
+ = view_marker
3
+
4
+ validatables.each do |arg_or_flag|
5
+ = arg_or_flag.render(:validations)
6
+ end
7
+ end
@@ -1,7 +1,6 @@
1
1
  = view_marker
2
2
 
3
3
  > if [[ -n ${2+x} ]]; then
4
- = render(:validations).indent 2
5
4
 
6
5
  if repeatable
7
6
  > if [[ -z ${args['{{ name }}']+x} ]]; then
@@ -1,11 +1,22 @@
1
1
  if validate
2
-
3
2
  = view_marker
4
3
 
5
- > if [[ -n $(validate_{{ validate }} "$2") ]]; then
6
- > printf "{{ strings[:validation_error] }}\n" "{{ usage_string }}" "$(validate_{{ validate }} "$2")" >&2
7
- > exit 1
8
- > fi
9
- >
4
+ if repeatable
5
+ > if [[ -v args['{{ long }}'] ]]; then
6
+ > eval "values=(${args['{{ long }}']})"
7
+ > for value in "${values[@]}"; do
8
+ > if [[ -n $(validate_{{ validate }} "$value") ]]; then
9
+ > printf "{{ strings[:validation_error] }}\n" "{{ usage_string }}" "$(validate_{{ validate }} "$value")" >&2
10
+ > exit 1
11
+ > fi
12
+ > done
13
+ > fi
14
+ else
15
+ > if [[ -v args['{{ long }}'] && -n $(validate_{{ validate }} "${args['{{ long }}']:-}") ]]; then
16
+ > printf "{{ strings[:validation_error] }}\n" "{{ usage_string }}" "$(validate_{{ validate }} "${args['{{ long }}']:-}")" >&2
17
+ > exit 1
18
+ > fi
19
+ >
20
+ end
10
21
 
11
22
  end
data/lib/bashly.rb CHANGED
@@ -1,5 +1,5 @@
1
- if ENV['BYEBUG']
2
- require 'byebug'
1
+ if ENV['DEBUGGER']
2
+ require 'debug'
3
3
  require 'lp'
4
4
  end
5
5
 
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.6
4
+ version: 1.1.8
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-12-29 00:00:00.000000000 Z
11
+ date: 2024-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -161,6 +161,7 @@ files:
161
161
  - lib/bashly/completions/completely.yaml.gtx
162
162
  - lib/bashly/concerns/asset_helper.rb
163
163
  - lib/bashly/concerns/completions.rb
164
+ - lib/bashly/concerns/indentation_helper.rb
164
165
  - lib/bashly/concerns/renderable.rb
165
166
  - lib/bashly/concerns/validation_helpers.rb
166
167
  - lib/bashly/config.rb
@@ -265,6 +266,7 @@ files:
265
266
  - lib/bashly/views/command/user_filter.gtx
266
267
  - lib/bashly/views/command/user_hooks.gtx
267
268
  - lib/bashly/views/command/user_lib.gtx
269
+ - lib/bashly/views/command/validations.gtx
268
270
  - lib/bashly/views/command/version_command.gtx
269
271
  - lib/bashly/views/command/whitelist_filter.gtx
270
272
  - lib/bashly/views/environment_variable/usage.gtx
@@ -301,7 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
303
  - !ruby/object:Gem::Version
302
304
  version: '0'
303
305
  requirements: []
304
- rubygems_version: 3.3.26
306
+ rubygems_version: 3.5.6
305
307
  signing_key:
306
308
  specification_version: 4
307
309
  summary: Bash Command Line Tool Generator