bashly 0.8.10 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -0
- data/bin/bashly +2 -2
- data/lib/bashly/cli.rb +2 -3
- data/lib/bashly/commands/add.rb +74 -50
- data/lib/bashly/commands/base.rb +4 -3
- data/lib/bashly/commands/generate.rb +41 -35
- data/lib/bashly/commands/init.rb +10 -9
- data/lib/bashly/commands/preview.rb +4 -4
- data/lib/bashly/commands/validate.rb +8 -7
- data/lib/bashly/concerns/asset_helper.rb +1 -1
- data/lib/bashly/concerns/completions.rb +24 -15
- data/lib/bashly/concerns/renderable.rb +5 -5
- data/lib/bashly/concerns/validation_helpers.rb +20 -12
- data/lib/bashly/config.rb +1 -1
- data/lib/bashly/config_validator.rb +46 -22
- data/lib/bashly/deprecation.rb +9 -7
- data/lib/bashly/exceptions.rb +1 -1
- data/lib/bashly/extensions/array.rb +4 -4
- data/lib/bashly/extensions/file.rb +3 -3
- data/lib/bashly/extensions/string.rb +6 -6
- data/lib/bashly/libraries/base.rb +11 -1
- data/lib/bashly/libraries/completions_function.rb +9 -10
- data/lib/bashly/libraries/completions_script.rb +7 -8
- data/lib/bashly/libraries/completions_yaml.rb +7 -8
- data/lib/bashly/libraries/help.rb +36 -0
- data/lib/bashly/libraries.yml +3 -1
- data/lib/bashly/library.rb +7 -5
- data/lib/bashly/message_strings.rb +1 -1
- data/lib/bashly/refinements/compose_refinements.rb +2 -2
- data/lib/bashly/script/argument.rb +1 -1
- data/lib/bashly/script/base.rb +3 -2
- data/lib/bashly/script/catch_all.rb +6 -4
- data/lib/bashly/script/command.rb +47 -53
- data/lib/bashly/script/environment_variable.rb +5 -5
- data/lib/bashly/script/flag.rb +7 -7
- data/lib/bashly/script/wrapper.rb +5 -4
- data/lib/bashly/settings.rb +4 -5
- data/lib/bashly/templates/help/help_command.sh +30 -0
- data/lib/bashly/templates/lib/colors.sh +2 -2
- data/lib/bashly/templates/lib/config.sh +10 -10
- data/lib/bashly/templates/lib/yaml.sh +9 -9
- data/lib/bashly/templates/test/approvals.bash +36 -12
- data/lib/bashly/templates/test/approve +14 -9
- data/lib/bashly/version.rb +2 -2
- data/lib/bashly/views/command/command_fallback.gtx +2 -2
- data/lib/bashly/views/command/command_filter.gtx +9 -9
- data/lib/bashly/views/command/dependencies_filter.gtx +7 -2
- data/lib/bashly/views/command/fixed_flags_filter.gtx +18 -12
- data/lib/bashly/views/command/inspect_args.gtx +2 -2
- data/lib/bashly/views/command/normalize_input.gtx +1 -1
- data/lib/bashly/views/command/parse_requirements_while.gtx +11 -11
- data/lib/bashly/views/command/run.gtx +14 -13
- data/lib/bashly/views/command/usage_environment_variables.gtx +1 -1
- data/lib/bashly/views/flag/case.gtx +1 -1
- data/lib/bashly/views/flag/case_no_arg.gtx +1 -1
- metadata +10 -8
- data/lib/bashly/libraries/completions.rb +0 -14
@@ -18,12 +18,15 @@ module Bashly
|
|
18
18
|
{}
|
19
19
|
end
|
20
20
|
|
21
|
-
new
|
21
|
+
new(**options)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def initialize(label: nil, help: nil, required: false, enabled: true)
|
26
|
-
@label
|
26
|
+
@label = label
|
27
|
+
@help = help
|
28
|
+
@required = required
|
29
|
+
@enabled = enabled
|
27
30
|
end
|
28
31
|
|
29
32
|
def enabled?
|
@@ -44,10 +47,9 @@ module Bashly
|
|
44
47
|
|
45
48
|
def usage_string
|
46
49
|
return nil unless enabled?
|
50
|
+
|
47
51
|
required? ? label : "[#{label}]"
|
48
52
|
end
|
49
|
-
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
53
|
-
|
@@ -26,7 +26,7 @@ module Bashly
|
|
26
26
|
# by space. For example, for a command like "docker container run"
|
27
27
|
# the action name is "container run".
|
28
28
|
def action_name
|
29
|
-
parents.any? ? (parents[1
|
29
|
+
parents.any? ? (parents[1..] + [name]).join(' ') : 'root'
|
30
30
|
end
|
31
31
|
|
32
32
|
# Returns all the possible aliases for this command
|
@@ -34,28 +34,20 @@ module Bashly
|
|
34
34
|
[name] + alt
|
35
35
|
end
|
36
36
|
|
37
|
-
# Returns an array of all full names (including aliases and aliases of
|
38
|
-
# parents)
|
39
|
-
def all_full_names
|
40
|
-
if parent_command
|
41
|
-
parent_command.all_full_names.product(aliases).map { |a| a.join ' ' }
|
42
|
-
else
|
43
|
-
aliases
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
37
|
# Returns an array of alternative aliases if any
|
48
38
|
def alt
|
49
39
|
# DEPRECATION 0.8.0
|
50
40
|
options['alias'] ||= options['short']
|
51
|
-
return [] unless options[
|
41
|
+
return [] unless options['alias']
|
42
|
+
|
52
43
|
options['alias'].is_a?(String) ? [options['alias']] : options['alias']
|
53
44
|
end
|
54
45
|
|
55
46
|
# Returns an array of Arguments
|
56
47
|
def args
|
57
|
-
return [] unless options[
|
58
|
-
|
48
|
+
return [] unless options['args']
|
49
|
+
|
50
|
+
options['args'].map do |options|
|
59
51
|
Argument.new options
|
60
52
|
end
|
61
53
|
end
|
@@ -85,8 +77,8 @@ module Bashly
|
|
85
77
|
|
86
78
|
command.public_commands.each do |subcommand|
|
87
79
|
result[command.group_string]["#{command.name} #{subcommand.name}"] = {
|
88
|
-
summary:
|
89
|
-
help_only: command.expose != 'always'
|
80
|
+
summary: subcommand.summary_string,
|
81
|
+
help_only: command.expose != 'always',
|
90
82
|
}
|
91
83
|
end
|
92
84
|
end
|
@@ -96,13 +88,14 @@ module Bashly
|
|
96
88
|
|
97
89
|
# Returns only the names of the Commands
|
98
90
|
def command_names
|
99
|
-
commands.map
|
91
|
+
commands.map(&:name)
|
100
92
|
end
|
101
93
|
|
102
94
|
# Returns an array of the Commands
|
103
95
|
def commands
|
104
|
-
return [] unless options[
|
105
|
-
|
96
|
+
return [] unless options['commands']
|
97
|
+
|
98
|
+
options['commands'].map do |options|
|
106
99
|
result = Command.new options
|
107
100
|
result.parents = parents + [name]
|
108
101
|
result.parent_command = self
|
@@ -126,48 +119,51 @@ module Bashly
|
|
126
119
|
# If any of this command's subcommands has the default option set to
|
127
120
|
# true, this default command will be returned, nil otherwise.
|
128
121
|
def default_command
|
129
|
-
commands.find
|
122
|
+
commands.find(&:default)
|
130
123
|
end
|
131
124
|
|
132
125
|
# Returns an array of all the default Args
|
133
126
|
def default_args
|
134
|
-
args.select
|
127
|
+
args.select(&:default)
|
135
128
|
end
|
136
129
|
|
137
130
|
# Returns an array of all the default Environment Variables
|
138
131
|
def default_environment_variables
|
139
|
-
environment_variables.select
|
132
|
+
environment_variables.select(&:default)
|
140
133
|
end
|
141
134
|
|
142
135
|
# Returns an array of all the default Flags
|
143
136
|
def default_flags
|
144
|
-
flags.select
|
137
|
+
flags.select(&:default)
|
145
138
|
end
|
146
139
|
|
147
140
|
# Returns an array of EnvironmentVariables
|
148
141
|
def environment_variables
|
149
|
-
return [] unless options[
|
150
|
-
|
142
|
+
return [] unless options['environment_variables']
|
143
|
+
|
144
|
+
options['environment_variables'].map do |options|
|
151
145
|
EnvironmentVariable.new options
|
152
146
|
end
|
153
147
|
end
|
154
148
|
|
155
149
|
# Returns an array of examples
|
156
150
|
def examples
|
157
|
-
return nil unless options[
|
158
|
-
|
151
|
+
return nil unless options['examples']
|
152
|
+
|
153
|
+
options['examples'].is_a?(Array) ? options['examples'] : [options['examples']]
|
159
154
|
end
|
160
155
|
|
161
156
|
# Returns the bash filename that is expected to hold the user code
|
162
157
|
# for this command
|
163
158
|
def filename
|
164
|
-
options[
|
159
|
+
options['filename'] || "#{action_name.to_underscore}_command.sh"
|
165
160
|
end
|
166
161
|
|
167
162
|
# Returns an array of Flags
|
168
163
|
def flags
|
169
|
-
return [] unless options[
|
170
|
-
|
164
|
+
return [] unless options['flags']
|
165
|
+
|
166
|
+
options['flags'].map do |options|
|
171
167
|
Flag.new options
|
172
168
|
end
|
173
169
|
end
|
@@ -192,7 +188,7 @@ module Bashly
|
|
192
188
|
# Returns the string for the group caption
|
193
189
|
def group_string
|
194
190
|
if group
|
195
|
-
strings[:group] % { group: group }
|
191
|
+
strings[:group] % { group: group }
|
196
192
|
else
|
197
193
|
strings[:commands]
|
198
194
|
end
|
@@ -200,18 +196,17 @@ module Bashly
|
|
200
196
|
|
201
197
|
# Returns a mode identifier
|
202
198
|
def mode
|
203
|
-
@mode ||=
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
end
|
199
|
+
@mode ||= if global_flags? then :global_flags
|
200
|
+
elsif commands.any? then :commands
|
201
|
+
elsif args.any? && flags.any? then :args_and_flags
|
202
|
+
elsif args.any? then :args
|
203
|
+
elsif flags.any? then :flags
|
204
|
+
else
|
205
|
+
:empty
|
211
206
|
end
|
212
207
|
end
|
213
208
|
|
214
|
-
# Returns an array of all parents. For example, the command
|
209
|
+
# Returns an array of all parents. For example, the command
|
215
210
|
# "docker container run" will have [docker, container] as its parents
|
216
211
|
def parents
|
217
212
|
@parents ||= []
|
@@ -219,7 +214,7 @@ module Bashly
|
|
219
214
|
|
220
215
|
# Returns only commands that are not private
|
221
216
|
def public_commands
|
222
|
-
commands.reject
|
217
|
+
commands.reject(&:private)
|
223
218
|
end
|
224
219
|
|
225
220
|
# Returns true if one of the args is repeatable
|
@@ -229,17 +224,17 @@ module Bashly
|
|
229
224
|
|
230
225
|
# Returns an array of all the required Arguments
|
231
226
|
def required_args
|
232
|
-
args.select
|
227
|
+
args.select(&:required)
|
233
228
|
end
|
234
229
|
|
235
230
|
# Returns an array of all the required EnvironmentVariables
|
236
231
|
def required_environment_variables
|
237
|
-
environment_variables.select
|
232
|
+
environment_variables.select(&:required)
|
238
233
|
end
|
239
234
|
|
240
235
|
# Returns an array of all the required Flags
|
241
236
|
def required_flags
|
242
|
-
flags.select
|
237
|
+
flags.select(&:required)
|
243
238
|
end
|
244
239
|
|
245
240
|
# Returns true if this is the root command (no parents)
|
@@ -266,21 +261,20 @@ module Bashly
|
|
266
261
|
result = [full_name]
|
267
262
|
|
268
263
|
result.push case mode
|
269
|
-
when :global_flags then [
|
270
|
-
when :commands then [
|
271
|
-
when :args_and_flags then usage_string_args + [
|
264
|
+
when :global_flags then ['[OPTIONS]', 'COMMAND']
|
265
|
+
when :commands then ['COMMAND']
|
266
|
+
when :args_and_flags then usage_string_args + ['[OPTIONS]']
|
272
267
|
when :args then usage_string_args
|
273
|
-
when :flags then [
|
274
|
-
else nil
|
268
|
+
when :flags then ['[OPTIONS]']
|
275
269
|
end
|
276
270
|
|
277
271
|
result.push catch_all.usage_string if catch_all.enabled? && commands.empty?
|
278
|
-
result.compact.join
|
272
|
+
result.compact.join ' '
|
279
273
|
end
|
280
274
|
|
281
275
|
# Returns an array of args usage_string for the command's usage_string
|
282
276
|
def usage_string_args
|
283
|
-
args.map
|
277
|
+
args.map(&:usage_string)
|
284
278
|
end
|
285
279
|
|
286
280
|
# Returns an array of files to include as is inside the script
|
@@ -292,12 +286,12 @@ module Bashly
|
|
292
286
|
|
293
287
|
# Returns an array of all the args with a whitelist
|
294
288
|
def whitelisted_args
|
295
|
-
args.select
|
289
|
+
args.select(&:allowed)
|
296
290
|
end
|
297
291
|
|
298
292
|
# Returns an array of all the flags with a whitelist arg
|
299
293
|
def whitelisted_flags
|
300
|
-
flags.select
|
294
|
+
flags.select(&:allowed)
|
301
295
|
end
|
302
296
|
end
|
303
297
|
end
|
@@ -3,15 +3,15 @@ module Bashly
|
|
3
3
|
class EnvironmentVariable < Base
|
4
4
|
class << self
|
5
5
|
def option_keys
|
6
|
-
@option_keys ||= %i[default help name required]
|
6
|
+
@option_keys ||= %i[default help name required private]
|
7
7
|
end
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def usage_string(extended: false)
|
11
11
|
result = [name.upcase]
|
12
|
-
result << strings[:required] if required
|
13
|
-
result.join
|
12
|
+
result << strings[:required] if required && extended
|
13
|
+
result.join ' '
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
-
end
|
17
|
+
end
|
data/lib/bashly/script/flag.rb
CHANGED
@@ -11,9 +11,9 @@ module Bashly
|
|
11
11
|
]
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def aliases
|
16
|
-
if long
|
16
|
+
if long && short
|
17
17
|
[long, short]
|
18
18
|
elsif long
|
19
19
|
[long]
|
@@ -27,12 +27,12 @@ module Bashly
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def usage_string(extended: false)
|
30
|
-
result = [aliases.join(
|
30
|
+
result = [aliases.join(', ')]
|
31
31
|
result << arg.upcase if arg
|
32
|
-
result << strings[:required] if required
|
33
|
-
result << strings[:repeatable] if repeatable
|
34
|
-
result.join
|
32
|
+
result << strings[:required] if required && extended
|
33
|
+
result << strings[:repeatable] if repeatable && extended
|
34
|
+
result.join ' '
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
end
|
38
|
+
end
|
@@ -6,7 +6,8 @@ module Bashly
|
|
6
6
|
attr_reader :command, :function_name
|
7
7
|
|
8
8
|
def initialize(command, function_name = nil)
|
9
|
-
@command
|
9
|
+
@command = command
|
10
|
+
@function_name = function_name
|
10
11
|
end
|
11
12
|
|
12
13
|
def code(tab_indent: false)
|
@@ -38,13 +39,13 @@ module Bashly
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def default_header
|
41
|
-
result = render
|
42
|
+
result = render 'header'
|
42
43
|
result += render('bash3_bouncer') unless function_name
|
43
44
|
result
|
44
45
|
end
|
45
46
|
|
46
47
|
def body
|
47
|
-
@body ||= command.render
|
48
|
+
@body ||= command.render 'master_script'
|
48
49
|
end
|
49
50
|
|
50
51
|
def custom_header_path
|
@@ -52,4 +53,4 @@ module Bashly
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
end
|
55
|
-
end
|
56
|
+
end
|
data/lib/bashly/settings.rb
CHANGED
@@ -51,8 +51,8 @@ module Bashly
|
|
51
51
|
def get(key)
|
52
52
|
case env_value key
|
53
53
|
when nil then config[key.to_s]
|
54
|
-
when
|
55
|
-
when
|
54
|
+
when '0', 'false', 'no' then false
|
55
|
+
when '1', 'true', 'yes' then true
|
56
56
|
else env_value key
|
57
57
|
end
|
58
58
|
end
|
@@ -70,13 +70,12 @@ module Bashly
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def defsult_settings
|
73
|
-
@defsult_settings ||= Config.new
|
73
|
+
@defsult_settings ||= Config.new default_settings_path
|
74
74
|
end
|
75
75
|
|
76
76
|
def default_settings_path
|
77
|
-
asset
|
77
|
+
asset 'templates/settings.yml'
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
end
|
82
81
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
## Help command [@bashly-upgrade help]
|
2
|
+
## This file is a part of Bashly standard library
|
3
|
+
##
|
4
|
+
## Add this as a command to your bashly.yml:
|
5
|
+
##
|
6
|
+
## commands:
|
7
|
+
## - name: help
|
8
|
+
## help: Show help about a command
|
9
|
+
## args:
|
10
|
+
## - name: command
|
11
|
+
## help: Help subject
|
12
|
+
##
|
13
|
+
command="${args[command]}"
|
14
|
+
long_usage=yes
|
15
|
+
|
16
|
+
if [[ -z "$command" ]]; then
|
17
|
+
# No command argument, show the global help
|
18
|
+
help_function=%{name}_usage
|
19
|
+
else
|
20
|
+
# Show the help for the requested command
|
21
|
+
help_function="%{name}_${command}_usage"
|
22
|
+
fi
|
23
|
+
|
24
|
+
# Call the help function if it exists
|
25
|
+
if [[ $(type -t "$help_function") ]]; then
|
26
|
+
"$help_function"
|
27
|
+
else
|
28
|
+
echo "No help available for this command"
|
29
|
+
exit 1
|
30
|
+
fi
|
@@ -24,13 +24,13 @@ config_get() {
|
|
24
24
|
local value=""
|
25
25
|
|
26
26
|
config_init
|
27
|
-
|
27
|
+
|
28
28
|
while IFS= read -r line || [ -n "$line" ]; do
|
29
29
|
if [[ $line =~ $regex ]]; then
|
30
30
|
value="${BASH_REMATCH[1]}"
|
31
31
|
break
|
32
32
|
fi
|
33
|
-
done <
|
33
|
+
done <"$CONFIG_FILE"
|
34
34
|
|
35
35
|
echo "$value"
|
36
36
|
}
|
@@ -48,7 +48,7 @@ config_set() {
|
|
48
48
|
local output=""
|
49
49
|
local found_key=""
|
50
50
|
local newline
|
51
|
-
|
51
|
+
|
52
52
|
while IFS= read -r line || [ -n "$line" ]; do
|
53
53
|
newline=$line
|
54
54
|
if [[ $line =~ $regex ]]; then
|
@@ -58,13 +58,13 @@ config_set() {
|
|
58
58
|
elif [[ $line ]]; then
|
59
59
|
output="$output$line\n"
|
60
60
|
fi
|
61
|
-
done <
|
61
|
+
done <"$CONFIG_FILE"
|
62
62
|
|
63
63
|
if [[ -z $found_key ]]; then
|
64
64
|
output="$output$key = $value\n"
|
65
65
|
fi
|
66
66
|
|
67
|
-
printf "%b\n" "$output" >
|
67
|
+
printf "%b\n" "$output" >"$CONFIG_FILE"
|
68
68
|
}
|
69
69
|
|
70
70
|
## Delete a key from the config.
|
@@ -81,9 +81,9 @@ config_del() {
|
|
81
81
|
if [[ $line ]] && [[ ! $line =~ $regex ]]; then
|
82
82
|
output="$output$line\n"
|
83
83
|
fi
|
84
|
-
done <
|
84
|
+
done <"$CONFIG_FILE"
|
85
85
|
|
86
|
-
printf "%b\n" "$output" >
|
86
|
+
printf "%b\n" "$output" >"$CONFIG_FILE"
|
87
87
|
}
|
88
88
|
|
89
89
|
## Show the config file
|
@@ -106,20 +106,20 @@ config_keys() {
|
|
106
106
|
|
107
107
|
local keys=()
|
108
108
|
local key
|
109
|
-
|
109
|
+
|
110
110
|
while IFS= read -r line || [ -n "$line" ]; do
|
111
111
|
if [[ $line =~ $regex ]]; then
|
112
112
|
key="${BASH_REMATCH[1]}"
|
113
113
|
keys+=("$key")
|
114
114
|
fi
|
115
|
-
done <
|
115
|
+
done <"$CONFIG_FILE"
|
116
116
|
echo "${keys[@]}"
|
117
117
|
}
|
118
118
|
|
119
119
|
## Returns true if the specified key exists in the config file.
|
120
120
|
## Usage:
|
121
121
|
##
|
122
|
-
## if config_has_key "key"
|
122
|
+
## if config_has_key "key"; then
|
123
123
|
## echo "key exists"
|
124
124
|
## fi
|
125
125
|
##
|
@@ -11,16 +11,16 @@
|
|
11
11
|
## eval $(yaml_load "settings.yml") # create variables in scope
|
12
12
|
##
|
13
13
|
yaml_load() {
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
local prefix=$2
|
15
|
+
local s='[[:space:]]*' w='[a-zA-Z0-9_]*'
|
16
|
+
local fs
|
17
17
|
|
18
|
-
|
18
|
+
fs=$(echo @ | tr @ '\034')
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
sed -ne "s|^\($s\):|\1|" \
|
21
|
+
-e "s|^\($s\)\($w\)$s:${s}[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
|
22
|
+
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" |
|
23
|
+
awk -F"$fs" '{
|
24
24
|
indent = length($1)/2;
|
25
25
|
vname[indent] = $2;
|
26
26
|
for (i in vname) {if (i > indent) {delete vname[i]}}
|
@@ -28,5 +28,5 @@ yaml_load() {
|
|
28
28
|
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
|
29
29
|
printf("%s%s%s=\"%s\"\n", "'"$prefix"'",vn, $2, $3);
|
30
30
|
}
|
31
|
-
|
31
|
+
}'
|
32
32
|
}
|
@@ -1,14 +1,14 @@
|
|
1
|
-
# approvals.bash v0.
|
1
|
+
# approvals.bash v0.3.3
|
2
2
|
#
|
3
3
|
# Interactive approval testing for Bash.
|
4
4
|
# https://github.com/DannyBen/approvals.bash
|
5
5
|
approve() {
|
6
6
|
local expected approval approval_file actual cmd
|
7
7
|
approvals_dir=${APPROVALS_DIR:=approvals}
|
8
|
-
|
8
|
+
|
9
9
|
cmd=$1
|
10
|
-
|
11
|
-
last_exit_code=$?
|
10
|
+
last_exit_code=0
|
11
|
+
actual=$(eval "$cmd" 2>&1) || last_exit_code=$?
|
12
12
|
approval=$(printf "%b" "$cmd" | tr -s -c "[:alnum:]" _)
|
13
13
|
approval_file="$approvals_dir/${2:-"$approval"}"
|
14
14
|
|
@@ -26,26 +26,32 @@ approve() {
|
|
26
26
|
fi
|
27
27
|
|
28
28
|
if [[ "$(printf "%b" "$actual")" = "$(printf "%b" "$expected")" ]]; then
|
29
|
-
|
29
|
+
pass "$cmd"
|
30
30
|
else
|
31
31
|
echo "--- [$(blue "diff: $cmd")] ---"
|
32
|
-
$diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n"
|
32
|
+
$diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n") | tail -n +4
|
33
33
|
echo "--- [$(blue "diff: $cmd")] ---"
|
34
34
|
user_approval "$cmd" "$actual" "$approval_file"
|
35
35
|
fi
|
36
36
|
}
|
37
37
|
|
38
38
|
describe() {
|
39
|
-
|
39
|
+
echo
|
40
|
+
blue "= $*"
|
41
|
+
}
|
42
|
+
|
43
|
+
context() {
|
44
|
+
echo
|
45
|
+
magenta "= $*"
|
40
46
|
}
|
41
47
|
|
42
48
|
fail() {
|
43
|
-
red "
|
49
|
+
red " FAILED: $*"
|
44
50
|
exit 1
|
45
51
|
}
|
46
52
|
|
47
53
|
pass() {
|
48
|
-
green "
|
54
|
+
green " approved: $*"
|
49
55
|
return 0
|
50
56
|
}
|
51
57
|
|
@@ -74,19 +80,37 @@ user_approval() {
|
|
74
80
|
fail "$cmd"
|
75
81
|
fi
|
76
82
|
|
77
|
-
echo
|
83
|
+
echo
|
78
84
|
printf "[A]pprove? \n"
|
79
85
|
response=$(bash -c "read -n 1 key; echo \$key")
|
80
86
|
printf "\r"
|
81
87
|
if [[ $response =~ [Aa] ]]; then
|
82
|
-
printf "%b\n" "$actual" >
|
88
|
+
printf "%b\n" "$actual" >"$approval_file"
|
83
89
|
pass "$cmd"
|
84
90
|
else
|
85
91
|
fail "$cmd"
|
86
92
|
fi
|
87
93
|
}
|
88
94
|
|
89
|
-
|
95
|
+
onexit() {
|
96
|
+
exitcode=$?
|
97
|
+
if [[ "$exitcode" == 0 ]]; then
|
98
|
+
green "\nFinished successfully"
|
99
|
+
else
|
100
|
+
red "\nFinished with failures"
|
101
|
+
fi
|
102
|
+
exit $exitcode
|
103
|
+
}
|
104
|
+
|
105
|
+
onerror() {
|
106
|
+
fail "Caller: $(caller)"
|
107
|
+
}
|
108
|
+
|
109
|
+
set -e
|
110
|
+
trap 'onexit' EXIT
|
111
|
+
trap 'onerror' ERR
|
112
|
+
|
113
|
+
if diff --help | grep -- --color >/dev/null 2>&1; then
|
90
114
|
diff_cmd="diff --unified --color=always"
|
91
115
|
else
|
92
116
|
diff_cmd="diff --unified"
|
@@ -3,18 +3,23 @@
|
|
3
3
|
|
4
4
|
cd ./test || exit
|
5
5
|
source approvals.bash
|
6
|
-
PATH="$PATH:../"
|
7
6
|
|
8
7
|
# Update me
|
9
|
-
cli
|
8
|
+
cli=./download
|
10
9
|
|
11
|
-
# Tests
|
12
|
-
|
13
|
-
|
14
|
-
approve "$cli --help"
|
10
|
+
# Tests (context, describe and indentation are optional)
|
11
|
+
context "when DEBUG is on"
|
12
|
+
export DEBUG=1
|
15
13
|
|
16
|
-
describe "
|
17
|
-
|
18
|
-
|
14
|
+
describe "root command"
|
15
|
+
approve "$cli"
|
16
|
+
approve "$cli --help"
|
17
|
+
|
18
|
+
context "when DEBUG is off"
|
19
|
+
unset DEBUG
|
20
|
+
|
21
|
+
describe "some other command"
|
22
|
+
approve "$cli other"
|
23
|
+
approve "$cli other --help"
|
19
24
|
|
20
25
|
# ...more tests...
|
data/lib/bashly/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Bashly
|
2
|
-
VERSION =
|
3
|
-
end
|
2
|
+
VERSION = '0.9.0'
|
3
|
+
end
|