hammer_cli 0.19.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/hammer-complete +28 -0
- data/config/cli_config.template.yml +2 -0
- data/config/hammer.completion +5 -0
- data/doc/creating_commands.md +27 -0
- data/doc/installation.md +47 -4
- data/doc/release_notes.md +17 -9
- data/lib/hammer_cli.rb +1 -0
- data/lib/hammer_cli/abstract.rb +32 -2
- data/lib/hammer_cli/apipie/api_connection.rb +5 -1
- data/lib/hammer_cli/apipie/command.rb +3 -2
- data/lib/hammer_cli/bash.rb +2 -0
- data/lib/hammer_cli/bash/completion.rb +159 -0
- data/lib/hammer_cli/bash/prebuild_command.rb +21 -0
- data/lib/hammer_cli/connection.rb +4 -0
- data/lib/hammer_cli/exception_handler.rb +10 -1
- data/lib/hammer_cli/main.rb +5 -3
- data/lib/hammer_cli/options/normalizers.rb +7 -3
- data/lib/hammer_cli/options/option_definition.rb +22 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +1 -5
- data/lib/hammer_cli/output/adapter/base.rb +1 -1
- data/lib/hammer_cli/output/adapter/csv.rb +3 -2
- data/lib/hammer_cli/output/adapter/json.rb +14 -3
- data/lib/hammer_cli/output/adapter/silent.rb +1 -1
- data/lib/hammer_cli/output/adapter/table.rb +26 -7
- data/lib/hammer_cli/output/adapter/yaml.rb +6 -3
- data/lib/hammer_cli/output/output.rb +2 -4
- data/lib/hammer_cli/settings.rb +2 -1
- data/lib/hammer_cli/utils.rb +5 -0
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
- data/man/hammer.1.gz +0 -0
- data/test/unit/apipie/api_connection_test.rb +1 -0
- data/test/unit/bash_test.rb +138 -0
- data/test/unit/exception_handler_test.rb +44 -0
- data/test/unit/output/adapter/base_test.rb +58 -0
- data/test/unit/output/adapter/csv_test.rb +63 -1
- data/test/unit/output/adapter/json_test.rb +61 -0
- data/test/unit/output/adapter/table_test.rb +70 -1
- data/test/unit/output/adapter/yaml_test.rb +59 -0
- data/test/unit/output/output_test.rb +3 -3
- metadata +75 -68
- data/hammer_cli_complete +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1beb690641cf038528a35bee7964c73e60acbe8a70e94bb9d1a72af372218ea1
|
4
|
+
data.tar.gz: 516fd63e88f8df2996aefd0d3276a9ff56e1bf5f17c1a7a8b656210512f2896c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b35646b4dc9c494687b7bbd38c578ce5cf70e90080025f622b89a28f1c1d29abeafc11dbe1e16cb0786fe8ae3ac4c8673b905e8bf03cf87de86383817c653a6
|
7
|
+
data.tar.gz: 3a01e546cf71e7f015ec27d8c127328e380c3736106bc01b95d1b81593f2c7fa0a027e90a95bbf179407a953da871911e8dd0349c0ed980ed5cad613bd98363b
|
data/bin/hammer-complete
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
@project_root = File.expand_path('../..', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(File.join(@project_root, 'lib'))
|
6
|
+
HAMMER = ENV['HAMMER'] || File.join(@project_root, 'bin/hammer')
|
7
|
+
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
completion_cache_file = ENV['HAMMER_COMPLETION_CACHE'] || '~/.cache/hammer_completion.yml'
|
11
|
+
completion_cache_file = File.expand_path(completion_cache_file)
|
12
|
+
|
13
|
+
# build the cache if it does not exist
|
14
|
+
unless File.exist?(completion_cache_file)
|
15
|
+
require 'hammer_cli'
|
16
|
+
`#{HAMMER} prebuild-bash-completion`
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'hammer_cli/bash/completion'
|
20
|
+
|
21
|
+
dict = HammerCLI::Bash::Completion.load_description(completion_cache_file)
|
22
|
+
|
23
|
+
comp_line = ENV['COMP_LINE'] || ''
|
24
|
+
comp_args = comp_line.split(' ', 2).last || ''
|
25
|
+
|
26
|
+
result = HammerCLI::Bash::Completion.new(dict).complete(comp_args)
|
27
|
+
|
28
|
+
puts result.join("\n")
|
data/doc/creating_commands.md
CHANGED
@@ -494,6 +494,33 @@ You first create an _output definition_ that you apply to your data. The result
|
|
494
494
|
is a collection of fields, each having its type. The collection is then passed to an
|
495
495
|
_output adapter_ which handles the actual formatting and printing.
|
496
496
|
|
497
|
+
Adapters support printing by chunks, e.g. if you want to print a large set of
|
498
|
+
data (1000+ records), but you make several calls to the server instead of one,
|
499
|
+
you may want to print received data right away instead of waiting for the rest.
|
500
|
+
This can be achieved via `:current_chunk` option for
|
501
|
+
`print_collection` and `print_data` methods. Allowed values for `:current_chunk`
|
502
|
+
are `:first`, `:another`, `:last`. By default adapters use `:single` value that
|
503
|
+
means only one record will be printed.
|
504
|
+
|
505
|
+
##### Printing by chunks
|
506
|
+
```ruby
|
507
|
+
# ...
|
508
|
+
def execute
|
509
|
+
loop do
|
510
|
+
# ...
|
511
|
+
data = send_request
|
512
|
+
print_data(data, current_chunk: :first)
|
513
|
+
# ...
|
514
|
+
data = send_request
|
515
|
+
print_data(data, current_chunk: :another)
|
516
|
+
# ...
|
517
|
+
data = send_request
|
518
|
+
print_data(data, current_chunk: :last)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
# ...
|
522
|
+
```
|
523
|
+
|
497
524
|
Hammer provides a DSL for defining the output. Next rather complex example will
|
498
525
|
explain how to use it in action.
|
499
526
|
|
data/doc/installation.md
CHANGED
@@ -132,8 +132,51 @@ And you are done. Your hammer client is configured and ready to use.
|
|
132
132
|
Autocompletion
|
133
133
|
--------------
|
134
134
|
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
The completion offers suggestion of possible command-line subcommands and their
|
136
|
+
options as usual. It can also suggest values for options and params where file
|
137
|
+
or directory path is expected.
|
138
|
+
|
139
|
+
Bash completion is automatically installed by RPM. To use it for development
|
140
|
+
setup `cp ./config/hammer.completion /etc/bash_completion.d/hammer` and load it
|
141
|
+
to the current shell `source /etc/bash_completion.d/hammer`. Make sure
|
142
|
+
the `$PWD/bin` is in `PATH` or there is full path to `hammer-complete`
|
143
|
+
executable specified in `/etc/bash_completion.d/hammer`.
|
144
|
+
|
145
|
+
Bash completion for hammer needs pre-built cache that holds description of
|
146
|
+
all subcommands and its parameters. The cache is located by default in
|
147
|
+
`~/.cache/hammer_completion.yml`. The location can be changed in hammer's
|
148
|
+
config file. The cache can be built manually with
|
149
|
+
`hammer prebuild-bash-completion` or is built automatically when completion is
|
150
|
+
used and the cache is missing (this may cause slight delay). The cache expires
|
151
|
+
if your API cache was changed (it indicates that the features on the instance
|
152
|
+
may have changed which has impact on hammer CLI options and subcommands).
|
153
|
+
|
154
|
+
#### Available value types
|
155
|
+
|
156
|
+
Completion of values is dependent on CLI option and prameter settings, e.g.:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
option '--value', 'VALUE', 'One of a, b, c', completion: { type: :enum, values: %w[a b c] }
|
160
|
+
```
|
138
161
|
|
139
|
-
|
162
|
+
Possible options for the `:completion` attribute are:
|
163
|
+
- `{ type: :flag }` option has no value, default for flags.
|
164
|
+
- `{ type: :value }` option has value of unknown type, no suggestions for the
|
165
|
+
value, default.
|
166
|
+
- `{ type: :list }` option has value of list type, no suggestions for the
|
167
|
+
value.
|
168
|
+
- `{ type: :key_value_list }` option has value of key=value list type, no
|
169
|
+
suggestions for the value.
|
170
|
+
- `{ type: :directory }` value is directory, suggestions follow directory
|
171
|
+
structure.
|
172
|
+
- `{ type: :file, filter: '\.txt$' }` value is file, suggestions follow
|
173
|
+
directory structure, optional `:filter` is regexp to filter the results.
|
174
|
+
- `{ type: :enum, values: ['first', 'second']}` option can have one of the
|
175
|
+
listed values, suggestions follow specified `values`.
|
176
|
+
- `{ type: :multienum, values: ['first', 'second']}` option can have one or
|
177
|
+
more of the listed values, suggestions follow specified `values`.
|
178
|
+
- `{ type: :schema, schema: 'a=int\,b=string' }` option should have value
|
179
|
+
according to specified schema, suggestion is the specified schema.
|
180
|
+
|
181
|
+
All those completion attributes are generated automatically, specify you own to
|
182
|
+
override.
|
data/doc/release_notes.md
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
|
-
### 0.
|
4
|
-
*
|
5
|
-
|
6
|
-
|
3
|
+
### 2.0.0 (2020-02-12)
|
4
|
+
* Bump version to 2.0.0
|
5
|
+
* Bump version to 2.0 ([PR #324](https://github.com/theforeman/hammer-cli/pull/324))
|
6
|
+
* Better promts for missing arguments, [#28793](http://projects.theforeman.org/issues/28793)
|
7
7
|
* Allow column max width more than 80, [#28503](http://projects.theforeman.org/issues/28503)
|
8
|
+
* Remove computing sha, [#27728](http://projects.theforeman.org/issues/27728)
|
9
|
+
* Fixed userdata false display in image list, [#28134](http://projects.theforeman.org/issues/28134)
|
10
|
+
* Add new bash completion, [#27728](http://projects.theforeman.org/issues/27728)
|
11
|
+
* Allow adapters print page by page, [#17819](http://projects.theforeman.org/issues/17819)
|
12
|
+
* Add release documentation ([PR #317](https://github.com/theforeman/hammer-cli/pull/317)), [#28149](http://projects.theforeman.org/issues/28149)
|
13
|
+
* Fix pr links in release notes ([PR #318](https://github.com/theforeman/hammer-cli/pull/318)), [#28202](http://projects.theforeman.org/issues/28202)
|
8
14
|
* Extract table generator into reusable component ([PR #314](https://github.com/theforeman/hammer-cli/pull/314)), [#27318](http://projects.theforeman.org/issues/27318)
|
15
|
+
* Better prompts for missing arguments ([PR #313](https://github.com/theforeman/hammer-cli/pull/313)), [#27595](http://projects.theforeman.org/issues/27595)
|
16
|
+
* Bump to 0.20-develop
|
9
17
|
|
10
18
|
### 0.19.0 (2019-10-26)
|
11
|
-
* Allow schema building for custom options ([PR #316](https://github.com/
|
12
|
-
* New lines in text attr dont break output ([PR #300](https://github.com/
|
13
|
-
* Added error to wrong --output ([PR #315](https://github.com/
|
14
|
-
* Pr review checklist ([PR #305](https://github.com/
|
15
|
-
* List items in help with customization ([PR #309](https://github.com/
|
19
|
+
* Allow schema building for custom options ([PR #316](https://github.com/theforeman/hammer-cli/pull/316)), [#27899](http://projects.theforeman.org/issues/27899)
|
20
|
+
* New lines in text attr dont break output ([PR #300](https://github.com/theforeman/hammer-cli/pull/300)), [#25878](http://projects.theforeman.org/issues/25878)
|
21
|
+
* Added error to wrong --output ([PR #315](https://github.com/theforeman/hammer-cli/pull/315)), [#21590](http://projects.theforeman.org/issues/21590)
|
22
|
+
* Pr review checklist ([PR #305](https://github.com/theforeman/hammer-cli/pull/305)), [#26950](http://projects.theforeman.org/issues/26950)
|
23
|
+
* List items in help with customization ([PR #309](https://github.com/theforeman/hammer-cli/pull/309)), [#27237](http://projects.theforeman.org/issues/27237)
|
16
24
|
|
17
25
|
### 0.18.0 (2019-08-01)
|
18
26
|
* Unsure minimal label length ([PR #310](https://github.com/theforeman/hammer-cli/pull/310)) ([#26960](http://projects.theforeman.org/issues/26960))
|
data/lib/hammer_cli.rb
CHANGED
data/lib/hammer_cli/abstract.rb
CHANGED
@@ -74,6 +74,7 @@ module HammerCLI
|
|
74
74
|
begin
|
75
75
|
begin
|
76
76
|
exit_code = super
|
77
|
+
context.delete(:fields)
|
77
78
|
raise "exit code must be integer" unless exit_code.is_a? Integer
|
78
79
|
rescue => e
|
79
80
|
exit_code = handle_exception(e)
|
@@ -194,6 +195,7 @@ module HammerCLI
|
|
194
195
|
block ||= option.default_conversion_block
|
195
196
|
define_accessors_for(option, &block)
|
196
197
|
extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
|
198
|
+
completion_type_for(option)
|
197
199
|
end
|
198
200
|
end
|
199
201
|
|
@@ -242,8 +244,8 @@ module HammerCLI
|
|
242
244
|
output.print_record(definition, record)
|
243
245
|
end
|
244
246
|
|
245
|
-
def print_collection(definition, collection)
|
246
|
-
output.print_collection(definition, collection)
|
247
|
+
def print_collection(definition, collection, options = {})
|
248
|
+
output.print_collection(definition, collection, options)
|
247
249
|
end
|
248
250
|
|
249
251
|
def print_message(msg, msg_params = {}, options = {})
|
@@ -314,6 +316,7 @@ module HammerCLI
|
|
314
316
|
declared_options << option
|
315
317
|
block ||= option.default_conversion_block
|
316
318
|
define_accessors_for(option, &block)
|
319
|
+
completion_type_for(option, opts)
|
317
320
|
end
|
318
321
|
extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
|
319
322
|
option
|
@@ -352,6 +355,33 @@ module HammerCLI
|
|
352
355
|
sources
|
353
356
|
end
|
354
357
|
|
358
|
+
def self.completion_map
|
359
|
+
completion = {}
|
360
|
+
# collect options
|
361
|
+
recognised_options.each do |opt|
|
362
|
+
opt.switches.each do |switch|
|
363
|
+
completion[switch] = completion_types.fetch(switch, {})
|
364
|
+
end
|
365
|
+
end
|
366
|
+
# collect subcommands recursively
|
367
|
+
recognised_subcommands.each do |cmd|
|
368
|
+
completion[cmd.names.first] = cmd.subcommand_class.completion_map
|
369
|
+
end
|
370
|
+
# collect params
|
371
|
+
completion[:params] = completion_types[:params] unless completion_types[:params].empty?
|
372
|
+
completion
|
373
|
+
end
|
374
|
+
|
375
|
+
def self.completion_types
|
376
|
+
@completion_types ||= { :params => [] }
|
377
|
+
end
|
378
|
+
|
379
|
+
def self.completion_type_for(option, opts = {})
|
380
|
+
completion_type = opts.delete(:completion)
|
381
|
+
completion_type ||= option.completion_type(opts[:format])
|
382
|
+
[option.switches].flatten(1).each { |s| completion_types[s] = completion_type }
|
383
|
+
end
|
384
|
+
|
355
385
|
private
|
356
386
|
|
357
387
|
def self.inherited_output_definition
|
@@ -10,7 +10,11 @@ module HammerCLI::Apipie
|
|
10
10
|
@api = ApipieBindings::API.new(params, HammerCLI::SSLOptions.new.get_options(params[:uri]))
|
11
11
|
if options[:reload_cache]
|
12
12
|
@api.clean_cache
|
13
|
-
|
13
|
+
HammerCLI.clear_cache
|
14
|
+
unless @logger.nil?
|
15
|
+
@logger.debug 'Apipie cache was cleared'
|
16
|
+
@logger.debug 'Completion cache was cleared'
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
@@ -65,8 +65,8 @@ module HammerCLI::Apipie
|
|
65
65
|
method_options(options)
|
66
66
|
end
|
67
67
|
|
68
|
-
def print_data(data)
|
69
|
-
print_collection(output_definition, data) unless output_definition.empty?
|
68
|
+
def print_data(data, options = {})
|
69
|
+
print_collection(output_definition, data, options) unless output_definition.empty?
|
70
70
|
print_success_message(data) unless success_message.nil?
|
71
71
|
end
|
72
72
|
|
@@ -86,6 +86,7 @@ module HammerCLI::Apipie
|
|
86
86
|
declared_options << option
|
87
87
|
block ||= option.default_conversion_block
|
88
88
|
define_accessors_for(option, &block)
|
89
|
+
completion_type_for(option, opts)
|
89
90
|
end
|
90
91
|
extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
|
91
92
|
option
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module HammerCLI
|
4
|
+
module Bash
|
5
|
+
class Completion
|
6
|
+
def initialize(dict)
|
7
|
+
@dict = dict
|
8
|
+
end
|
9
|
+
|
10
|
+
def complete(line)
|
11
|
+
@complete_line = line.end_with?(' ')
|
12
|
+
full_path = line.split(' ')
|
13
|
+
complete_path = @complete_line ? full_path : full_path[0..-2]
|
14
|
+
dict, path = traverse_tree(@dict, complete_path)
|
15
|
+
|
16
|
+
return [] unless path.empty? # lost during traversing
|
17
|
+
|
18
|
+
partial = @complete_line ? '' : full_path.last
|
19
|
+
finish_word(dict, partial)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.load_description(path)
|
23
|
+
JSON.load(File.open(path))
|
24
|
+
rescue Errno::ENOENT
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def finish_word(dict, incomplete)
|
31
|
+
finish_option_value(dict, incomplete) ||
|
32
|
+
(finish_option_or_subcommand(dict, incomplete) + finish_param(dict, incomplete))
|
33
|
+
end
|
34
|
+
|
35
|
+
def finish_option_or_subcommand(dict, incomplete)
|
36
|
+
dict.keys.select { |k| k.is_a?(String) && k =~ /^#{incomplete}/ }.map { |k| k + ' ' }
|
37
|
+
end
|
38
|
+
|
39
|
+
def complete_value(value_description, partial, is_param)
|
40
|
+
case value_description['type']
|
41
|
+
when 'value'
|
42
|
+
if !partial.empty?
|
43
|
+
[]
|
44
|
+
elsif is_param
|
45
|
+
['--->', 'Add parameter']
|
46
|
+
else
|
47
|
+
['--->', 'Add option <value>']
|
48
|
+
end
|
49
|
+
when 'directory'
|
50
|
+
directories(partial)
|
51
|
+
when 'file'
|
52
|
+
files(partial, value_description)
|
53
|
+
when 'enum'
|
54
|
+
enum(partial, value_description['values'])
|
55
|
+
when 'multienum'
|
56
|
+
multienum(partial, value_description['values'])
|
57
|
+
when 'schema'
|
58
|
+
schema(value_description['schema'])
|
59
|
+
when 'list'
|
60
|
+
['--->', 'Add comma-separated list of values']
|
61
|
+
when 'key_value_list'
|
62
|
+
['--->', 'Add comma-separated list of key=value']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def finish_param(dict, incomplete)
|
67
|
+
if dict['params'] && !dict['params'].empty?
|
68
|
+
complete_value(dict['params'].first, incomplete, true)
|
69
|
+
else
|
70
|
+
[]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def finish_option_value(dict, incomplete)
|
75
|
+
complete_value(dict, incomplete, false) if dict.key?('type')
|
76
|
+
end
|
77
|
+
|
78
|
+
def traverse_tree(dict, path)
|
79
|
+
return [dict, []] if path.nil? || path.empty?
|
80
|
+
result = if dict.key?(path.first)
|
81
|
+
if path.first.start_with?('-')
|
82
|
+
parse_option(dict, path)
|
83
|
+
else
|
84
|
+
parse_subcommand(dict, path)
|
85
|
+
end
|
86
|
+
elsif dict['params']
|
87
|
+
# traverse params one by one
|
88
|
+
parse_params(dict, path)
|
89
|
+
else
|
90
|
+
# not found
|
91
|
+
[{}, path]
|
92
|
+
end
|
93
|
+
result
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_params(dict, path)
|
97
|
+
traverse_tree({ 'params' => dict['params'][1..-1] }, path[1..-1])
|
98
|
+
end
|
99
|
+
|
100
|
+
def parse_subcommand(dict, path)
|
101
|
+
traverse_tree(dict[path.first], path[1..-1])
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_option(dict, path)
|
105
|
+
if dict[path.first]['type'] == 'flag' # flag
|
106
|
+
traverse_tree(dict, path[1..-1])
|
107
|
+
elsif path.length >= 2 # option with value
|
108
|
+
traverse_tree(dict, path[2..-1])
|
109
|
+
else # option with value missing
|
110
|
+
[dict[path.first], path[1..-1]]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def directories(partial = '')
|
115
|
+
dirs = []
|
116
|
+
dirs += Dir.glob("#{partial}*").select { |f| File.directory?(f) }
|
117
|
+
dirs = dirs.map { |d| d + '/' } if dirs.length == 1
|
118
|
+
dirs
|
119
|
+
end
|
120
|
+
|
121
|
+
def files(partial = '', opts = {})
|
122
|
+
filter = opts.fetch('filter', '.*')
|
123
|
+
file_names = []
|
124
|
+
file_names += Dir.glob("#{partial}*").select do |f|
|
125
|
+
File.directory?(f) || f =~ /#{filter}/
|
126
|
+
end
|
127
|
+
file_names.map { |f| File.directory?(f) ? f + '/' : f + ' ' }
|
128
|
+
end
|
129
|
+
|
130
|
+
def enum(partial = '', values = [])
|
131
|
+
values.select { |v| v.start_with?(partial) }.map { |v| v + ' ' }
|
132
|
+
end
|
133
|
+
|
134
|
+
def multienum(partial = '', values = [])
|
135
|
+
return values if partial.empty?
|
136
|
+
|
137
|
+
parts = partial.split(',')
|
138
|
+
resolved = []
|
139
|
+
to_complete = parts.each_with_object([]) do |part, res|
|
140
|
+
next resolved << part if values.include?(part)
|
141
|
+
|
142
|
+
res << part
|
143
|
+
end
|
144
|
+
|
145
|
+
hints = to_complete.map do |p|
|
146
|
+
values.select { |v| v.start_with?(p) }
|
147
|
+
end.flatten(1).uniq
|
148
|
+
return values - parts if hints.empty?
|
149
|
+
return [(resolved + hints).join(',')] if hints.size == 1
|
150
|
+
|
151
|
+
hints
|
152
|
+
end
|
153
|
+
|
154
|
+
def schema(template = '')
|
155
|
+
['--->', "Add value by following schema: #{template}"]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|