bashly 0.7.0 → 0.7.1
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/cli.rb +1 -0
- data/lib/bashly/commands/add.rb +14 -25
- data/lib/bashly/commands/generate.rb +18 -17
- data/lib/bashly/commands/validate.rb +19 -0
- data/lib/bashly/config_validator.rb +135 -0
- data/lib/bashly/extensions/string.rb +4 -0
- data/lib/bashly/libraries/base.rb +19 -0
- data/lib/bashly/libraries/completions.rb +14 -0
- data/lib/bashly/{library → libraries}/completions_function.rb +18 -6
- data/lib/bashly/libraries/completions_script.rb +29 -0
- data/lib/bashly/libraries/completions_yaml.rb +27 -0
- data/lib/bashly/libraries.yml +39 -0
- data/lib/bashly/library.rb +63 -0
- data/lib/bashly/refinements/compose_refinements.rb +45 -0
- data/lib/bashly/script/base.rb +2 -1
- data/lib/bashly/script/command.rb +10 -21
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/command/command_filter.erb +1 -1
- data/lib/bashly/views/command/default_assignments.erb +2 -2
- data/lib/bashly/views/command/default_initialize_script.erb +6 -6
- data/lib/bashly/views/command/environment_variables_filter.erb +1 -1
- data/lib/bashly/views/command/fixed_flags_filter.erb +1 -1
- data/lib/bashly/views/command/initialize.erb +1 -1
- data/lib/bashly/views/command/run.erb +4 -4
- data/lib/bashly/views/command/usage_commands.erb +1 -1
- data/lib/bashly.rb +2 -1
- metadata +12 -13
- data/lib/bashly/library/base.rb +0 -57
- data/lib/bashly/library/colors.rb +0 -9
- data/lib/bashly/library/completions.rb +0 -28
- data/lib/bashly/library/completions_script.rb +0 -17
- data/lib/bashly/library/completions_yaml.rb +0 -15
- data/lib/bashly/library/config.rb +0 -9
- data/lib/bashly/library/sample.rb +0 -9
- data/lib/bashly/library/strings.rb +0 -12
- data/lib/bashly/library/validations.rb +0 -9
- data/lib/bashly/library/yaml.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53a5744ae1746cdd47de191ea91539ab7336aca894f583384ef0b170c03a746e
|
4
|
+
data.tar.gz: 0e1e9bc417d3947bcce84c3c6f44df87521dfeeae2329cc736a53816cb66cba3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72154aafdc3c3787b4d23a2935192a92c21b94b830d7fb01c22057ed839d30120d8a31a8962b7b075110551d034b2c971b92010e55c88a17d4e9041ecb309ad7
|
7
|
+
data.tar.gz: a02638101b685d5e9de575fe4537991c558c462dc030355b5e8ab6ffe4f32b8018c510afb516f51c02d4412a20c21a3703b5dc5872a0f377baa343345f045605
|
data/lib/bashly/cli.rb
CHANGED
data/lib/bashly/commands/add.rb
CHANGED
@@ -32,27 +32,27 @@ module Bashly
|
|
32
32
|
environment "BASHLY_SOURCE_DIR", "The path containing the bashly configuration and source files [default: src]"
|
33
33
|
|
34
34
|
def strings_command
|
35
|
-
add_lib
|
35
|
+
add_lib 'strings'
|
36
36
|
end
|
37
37
|
|
38
38
|
def lib_command
|
39
|
-
add_lib
|
39
|
+
add_lib 'lib'
|
40
40
|
end
|
41
41
|
|
42
42
|
def config_command
|
43
|
-
add_lib
|
43
|
+
add_lib 'config'
|
44
44
|
end
|
45
45
|
|
46
46
|
def colors_command
|
47
|
-
add_lib
|
47
|
+
add_lib 'colors'
|
48
48
|
end
|
49
49
|
|
50
50
|
def yaml_command
|
51
|
-
add_lib
|
51
|
+
add_lib 'yaml'
|
52
52
|
end
|
53
53
|
|
54
54
|
def validations_command
|
55
|
-
add_lib
|
55
|
+
add_lib 'validations'
|
56
56
|
end
|
57
57
|
|
58
58
|
def comp_command
|
@@ -60,35 +60,24 @@ module Bashly
|
|
60
60
|
output = args['OUTPUT']
|
61
61
|
|
62
62
|
case format
|
63
|
-
when "script"
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
when "function"
|
68
|
-
function = output || "send_completions"
|
69
|
-
path = "#{Settings.source_dir}/lib/#{function}.sh"
|
70
|
-
add_lib Library::CompletionsFunction.new(path, function: function)
|
71
|
-
|
72
|
-
when "yaml"
|
73
|
-
path = output || "#{Settings.target_dir}/completions.yml"
|
74
|
-
add_lib Library::CompletionsYAML.new(path)
|
75
|
-
|
76
|
-
else
|
77
|
-
raise Error, "Unrecognized format: #{format}"
|
78
|
-
|
63
|
+
when "script" then add_lib 'completions_script', output
|
64
|
+
when "function" then add_lib 'completions', output
|
65
|
+
when "yaml" then add_lib 'completions_yaml', output
|
66
|
+
else raise Error, "Unrecognized format: #{format}"
|
79
67
|
end
|
80
68
|
|
81
69
|
end
|
82
70
|
|
83
71
|
private
|
84
72
|
|
85
|
-
def add_lib(
|
73
|
+
def add_lib(name, *args)
|
74
|
+
library = Bashly::Library.new name, *args
|
86
75
|
files_created = 0
|
87
|
-
|
76
|
+
library.files.each do |file|
|
88
77
|
created = safe_write file[:path], file[:content]
|
89
78
|
files_created += 1 if created
|
90
79
|
end
|
91
|
-
message =
|
80
|
+
message = library.post_install_message
|
92
81
|
say "\n#{message}" if message and files_created > 0
|
93
82
|
end
|
94
83
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Bashly
|
2
2
|
module Commands
|
3
3
|
class Generate < Base
|
4
|
+
using ComposeRefinements
|
5
|
+
|
4
6
|
help "Generate the bash script and required files"
|
5
7
|
|
6
8
|
usage "bashly generate [--force --quiet --upgrade --wrap FUNCTION]"
|
@@ -13,6 +15,7 @@ module Bashly
|
|
13
15
|
|
14
16
|
environment "BASHLY_SOURCE_DIR", "The path containing the bashly configuration and source files [default: src]"
|
15
17
|
environment "BASHLY_TARGET_DIR", "The path to use for creating the bash script [default: .]"
|
18
|
+
environment "BASHLY_STRICT", "When not empty, enable bash strict mode (set -euo pipefail)"
|
16
19
|
|
17
20
|
example "bashly generate --force"
|
18
21
|
example "bashly generate --wrap my_function"
|
@@ -35,20 +38,9 @@ module Bashly
|
|
35
38
|
content = File.read file
|
36
39
|
|
37
40
|
if content =~ /\[@bashly-upgrade (.+)\]/
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
when "colors"
|
42
|
-
upgrade file, Library::Colors.new
|
43
|
-
when "config"
|
44
|
-
upgrade file, Library::Config.new
|
45
|
-
when "yaml"
|
46
|
-
upgrade file, Library::YAML.new
|
47
|
-
when "validations"
|
48
|
-
upgrade file, Library::Validations.new
|
49
|
-
when /completions (.+)/
|
50
|
-
upgrade file, Library::CompletionsFunction.new(file, function: $1)
|
51
|
-
end
|
41
|
+
args = $1.split ' '
|
42
|
+
library_name = args.shift
|
43
|
+
upgrade file, library_name, *args
|
52
44
|
end
|
53
45
|
end
|
54
46
|
end
|
@@ -57,8 +49,17 @@ module Bashly
|
|
57
49
|
Dir["#{Settings.source_dir}/**/*.*"].sort
|
58
50
|
end
|
59
51
|
|
60
|
-
def upgrade(existing_file,
|
61
|
-
|
52
|
+
def upgrade(existing_file, library_name, *args)
|
53
|
+
if Library.exist? library_name
|
54
|
+
upgrade! existing_file, library_name, *args
|
55
|
+
else
|
56
|
+
quiet_say "!txtred!warning!txtrst! not upgrading !txtcyn!#{existing_file}!txtrst!, unknown library '#{library_name}'"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def upgrade!(existing_file, library_name, *args)
|
61
|
+
library = Bashly::Library.new library_name, *args
|
62
|
+
file = library.find_file existing_file
|
62
63
|
|
63
64
|
if file
|
64
65
|
File.deep_write file[:path], file[:content]
|
@@ -117,7 +118,7 @@ module Bashly
|
|
117
118
|
end
|
118
119
|
|
119
120
|
def config
|
120
|
-
@config ||= Config.new
|
121
|
+
@config ||= Config.new("#{Settings.source_dir}/bashly.yml").compose
|
121
122
|
end
|
122
123
|
|
123
124
|
def command
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bashly
|
2
|
+
module Commands
|
3
|
+
class Validate < Base
|
4
|
+
help "Scan the configuration file for errors"
|
5
|
+
|
6
|
+
usage "bashly validate"
|
7
|
+
usage "bashly validate (-h|--help)"
|
8
|
+
|
9
|
+
environment "BASHLY_SOURCE_DIR", "The path containing the bashly configuration and source files [default: src]"
|
10
|
+
|
11
|
+
def run
|
12
|
+
config = Config.new "#{Settings.source_dir}/bashly.yml"
|
13
|
+
validator = ConfigValidator.new config
|
14
|
+
validator.validate
|
15
|
+
say "!txtgrn!OK"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Bashly
|
2
|
+
class ConfigValidator
|
3
|
+
attr_reader :data
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate
|
10
|
+
assert_command "root", data
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def assert(valid, message)
|
16
|
+
raise ConfigurationError, message unless valid
|
17
|
+
end
|
18
|
+
|
19
|
+
def refute(invalid, message)
|
20
|
+
assert !invalid, message
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_string(key, value)
|
24
|
+
assert value.is_a?(String), "#{key} must be a string"
|
25
|
+
end
|
26
|
+
|
27
|
+
def assert_optional_string(key, value)
|
28
|
+
assert_string key, value if value
|
29
|
+
end
|
30
|
+
|
31
|
+
def assert_boolean(key, value)
|
32
|
+
assert [true, false, nil].include?(value), "#{key} must be a boolean"
|
33
|
+
end
|
34
|
+
|
35
|
+
def assert_array(key, value, of: nil)
|
36
|
+
return unless value
|
37
|
+
assert value.is_a?(Array), "#{key} must be an array"
|
38
|
+
if of
|
39
|
+
value.each_with_index do |val, i|
|
40
|
+
send "assert_#{of}".to_sym, "#{key}[#{i}]", val
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_hash(key, value)
|
46
|
+
assert value.is_a?(Hash), "#{key} must be a hash"
|
47
|
+
end
|
48
|
+
|
49
|
+
def assert_version(key, value)
|
50
|
+
return unless value
|
51
|
+
assert [String, Integer, Float].include?(value.class),
|
52
|
+
"#{key} must be a string or a number"
|
53
|
+
end
|
54
|
+
|
55
|
+
def assert_catch_all(key, value)
|
56
|
+
return unless value
|
57
|
+
assert [TrueClass, String, Hash].include?(value.class),
|
58
|
+
"#{key} must be a boolean, a string or a hash"
|
59
|
+
|
60
|
+
assert_catch_all_hash key, value if value.is_a? Hash
|
61
|
+
end
|
62
|
+
|
63
|
+
def assert_catch_all_hash(key, value)
|
64
|
+
assert_string "#{key}.label", value['label']
|
65
|
+
assert_optional_string "#{key}.help", value['help']
|
66
|
+
assert_boolean "#{key}.required", value['required']
|
67
|
+
end
|
68
|
+
|
69
|
+
def assert_extensible(key, value)
|
70
|
+
return unless value
|
71
|
+
assert [TrueClass, String].include?(value.class),
|
72
|
+
"#{key} must be a boolean or a string"
|
73
|
+
end
|
74
|
+
|
75
|
+
def assert_arg(key, value)
|
76
|
+
assert_hash key, value
|
77
|
+
assert_string "#{key}.name", value['name']
|
78
|
+
assert_optional_string "#{key}.help", value['help']
|
79
|
+
assert_optional_string "#{key}.default", value['default']
|
80
|
+
assert_optional_string "#{key}.validate", value['validate']
|
81
|
+
assert_boolean "#{key}.required", value['required']
|
82
|
+
|
83
|
+
assert_array "#{key}.allowed", value['allowed'], of: :string
|
84
|
+
end
|
85
|
+
|
86
|
+
def assert_flag(key, value)
|
87
|
+
assert_hash key, value
|
88
|
+
assert value['short'] || value['long'], "#{key} must have at least one of long or short name"
|
89
|
+
|
90
|
+
assert_optional_string "#{key}.long", value['long']
|
91
|
+
assert_optional_string "#{key}.short", value['short']
|
92
|
+
assert_optional_string "#{key}.help", value['help']
|
93
|
+
assert_optional_string "#{key}.arg", value['arg']
|
94
|
+
assert_optional_string "#{key}.default", value['default']
|
95
|
+
assert_optional_string "#{key}.validate", value['validate']
|
96
|
+
|
97
|
+
assert_boolean "#{key}.required", value['required']
|
98
|
+
assert_array "#{key}.allowed", value['allowed'], of: :string
|
99
|
+
end
|
100
|
+
|
101
|
+
def assert_env_var(key, value)
|
102
|
+
assert_hash key, value
|
103
|
+
assert_string "#{key}.name", value['name']
|
104
|
+
assert_optional_string "#{key}.help", value['help']
|
105
|
+
assert_optional_string "#{key}.default", value['default']
|
106
|
+
assert_boolean "#{key}.required", value['required']
|
107
|
+
end
|
108
|
+
|
109
|
+
def assert_command(key, value)
|
110
|
+
assert_hash key, value
|
111
|
+
|
112
|
+
refute value['commands'] && value['args'], "#{key} cannot have both commands and args"
|
113
|
+
refute value['commands'] && value['flags'], "#{key} cannot have both commands and flags"
|
114
|
+
|
115
|
+
assert_string "#{key}.name", value['name']
|
116
|
+
assert_optional_string "#{key}.short", value['short']
|
117
|
+
assert_optional_string "#{key}.help", value['help']
|
118
|
+
assert_optional_string "#{key}.footer", value['footer']
|
119
|
+
assert_optional_string "#{key}.group", value['group']
|
120
|
+
|
121
|
+
assert_boolean "#{key}.default", value['default']
|
122
|
+
assert_version "#{key}.version", value['version']
|
123
|
+
assert_catch_all "#{key}.catch_all", value['catch_all']
|
124
|
+
assert_extensible "#{key}.extensible", value['extensible']
|
125
|
+
|
126
|
+
assert_array "#{key}.args", value['args'], of: :arg
|
127
|
+
assert_array "#{key}.flags", value['flags'] , of: :flag
|
128
|
+
assert_array "#{key}.commands", value['commands'], of: :command
|
129
|
+
assert_array "#{key}.completions", value['completions'], of: :string
|
130
|
+
assert_array "#{key}.dependencies", value['dependencies'], of: :string
|
131
|
+
assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var
|
132
|
+
assert_array "#{key}.examples", value['examples'], of: :string
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bashly
|
2
|
+
module Libraries
|
3
|
+
class Base
|
4
|
+
attr_reader :args
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
@args = args
|
8
|
+
end
|
9
|
+
|
10
|
+
def files
|
11
|
+
raise NotImplementedError, "Please implement #files"
|
12
|
+
end
|
13
|
+
|
14
|
+
def post_install_message
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module Bashly
|
2
|
-
module
|
2
|
+
module Libraries
|
3
3
|
class CompletionsFunction < Completions
|
4
|
-
def
|
4
|
+
def files
|
5
5
|
[
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
{
|
7
|
+
path: "#{Settings.source_dir}/lib/#{function_name}.sh",
|
8
|
+
content: completions_function_code(function_name)
|
9
|
+
}
|
10
|
+
]
|
9
11
|
end
|
10
12
|
|
11
13
|
def post_install_message
|
@@ -18,9 +20,19 @@ module Bashly
|
|
18
20
|
EOF
|
19
21
|
end
|
20
22
|
|
23
|
+
private
|
24
|
+
|
21
25
|
def function_name
|
22
|
-
|
26
|
+
@function_name ||= args[0] || 'send_completions'
|
23
27
|
end
|
28
|
+
|
29
|
+
def completions_function_code(function_name)
|
30
|
+
[
|
31
|
+
"## [@bashly-upgrade completions #{function_name}]",
|
32
|
+
command.completion_function(function_name)
|
33
|
+
].join "\n"
|
34
|
+
end
|
35
|
+
|
24
36
|
end
|
25
37
|
end
|
26
38
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Bashly
|
2
|
+
module Libraries
|
3
|
+
class CompletionsScript < Completions
|
4
|
+
def files
|
5
|
+
[
|
6
|
+
{
|
7
|
+
path: target_path,
|
8
|
+
content: command.completion_script
|
9
|
+
}
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_install_message
|
14
|
+
<<~EOF
|
15
|
+
In order to enable completions, run:
|
16
|
+
|
17
|
+
!txtpur!$ source #{target_path}
|
18
|
+
EOF
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def target_path
|
24
|
+
@target_path ||= args[0] || "#{Settings.target_dir}/completions.bash"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Bashly
|
2
|
+
module Libraries
|
3
|
+
class CompletionsYAML < Completions
|
4
|
+
def files
|
5
|
+
[
|
6
|
+
{
|
7
|
+
path: target_path,
|
8
|
+
content: command.completion_data.to_yaml
|
9
|
+
}
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
def post_install_message
|
14
|
+
<<~EOF
|
15
|
+
This file can be converted to a completions script using the !txtgrn!completely!txtrst! gem.
|
16
|
+
EOF
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def target_path
|
22
|
+
@target_path ||= args[0] || "#{Settings.target_dir}/completions.yml"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
colors:
|
2
|
+
files:
|
3
|
+
- source: "templates/lib/colors.sh"
|
4
|
+
target: "%{user_source_dir}/lib/colors.sh"
|
5
|
+
|
6
|
+
config:
|
7
|
+
files:
|
8
|
+
- source: "templates/lib/config.sh"
|
9
|
+
target: "%{user_source_dir}/lib/config.sh"
|
10
|
+
|
11
|
+
yaml:
|
12
|
+
files:
|
13
|
+
- source: "templates/lib/yaml.sh"
|
14
|
+
target: "%{user_source_dir}/lib/yaml.sh"
|
15
|
+
|
16
|
+
lib:
|
17
|
+
files:
|
18
|
+
- source: "templates/lib/sample_function.sh"
|
19
|
+
target: "%{user_source_dir}/lib/sample_function.sh"
|
20
|
+
|
21
|
+
strings:
|
22
|
+
files:
|
23
|
+
- source: "templates/strings.yml"
|
24
|
+
target: "%{user_source_dir}/bashly-strings.yml"
|
25
|
+
|
26
|
+
validations:
|
27
|
+
files:
|
28
|
+
- source: "templates/lib/validations/validate_dir_exists.sh"
|
29
|
+
target: "%{user_source_dir}/lib/validations/validate_dir_exists.sh"
|
30
|
+
- source: "templates/lib/validations/validate_file_exists.sh"
|
31
|
+
target: "%{user_source_dir}/lib/validations/validate_file_exists.sh"
|
32
|
+
- source: "templates/lib/validations/validate_integer.sh"
|
33
|
+
target: "%{user_source_dir}/lib/validations/validate_integer.sh"
|
34
|
+
- source: "templates/lib/validations/validate_not_empty.sh"
|
35
|
+
target: "%{user_source_dir}/lib/validations/validate_not_empty.sh"
|
36
|
+
|
37
|
+
completions: :CompletionsFunction
|
38
|
+
completions_script: :CompletionsScript
|
39
|
+
completions_yaml: :CompletionsYAML
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Bashly
|
2
|
+
class Library
|
3
|
+
class << self
|
4
|
+
def exist?(name)
|
5
|
+
config.has_key? name.to_s
|
6
|
+
end
|
7
|
+
|
8
|
+
def config
|
9
|
+
@config ||= YAML.load_file(config_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def config_path
|
13
|
+
@config_path ||= File.expand_path 'libraries.yml', __dir__
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
include AssetHelper
|
18
|
+
attr_reader :name, :args
|
19
|
+
|
20
|
+
def initialize(name, *args)
|
21
|
+
@name, @args = name.to_s, args
|
22
|
+
end
|
23
|
+
|
24
|
+
def files
|
25
|
+
if custom_handler
|
26
|
+
custom_handler.files
|
27
|
+
|
28
|
+
else
|
29
|
+
config['files'].map do |file|
|
30
|
+
{ path: file['target'] % target_file_args,
|
31
|
+
content: asset_content(file['source']) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def post_install_message
|
37
|
+
if custom_handler
|
38
|
+
custom_handler.post_install_message
|
39
|
+
else
|
40
|
+
config['post_install_message']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_file(path)
|
45
|
+
files.select { |f| f[:path] == path }.first
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def custom_handler
|
51
|
+
return nil unless config.is_a? Symbol
|
52
|
+
@custom_handler ||= Bashly::Libraries.const_get(config).new(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def config
|
56
|
+
@config ||= self.class.config[name]
|
57
|
+
end
|
58
|
+
|
59
|
+
def target_file_args
|
60
|
+
{ user_source_dir: Settings.source_dir }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module ComposeRefinements
|
4
|
+
refine Hash do
|
5
|
+
def compose(keyword = 'import')
|
6
|
+
result = {}
|
7
|
+
each do |k, v|
|
8
|
+
if k.to_s == keyword
|
9
|
+
sub = safe_load_yaml(v).compose keyword
|
10
|
+
if sub.is_a? Array
|
11
|
+
result = sub
|
12
|
+
else
|
13
|
+
result.merge! sub
|
14
|
+
end
|
15
|
+
elsif v.respond_to? :compose
|
16
|
+
result[k] = v.compose keyword
|
17
|
+
else
|
18
|
+
result[k] = v
|
19
|
+
end
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def safe_load_yaml(path)
|
25
|
+
loaded = YAML.load_file path
|
26
|
+
return loaded if loaded.is_a? Array or loaded.is_a? Hash
|
27
|
+
raise Bashly::ConfigurationError, "Cannot find a valid YAML in !txtgrn!#{path}"
|
28
|
+
|
29
|
+
rescue Errno::ENOENT
|
30
|
+
raise Bashly::ConfigurationError, "Cannot find import file !txtgrn!#{path}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
refine Array do
|
35
|
+
def compose(keyword = 'import')
|
36
|
+
map do |x|
|
37
|
+
if x.respond_to? :compose
|
38
|
+
x.compose keyword
|
39
|
+
else
|
40
|
+
x
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bashly/script/base.rb
CHANGED
@@ -23,6 +23,7 @@ module Bashly
|
|
23
23
|
long
|
24
24
|
name
|
25
25
|
parent_name
|
26
|
+
private
|
26
27
|
required
|
27
28
|
short
|
28
29
|
validate
|
@@ -32,7 +33,7 @@ module Bashly
|
|
32
33
|
def initialize(options)
|
33
34
|
raise Error, "Invalid options provided" unless options.respond_to? :keys
|
34
35
|
@options = options
|
35
|
-
|
36
|
+
validate_options if respond_to? :validate_options
|
36
37
|
end
|
37
38
|
|
38
39
|
def optional
|
@@ -32,18 +32,15 @@ module Bashly
|
|
32
32
|
|
33
33
|
# Returns a label for the catch_all directive
|
34
34
|
def catch_all_label
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
"#{catch_all['label'].upcase}..."
|
41
|
-
else
|
42
|
-
"..."
|
35
|
+
case catch_all
|
36
|
+
when nil then nil
|
37
|
+
when String then "#{catch_all.upcase}..."
|
38
|
+
when Hash then "#{catch_all['label'].upcase}..."
|
39
|
+
else "..."
|
43
40
|
end
|
44
41
|
end
|
45
42
|
|
46
|
-
# Returns a
|
43
|
+
# Returns a user defined help string for the catch_all directive
|
47
44
|
def catch_all_help
|
48
45
|
return nil unless catch_all
|
49
46
|
|
@@ -154,7 +151,7 @@ module Bashly
|
|
154
151
|
default_content = placeholder ? "echo \"error: cannot load file\"" : ''
|
155
152
|
|
156
153
|
content = if File.exist? path
|
157
|
-
File.read
|
154
|
+
File.read(path).remove_front_matter
|
158
155
|
else
|
159
156
|
default_content
|
160
157
|
end
|
@@ -213,9 +210,9 @@ module Bashly
|
|
213
210
|
end
|
214
211
|
|
215
212
|
# Raise an exception if there are some serious issues with the command
|
216
|
-
# definition.
|
217
|
-
def
|
218
|
-
|
213
|
+
# definition. This is called by Base#initialize.
|
214
|
+
def validate_options
|
215
|
+
Bashly::ConfigValidator.new(options).validate
|
219
216
|
end
|
220
217
|
|
221
218
|
# Returns an array of all the args with a whitelist
|
@@ -228,14 +225,6 @@ module Bashly
|
|
228
225
|
flags.select &:allowed
|
229
226
|
end
|
230
227
|
|
231
|
-
private
|
232
|
-
|
233
|
-
def verify_commands
|
234
|
-
if args.any? or flags.any?
|
235
|
-
raise ConfigurationError, "Error in the !txtgrn!#{full_name}!txtrst! command.\nThe !txtgrn!commands!txtrst! key cannot be at the same level as the !txtgrn!args!txtrst! or !txtgrn!flags!txtrst! keys."
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
228
|
end
|
240
229
|
end
|
241
230
|
end
|
data/lib/bashly/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# :command.default_assignments
|
2
2
|
% default_args.each do |arg|
|
3
|
-
[[ -n ${args[<%= arg.name %>]} ]] || args[<%= arg.name %>]="<%= arg.default %>"
|
3
|
+
[[ -n ${args[<%= arg.name %>]:-} ]] || args[<%= arg.name %>]="<%= arg.default %>"
|
4
4
|
% end
|
5
5
|
% default_flags.each do |flag|
|
6
|
-
[[ -n ${args[<%= flag.long %>]} ]] || args[<%= flag.long %>]="<%= flag.default %>"
|
6
|
+
[[ -n ${args[<%= flag.long %>]:-} ]] || args[<%= flag.long %>]="<%= flag.default %>"
|
7
7
|
% end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
## Code here runs inside the initialize() function
|
2
|
+
## Use it for anything that you need to run before any other function, like
|
3
|
+
## setting environment vairables:
|
4
|
+
## CONFIG_FILE=settings.ini
|
5
|
+
##
|
6
|
+
## Feel free to empty (but not delete) this file.
|
@@ -6,7 +6,7 @@ export <%= env_var.name.upcase %>="${<%= env_var.name.upcase %>:-<%= env_var.def
|
|
6
6
|
% end
|
7
7
|
% if required_environment_variables.any?
|
8
8
|
% required_environment_variables.each do |env_var|
|
9
|
-
if [[ -z "
|
9
|
+
if [[ -z "${<%= env_var.name.upcase %>:-}" ]]; then
|
10
10
|
printf "<%= strings[:missing_required_environment_variable] % { var: env_var.name.upcase } %>\n"
|
11
11
|
exit 1
|
12
12
|
fi
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# :command.run
|
2
2
|
run() {
|
3
|
-
declare -A args
|
4
|
-
declare -a other_args
|
5
|
-
declare -a input
|
3
|
+
declare -A args=()
|
4
|
+
declare -a other_args=()
|
5
|
+
declare -a input=()
|
6
6
|
normalize_input "$@"
|
7
7
|
parse_requirements "${input[@]}"
|
8
8
|
|
9
9
|
<%- condition = "if" -%>
|
10
10
|
<%- deep_commands.each do |command| -%>
|
11
11
|
<%= condition %> [[ $action == "<%= command.action_name %>" ]]; then
|
12
|
-
if [[ ${args[--help]} ]]; then
|
12
|
+
if [[ ${args[--help]:-} ]]; then
|
13
13
|
long_usage=yes
|
14
14
|
<%= command.function_name %>_usage
|
15
15
|
else
|
@@ -3,7 +3,7 @@
|
|
3
3
|
printf "<%= strings[:commands] %>\n"
|
4
4
|
% end
|
5
5
|
% maxlen = command_names.map(&:size).max
|
6
|
-
% commands.each do |command|
|
6
|
+
% commands.reject(&:private).each do |command|
|
7
7
|
% summary = command.summary
|
8
8
|
% summary = strings[:default_command_summary] % { summary: summary } if command.default
|
9
9
|
% if command.group
|
data/lib/bashly.rb
CHANGED
@@ -9,7 +9,8 @@ requires 'bashly/concerns'
|
|
9
9
|
|
10
10
|
requires 'bashly/settings'
|
11
11
|
requires 'bashly/exceptions'
|
12
|
+
requires 'bashly/refinements'
|
12
13
|
requires 'bashly/script/base'
|
13
14
|
requires 'bashly/commands/base'
|
14
|
-
requires 'bashly/
|
15
|
+
requires 'bashly/libraries/base'
|
15
16
|
requires 'bashly'
|
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.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: 2021-
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|
@@ -82,26 +82,25 @@ files:
|
|
82
82
|
- lib/bashly/commands/generate.rb
|
83
83
|
- lib/bashly/commands/init.rb
|
84
84
|
- lib/bashly/commands/preview.rb
|
85
|
+
- lib/bashly/commands/validate.rb
|
85
86
|
- lib/bashly/concerns/asset_helper.rb
|
86
87
|
- lib/bashly/concerns/completions.rb
|
87
88
|
- lib/bashly/concerns/renderable.rb
|
88
89
|
- lib/bashly/config.rb
|
90
|
+
- lib/bashly/config_validator.rb
|
89
91
|
- lib/bashly/exceptions.rb
|
90
92
|
- lib/bashly/extensions/array.rb
|
91
93
|
- lib/bashly/extensions/file.rb
|
92
94
|
- lib/bashly/extensions/string.rb
|
93
|
-
- lib/bashly/
|
94
|
-
- lib/bashly/
|
95
|
-
- lib/bashly/
|
96
|
-
- lib/bashly/
|
97
|
-
- lib/bashly/
|
98
|
-
- lib/bashly/
|
99
|
-
- lib/bashly/library
|
100
|
-
- lib/bashly/library/sample.rb
|
101
|
-
- lib/bashly/library/strings.rb
|
102
|
-
- lib/bashly/library/validations.rb
|
103
|
-
- lib/bashly/library/yaml.rb
|
95
|
+
- lib/bashly/libraries.yml
|
96
|
+
- lib/bashly/libraries/base.rb
|
97
|
+
- lib/bashly/libraries/completions.rb
|
98
|
+
- lib/bashly/libraries/completions_function.rb
|
99
|
+
- lib/bashly/libraries/completions_script.rb
|
100
|
+
- lib/bashly/libraries/completions_yaml.rb
|
101
|
+
- lib/bashly/library.rb
|
104
102
|
- lib/bashly/message_strings.rb
|
103
|
+
- lib/bashly/refinements/compose_refinements.rb
|
105
104
|
- lib/bashly/script/argument.rb
|
106
105
|
- lib/bashly/script/base.rb
|
107
106
|
- lib/bashly/script/command.rb
|
data/lib/bashly/library/base.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Bashly
|
2
|
-
module Library
|
3
|
-
class Base
|
4
|
-
include AssetHelper
|
5
|
-
|
6
|
-
attr_reader :target_path, :options
|
7
|
-
|
8
|
-
def initialize(target_path = nil, options = nil)
|
9
|
-
@target_path = target_path || Settings.source_dir
|
10
|
-
@options = options || {}
|
11
|
-
end
|
12
|
-
|
13
|
-
def files
|
14
|
-
case content
|
15
|
-
when String then content_from_string content
|
16
|
-
when Hash then [content]
|
17
|
-
else content
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def post_install_message
|
22
|
-
nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def content
|
26
|
-
raise NotImplementedError, "Please implement either #content"
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def content_from_string(string)
|
32
|
-
if File.directory? asset("templates/lib/#{string}")
|
33
|
-
content_for_dir string
|
34
|
-
else
|
35
|
-
[content_for_file(string)]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def content_for_file(file)
|
40
|
-
{
|
41
|
-
path: "#{target_path}/lib/#{file}",
|
42
|
-
content: asset_content("templates/lib/#{file}")
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
def content_for_dir(dir)
|
47
|
-
Dir[asset("templates/lib/#{dir}/*.sh")].sort.map do |file|
|
48
|
-
{
|
49
|
-
path: "#{target_path}/lib/#{dir}/#{File.basename file}",
|
50
|
-
content: File.read(file)
|
51
|
-
}
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Bashly
|
2
|
-
module Library
|
3
|
-
class Completions < Base
|
4
|
-
def content
|
5
|
-
{ path: target_path, content: file_content }
|
6
|
-
end
|
7
|
-
|
8
|
-
def file_content
|
9
|
-
raise NotImplementedError, "Please implement #file_content"
|
10
|
-
end
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def completions
|
15
|
-
@completions ||= command.completion_data
|
16
|
-
end
|
17
|
-
|
18
|
-
def config
|
19
|
-
@config ||= Bashly::Config.new "#{Settings.source_dir}/bashly.yml"
|
20
|
-
end
|
21
|
-
|
22
|
-
def command
|
23
|
-
@command ||= Script::Command.new config
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Bashly
|
2
|
-
module Library
|
3
|
-
class CompletionsScript < Completions
|
4
|
-
def file_content
|
5
|
-
command.completion_script
|
6
|
-
end
|
7
|
-
|
8
|
-
def post_install_message
|
9
|
-
<<~EOF
|
10
|
-
In order to enable completions, run:
|
11
|
-
|
12
|
-
!txtpur!$ source #{target_path}
|
13
|
-
EOF
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Bashly
|
2
|
-
module Library
|
3
|
-
class CompletionsYAML < Completions
|
4
|
-
def file_content
|
5
|
-
completions.to_yaml
|
6
|
-
end
|
7
|
-
|
8
|
-
def post_install_message
|
9
|
-
<<~EOF
|
10
|
-
This file can be converted to a completions script using the !txtgrn!completely!txtrst! gem.
|
11
|
-
EOF
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|