bashly 1.4.0.rc2 → 2.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/bashly/commands/completions.rb +3 -41
- data/lib/bashly/completions/README.md +3 -7
- data/lib/bashly/completions/bashly-completions.bash +178 -382
- data/lib/bashly/completions/completely.yaml +2 -4
- data/lib/bashly/config_validator.rb +55 -5
- data/lib/bashly/docs/arg.yml +12 -6
- data/lib/bashly/docs/command.yml +0 -12
- data/lib/bashly/docs/flag.yml +29 -5
- data/lib/bashly/libraries/libraries.yml +0 -15
- data/lib/bashly/libraries/settings/settings.yml +9 -1
- data/lib/bashly/script/argument.rb +12 -0
- data/lib/bashly/script/command.rb +1 -2
- data/lib/bashly/script/flag.rb +48 -11
- data/lib/bashly/script/introspection/commands.rb +5 -0
- data/lib/bashly/script/wrapper.rb +1 -1
- data/lib/bashly/settings.rb +28 -3
- data/lib/bashly/version.rb +1 -1
- data/lib/bashly/views/argument/completion.gtx +31 -0
- data/lib/bashly/views/argument/completion_filter.gtx +1 -0
- data/lib/bashly/views/command/completion_argument_candidates.gtx +11 -0
- data/lib/bashly/views/command/completion_argument_filter.gtx +25 -0
- data/lib/bashly/views/command/completion_command_candidates.gtx +3 -0
- data/lib/bashly/views/command/completion_flag_candidates.gtx +21 -0
- data/lib/bashly/views/command/completion_function.gtx +24 -0
- data/lib/bashly/views/command/completion_script.gtx +21 -0
- data/lib/bashly/views/command/completion_script_bash.gtx +63 -0
- data/lib/bashly/views/command/completion_script_zsh.gtx +52 -0
- data/lib/bashly/views/command/completion_word_filter.gtx +44 -0
- data/lib/bashly/views/command/completions.gtx +81 -0
- data/lib/bashly/views/command/inspect_args.gtx +3 -3
- data/lib/bashly/views/command/master_script.gtx +1 -0
- data/lib/bashly/views/command/start.gtx +9 -0
- data/lib/bashly/views/flag/argfile_case.gtx +8 -1
- data/lib/bashly/views/flag/case.gtx +9 -1
- data/lib/bashly/views/flag/completion.gtx +1 -0
- data/lib/bashly/views/flag/completion_filter.gtx +7 -0
- data/lib/bashly/views/flag/completion_filter_arg.gtx +10 -0
- data/lib/bashly/views/flag/completion_filter_block.gtx +8 -0
- data/lib/bashly/views/flag/completion_filter_no_arg.gtx +2 -0
- data/lib/bashly/views/flag/completion_value_candidates.gtx +31 -0
- data/lib/bashly.rb +2 -5
- metadata +22 -37
- data/lib/bashly/completion_builder.rb +0 -231
- data/lib/bashly/concerns/completions.rb +0 -48
- data/lib/bashly/libraries/completions/completions_function.rb +0 -37
- data/lib/bashly/libraries/completions/completions_script.rb +0 -28
- data/lib/bashly/libraries/completions/completions_yaml.rb +0 -26
- /data/lib/bashly/views/wrapper/{bash3_bouncer.gtx → bash_version_bouncer.gtx} +0 -0
|
@@ -60,9 +60,6 @@ tokens:
|
|
|
60
60
|
path:
|
|
61
61
|
library:
|
|
62
62
|
- colors
|
|
63
|
-
- completions
|
|
64
|
-
- completions_script
|
|
65
|
-
- completions_yaml
|
|
66
63
|
- config
|
|
67
64
|
- help
|
|
68
65
|
- hooks
|
|
@@ -91,7 +88,6 @@ tokens:
|
|
|
91
88
|
- command.args
|
|
92
89
|
- command.catch_all
|
|
93
90
|
- command.commands
|
|
94
|
-
- command.completions
|
|
95
91
|
- command.default
|
|
96
92
|
- command.dependencies
|
|
97
93
|
- command.environment_variables
|
|
@@ -118,6 +114,7 @@ tokens:
|
|
|
118
114
|
- environment_variable.required
|
|
119
115
|
- environment_variable.validate
|
|
120
116
|
- flag
|
|
117
|
+
- flag.alias
|
|
121
118
|
- flag.allowed
|
|
122
119
|
- flag.arg
|
|
123
120
|
- flag.completions
|
|
@@ -126,6 +123,7 @@ tokens:
|
|
|
126
123
|
- flag.help
|
|
127
124
|
- flag.long
|
|
128
125
|
- flag.needs
|
|
126
|
+
- flag.negatable
|
|
129
127
|
- flag.private
|
|
130
128
|
- flag.repeatable
|
|
131
129
|
- flag.required
|
|
@@ -88,6 +88,20 @@ module Bashly
|
|
|
88
88
|
assert [true, false, nil, 'always'].include?(value), "#{key} must be a boolean, or the string 'always'"
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
def assert_completions(key, value)
|
|
92
|
+
return unless value
|
|
93
|
+
|
|
94
|
+
assert_hash key, value, keys: %i[static dynamic options]
|
|
95
|
+
assert_array "#{key}.static", value['static'], of: :string
|
|
96
|
+
assert_array "#{key}.dynamic", value['dynamic'], of: :string
|
|
97
|
+
assert_array "#{key}.options", value['options'], of: :string
|
|
98
|
+
|
|
99
|
+
Array(value['options']).each do |option|
|
|
100
|
+
assert %w[files directories no-space].include?(option),
|
|
101
|
+
"#{key}.options contains an unknown option: #{option}"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
91
105
|
def assert_arg(key, value)
|
|
92
106
|
assert_hash key, value, keys: Script::Argument.option_keys
|
|
93
107
|
refute value['allowed'] && value['completions'], "#{key} cannot have both nub`allowed` and nub`completions`"
|
|
@@ -101,7 +115,7 @@ module Bashly
|
|
|
101
115
|
assert_boolean "#{key}.unique", value['unique']
|
|
102
116
|
|
|
103
117
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
|
104
|
-
|
|
118
|
+
assert_completions "#{key}.completions", value['completions']
|
|
105
119
|
|
|
106
120
|
refute value['name'].match(/^-/), "#{key}.name must not start with '-'"
|
|
107
121
|
|
|
@@ -126,23 +140,36 @@ module Bashly
|
|
|
126
140
|
assert_optional_string "#{key}.short", value['short']
|
|
127
141
|
assert_optional_string "#{key}.help", value['help']
|
|
128
142
|
assert_optional_string "#{key}.arg", value['arg']
|
|
143
|
+
assert_string_or_array "#{key}.alias", value['alias']
|
|
129
144
|
assert_string_or_array "#{key}.default", value['default']
|
|
130
145
|
assert_string_or_array "#{key}.validate", value['validate']
|
|
131
146
|
|
|
147
|
+
assert_boolean "#{key}.negatable", value['negatable']
|
|
132
148
|
assert_boolean "#{key}.private", value['private']
|
|
133
149
|
assert_boolean "#{key}.repeatable", value['repeatable']
|
|
134
150
|
assert_boolean "#{key}.unique", value['unique']
|
|
135
151
|
assert_boolean "#{key}.required", value['required']
|
|
136
152
|
assert_array "#{key}.allowed", value['allowed'], of: :string
|
|
137
153
|
assert_array "#{key}.conflicts", value['conflicts'], of: :string
|
|
138
|
-
|
|
154
|
+
assert_completions "#{key}.completions", value['completions']
|
|
139
155
|
|
|
140
156
|
assert value['long'].match(/^--[a-zA-Z0-9_-]+$/), "#{key}.long must be in the form of '--name'" if value['long']
|
|
141
157
|
assert value['short'].match(/^-[a-zA-Z0-9]$/), "#{key}.short must be in the form of '-n'" if value['short']
|
|
158
|
+
Array(value['alias']).each_with_index do |flag_alias, index|
|
|
159
|
+
alias_key = value['alias'].is_a?(Array) ? "#{key}.alias[#{index}]" : "#{key}.alias"
|
|
160
|
+
assert_flag_alias alias_key, flag_alias
|
|
161
|
+
end
|
|
142
162
|
refute value['arg'].match(/^-/), "#{key}.arg must not start with '-'" if value['arg']
|
|
143
163
|
|
|
144
164
|
refute value['required'] && value['default'], "#{key} cannot have both nub`required` and nub`default`"
|
|
145
165
|
|
|
166
|
+
if value['negatable']
|
|
167
|
+
assert value['long'], "#{key}.negatable requires nub`long`"
|
|
168
|
+
refute value['arg'], "#{key}.negatable does not make sense with nub`arg`"
|
|
169
|
+
refute value['repeatable'], "#{key}.negatable does not make sense with nub`repeatable`"
|
|
170
|
+
refute value['required'], "#{key}.negatable does not make sense with nub`required`"
|
|
171
|
+
end
|
|
172
|
+
|
|
146
173
|
if value['default']
|
|
147
174
|
assert value['arg'], "#{key}.default does not make sense without nub`arg`"
|
|
148
175
|
end
|
|
@@ -165,6 +192,13 @@ module Bashly
|
|
|
165
192
|
end
|
|
166
193
|
end
|
|
167
194
|
|
|
195
|
+
def assert_flag_alias(key, value)
|
|
196
|
+
assert(
|
|
197
|
+
value.match(/^--[a-zA-Z0-9_-]+$/) || value.match(/^-[a-zA-Z0-9]$/),
|
|
198
|
+
"#{key} must be in the form of '--name' or '-n'"
|
|
199
|
+
)
|
|
200
|
+
end
|
|
201
|
+
|
|
168
202
|
def assert_env_var(key, value)
|
|
169
203
|
assert_hash key, value, keys: Script::EnvironmentVariable.option_keys
|
|
170
204
|
assert_string "#{key}.name", value['name']
|
|
@@ -216,14 +250,12 @@ module Bashly
|
|
|
216
250
|
assert_array "#{key}.args", value['args'], of: :arg
|
|
217
251
|
assert_array "#{key}.flags", value['flags'], of: :flag
|
|
218
252
|
assert_array "#{key}.commands", value['commands'], of: :command
|
|
219
|
-
assert_array "#{key}.completions", value['completions'], of: :string
|
|
220
253
|
assert_array "#{key}.filters", value['filters'], of: :string
|
|
221
254
|
assert_array "#{key}.environment_variables", value['environment_variables'], of: :env_var
|
|
222
255
|
assert_array "#{key}.variables", value['variables'], of: :var
|
|
223
256
|
|
|
224
257
|
assert_uniq "#{key}.commands", value['commands'], %w[name alias]
|
|
225
|
-
|
|
226
|
-
assert_uniq "#{key}.flags", value['flags'], 'short'
|
|
258
|
+
assert_uniq_flags key, value['flags']
|
|
227
259
|
assert_uniq "#{key}.args", value['args'], 'name'
|
|
228
260
|
|
|
229
261
|
if value['function']
|
|
@@ -265,5 +297,23 @@ module Bashly
|
|
|
265
297
|
refute value['extensible'], "#{key}.extensible makes no sense"
|
|
266
298
|
end
|
|
267
299
|
end
|
|
300
|
+
|
|
301
|
+
def assert_uniq_flags(key, flags)
|
|
302
|
+
return unless flags
|
|
303
|
+
|
|
304
|
+
list = flags.flat_map do |flag|
|
|
305
|
+
[flag['long'], flag['short'], *Array(flag['alias']), negated_flag_name(flag)].compact
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
nonuniqs = list.nonuniq
|
|
309
|
+
assert nonuniqs.empty?,
|
|
310
|
+
"#{key}.flags contains non-unique elements (#{nonuniqs.join ', '}) in long or short or alias"
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def negated_flag_name(flag)
|
|
314
|
+
return unless flag['negatable'] == true && flag['long']
|
|
315
|
+
|
|
316
|
+
"--no-#{flag['long'].delete_prefix '--'}"
|
|
317
|
+
end
|
|
268
318
|
end
|
|
269
319
|
end
|
data/lib/bashly/docs/arg.yml
CHANGED
|
@@ -34,15 +34,21 @@ arg.allowed:
|
|
|
34
34
|
default: development
|
|
35
35
|
|
|
36
36
|
arg.completions:
|
|
37
|
-
help:
|
|
37
|
+
help: |-
|
|
38
|
+
Configure additional runtime completions.
|
|
39
|
+
`static` contains literal candidates. `dynamic` contains Bash commands that
|
|
40
|
+
print one candidate per line. `options` accepts `files`, `directories`, and
|
|
41
|
+
`no-space`.
|
|
38
42
|
url: https://bashly.dev/configuration/argument/#completions
|
|
39
43
|
example: |-
|
|
40
44
|
args:
|
|
41
|
-
- name:
|
|
42
|
-
help:
|
|
45
|
+
- name: branch
|
|
46
|
+
help: Branch to process
|
|
43
47
|
completions:
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
static: [main, develop]
|
|
49
|
+
dynamic:
|
|
50
|
+
- git branch --format='%(refname:short)'
|
|
51
|
+
options: [no-space]
|
|
46
52
|
|
|
47
53
|
arg.default:
|
|
48
54
|
help: Specify the value to apply when not provided by the user.
|
|
@@ -102,4 +108,4 @@ arg.validate:
|
|
|
102
108
|
example: |-
|
|
103
109
|
args:
|
|
104
110
|
- name: path
|
|
105
|
-
validate: file_exists
|
|
111
|
+
validate: file_exists
|
data/lib/bashly/docs/command.yml
CHANGED
|
@@ -74,18 +74,6 @@ command.commands:
|
|
|
74
74
|
alias: a
|
|
75
75
|
help: Register a local repository
|
|
76
76
|
|
|
77
|
-
command.completions:
|
|
78
|
-
help: Specify a list of additional completion suggestions when used in conjunction with `bashly add completions`.
|
|
79
|
-
url: https://bashly.dev/configuration/command/#completions
|
|
80
|
-
example: |-
|
|
81
|
-
commands:
|
|
82
|
-
- name: view
|
|
83
|
-
help: View a directory, system user or a git branch
|
|
84
|
-
completions:
|
|
85
|
-
- <directory>
|
|
86
|
-
- <user>
|
|
87
|
-
- $(git branch 2> /dev/null)
|
|
88
|
-
|
|
89
77
|
command.default:
|
|
90
78
|
help: Specify that this sub-command will be executed implicitly.
|
|
91
79
|
url: https://bashly.dev/configuration/command/#default
|
data/lib/bashly/docs/flag.yml
CHANGED
|
@@ -13,6 +13,17 @@ flag:
|
|
|
13
13
|
help: Repository user name
|
|
14
14
|
required: true
|
|
15
15
|
|
|
16
|
+
flag.alias:
|
|
17
|
+
help: Specify one or more aliases for this flag. Each alias must include the `--` or `-` prefix.
|
|
18
|
+
url: https://bashly.dev/configuration/flag/#alias
|
|
19
|
+
example: |-
|
|
20
|
+
flags:
|
|
21
|
+
- long: --container
|
|
22
|
+
short: -c
|
|
23
|
+
alias: [--pod, -p]
|
|
24
|
+
arg: name
|
|
25
|
+
help: Container name
|
|
26
|
+
|
|
16
27
|
flag.allowed:
|
|
17
28
|
help: Specify a list of allowed values. Can be used in conjunction with `default` and `required`, and must be accompanied by `arg`.
|
|
18
29
|
url: https://bashly.dev/configuration/flag/#allowed
|
|
@@ -47,14 +58,18 @@ flag.arg:
|
|
|
47
58
|
help: Specify the user name
|
|
48
59
|
|
|
49
60
|
flag.completions:
|
|
50
|
-
help:
|
|
61
|
+
help: |-
|
|
62
|
+
Configure additional runtime completions. Must be accompanied by `arg`.
|
|
63
|
+
`static` contains literal candidates. `dynamic` contains Bash commands that
|
|
64
|
+
print one candidate per line. `options` accepts `files`, `directories`, and
|
|
65
|
+
`no-space`.
|
|
51
66
|
url: https://bashly.dev/configuration/flag/#completions
|
|
52
67
|
example: |-
|
|
53
68
|
flags:
|
|
54
|
-
- long: --
|
|
55
|
-
arg:
|
|
69
|
+
- long: --config
|
|
70
|
+
arg: file
|
|
56
71
|
completions:
|
|
57
|
-
|
|
72
|
+
options: [files]
|
|
58
73
|
|
|
59
74
|
# Anything in the 'allowed' option is automatically added as a completion.
|
|
60
75
|
- long: --protocol
|
|
@@ -136,6 +151,15 @@ flag.needs:
|
|
|
136
151
|
help: Where to add the alias
|
|
137
152
|
needs: [--add]
|
|
138
153
|
|
|
154
|
+
flag.negatable:
|
|
155
|
+
help: Allow a boolean long flag to also be disabled with its `--no-` form.
|
|
156
|
+
url: https://bashly.dev/configuration/flag/#negatable
|
|
157
|
+
example: |-
|
|
158
|
+
flags:
|
|
159
|
+
- long: --color
|
|
160
|
+
help: Enable color output
|
|
161
|
+
negatable: true
|
|
162
|
+
|
|
139
163
|
flag.private:
|
|
140
164
|
help: Specify that this flag should not be displayed in the help text.
|
|
141
165
|
url: https://bashly.dev/configuration/flag/#private
|
|
@@ -205,4 +229,4 @@ flag.validate:
|
|
|
205
229
|
- long: --config
|
|
206
230
|
arg: path
|
|
207
231
|
help: Load configuration from a file
|
|
208
|
-
validate: file_exists
|
|
232
|
+
validate: file_exists
|
|
@@ -12,21 +12,6 @@ colors:
|
|
|
12
12
|
|
|
13
13
|
m`$ bashly add hooks`
|
|
14
14
|
|
|
15
|
-
completions:
|
|
16
|
-
help: Generate a bash completions function.
|
|
17
|
-
usage: '[PATH]'
|
|
18
|
-
handler: Bashly::Libraries::CompletionsFunction
|
|
19
|
-
|
|
20
|
-
completions_script:
|
|
21
|
-
help: Generate a standalone bash completions script.
|
|
22
|
-
usage: '[PATH]'
|
|
23
|
-
handler: Bashly::Libraries::CompletionsScript
|
|
24
|
-
|
|
25
|
-
completions_yaml:
|
|
26
|
-
help: Generate a completions YAML configuration for Completely.
|
|
27
|
-
usage: '[PATH]'
|
|
28
|
-
handler: Bashly::Libraries::CompletionsYAML
|
|
29
|
-
|
|
30
15
|
config:
|
|
31
16
|
help: Add functions for handling INI configuration files to the lib directory.
|
|
32
17
|
files:
|
|
@@ -157,13 +157,21 @@ env: development
|
|
|
157
157
|
# - always # render this feature in any environment
|
|
158
158
|
# - never # do not render this feature
|
|
159
159
|
enable_header_comment: always
|
|
160
|
-
|
|
160
|
+
enable_bash_version_bouncer: always
|
|
161
161
|
enable_view_markers: development
|
|
162
162
|
enable_inspect_args: development
|
|
163
163
|
enable_deps_array: always
|
|
164
164
|
enable_env_var_names_array: always
|
|
165
165
|
enable_sourcing: development
|
|
166
166
|
|
|
167
|
+
# Generate native runtime completions. Supported values:
|
|
168
|
+
# - ~ or false # disable completions (default)
|
|
169
|
+
# - minimal # generate the runtime completion engine without shell adapters
|
|
170
|
+
# - bash or zsh # generate the runtime engine and one shell adapter
|
|
171
|
+
# - bash,zsh # generate the runtime engine and selected shell adapters
|
|
172
|
+
# - full # generate the runtime engine and all available shell adapters
|
|
173
|
+
completions: ~
|
|
174
|
+
|
|
167
175
|
|
|
168
176
|
#-------------------------------------------------------------------------------
|
|
169
177
|
# DEVELOPER OPTIONS
|
|
@@ -23,6 +23,18 @@ module Bashly
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def completion_static
|
|
27
|
+
completions&.fetch('static', []) || []
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def completion_dynamic
|
|
31
|
+
completions&.fetch('dynamic', []) || []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def completion_options
|
|
35
|
+
completions&.fetch('options', []) || []
|
|
36
|
+
end
|
|
37
|
+
|
|
26
38
|
def label
|
|
27
39
|
repeatable ? "#{name.upcase}..." : name.upcase
|
|
28
40
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module Bashly
|
|
2
2
|
module Script
|
|
3
3
|
class Command < Base
|
|
4
|
-
include Completions::Command
|
|
5
4
|
include Introspection::Arguments
|
|
6
5
|
include Introspection::Commands
|
|
7
6
|
include Introspection::Dependencies
|
|
@@ -14,7 +13,7 @@ module Bashly
|
|
|
14
13
|
class << self
|
|
15
14
|
def option_keys
|
|
16
15
|
@option_keys ||= %i[
|
|
17
|
-
alias argfile args catch_all commands
|
|
16
|
+
alias argfile args catch_all commands
|
|
18
17
|
default dependencies environment_variables examples
|
|
19
18
|
extensible expose filename filters flags
|
|
20
19
|
footer function group help help_header_override name
|
data/lib/bashly/script/flag.rb
CHANGED
|
@@ -3,27 +3,34 @@ require 'shellwords'
|
|
|
3
3
|
module Bashly
|
|
4
4
|
module Script
|
|
5
5
|
class Flag < Base
|
|
6
|
-
include Completions::Flag
|
|
7
6
|
include Introspection::Visibility
|
|
8
7
|
include Introspection::Validate
|
|
9
8
|
|
|
10
9
|
class << self
|
|
11
10
|
def option_keys
|
|
12
11
|
@option_keys ||= %i[
|
|
13
|
-
allowed arg completions conflicts default help long needs
|
|
14
|
-
private repeatable required short unique validate
|
|
12
|
+
alias allowed arg completions conflicts default help long needs
|
|
13
|
+
negatable private repeatable required short unique validate
|
|
15
14
|
]
|
|
16
15
|
end
|
|
17
16
|
end
|
|
18
17
|
|
|
18
|
+
def alt
|
|
19
|
+
return [] unless options['alias']
|
|
20
|
+
|
|
21
|
+
options['alias'].is_a?(String) ? [options['alias']] : options['alias']
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
def aliases
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
[long, negated_long, short].compact + alt
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def positive_aliases
|
|
29
|
+
primary_aliases + alt
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def negated_long
|
|
33
|
+
"--no-#{long_without_prefix}" if negatable && long
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
def default_string
|
|
@@ -36,17 +43,47 @@ module Bashly
|
|
|
36
43
|
end
|
|
37
44
|
end
|
|
38
45
|
|
|
46
|
+
def completion_static
|
|
47
|
+
completions&.fetch('static', []) || []
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def completion_dynamic
|
|
51
|
+
completions&.fetch('dynamic', []) || []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def completion_options
|
|
55
|
+
completions&.fetch('options', []) || []
|
|
56
|
+
end
|
|
57
|
+
|
|
39
58
|
def name
|
|
40
59
|
long || short
|
|
41
60
|
end
|
|
42
61
|
|
|
43
62
|
def usage_string(extended: false)
|
|
44
|
-
result = [
|
|
63
|
+
result = [usage_aliases.join(', ')]
|
|
45
64
|
result << arg.upcase if arg
|
|
46
65
|
result << strings[:required] if required && extended
|
|
47
66
|
result << strings[:repeatable] if repeatable && extended
|
|
48
67
|
result.join ' '
|
|
49
68
|
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def primary_aliases
|
|
73
|
+
[long, short].compact
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def usage_aliases
|
|
77
|
+
[usage_long, short].compact + alt
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def usage_long
|
|
81
|
+
negatable && long ? "--[no-]#{long_without_prefix}" : long
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def long_without_prefix
|
|
85
|
+
long.delete_prefix '--'
|
|
86
|
+
end
|
|
50
87
|
end
|
|
51
88
|
end
|
|
52
89
|
end
|
|
@@ -41,6 +41,11 @@ module Bashly
|
|
|
41
41
|
commands.map(&:name)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Returns command names and aliases that can be offered as completions
|
|
45
|
+
def completion_aliases
|
|
46
|
+
public_commands.flat_map(&:aliases).reject { |name| name.end_with? '*' }
|
|
47
|
+
end
|
|
48
|
+
|
|
44
49
|
# Returns an array of the Commands
|
|
45
50
|
def commands
|
|
46
51
|
return [] unless options['commands']
|
|
@@ -46,7 +46,7 @@ module Bashly
|
|
|
46
46
|
|
|
47
47
|
def default_header
|
|
48
48
|
result = render 'header'
|
|
49
|
-
result += render('
|
|
49
|
+
result += render('bash_version_bouncer') unless function_name || !Settings.enabled?(:bash_version_bouncer)
|
|
50
50
|
result
|
|
51
51
|
end
|
|
52
52
|
|
data/lib/bashly/settings.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module Bashly
|
|
2
2
|
class Settings
|
|
3
|
+
COMPLETION_SHELLS = %w[bash zsh].freeze
|
|
4
|
+
|
|
3
5
|
class << self
|
|
4
6
|
include AssetHelper
|
|
5
7
|
|
|
@@ -7,9 +9,10 @@ module Bashly
|
|
|
7
9
|
:argfile_var,
|
|
8
10
|
:commands_dir,
|
|
9
11
|
:compact_short_flags,
|
|
12
|
+
:completions,
|
|
10
13
|
:conjoined_flag_args,
|
|
11
14
|
:config_path,
|
|
12
|
-
:
|
|
15
|
+
:enable_bash_version_bouncer,
|
|
13
16
|
:enable_deps_array,
|
|
14
17
|
:enable_env_var_names_array,
|
|
15
18
|
:enable_header_comment,
|
|
@@ -50,6 +53,28 @@ module Bashly
|
|
|
50
53
|
@compact_short_flags ||= get :compact_short_flags
|
|
51
54
|
end
|
|
52
55
|
|
|
56
|
+
def completions
|
|
57
|
+
@completions ||= get :completions
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def completions?
|
|
61
|
+
completions == 'minimal' || completion_shells.any?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def completion_shells
|
|
65
|
+
value = completions
|
|
66
|
+
return [] if value.nil? || value == false || value == 'minimal'
|
|
67
|
+
return COMPLETION_SHELLS if value == 'full'
|
|
68
|
+
|
|
69
|
+
shells = value.split(',', -1).map(&:strip) if value.is_a? String
|
|
70
|
+
valid = shells&.any? && shells.all? { |shell| COMPLETION_SHELLS.include? shell }
|
|
71
|
+
unique = shells&.uniq == shells
|
|
72
|
+
return shells if valid && unique
|
|
73
|
+
|
|
74
|
+
raise ConfigurationError,
|
|
75
|
+
"completions must be false, minimal, full, or a comma-separated list of: #{COMPLETION_SHELLS.join ', '}"
|
|
76
|
+
end
|
|
77
|
+
|
|
53
78
|
def conjoined_flag_args
|
|
54
79
|
@conjoined_flag_args ||= get :conjoined_flag_args
|
|
55
80
|
end
|
|
@@ -64,8 +89,8 @@ module Bashly
|
|
|
64
89
|
(send(:"enable_#{feature}") == 'development' && !production?)
|
|
65
90
|
end
|
|
66
91
|
|
|
67
|
-
def
|
|
68
|
-
@
|
|
92
|
+
def enable_bash_version_bouncer
|
|
93
|
+
@enable_bash_version_bouncer ||= get :enable_bash_version_bouncer
|
|
69
94
|
end
|
|
70
95
|
|
|
71
96
|
def enable_deps_array
|
data/lib/bashly/version.rb
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
if allowed
|
|
2
|
+
> local -a completion_values=(
|
|
3
|
+
allowed.each do |value|
|
|
4
|
+
> "{{ value }}"
|
|
5
|
+
end
|
|
6
|
+
> )
|
|
7
|
+
if unique
|
|
8
|
+
> local completion_value
|
|
9
|
+
> for completion_value in "${completion_values[@]}"; do
|
|
10
|
+
> if [[ -z "${completion_used_arguments["{{ name }}:$completion_value"]:-}" ]]; then
|
|
11
|
+
> completion_candidates "$completion_current" "$completion_value"
|
|
12
|
+
> fi
|
|
13
|
+
> done
|
|
14
|
+
else
|
|
15
|
+
> completion_candidates "$completion_current" "${completion_values[@]}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if completion_static.any?
|
|
20
|
+
> completion_candidates "$completion_current" {{ completion_static.map { |value| Shellwords.shellescape value }.join ' ' }}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
completion_dynamic.each do |command|
|
|
24
|
+
> if completion_output="$({ {{ command }}; } 2>/dev/null)"; then
|
|
25
|
+
> completion_dynamic_candidates "$completion_current" "$completion_output"
|
|
26
|
+
> fi
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if completion_options.any?
|
|
30
|
+
> completion_add_options {{ completion_options.join ' ' }}
|
|
31
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
> completion_used_arguments["{{ name }}:$1"]=1
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
if args.any?(&:unique)
|
|
2
|
+
> case "$completion_arg_index" in
|
|
3
|
+
args.each_with_index do |arg, index|
|
|
4
|
+
next unless arg.unique
|
|
5
|
+
|
|
6
|
+
> {{ index }})
|
|
7
|
+
= arg.render(:completion_filter).indent 4
|
|
8
|
+
> ;;
|
|
9
|
+
end
|
|
10
|
+
> esac
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if args.last.repeatable
|
|
14
|
+
last_arg_index = args.length - 1
|
|
15
|
+
> if [[ $completion_arg_index -lt {{ last_arg_index }} ]]; then
|
|
16
|
+
> completion_arg_index=$((completion_arg_index + 1))
|
|
17
|
+
> fi
|
|
18
|
+
> shift
|
|
19
|
+
else
|
|
20
|
+
> if [[ $completion_arg_index -ge {{ args.length }} ]]; then
|
|
21
|
+
> return
|
|
22
|
+
> fi
|
|
23
|
+
> completion_arg_index=$((completion_arg_index + 1))
|
|
24
|
+
> shift
|
|
25
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
if fixed_flags? || public_flags.any?
|
|
2
|
+
> if [[ $completion_current == -* ]]; then
|
|
3
|
+
if fixed_flags?
|
|
4
|
+
if short_flag_exist? '-h'
|
|
5
|
+
> completion_flag_candidates --help "$completion_current" --help
|
|
6
|
+
else
|
|
7
|
+
> completion_flag_candidates --help "$completion_current" --help -h
|
|
8
|
+
end
|
|
9
|
+
if root_command?
|
|
10
|
+
if short_flag_exist? '-v'
|
|
11
|
+
> completion_flag_candidates --version "$completion_current" --version
|
|
12
|
+
else
|
|
13
|
+
> completion_flag_candidates --version "$completion_current" --version -v
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
public_flags.each do |flag|
|
|
18
|
+
= flag.render(:completion).indent 2
|
|
19
|
+
end
|
|
20
|
+
> fi
|
|
21
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
= view_marker
|
|
2
|
+
|
|
3
|
+
> {{ function_name }}_completion() {
|
|
4
|
+
> local completion_current="$1"
|
|
5
|
+
if args.any?
|
|
6
|
+
> local completion_arg_index=0
|
|
7
|
+
end
|
|
8
|
+
if args.any?(&:unique)
|
|
9
|
+
> local -A completion_used_arguments=()
|
|
10
|
+
end
|
|
11
|
+
if flags.any?(&:unique)
|
|
12
|
+
> local -A completion_used_flag_values=()
|
|
13
|
+
end
|
|
14
|
+
> shift
|
|
15
|
+
>
|
|
16
|
+
= render(:completion_word_filter).indent 2
|
|
17
|
+
= render(:completion_command_candidates).indent 2
|
|
18
|
+
if default_command
|
|
19
|
+
> {{ default_command.function_name }}_completion "$completion_current"
|
|
20
|
+
end
|
|
21
|
+
= render(:completion_flag_candidates).indent 2
|
|
22
|
+
= render(:completion_argument_candidates).indent 2
|
|
23
|
+
> }
|
|
24
|
+
>
|