bashly 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|