bashly 0.7.2 → 0.7.6
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 +4 -4
- data/lib/bashly/commands/add.rb +6 -0
- data/lib/bashly/commands/generate.rb +3 -5
- data/lib/bashly/config.rb +3 -1
- data/lib/bashly/config_validator.rb +10 -0
- data/lib/bashly/libraries/completions.rb +1 -1
- data/lib/bashly/libraries.yml +15 -0
- data/lib/bashly/library.rb +4 -1
- data/lib/bashly/script/base.rb +5 -2
- data/lib/bashly/script/command.rb +1 -1
- data/lib/bashly/script/flag.rb +1 -0
- data/lib/bashly/templates/strings.yml +2 -0
- data/lib/bashly/templates/test/approvals.bash +93 -0
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/command/default_root_script.erb +1 -1
- data/lib/bashly/views/command/parse_requirements.erb +1 -0
- data/lib/bashly/views/command/root_command.erb +1 -1
- data/lib/bashly/views/command/user_filter.erb +11 -0
- data/lib/bashly/views/flag/case.erb +13 -0
- data/lib/bashly/views/flag/conflicts.erb +18 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98fc7fa0a703a1bdef30afdd0e4ff4b5a4d5cc6025380e4aa952aeb77c0b9aa8
|
4
|
+
data.tar.gz: 2d148783f32363862d4039b424ef8ddd5fa050c849bbe742f7195096cdf78830
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 309afb5a2c73c170fafacf9ab02066bd1e4d29934c6a94f6518328dbfd246a8679fc0e8ffc51e00a3359adc90cc25d1d9433e8944db7def0cf806ac5dd99d89d
|
7
|
+
data.tar.gz: fd16952f25275a54d0aaaf990b00575a19fc5d38cab3206918722240466df9e1ae7f55f439ccfc1129ca5d8733181583fbd4280bf18cb42615119a9122f666d8
|
data/lib/bashly/commands/add.rb
CHANGED
@@ -9,6 +9,7 @@ module Bashly
|
|
9
9
|
usage "bashly add colors [--force]"
|
10
10
|
usage "bashly add yaml [--force]"
|
11
11
|
usage "bashly add validations [--force]"
|
12
|
+
usage "bashly add test [--force]"
|
12
13
|
usage "bashly add comp FORMAT [OUTPUT --force]"
|
13
14
|
usage "bashly add (-h|--help)"
|
14
15
|
|
@@ -23,6 +24,7 @@ module Bashly
|
|
23
24
|
command "colors", "Add standard functions for printing colorful and formatted text to the lib directory."
|
24
25
|
command "yaml", "Add standard functions for reading YAML files to the lib directory."
|
25
26
|
command "validations", "Add argument validation functions to the lib directory."
|
27
|
+
command "test", "Add approval testing."
|
26
28
|
command "comp", "Generate a bash completions script or function."
|
27
29
|
|
28
30
|
example "bashly add strings --force"
|
@@ -55,6 +57,10 @@ module Bashly
|
|
55
57
|
add_lib 'validations'
|
56
58
|
end
|
57
59
|
|
60
|
+
def test_command
|
61
|
+
add_lib 'test'
|
62
|
+
end
|
63
|
+
|
58
64
|
def comp_command
|
59
65
|
format = args['FORMAT']
|
60
66
|
output = args['OUTPUT']
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Bashly
|
2
2
|
module Commands
|
3
3
|
class Generate < Base
|
4
|
-
using ComposeRefinements
|
5
|
-
|
6
4
|
help "Generate the bash script and required files"
|
7
5
|
|
8
6
|
usage "bashly generate [--force --quiet --upgrade --wrap FUNCTION]"
|
@@ -82,7 +80,7 @@ module Bashly
|
|
82
80
|
end
|
83
81
|
|
84
82
|
def create_root_command_file
|
85
|
-
create_file "#{Settings.source_dir}
|
83
|
+
create_file "#{Settings.source_dir}/#{command.filename}", command.render(:default_root_script)
|
86
84
|
end
|
87
85
|
|
88
86
|
def create_all_command_files
|
@@ -98,7 +96,7 @@ module Bashly
|
|
98
96
|
if File.exist? file and !args['--force']
|
99
97
|
quiet_say "!txtblu!skipped!txtrst! #{file} (exists)"
|
100
98
|
else
|
101
|
-
File.
|
99
|
+
File.deep_write file, content
|
102
100
|
quiet_say "!txtgrn!created!txtrst! #{file}"
|
103
101
|
end
|
104
102
|
end
|
@@ -118,7 +116,7 @@ module Bashly
|
|
118
116
|
end
|
119
117
|
|
120
118
|
def config
|
121
|
-
@config ||= Config.new
|
119
|
+
@config ||= Config.new "#{Settings.source_dir}/bashly.yml"
|
122
120
|
end
|
123
121
|
|
124
122
|
def command
|
data/lib/bashly/config.rb
CHANGED
@@ -4,11 +4,13 @@ module Bashly
|
|
4
4
|
# A convenience class to use either a hash or a filename as a configuration
|
5
5
|
# source
|
6
6
|
class Config
|
7
|
+
using ComposeRefinements
|
8
|
+
|
7
9
|
attr_reader :config
|
8
10
|
|
9
11
|
def self.new(config)
|
10
12
|
if config.is_a? String
|
11
|
-
YAML.load_file
|
13
|
+
YAML.load_file(config).compose
|
12
14
|
else
|
13
15
|
config
|
14
16
|
end
|
@@ -79,8 +79,11 @@ module Bashly
|
|
79
79
|
assert_optional_string "#{key}.default", value['default']
|
80
80
|
assert_optional_string "#{key}.validate", value['validate']
|
81
81
|
assert_boolean "#{key}.required", value['required']
|
82
|
+
assert_boolean "#{key}.repeatable", value['repeatable']
|
82
83
|
|
83
84
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
85
|
+
|
86
|
+
refute value['name'].match(/^-/), "#{key}.name must not start with '-'"
|
84
87
|
end
|
85
88
|
|
86
89
|
def assert_flag(key, value)
|
@@ -96,6 +99,11 @@ module Bashly
|
|
96
99
|
|
97
100
|
assert_boolean "#{key}.required", value['required']
|
98
101
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
102
|
+
assert_array "#{key}.conflicts", value['conflicts'], of: :string
|
103
|
+
|
104
|
+
assert value['long'].match(/^--[a-zA-Z0-9_\-]+$/), "#{key}.long must be in the form of '--name'" if value['long']
|
105
|
+
assert value['short'].match(/^-[a-zA-Z0-9]$/), "#{key}.short must be in the form of '-n'" if value['short']
|
106
|
+
refute value['arg'].match(/^-/), "#{key}.arg must not start with '-'" if value['arg']
|
99
107
|
end
|
100
108
|
|
101
109
|
def assert_env_var(key, value)
|
@@ -117,6 +125,7 @@ module Bashly
|
|
117
125
|
assert_optional_string "#{key}.help", value['help']
|
118
126
|
assert_optional_string "#{key}.footer", value['footer']
|
119
127
|
assert_optional_string "#{key}.group", value['group']
|
128
|
+
assert_optional_string "#{key}.filename", value['filename']
|
120
129
|
|
121
130
|
assert_boolean "#{key}.default", value['default']
|
122
131
|
assert_version "#{key}.version", value['version']
|
@@ -128,6 +137,7 @@ module Bashly
|
|
128
137
|
assert_array "#{key}.commands", value['commands'], of: :command
|
129
138
|
assert_array "#{key}.completions", value['completions'], of: :string
|
130
139
|
assert_array "#{key}.dependencies", value['dependencies'], of: :string
|
140
|
+
assert_array "#{key}.filters", value['filters'], of: :string
|
131
141
|
assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var
|
132
142
|
assert_array "#{key}.examples", value['examples'], of: :string
|
133
143
|
end
|
data/lib/bashly/libraries.yml
CHANGED
@@ -23,6 +23,21 @@ strings:
|
|
23
23
|
- source: "templates/strings.yml"
|
24
24
|
target: "%{user_source_dir}/bashly-strings.yml"
|
25
25
|
|
26
|
+
test:
|
27
|
+
files:
|
28
|
+
- source: "templates/test/approvals.bash"
|
29
|
+
target: "%{user_target_dir}/test/approvals.bash"
|
30
|
+
- source: "templates/test/approve"
|
31
|
+
target: "%{user_target_dir}/test/approve"
|
32
|
+
|
33
|
+
post_install_message: |
|
34
|
+
Edit your tests in !txtgrn!test/approve!txtrst! and then run:
|
35
|
+
|
36
|
+
!txtpur!$ ./test/approve!txtrst!"
|
37
|
+
|
38
|
+
Docs: !undblu!https://github.com/DannyBen/approvals.bash
|
39
|
+
|
40
|
+
|
26
41
|
validations:
|
27
42
|
files:
|
28
43
|
- source: "templates/lib/validations/validate_dir_exists.sh"
|
data/lib/bashly/library.rb
CHANGED
data/lib/bashly/script/base.rb
CHANGED
@@ -10,12 +10,14 @@ module Bashly
|
|
10
10
|
arg
|
11
11
|
catch_all
|
12
12
|
completions
|
13
|
+
conflicts
|
13
14
|
default
|
14
15
|
dependencies
|
15
16
|
description
|
16
17
|
environment_variables
|
17
18
|
examples
|
18
19
|
extensible
|
20
|
+
filters
|
19
21
|
flags
|
20
22
|
footer
|
21
23
|
group
|
@@ -24,6 +26,7 @@ module Bashly
|
|
24
26
|
name
|
25
27
|
parent_name
|
26
28
|
private
|
29
|
+
repeatable
|
27
30
|
required
|
28
31
|
short
|
29
32
|
validate
|
@@ -53,9 +56,9 @@ module Bashly
|
|
53
56
|
respond_to?(method_name) ? options[key] : super
|
54
57
|
end
|
55
58
|
|
56
|
-
def
|
59
|
+
def respond_to_missing?(method_name, include_private = false)
|
57
60
|
OPTION_KEYS.include?(method_name) || super
|
58
61
|
end
|
59
62
|
end
|
60
63
|
end
|
61
|
-
end
|
64
|
+
end
|
@@ -55,7 +55,7 @@ module Bashly
|
|
55
55
|
# Returns the bash filename that is expected to hold the user code
|
56
56
|
# for this command
|
57
57
|
def filename
|
58
|
-
"#{action_name.to_underscore}_command.sh"
|
58
|
+
options["filename"] || "#{action_name.to_underscore}_command.sh"
|
59
59
|
end
|
60
60
|
|
61
61
|
# Returns an array of Flags
|
data/lib/bashly/script/flag.rb
CHANGED
@@ -14,6 +14,7 @@ group: "%{group} Commands:"
|
|
14
14
|
command_shortcut: "Shortcut: %{short}"
|
15
15
|
default_command_summary: "%{summary} (default)"
|
16
16
|
required: "(required)"
|
17
|
+
repeatable: "(repeatable)"
|
17
18
|
default: "Default: %{value}"
|
18
19
|
allowed: "Allowed: %{values}"
|
19
20
|
|
@@ -25,6 +26,7 @@ version_flag_text: Show version number
|
|
25
26
|
flag_requires_an_argument: "%{name} requires an argument: %{usage}"
|
26
27
|
invalid_argument: "invalid argument: %s"
|
27
28
|
invalid_flag: "invalid option: %s"
|
29
|
+
conflicting_flags: "conflicting options: %s cannot be used with %s"
|
28
30
|
missing_required_argument: "missing required argument: %{arg}\\nusage: %{usage}"
|
29
31
|
missing_required_flag: "missing required flag: %{usage}"
|
30
32
|
missing_required_environment_variable: "missing required environment variable: %{var}"
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# approvals.bash v0.2.7
|
2
|
+
#
|
3
|
+
# Interactive approval testing for Bash.
|
4
|
+
# https://github.com/DannyBen/approvals.bash
|
5
|
+
approve() {
|
6
|
+
local expected approval approval_file actual cmd
|
7
|
+
approvals_dir=${APPROVALS_DIR:=approvals}
|
8
|
+
|
9
|
+
cmd=$1
|
10
|
+
actual=$(eval "$cmd" 2>&1)
|
11
|
+
last_exit_code=$?
|
12
|
+
approval=$(printf "%b" "$cmd" | tr -s -c "[:alnum:]" _)
|
13
|
+
approval_file="$approvals_dir/${2:-"$approval"}"
|
14
|
+
|
15
|
+
[[ -d "$approvals_dir" ]] || mkdir "$approvals_dir"
|
16
|
+
|
17
|
+
if [[ -f "$approval_file" ]]; then
|
18
|
+
expected=$(cat "$approval_file")
|
19
|
+
else
|
20
|
+
echo "--- [$(blue "new: $cmd")] ---"
|
21
|
+
printf "%b\n" "$actual"
|
22
|
+
echo "--- [$(blue "new: $cmd")] ---"
|
23
|
+
expected="$actual"
|
24
|
+
user_approval "$cmd" "$actual" "$approval_file"
|
25
|
+
return
|
26
|
+
fi
|
27
|
+
|
28
|
+
if [[ "$(printf "%b" "$actual")" = "$(printf "%b" "$expected")" ]]; then
|
29
|
+
green "PASS $cmd"
|
30
|
+
else
|
31
|
+
echo "--- [$(blue "diff: $cmd")] ---"
|
32
|
+
$diff_cmd <(printf "%b" "$expected\n") <(printf "%b" "$actual\n" ) | tail -n +4
|
33
|
+
echo "--- [$(blue "diff: $cmd")] ---"
|
34
|
+
user_approval "$cmd" "$actual" "$approval_file"
|
35
|
+
fi
|
36
|
+
}
|
37
|
+
|
38
|
+
describe() {
|
39
|
+
cyan "TEST $*"
|
40
|
+
}
|
41
|
+
|
42
|
+
fail() {
|
43
|
+
red "FAIL $*"
|
44
|
+
exit 1
|
45
|
+
}
|
46
|
+
|
47
|
+
pass() {
|
48
|
+
green "PASS $*"
|
49
|
+
return 0
|
50
|
+
}
|
51
|
+
|
52
|
+
expect_exit_code() {
|
53
|
+
if [[ $last_exit_code == "$1" ]]; then
|
54
|
+
pass "exit $last_exit_code"
|
55
|
+
else
|
56
|
+
fail "Expected exit code $1, got $last_exit_code"
|
57
|
+
fi
|
58
|
+
}
|
59
|
+
|
60
|
+
red() { printf "\e[31m%b\e[0m\n" "$*"; }
|
61
|
+
green() { printf "\e[32m%b\e[0m\n" "$*"; }
|
62
|
+
blue() { printf "\e[34m%b\e[0m\n" "$*"; }
|
63
|
+
magenta() { printf "\e[35m%b\e[0m\n" "$*"; }
|
64
|
+
cyan() { printf "\e[36m%b\e[0m\n" "$*"; }
|
65
|
+
|
66
|
+
# Private
|
67
|
+
|
68
|
+
user_approval() {
|
69
|
+
local cmd="$1"
|
70
|
+
local actual="$2"
|
71
|
+
local approval_file="$3"
|
72
|
+
|
73
|
+
if [[ -v CI || -v GITHUB_ACTIONS ]]; then
|
74
|
+
fail "$cmd"
|
75
|
+
fi
|
76
|
+
|
77
|
+
echo
|
78
|
+
printf "[A]pprove? \n"
|
79
|
+
response=$(bash -c "read -n 1 key; echo \$key")
|
80
|
+
printf "\r"
|
81
|
+
if [[ $response =~ [Aa] ]]; then
|
82
|
+
printf "%b\n" "$actual" > "$approval_file"
|
83
|
+
pass "$cmd"
|
84
|
+
else
|
85
|
+
fail "$cmd"
|
86
|
+
fi
|
87
|
+
}
|
88
|
+
|
89
|
+
if diff --help | grep -- --color > /dev/null 2>&1; then
|
90
|
+
diff_cmd="diff --unified --color=always"
|
91
|
+
else
|
92
|
+
diff_cmd="diff --unified"
|
93
|
+
fi
|
data/lib/bashly/version.rb
CHANGED
@@ -1,17 +1,30 @@
|
|
1
1
|
# :flag.case
|
2
2
|
<%= aliases.join " | " %> )
|
3
|
+
<%= render(:conflicts).indent 2 %>
|
3
4
|
% if arg
|
4
5
|
if [[ -n ${2+x} ]]; then
|
5
6
|
<%= render(:validations).indent 4 %>
|
7
|
+
% if repeatable
|
8
|
+
if [[ -z ${args[<%= name %>]+x} ]]; then
|
9
|
+
args[<%= name %>]="\"$2\""
|
10
|
+
else
|
11
|
+
args[<%= name %>]="${args[<%= name %>]} \"$2\""
|
12
|
+
fi
|
13
|
+
% else
|
6
14
|
args[<%= name %>]="$2"
|
15
|
+
% end
|
7
16
|
shift
|
8
17
|
shift
|
9
18
|
else
|
10
19
|
printf "%s\n" "<%= strings[:flag_requires_an_argument] % { name: name, usage: usage_string } %>"
|
11
20
|
exit 1
|
12
21
|
fi
|
22
|
+
% else
|
23
|
+
% if repeatable
|
24
|
+
(( args[<%= name %>]+=1 ))
|
13
25
|
% else
|
14
26
|
args[<%= name %>]=1
|
27
|
+
% end
|
15
28
|
shift
|
16
29
|
% end
|
17
30
|
;;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# :flag.conflicts
|
2
|
+
% if conflicts
|
3
|
+
% if conflicts.count == 1
|
4
|
+
if [[ -n "${args[<%= conflicts.first %>]:-}" ]]; then
|
5
|
+
printf "<%= strings[:conflicting_flags] %>\n" "$key" "<%= conflicts.first %>"
|
6
|
+
exit 1
|
7
|
+
fi
|
8
|
+
|
9
|
+
% else
|
10
|
+
for conflict in <%= conflicts.join ' ' %>; do
|
11
|
+
if [[ -n "${args[$conflict]:-}" ]]; then
|
12
|
+
printf "<%= strings[:conflicting_flags] %>\n" "$key" "$conflict"
|
13
|
+
exit 1
|
14
|
+
fi
|
15
|
+
done
|
16
|
+
|
17
|
+
% end
|
18
|
+
% end
|
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: 0.7.
|
4
|
+
version: 0.7.6
|
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: 2022-
|
11
|
+
date: 2022-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- lib/bashly/templates/lib/yaml.sh
|
122
122
|
- lib/bashly/templates/minimal.yml
|
123
123
|
- lib/bashly/templates/strings.yml
|
124
|
+
- lib/bashly/templates/test/approvals.bash
|
124
125
|
- lib/bashly/version.rb
|
125
126
|
- lib/bashly/views/argument/usage.erb
|
126
127
|
- lib/bashly/views/argument/validations.erb
|
@@ -155,11 +156,13 @@ files:
|
|
155
156
|
- lib/bashly/views/command/usage_examples.erb
|
156
157
|
- lib/bashly/views/command/usage_fixed_flags.erb
|
157
158
|
- lib/bashly/views/command/usage_flags.erb
|
159
|
+
- lib/bashly/views/command/user_filter.erb
|
158
160
|
- lib/bashly/views/command/user_lib.erb
|
159
161
|
- lib/bashly/views/command/version_command.erb
|
160
162
|
- lib/bashly/views/command/whitelist_filter.erb
|
161
163
|
- lib/bashly/views/environment_variable/usage.erb
|
162
164
|
- lib/bashly/views/flag/case.erb
|
165
|
+
- lib/bashly/views/flag/conflicts.erb
|
163
166
|
- lib/bashly/views/flag/usage.erb
|
164
167
|
- lib/bashly/views/flag/validations.erb
|
165
168
|
- lib/bashly/views/wrapper/bash3_bouncer.erb
|
@@ -188,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
191
|
- !ruby/object:Gem::Version
|
189
192
|
version: '0'
|
190
193
|
requirements: []
|
191
|
-
rubygems_version: 3.
|
194
|
+
rubygems_version: 3.3.7
|
192
195
|
signing_key:
|
193
196
|
specification_version: 4
|
194
197
|
summary: Bash Command Line Tool Generator
|