bashly 1.1.8 → 1.1.9

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: d11d229ff42dc84aa910ee8292e145b63641c5520315583e92d5aa0747e6e578
4
- data.tar.gz: 61a2ddcb970af41f7a086da0a75d0452a637e3fe650569e2768f1a0eefe49849
3
+ metadata.gz: 57e204b6791653f135c34bdf18a2b882d180087bbec57044db09540e342d81f0
4
+ data.tar.gz: ef1bc1015e325d227b3bc32d537a51fc369ea7833972f6f9a15e592d79ddc131
5
5
  SHA512:
6
- metadata.gz: b9ffdaa7a7a862b11d932e6533d4b7e1b1e76407292bbaf5ca8afdc192249b0f51ea504adfc459e37b712074291ef612fc5b29965700043676bc94709062e696
7
- data.tar.gz: 629b81b7ef43fa64523a465968828d74192fbd17440e9f20f724a6ef040ebe0c805bed339f899ca6047f53043c29d88537829075bd60be2f752a69e09eaaee55
6
+ metadata.gz: 4947a104aa165d0e216a53a07908b72c290ff8e905e96acde044025bccefbab783ed5c87f3c217b674bdfb57db21c5d149827a9d8383065fef78eaac701826c0
7
+ data.tar.gz: 99eb5313b587980c540f22596cc8e99794cf7ed24cb0f62e06c4179a64399e80099c6cbc7d2803fe96827cdbf5734bbb9fc7364533979da45cd44973d0511748
@@ -2,7 +2,10 @@ require 'gtx'
2
2
 
3
3
  module Bashly
4
4
  module Renderable
5
- def render(view)
5
+ attr_reader :render_options
6
+
7
+ def render(view, render_options = {})
8
+ @render_options = render_options
6
9
  GTX.render_file view_path(view), context: binding, filename: "#{views_subfolder}.#{view}"
7
10
  end
8
11
 
@@ -1,4 +1,4 @@
1
- # approvals.bash v0.5.0
1
+ # approvals.bash v0.5.1
2
2
  #
3
3
  # Interactive approval testing for Bash.
4
4
  # https://github.com/DannyBen/approvals.bash
@@ -54,6 +54,10 @@ context() {
54
54
  printf "$context_string\n" "$*"
55
55
  }
56
56
 
57
+ it() {
58
+ printf "$it_string\n" "$*"
59
+ }
60
+
57
61
  fail() {
58
62
  printf "$fail_string\n" "$*"
59
63
  exit 1
@@ -72,29 +76,57 @@ expect_exit_code() {
72
76
  fi
73
77
  }
74
78
 
75
- bold() { printf "\e[1m%b\e[0m\n" "$*"; }
76
- blue() { printf "\e[34m%b\e[0m\n" "$*"; }
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" "$*"; }
82
-
83
79
  # Private
84
80
 
81
+ print_in_color() {
82
+ local color="$1"
83
+ shift
84
+ if [[ -z ${NO_COLOR+x} ]]; then
85
+ printf "$color%b\e[0m\n" "$*"
86
+ else
87
+ printf "%b\n" "$*"
88
+ fi
89
+ }
90
+
91
+ red() { print_in_color "\e[31m" "$*"; }
92
+ green() { print_in_color "\e[32m" "$*"; }
93
+ yellow() { print_in_color "\e[33m" "$*"; }
94
+ blue() { print_in_color "\e[34m" "$*"; }
95
+ magenta() { print_in_color "\e[35m" "$*"; }
96
+ cyan() { print_in_color "\e[36m" "$*"; }
97
+ bold() { print_in_color "\e[1m" "$*"; }
98
+ underlined() { print_in_color "\e[4m" "$*"; }
99
+ red_bold() { print_in_color "\e[1;31m" "$*"; }
100
+ green_bold() { print_in_color "\e[1;32m" "$*"; }
101
+ yellow_bold() { print_in_color "\e[1;33m" "$*"; }
102
+ blue_bold() { print_in_color "\e[1;34m" "$*"; }
103
+ magenta_bold() { print_in_color "\e[1;35m" "$*"; }
104
+ cyan_bold() { print_in_color "\e[1;36m" "$*"; }
105
+ red_underlined() { print_in_color "\e[4;31m" "$*"; }
106
+ green_underlined() { print_in_color "\e[4;32m" "$*"; }
107
+ yellow_underlined() { print_in_color "\e[4;33m" "$*"; }
108
+ blue_underlined() { print_in_color "\e[4;34m" "$*"; }
109
+ magenta_underlined() { print_in_color "\e[4;35m" "$*"; }
110
+ cyan_underlined() { print_in_color "\e[4;36m" "$*"; }
111
+
85
112
  user_approval() {
86
113
  local cmd="$1"
87
114
  local actual="$2"
88
115
  local approval_file="$3"
89
116
 
90
- if [[ -v CI || -v GITHUB_ACTIONS ]]; then
117
+ if [[ -v CI || -v GITHUB_ACTIONS ]] && [[ -z "${AUTO_APPROVE+x}" ]]; then
91
118
  fail "$cmd"
92
119
  fi
93
120
 
94
- echo
95
- printf "$approval_string"
96
- response=$(bash -c "read -n 1 key; echo \$key")
97
- printf "\b%.s" $(seq 1 $((${#approval_string} + 1)))
121
+ if [[ -v AUTO_APPROVE ]]; then
122
+ response=a
123
+ else
124
+ echo
125
+ printf "$approval_string"
126
+ response=$(bash -c "read -n 1 key; echo \$key")
127
+ printf "\b%.s" $(seq 1 $((${#approval_string} + 1)))
128
+ fi
129
+
98
130
  if [[ $response =~ [Aa] ]]; then
99
131
  printf "%b\n" "$actual" >"$approval_file"
100
132
  pass "$cmd"
@@ -122,14 +154,15 @@ set -e
122
154
  trap 'onexit' EXIT
123
155
  trap 'onerror' ERR
124
156
 
125
- describe_string="$(blue ▌ describe) %s"
126
- context_string="$(magenta ▌ context) %s"
127
- fail_string=" $(red FAILED) %s"
157
+ describe_string="$(bold ▌ describe) %s"
158
+ context_string="$(bold ▌ context) %s"
159
+ it_string="$(bold ▌ it) %s"
160
+ fail_string=" $(red_bold failed) %s"
128
161
  pass_string=" $(green approved) %s"
129
162
  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)) ├────"
163
+ exit_failed_string="$(red_bold ▌ exit) $(bold %s finished with errors)"
164
+ new_diff_string="────┤ $(yellow new): $(bold %s) ├────"
165
+ changed_diff_string="────┤ $(blue changed): $(bold %s) ├────"
133
166
  approval_string="[A]pprove? "
134
167
 
135
168
  if diff --help | grep -- --color >/dev/null 2>&1; then
@@ -101,9 +101,10 @@ module Bashly
101
101
  end
102
102
 
103
103
  # Returns a flat array containing all the commands in this tree.
104
- # This includes self + children + grandchildres + ...
105
- def deep_commands
104
+ # This includes children + grandchildren (recursive), and may include self
105
+ def deep_commands(include_self: false)
106
106
  result = []
107
+ result << self if include_self
107
108
  commands.each do |command|
108
109
  result << command
109
110
  if command.commands.any?
@@ -217,6 +218,16 @@ module Bashly
217
218
  result
218
219
  end
219
220
 
221
+ # Returns true if this command, or any subcommand (deep) as any arg or
222
+ # flag with arg that is defined as unique
223
+ def has_unique_args_or_flags?
224
+ deep_commands(include_self: true).each do |command|
225
+ return true if command.args.count(&:unique).positive? ||
226
+ command.flags.count(&:unique).positive?
227
+ end
228
+ false
229
+ end
230
+
220
231
  # Returns a mode identifier
221
232
  def mode
222
233
  @mode ||= if global_flags? then :global_flags
@@ -1,3 +1,3 @@
1
1
  module Bashly
2
- VERSION = '1.1.8'
2
+ VERSION = '1.1.9'
3
3
  end
@@ -0,0 +1,6 @@
1
+ = view_marker
2
+
3
+ condition = render_options[:index].zero? ? 'if' : 'elif'
4
+ > {{ condition }} [[ -z ${args['{{ name }}']+x} ]]; then
5
+ > args['{{ name }}']=$1
6
+ > shift
@@ -0,0 +1,25 @@
1
+ = view_marker
2
+
3
+ condition = render_options[:index].zero? ? 'if' : 'elif'
4
+
5
+ if render_options[:index] == 0
6
+ > escaped="$(printf '%q' "$1")"
7
+ end
8
+
9
+ > {{ condition }} [[ -z ${args['{{ name }}']+x} ]]; then
10
+ if repeatable
11
+ > args['{{ name }}']="$escaped"
12
+ if unique
13
+ > unique_lookup["{{ name }}:$escaped"]=1
14
+ > elif [[ -z "${unique_lookup["{{ name }}:$escaped"]:-}" ]]; then
15
+ > args['{{ name }}']="${args['{{ name }}']} $escaped"
16
+ > unique_lookup["{{ name }}:$escaped"]=1
17
+ else
18
+ > else
19
+ > args['{{ name }}']="${args['{{ name }}']} $escaped"
20
+ end
21
+
22
+ else
23
+ > args['{{ name }}']="$1"
24
+
25
+ end
@@ -1,13 +1,8 @@
1
1
  = view_marker
2
2
 
3
3
  if args.any?
4
- condition = "if"
5
- args.each do |arg|
6
- > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
7
- > args['{{ arg.name }}']=$1
8
- > shift
9
-
10
- condition = "elif"
4
+ args.each_with_index do |arg, index|
5
+ = arg.render :case, index: index
11
6
  end
12
7
 
13
8
  > else
@@ -1,30 +1,9 @@
1
1
  = view_marker
2
2
 
3
- condition = "if"
4
- args.each do |arg|
5
- > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
6
- if arg.repeatable
7
- > args['{{ arg.name }}']="\"$1\""
8
- > shift
9
- if arg.unique
10
- > elif [[ ! "${args['{{ arg.name }}']}" =~ \"$1\" ]]; then
11
- > args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
12
- > shift
13
- > else
14
- > shift
15
- else
16
- > else
17
- > args['{{ arg.name }}']="${args[{{ arg.name }}]} \"$1\""
18
- > shift
19
- end
20
-
21
- else
22
- > args['{{ arg.name }}']=$1
23
- > shift
24
-
25
- end
26
- condition = "elif"
3
+ args.each_with_index do |arg, index|
4
+ = arg.render :case_repeatable, index: index
27
5
  end
28
6
 
29
7
  > fi
30
- >
8
+ > shift
9
+ >
@@ -1,13 +1,8 @@
1
1
  = view_marker
2
2
 
3
3
  if args.any?
4
- condition = "if"
5
- args.each do |arg|
6
- > {{ condition }} [[ -z ${args['{{ arg.name }}']+x} ]]; then
7
- > args['{{ arg.name }}']=$1
8
- > shift
9
-
10
- condition = "elif"
4
+ args.each_with_index do |arg, index|
5
+ = arg.render :case, index: index
11
6
  end
12
7
 
13
8
  > else
@@ -6,6 +6,9 @@
6
6
  > declare -a other_args=()
7
7
  > declare -a env_var_names=()
8
8
  > declare -a input=()
9
+ if has_unique_args_or_flags?
10
+ > declare -A unique_lookup=()
11
+ end
9
12
  > normalize_input "$@"
10
13
  > parse_requirements "${input[@]}"
11
14
  if user_file_exist?('before')
@@ -29,5 +32,3 @@ if user_file_exist?('after')
29
32
  end
30
33
 
31
34
  > }
32
-
33
-
@@ -3,15 +3,19 @@
3
3
  > if [[ -n ${2+x} ]]; then
4
4
 
5
5
  if repeatable
6
+ > escaped="$(printf '%q' "$2")"
6
7
  > if [[ -z ${args['{{ name }}']+x} ]]; then
7
- > args['{{ name }}']="\"$2\""
8
+ > args['{{ name }}']="$escaped"
8
9
  if unique
9
- > elif [[ ! "${args['{{ name }}']}" =~ \"$2\" ]]; then
10
+ > elif [[ -z "${unique_lookup["{{ name }}:${escaped}"]:-}" ]]; then
10
11
  else
11
12
  > else
12
13
  end
13
- > args['{{ name }}']="${args['{{ name }}']} \"$2\""
14
+ > args['{{ name }}']="${args['{{ name }}']} $escaped"
14
15
  > fi
16
+ if unique
17
+ > unique_lookup["{{ name }}:${escaped}"]=1
18
+ end
15
19
 
16
20
  else
17
21
  > args['{{ name }}']="$2"
@@ -25,4 +29,4 @@ end
25
29
  > exit 1
26
30
  > fi
27
31
  > ;;
28
- >
32
+ >
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.8
4
+ version: 1.1.9
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: 2024-03-02 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -226,6 +226,8 @@ files:
226
226
  - lib/bashly/templates/minimal.yml
227
227
  - lib/bashly/version.rb
228
228
  - lib/bashly/views/README.md
229
+ - lib/bashly/views/argument/case.gtx
230
+ - lib/bashly/views/argument/case_repeatable.gtx
229
231
  - lib/bashly/views/argument/usage.gtx
230
232
  - lib/bashly/views/argument/validations.gtx
231
233
  - lib/bashly/views/command/catch_all_filter.gtx