bashly 0.7.8 → 0.8.0
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 +2 -1
- data/lib/bashly/commands/add.rb +41 -33
- data/lib/bashly/commands/base.rb +21 -3
- data/lib/bashly/commands/generate.rb +23 -11
- data/lib/bashly/commands/preview.rb +5 -4
- data/lib/bashly/commands/validate.rb +7 -1
- data/lib/bashly/concerns/renderable.rb +8 -1
- data/lib/bashly/concerns/validation_helpers.rb +69 -0
- data/lib/bashly/config_validator.rb +28 -41
- data/lib/bashly/deprecation.rb +25 -0
- data/lib/bashly/extensions/array.rb +5 -0
- data/lib/bashly/extensions/string.rb +6 -0
- data/lib/bashly/extensions/yaml.rb +2 -0
- data/lib/bashly/libraries.yml +13 -9
- data/lib/bashly/script/argument.rb +13 -1
- data/lib/bashly/script/base.rb +7 -29
- data/lib/bashly/script/catch_all.rb +4 -0
- data/lib/bashly/script/command.rb +35 -7
- data/lib/bashly/script/environment_variable.rb +6 -0
- data/lib/bashly/script/flag.rb +9 -0
- data/lib/bashly/script/wrapper.rb +11 -7
- data/lib/bashly/settings.rb +34 -5
- data/lib/bashly/templates/bashly.yml +2 -2
- data/lib/bashly/templates/settings.yml +24 -0
- data/lib/bashly/templates/strings.yml +1 -1
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/argument/usage.erb +2 -2
- data/lib/bashly/views/argument/validations.erb +1 -1
- data/lib/bashly/views/command/catch_all_filter.erb +1 -1
- data/lib/bashly/views/command/command_fallback.erb +1 -1
- data/lib/bashly/views/command/command_filter.erb +1 -1
- data/lib/bashly/views/command/command_functions.erb +1 -1
- data/lib/bashly/views/command/default_assignments.erb +1 -1
- data/lib/bashly/views/command/dependencies_filter.erb +1 -1
- 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/footer.erb +1 -0
- data/lib/bashly/views/command/function.erb +1 -1
- data/lib/bashly/views/command/initialize.erb +1 -1
- data/lib/bashly/views/command/inspect_args.erb +1 -1
- data/lib/bashly/views/command/master_script.erb +1 -0
- data/lib/bashly/views/command/normalize_input.erb +1 -1
- data/lib/bashly/views/command/parse_requirements.erb +1 -1
- data/lib/bashly/views/command/parse_requirements_case.erb +5 -23
- data/lib/bashly/views/command/parse_requirements_case_catch_all.erb +18 -0
- data/lib/bashly/views/command/parse_requirements_case_repeatable.erb +18 -0
- data/lib/bashly/views/command/parse_requirements_case_simple.erb +18 -0
- data/lib/bashly/views/command/parse_requirements_while.erb +1 -1
- data/lib/bashly/views/command/required_args_filter.erb +1 -1
- data/lib/bashly/views/command/required_flags_filter.erb +1 -1
- data/lib/bashly/views/command/root_command.erb +1 -1
- data/lib/bashly/views/command/run.erb +1 -1
- data/lib/bashly/views/command/usage.erb +3 -3
- data/lib/bashly/views/command/usage_args.erb +1 -1
- data/lib/bashly/views/command/usage_commands.erb +1 -1
- data/lib/bashly/views/command/usage_environment_variables.erb +1 -1
- data/lib/bashly/views/command/usage_examples.erb +1 -1
- data/lib/bashly/views/command/usage_fixed_flags.erb +1 -1
- data/lib/bashly/views/command/usage_flags.erb +1 -1
- data/lib/bashly/views/command/user_filter.erb +1 -1
- data/lib/bashly/views/command/user_lib.erb +2 -2
- data/lib/bashly/views/command/version_command.erb +1 -1
- data/lib/bashly/views/command/whitelist_filter.erb +11 -1
- data/lib/bashly/views/environment_variable/usage.erb +1 -1
- data/lib/bashly/views/flag/case.erb +2 -28
- data/lib/bashly/views/flag/case_arg.erb +19 -0
- data/lib/bashly/views/flag/case_no_arg.erb +8 -0
- data/lib/bashly/views/flag/conflicts.erb +1 -1
- data/lib/bashly/views/flag/usage.erb +1 -1
- data/lib/bashly/views/flag/validations.erb +1 -1
- data/lib/bashly/views/wrapper/bash3_bouncer.erb +1 -1
- data/lib/bashly/views/wrapper/wrapper.erb +1 -1
- metadata +10 -2
data/lib/bashly/script/base.rb
CHANGED
|
@@ -5,33 +5,11 @@ module Bashly
|
|
|
5
5
|
|
|
6
6
|
attr_reader :options
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
conflicts
|
|
14
|
-
default
|
|
15
|
-
dependencies
|
|
16
|
-
description
|
|
17
|
-
environment_variables
|
|
18
|
-
examples
|
|
19
|
-
extensible
|
|
20
|
-
filters
|
|
21
|
-
flags
|
|
22
|
-
footer
|
|
23
|
-
group
|
|
24
|
-
help
|
|
25
|
-
long
|
|
26
|
-
name
|
|
27
|
-
parent_name
|
|
28
|
-
private
|
|
29
|
-
repeatable
|
|
30
|
-
required
|
|
31
|
-
short
|
|
32
|
-
validate
|
|
33
|
-
version
|
|
34
|
-
]
|
|
8
|
+
class << self
|
|
9
|
+
def option_keys
|
|
10
|
+
@option_keys ||= []
|
|
11
|
+
end
|
|
12
|
+
end
|
|
35
13
|
|
|
36
14
|
def initialize(options)
|
|
37
15
|
raise Error, "Invalid options provided" unless options.respond_to? :keys
|
|
@@ -39,7 +17,7 @@ module Bashly
|
|
|
39
17
|
end
|
|
40
18
|
|
|
41
19
|
def optional
|
|
42
|
-
!required
|
|
20
|
+
!options['required']
|
|
43
21
|
end
|
|
44
22
|
|
|
45
23
|
def summary
|
|
@@ -56,7 +34,7 @@ module Bashly
|
|
|
56
34
|
end
|
|
57
35
|
|
|
58
36
|
def respond_to_missing?(method_name, include_private = false)
|
|
59
|
-
|
|
37
|
+
self.class.option_keys.include?(method_name) || super
|
|
60
38
|
end
|
|
61
39
|
end
|
|
62
40
|
end
|
|
@@ -4,6 +4,20 @@ module Bashly
|
|
|
4
4
|
include Completions
|
|
5
5
|
include CommandScopes
|
|
6
6
|
|
|
7
|
+
class << self
|
|
8
|
+
def option_keys
|
|
9
|
+
@option_keys ||= %i[
|
|
10
|
+
alias args catch_all commands completions
|
|
11
|
+
default dependencies environment_variables examples
|
|
12
|
+
extensible filename filters flags
|
|
13
|
+
footer group help name
|
|
14
|
+
private version
|
|
15
|
+
short
|
|
16
|
+
]
|
|
17
|
+
# DEPRECATION 0.8.0
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
7
21
|
# Returns the name to be used as an action.
|
|
8
22
|
# - If it is the root command, the action is "root"
|
|
9
23
|
# - Else, it is all the parents, except the first one (root) joined
|
|
@@ -15,7 +29,15 @@ module Bashly
|
|
|
15
29
|
|
|
16
30
|
# Returns all the possible aliases for this command
|
|
17
31
|
def aliases
|
|
18
|
-
|
|
32
|
+
[name] + alt
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns an array of alternative aliases if any
|
|
36
|
+
def alt
|
|
37
|
+
# DEPRECATION 0.8.0
|
|
38
|
+
options['alias'] ||= options['short']
|
|
39
|
+
return [] unless options["alias"]
|
|
40
|
+
options['alias'].is_a?(String) ? [options['alias']] : options['alias']
|
|
19
41
|
end
|
|
20
42
|
|
|
21
43
|
# Returns an array of Arguments
|
|
@@ -28,7 +50,7 @@ module Bashly
|
|
|
28
50
|
|
|
29
51
|
# Returns a string suitable to be a headline
|
|
30
52
|
def caption_string
|
|
31
|
-
help ? "#{full_name} - #{summary}"
|
|
53
|
+
help.empty? ? full_name : "#{full_name} - #{summary}"
|
|
32
54
|
end
|
|
33
55
|
|
|
34
56
|
def catch_all
|
|
@@ -82,15 +104,16 @@ module Bashly
|
|
|
82
104
|
# If the file is not found, returns a string with a hint.
|
|
83
105
|
def load_user_file(file, placeholder: true)
|
|
84
106
|
path = "#{Settings.source_dir}/#{file}"
|
|
85
|
-
default_content = placeholder ? "echo \"error: cannot load file\"" : ''
|
|
86
107
|
|
|
87
108
|
content = if File.exist? path
|
|
88
109
|
File.read(path).remove_front_matter
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
elsif placeholder
|
|
111
|
+
%q[echo "error: cannot load file"]
|
|
112
|
+
else
|
|
113
|
+
''
|
|
91
114
|
end
|
|
92
115
|
|
|
93
|
-
"#
|
|
116
|
+
Settings.production? ? content : "#{view_marker path}\n#{content}"
|
|
94
117
|
end
|
|
95
118
|
|
|
96
119
|
# Returns an array of all parents. For example, the command
|
|
@@ -99,7 +122,12 @@ module Bashly
|
|
|
99
122
|
options['parents'] || []
|
|
100
123
|
end
|
|
101
124
|
|
|
102
|
-
# Returns
|
|
125
|
+
# Returns true if one of the args is repeatable
|
|
126
|
+
def repeatable_arg_exist?
|
|
127
|
+
args.select(&:repeatable).any?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Returns true if this is the root command (no parents)
|
|
103
131
|
def root_command?
|
|
104
132
|
parents.empty?
|
|
105
133
|
end
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
module Bashly
|
|
2
2
|
module Script
|
|
3
3
|
class EnvironmentVariable < Base
|
|
4
|
+
class << self
|
|
5
|
+
def option_keys
|
|
6
|
+
@option_keys ||= %i[default help name required]
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
4
10
|
def usage_string(extended: false)
|
|
5
11
|
result = [name.upcase]
|
|
6
12
|
result << strings[:required] if required and extended
|
data/lib/bashly/script/flag.rb
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
module Bashly
|
|
2
2
|
module Script
|
|
3
3
|
class Flag < Base
|
|
4
|
+
class << self
|
|
5
|
+
def option_keys
|
|
6
|
+
@option_keys ||= %i[
|
|
7
|
+
allowed arg conflicts default help long repeatable required
|
|
8
|
+
short validate
|
|
9
|
+
]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
4
13
|
def aliases
|
|
5
14
|
if long and short
|
|
6
15
|
[long, short]
|
|
@@ -9,18 +9,22 @@ module Bashly
|
|
|
9
9
|
@command, @function_name = command, function_name
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def code
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
def code(tab_indent: false)
|
|
13
|
+
tab_indent ? base_code.expand_tabs : base_code
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def base_code
|
|
19
|
+
result = if function_name
|
|
20
|
+
[header, render('wrapper')]
|
|
15
21
|
else
|
|
16
|
-
|
|
22
|
+
[header, body]
|
|
17
23
|
end
|
|
18
24
|
|
|
19
|
-
result.lint
|
|
25
|
+
result.join("\n").lint
|
|
20
26
|
end
|
|
21
27
|
|
|
22
|
-
private
|
|
23
|
-
|
|
24
28
|
def header
|
|
25
29
|
@header ||= header!
|
|
26
30
|
end
|
data/lib/bashly/settings.rb
CHANGED
|
@@ -1,27 +1,56 @@
|
|
|
1
1
|
module Bashly
|
|
2
2
|
class Settings
|
|
3
3
|
class << self
|
|
4
|
-
attr_writer :source_dir, :target_dir, :lib_dir, :strict
|
|
4
|
+
attr_writer :source_dir, :target_dir, :lib_dir, :strict, :tab_indent
|
|
5
5
|
|
|
6
6
|
def source_dir
|
|
7
|
-
@source_dir ||=
|
|
7
|
+
@source_dir ||= get :source_dir, 'src'
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def target_dir
|
|
11
|
-
@target_dir ||=
|
|
11
|
+
@target_dir ||= get :target_dir, '.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def lib_dir
|
|
15
|
-
@lib_dir ||=
|
|
15
|
+
@lib_dir ||= get :lib_dir, 'lib'
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def strict
|
|
19
|
-
@strict ||=
|
|
19
|
+
@strict ||= get :strict
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def tab_indent
|
|
23
|
+
@tab_indent ||= get :tab_indent
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def env
|
|
27
|
+
@env ||= get(:env, :development)&.to_sym
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def env=(value)
|
|
31
|
+
@env = value&.to_sym
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def production?
|
|
35
|
+
env == :production
|
|
20
36
|
end
|
|
21
37
|
|
|
22
38
|
def full_lib_dir
|
|
23
39
|
"#{source_dir}/#{lib_dir}"
|
|
24
40
|
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def get(key, default = nil)
|
|
45
|
+
ENV["BASHLY_#{key.upcase}"] || user_settings[key.to_s] || default
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def user_settings
|
|
49
|
+
@user_settings ||= begin
|
|
50
|
+
File.exist?('settings.yml') ? Config.new('settings.yml') : {}
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
25
54
|
end
|
|
26
55
|
end
|
|
27
56
|
end
|
|
@@ -8,7 +8,7 @@ environment_variables:
|
|
|
8
8
|
|
|
9
9
|
commands:
|
|
10
10
|
- name: download
|
|
11
|
-
|
|
11
|
+
alias: d
|
|
12
12
|
help: Download a file
|
|
13
13
|
|
|
14
14
|
args:
|
|
@@ -32,7 +32,7 @@ commands:
|
|
|
32
32
|
help: Set the default location to download to
|
|
33
33
|
|
|
34
34
|
- name: upload
|
|
35
|
-
|
|
35
|
+
alias: u
|
|
36
36
|
help: Upload a file
|
|
37
37
|
args:
|
|
38
38
|
- name: source
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# All settings are optional (with their default values provided below), and
|
|
2
|
+
# can also be set with an environment variable with the same name, capitalized
|
|
3
|
+
# and prefixed by `BASHLY_` - for example: BASHLY_SOURCE_DIR
|
|
4
|
+
|
|
5
|
+
# The path containing the bashly configuration and source files
|
|
6
|
+
source_dir: src
|
|
7
|
+
|
|
8
|
+
# The path to use for creating the bash script
|
|
9
|
+
target_dir: .
|
|
10
|
+
|
|
11
|
+
# The path to use for upgrading library files, relative to the source dir
|
|
12
|
+
lib_dir: lib
|
|
13
|
+
|
|
14
|
+
# When true, enable bash strict mode (set -euo pipefail)
|
|
15
|
+
strict: false
|
|
16
|
+
|
|
17
|
+
# When true, the generated script will use tab indentation instead of spaces
|
|
18
|
+
# (every 2 leading spaces will be converted to a tab character)
|
|
19
|
+
tab_indent: false
|
|
20
|
+
|
|
21
|
+
# Set to 'production' or 'development':
|
|
22
|
+
# - production generate a smaller script, without file markers
|
|
23
|
+
# - development generate with file markers
|
|
24
|
+
env: development
|
|
@@ -11,7 +11,7 @@ environment_variables: "Environment Variables:"
|
|
|
11
11
|
group: "%{group} Commands:"
|
|
12
12
|
|
|
13
13
|
# Usage helpers
|
|
14
|
-
|
|
14
|
+
command_alias: "Alias: %{alias}"
|
|
15
15
|
default_command_summary: "%{summary} (default)"
|
|
16
16
|
required: "(required)"
|
|
17
17
|
repeatable: "(repeatable)"
|
data/lib/bashly/version.rb
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
% if args.any?
|
|
3
|
-
% condition = "if"
|
|
4
|
-
% args.each do |arg|
|
|
5
|
-
<%= condition %> [[ -z ${args[<%= arg.name %>]+x} ]]; then
|
|
6
|
-
<%= arg.render(:validations).indent 2 %>
|
|
7
|
-
args[<%= arg.name %>]=$1
|
|
8
|
-
shift
|
|
9
|
-
% condition = "elif"
|
|
10
|
-
% end
|
|
11
|
-
else
|
|
1
|
+
<%= view_marker %>
|
|
12
2
|
% if catch_all.enabled?
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
printf "<%= strings[:invalid_argument] %>\n" "$key"
|
|
17
|
-
exit 1
|
|
18
|
-
% end
|
|
19
|
-
fi
|
|
20
|
-
% elsif catch_all.enabled?
|
|
21
|
-
other_args+=("$1")
|
|
22
|
-
shift
|
|
3
|
+
<%= render(:parse_requirements_case_catch_all) %>
|
|
4
|
+
% elsif repeatable_arg_exist?
|
|
5
|
+
<%= render(:parse_requirements_case_repeatable) %>
|
|
23
6
|
% else
|
|
24
|
-
|
|
25
|
-
exit 1
|
|
7
|
+
<%= render(:parse_requirements_case_simple) %>
|
|
26
8
|
% end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%= view_marker %>
|
|
2
|
+
% if args.any?
|
|
3
|
+
% condition = "if"
|
|
4
|
+
% args.each do |arg|
|
|
5
|
+
<%= condition %> [[ -z ${args[<%= arg.name %>]+x} ]]; then
|
|
6
|
+
<%= arg.render(:validations).indent 2 %>
|
|
7
|
+
args[<%= arg.name %>]=$1
|
|
8
|
+
shift
|
|
9
|
+
% condition = "elif"
|
|
10
|
+
% end
|
|
11
|
+
else
|
|
12
|
+
other_args+=("$1")
|
|
13
|
+
shift
|
|
14
|
+
fi
|
|
15
|
+
% else
|
|
16
|
+
other_args+=("$1")
|
|
17
|
+
shift
|
|
18
|
+
% end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%= view_marker %>
|
|
2
|
+
% condition = "if"
|
|
3
|
+
% args.each do |arg|
|
|
4
|
+
<%= condition %> [[ -z ${args[<%= arg.name %>]+x} ]]; then
|
|
5
|
+
<%= arg.render(:validations).indent 2 %>
|
|
6
|
+
% if arg.repeatable
|
|
7
|
+
args[<%= arg.name %>]="\"$1\""
|
|
8
|
+
shift
|
|
9
|
+
else
|
|
10
|
+
args[<%= arg.name %>]="${args[<%= arg.name %>]} \"$1\""
|
|
11
|
+
shift
|
|
12
|
+
% else
|
|
13
|
+
args[<%= arg.name %>]=$1
|
|
14
|
+
shift
|
|
15
|
+
% end
|
|
16
|
+
% condition = "elif"
|
|
17
|
+
% end
|
|
18
|
+
fi
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%= view_marker %>
|
|
2
|
+
% if args.any?
|
|
3
|
+
% condition = "if"
|
|
4
|
+
% args.each do |arg|
|
|
5
|
+
<%= condition %> [[ -z ${args[<%= arg.name %>]+x} ]]; then
|
|
6
|
+
<%= arg.render(:validations).indent 2 %>
|
|
7
|
+
args[<%= arg.name %>]=$1
|
|
8
|
+
shift
|
|
9
|
+
% condition = "elif"
|
|
10
|
+
% end
|
|
11
|
+
else
|
|
12
|
+
printf "<%= strings[:invalid_argument] %>\n" "$key"
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
% else
|
|
16
|
+
printf "<%= strings[:invalid_argument] %>\n" "$key"
|
|
17
|
+
exit 1
|
|
18
|
+
% end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<%= view_marker %>
|
|
2
2
|
<%= function_name %>_usage() {
|
|
3
3
|
if [[ -n $long_usage ]]; then
|
|
4
4
|
<%- if summary == help -%>
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
echo
|
|
16
16
|
fi
|
|
17
17
|
|
|
18
|
-
<%- if
|
|
19
|
-
printf "<%= strings[:
|
|
18
|
+
<%- if alt&.any? -%>
|
|
19
|
+
printf "<%= strings[:command_alias] % { alias: alt.join(', ') } %>\n"
|
|
20
20
|
echo
|
|
21
21
|
<%- end -%>
|
|
22
22
|
|