bashly 0.2.2 → 0.2.3
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/README.md +21 -10
- data/lib/bashly/commands/generate.rb +3 -2
- data/lib/bashly/concerns/renderable.rb +2 -0
- data/lib/bashly/extensions/string.rb +16 -9
- data/lib/bashly/models/argument.rb +0 -9
- data/lib/bashly/models/base.rb +12 -1
- data/lib/bashly/models/command.rb +45 -11
- data/lib/bashly/models/flag.rb +0 -9
- data/lib/bashly/templates/lib/config.sh +1 -2
- data/lib/bashly/templates/strings.yml +2 -2
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/argument/usage.erb +1 -1
- data/lib/bashly/views/command/command_filter.erb +3 -3
- data/lib/bashly/views/command/command_functions.erb +2 -2
- data/lib/bashly/views/command/default_script.erb +1 -1
- data/lib/bashly/views/command/fixed_flags_filter.erb +2 -2
- data/lib/bashly/views/command/function.erb +2 -2
- data/lib/bashly/views/command/parse_args.erb +5 -1
- data/lib/bashly/views/command/run.erb +4 -4
- data/lib/bashly/views/command/usage.erb +23 -3
- data/lib/bashly/views/command/usage_environment_variables.erb +1 -1
- data/lib/bashly/views/command/usage_examples.erb +2 -1
- data/lib/bashly/views/command/usage_fixed_flags.erb +4 -2
- data/lib/bashly/views/flag/usage.erb +1 -1
- metadata +2 -3
- data/lib/bashly/views/command/parse_args_secondary.erb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d40ad6e14ab17c88a939cea3be81f4b72fe8383021478d94c93328c4842fb395
|
4
|
+
data.tar.gz: 4cb84c229411360da7633dd4ad4a15bb53bfdf49fba81e82aecbf88ec3422d72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb14645de6f614ce24393820591f6917bd92a7c41c48f14456b789183648c8031653c0304f8e59a2c43fecd7a4f0ed0e9ab4cf6a5092f0e5bd742de157af7b0c
|
7
|
+
data.tar.gz: b1b9fca567512ade4957a9b484d853b871f2c2edbefb267fc0c8fdbea8e5c2b1c5792cc011e04b60d07dc9e09b62996e18c826fd67902d28549e505bce8c30ce
|
data/README.md
CHANGED
@@ -119,36 +119,42 @@ Configuration Reference
|
|
119
119
|
|
120
120
|
### Command options
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
any subcommand you define using `commands`.
|
122
|
+
Unless otherwise specified, these definitiona can be used for both the root
|
123
|
+
command and subcommands (under the `commands` definition).
|
125
124
|
|
126
125
|
```yaml
|
127
126
|
# The name of the script or subcommand
|
128
127
|
name: myscript
|
129
128
|
|
129
|
+
# An additional, optional name - usually used to denote a one letter
|
130
|
+
# variation of the command name
|
131
|
+
# Applicable only in subcommands
|
132
|
+
short: m
|
133
|
+
|
130
134
|
# The header text to display when using --help
|
131
135
|
# This can have multiple lines. In this case, the first line will be used as
|
132
136
|
# summary wherever appropriate.
|
133
137
|
help: a sample script generated with bashly
|
134
138
|
|
135
139
|
# The string to display when using --version
|
140
|
+
# Applicable only in the main command
|
136
141
|
version: 0.1.0
|
137
142
|
|
138
143
|
# Specify an array of examples to show when using --help
|
144
|
+
# Each example can have multiple lines.
|
139
145
|
examples:
|
140
146
|
- myscript download
|
141
147
|
- myscript download --force
|
142
148
|
|
143
149
|
# Specify an array of environment variables needed by your script
|
144
150
|
# This is used purely for displaying in the help text (when using --help)
|
151
|
+
# The help for each variable can have multiple lines.
|
145
152
|
environment_variable:
|
146
153
|
VARIABLE_NAME: Variable help text
|
147
154
|
|
148
155
|
# Specify the array of subcommands to generate.
|
149
156
|
# Each subcommand will have its own args and flags.
|
150
|
-
# If this is provided,
|
151
|
-
# script.
|
157
|
+
# If this is provided, you cannot provide flags or args for the main script.
|
152
158
|
commands:
|
153
159
|
- ...
|
154
160
|
|
@@ -185,8 +191,7 @@ bash function.
|
|
185
191
|
name: user
|
186
192
|
|
187
193
|
# The message to display when using --help.
|
188
|
-
# This can have multiple lines
|
189
|
-
# than ~70 characters, to avoid text wrapping in narrower terminals.
|
194
|
+
# This can have multiple lines.
|
190
195
|
help: Username to use for logging in
|
191
196
|
|
192
197
|
# Specify if this argument is required.
|
@@ -216,8 +221,7 @@ long: --output
|
|
216
221
|
short: -o
|
217
222
|
|
218
223
|
# The text to display when using --help
|
219
|
-
# This can have multiple lines
|
220
|
-
# than ~70 characters, to avoid text wrapping in narrower terminals.
|
224
|
+
# This can have multiple lines.
|
221
225
|
help: Specify the output directory
|
222
226
|
|
223
227
|
# If the flag requires an argument, specify its name here.
|
@@ -227,6 +231,13 @@ arg: directory
|
|
227
231
|
required: true
|
228
232
|
```
|
229
233
|
|
234
|
+
|
235
|
+
Real World Examples
|
236
|
+
--------------------------------------------------
|
237
|
+
|
238
|
+
- [Rush][rush] - a Personal Package Manager
|
239
|
+
|
240
|
+
|
230
241
|
Contributing / Support
|
231
242
|
--------------------------------------------------
|
232
243
|
|
@@ -234,4 +245,4 @@ If you experience any issue, have a question or a suggestion, or if you wish
|
|
234
245
|
to contribute, feel free to [open an issue][issues].
|
235
246
|
|
236
247
|
[issues]: https://github.com/DannyBen/bashly/issues
|
237
|
-
|
248
|
+
[rush]: https://github.com/DannyBen/rush-cli
|
@@ -36,8 +36,9 @@ module Bashly
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def create_all_command_files
|
39
|
-
command.
|
40
|
-
|
39
|
+
command.deep_commands.each do |subcommand|
|
40
|
+
next if subcommand.commands.any?
|
41
|
+
file = "#{Settings.source_dir}/#{subcommand.filename}"
|
41
42
|
content = subcommand.render :default_script
|
42
43
|
create_file file, content
|
43
44
|
end
|
@@ -1,20 +1,27 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'ostruct'
|
3
|
-
|
4
1
|
class String
|
2
|
+
def escape_newlines
|
3
|
+
gsub "\n", "\\n"
|
4
|
+
end
|
5
|
+
|
5
6
|
def indent(offset)
|
6
7
|
return self unless offset > 0
|
7
8
|
split("\n").indent(offset).join("\n")
|
8
9
|
end
|
9
10
|
|
10
|
-
def to_underscore
|
11
|
-
gsub
|
12
|
-
gsub!(' ', '_')
|
13
|
-
downcase!
|
11
|
+
def to_underscore
|
12
|
+
gsub(/(.)([A-Z])/,'\1_\2').gsub(' ', '_').downcase
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
17
|
-
|
15
|
+
def wrap(length = 80)
|
16
|
+
strip!
|
17
|
+
split("\n").collect! do |line|
|
18
|
+
if line.length > length
|
19
|
+
line.gsub!(/([^\s]{#{length}})([^\s$])/, "\\1 \\2")
|
20
|
+
line.gsub(/(.{1,#{length}})(\s+|$)/, "\\1\n").rstrip
|
21
|
+
else
|
22
|
+
line
|
23
|
+
end
|
24
|
+
end * "\n"
|
18
25
|
end
|
19
26
|
|
20
27
|
end
|
@@ -1,18 +1,9 @@
|
|
1
1
|
module Bashly
|
2
2
|
module Models
|
3
3
|
class Argument < Base
|
4
|
-
def optional
|
5
|
-
!required
|
6
|
-
end
|
7
|
-
|
8
4
|
def usage_string
|
9
5
|
required ? name.upcase : "[#{name.upcase}]"
|
10
6
|
end
|
11
|
-
|
12
|
-
def summary
|
13
|
-
return "" unless help
|
14
|
-
help.split("\n").first
|
15
|
-
end
|
16
7
|
end
|
17
8
|
end
|
18
9
|
end
|
data/lib/bashly/models/base.rb
CHANGED
@@ -26,13 +26,24 @@ module Bashly
|
|
26
26
|
verify if respond_to? :verify
|
27
27
|
end
|
28
28
|
|
29
|
+
def optional
|
30
|
+
!required
|
31
|
+
end
|
32
|
+
|
33
|
+
def summary
|
34
|
+
help.empty? ? "" : help.split("\n").first
|
35
|
+
end
|
36
|
+
|
37
|
+
def help
|
38
|
+
options['help'] ||= ''
|
39
|
+
end
|
40
|
+
|
29
41
|
def method_missing(method_name, *arguments, &block)
|
30
42
|
key = method_name.to_s
|
31
43
|
respond_to?(method_name) ? options[key] : super
|
32
44
|
end
|
33
45
|
|
34
46
|
def respond_to?(method_name, include_private = false)
|
35
|
-
# options.has_key?(method_name.to_s) || super
|
36
47
|
OPTION_KEYS.include?(method_name) || super
|
37
48
|
end
|
38
49
|
end
|
@@ -1,6 +1,15 @@
|
|
1
1
|
module Bashly
|
2
2
|
module Models
|
3
3
|
class Command < Base
|
4
|
+
# Returns the name to be used as an action.
|
5
|
+
# - If it is the root command, the action is "root"
|
6
|
+
# - Else, it is all the parents, except the first tone (root) joined
|
7
|
+
# by space. For example, for a command like "docker container run"
|
8
|
+
# the action name is "container run".
|
9
|
+
def action_name
|
10
|
+
parents.any? ? (parents[1..-1] + [name]).join(' ') : "root"
|
11
|
+
end
|
12
|
+
|
4
13
|
# Returns all the possible aliases for this command
|
5
14
|
def aliases
|
6
15
|
short ? [name, short] : [name]
|
@@ -28,11 +37,30 @@ module Bashly
|
|
28
37
|
def commands
|
29
38
|
return [] unless options["commands"]
|
30
39
|
options["commands"].map do |options|
|
31
|
-
options['
|
40
|
+
options['parents'] = parents + [name]
|
32
41
|
command = Command.new options
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|
45
|
+
# Returns a flat array containing all the commands in this tree.
|
46
|
+
# This includes self + children + grandchildres + ...
|
47
|
+
def deep_commands
|
48
|
+
result = []
|
49
|
+
commands.each do |command|
|
50
|
+
result << command
|
51
|
+
if command.commands.any?
|
52
|
+
result += command.deep_commands
|
53
|
+
end
|
54
|
+
end
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the bash filename that is expected to hold the user code
|
59
|
+
# for this command
|
60
|
+
def filename
|
61
|
+
"#{action_name.to_underscore}_command.sh"
|
62
|
+
end
|
63
|
+
|
36
64
|
# Returns an array of Flags
|
37
65
|
def flags
|
38
66
|
return [] unless options["flags"]
|
@@ -41,10 +69,15 @@ module Bashly
|
|
41
69
|
end
|
42
70
|
end
|
43
71
|
|
72
|
+
# Returns a unique name, suitable to be used in a bash function
|
73
|
+
def function_name
|
74
|
+
full_name.to_underscore
|
75
|
+
end
|
76
|
+
|
44
77
|
# Returns the name of the command, including its parent name (in case
|
45
78
|
# this is a subcommand)
|
46
79
|
def full_name
|
47
|
-
|
80
|
+
parents.any? ? (parents + [name]).join(' ') : name
|
48
81
|
end
|
49
82
|
|
50
83
|
# Reads a file from the userspace (Settings.source_dir) and returns
|
@@ -52,7 +85,7 @@ module Bashly
|
|
52
85
|
# If the file is not found, returns a string with a hint.
|
53
86
|
def load_user_file(file, placeholder: true)
|
54
87
|
path = "#{Settings.source_dir}/#{file}"
|
55
|
-
default_content = placeholder ? "
|
88
|
+
default_content = placeholder ? "echo \"error: cannot load file\"" : ''
|
56
89
|
|
57
90
|
content = if File.exist? path
|
58
91
|
File.read path
|
@@ -63,6 +96,12 @@ module Bashly
|
|
63
96
|
"# :#{path}\n#{content}"
|
64
97
|
end
|
65
98
|
|
99
|
+
# Returns an array of all parents. For example, the command
|
100
|
+
# "docker container run" will have [docker, container] as its parents
|
101
|
+
def parents
|
102
|
+
options['parents'] || []
|
103
|
+
end
|
104
|
+
|
66
105
|
# Returns an array of all the required Arguments
|
67
106
|
def required_args
|
68
107
|
args.select &:required
|
@@ -73,10 +112,9 @@ module Bashly
|
|
73
112
|
flags.select &:required
|
74
113
|
end
|
75
114
|
|
76
|
-
# Returns
|
77
|
-
def
|
78
|
-
|
79
|
-
help.split("\n").first
|
115
|
+
# Returns trus if this is the root command (no parents)
|
116
|
+
def root_command?
|
117
|
+
parents.empty?
|
80
118
|
end
|
81
119
|
|
82
120
|
# Returns a constructed string suitable for Usage pattern
|
@@ -109,10 +147,6 @@ module Bashly
|
|
109
147
|
if args.any? or flags.any?
|
110
148
|
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."
|
111
149
|
end
|
112
|
-
|
113
|
-
if parent_name
|
114
|
-
raise ConfigurationError, "Error in the !txtgrn!#{full_name}!txtrst! command.\nNested commands are not supported."
|
115
|
-
end
|
116
150
|
end
|
117
151
|
|
118
152
|
end
|
data/lib/bashly/models/flag.rb
CHANGED
@@ -11,15 +11,6 @@ module Bashly
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def optional
|
15
|
-
!required
|
16
|
-
end
|
17
|
-
|
18
|
-
def summary
|
19
|
-
return "" unless help
|
20
|
-
help.split("\n").first
|
21
|
-
end
|
22
|
-
|
23
14
|
def usage_string(extended: false)
|
24
15
|
result = [aliases.join(", ")]
|
25
16
|
result << arg.upcase if arg
|
@@ -100,7 +100,6 @@ config_show() {
|
|
100
100
|
# done
|
101
101
|
#
|
102
102
|
config_keys() {
|
103
|
-
key=$1
|
104
103
|
regex="^(.*)\s*="
|
105
104
|
|
106
105
|
config_init
|
@@ -112,5 +111,5 @@ config_keys() {
|
|
112
111
|
keys+=("$key")
|
113
112
|
fi
|
114
113
|
done < "$CONFIG_FILE"
|
115
|
-
echo ${keys[@]}
|
114
|
+
echo "${keys[@]}"
|
116
115
|
}
|
@@ -7,8 +7,8 @@ examples: "Examples:"
|
|
7
7
|
environment_variables: "Environment Variables:"
|
8
8
|
|
9
9
|
# Fixed flags help text
|
10
|
-
|
11
|
-
|
10
|
+
help_flag_text: Show this help
|
11
|
+
version_flag_text: Show version number
|
12
12
|
|
13
13
|
# Error messages
|
14
14
|
flag_requires_an_argument: "%{long} requires an argument: %{usage}"
|
data/lib/bashly/version.rb
CHANGED
@@ -10,17 +10,17 @@ case $action in
|
|
10
10
|
<%= command.aliases.join " | " %> )
|
11
11
|
action="<%= command.name %>"
|
12
12
|
shift
|
13
|
-
<%= command.
|
13
|
+
<%= command.function_name %>_parse_args "$@"
|
14
14
|
shift $#
|
15
15
|
;;
|
16
16
|
|
17
17
|
<%- end -%>
|
18
18
|
* )
|
19
|
-
<%=
|
19
|
+
<%= function_name %>_usage
|
20
20
|
exit 1
|
21
21
|
;;
|
22
22
|
|
23
23
|
esac
|
24
24
|
<%- else -%>
|
25
|
-
action=
|
25
|
+
action="<%= action_name %>"
|
26
26
|
<%- end -%>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
echo "# this file is located in '<%= Settings.source_dir
|
1
|
+
echo "# this file is located in '<%= "#{Settings.source_dir}/#{filename}" %>'"
|
2
2
|
echo "# code for '<%= full_name %>' goes here"
|
3
3
|
echo "# you can edit it freely and regenerate (it will not be overwritten)"
|
4
4
|
inspect_args
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# :command.parse_args
|
2
|
+
<%- if root_command? -%>
|
2
3
|
parse_args() {
|
4
|
+
<%- else -%>
|
5
|
+
<%= function_name %>_parse_args() {
|
6
|
+
<%- end -%>
|
3
7
|
<%= render(:fixed_flags_filter).indent 2 %>
|
4
8
|
<%= render(:command_filter).indent 2 %>
|
5
9
|
<%= render(:required_args_filter).indent 2 %>
|
@@ -8,5 +12,5 @@ parse_args() {
|
|
8
12
|
}
|
9
13
|
|
10
14
|
<%- commands.each do |command| %>
|
11
|
-
<%= command.render '
|
15
|
+
<%= command.render 'parse_args' %>
|
12
16
|
<%- end -%>
|
@@ -4,13 +4,13 @@ run() {
|
|
4
4
|
parse_args "$@"
|
5
5
|
|
6
6
|
<%- condition = "if" -%>
|
7
|
-
<%-
|
8
|
-
<%= condition %> [[ $action == "<%= command.
|
7
|
+
<%- deep_commands.each do |command| -%>
|
8
|
+
<%= condition %> [[ $action == "<%= command.action_name %>" ]]; then
|
9
9
|
if [[ ${args[--help]} ]]; then
|
10
10
|
long_usage=yes
|
11
|
-
<%= command.
|
11
|
+
<%= command.function_name %>_usage
|
12
12
|
else
|
13
|
-
<%= command.
|
13
|
+
<%= command.function_name %>_command
|
14
14
|
fi
|
15
15
|
<% condition = "elif" %>
|
16
16
|
<%- end -%>
|
@@ -1,9 +1,29 @@
|
|
1
1
|
# :command.usage
|
2
|
-
<%=
|
3
|
-
|
4
|
-
|
2
|
+
<%= function_name %>_usage() {
|
3
|
+
if [[ -n $long_usage ]]; then
|
4
|
+
<%- if summary == help -%>
|
5
|
+
echo -e "<%= caption_string %>"
|
6
|
+
echo
|
7
|
+
<%- else -%>
|
8
|
+
echo -e "<%= full_name %>"
|
9
|
+
echo
|
10
|
+
echo -e "<%= help.wrap(78).indent(2).escape_newlines %>"
|
11
|
+
echo
|
12
|
+
<%- end -%>
|
13
|
+
else
|
14
|
+
echo -e "<%= caption_string %>"
|
15
|
+
echo
|
16
|
+
fi
|
5
17
|
echo -e "<%= strings[:usage] %>"
|
6
18
|
echo -e " <%= usage_string %>"
|
19
|
+
<%- if commands.any? -%>
|
20
|
+
echo -e " <%= full_name %> [command] --help | -h"
|
21
|
+
<%- else -%>
|
22
|
+
echo -e " <%= full_name %> --help | -h"
|
23
|
+
<%- end -%>
|
24
|
+
<%- if root_command? -%>
|
25
|
+
echo -e " <%= full_name %> --version"
|
26
|
+
<%- end -%>
|
7
27
|
echo
|
8
28
|
<%= render(:usage_commands).indent 2 if commands.any? %>
|
9
29
|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# :command.usage_fixed_flags
|
2
2
|
echo " --help, -h"
|
3
|
-
echo -e " <%= strings[:
|
3
|
+
echo -e " <%= strings[:help_flag_text] %>"
|
4
4
|
echo
|
5
|
+
<%- if root_command? -%>
|
5
6
|
echo " --version"
|
6
|
-
echo -e " <%= strings[:
|
7
|
+
echo -e " <%= strings[:version_flag_text] %>"
|
7
8
|
echo
|
9
|
+
<%- 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.2.
|
4
|
+
version: 0.2.3
|
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: 2019-11-
|
11
|
+
date: 2019-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colsole
|
@@ -101,7 +101,6 @@ files:
|
|
101
101
|
- lib/bashly/views/command/master_script.erb
|
102
102
|
- lib/bashly/views/command/parse_args.erb
|
103
103
|
- lib/bashly/views/command/parse_args_case.erb
|
104
|
-
- lib/bashly/views/command/parse_args_secondary.erb
|
105
104
|
- lib/bashly/views/command/parse_args_while.erb
|
106
105
|
- lib/bashly/views/command/required_args_filter.erb
|
107
106
|
- lib/bashly/views/command/required_flags_filter.erb
|