hammer_cli 0.19.1 → 2.2.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/bin/hammer-complete +28 -0
- data/config/cli_config.template.yml +2 -0
- data/config/hammer.completion +5 -0
- data/doc/commands_extension.md +12 -0
- data/doc/creating_commands.md +100 -0
- data/doc/installation.md +47 -4
- data/doc/installation_rpm.md +2 -2
- data/doc/release_notes.md +31 -6
- data/lib/hammer_cli.rb +1 -0
- data/lib/hammer_cli/abstract.rb +61 -4
- data/lib/hammer_cli/apipie/api_connection.rb +5 -1
- data/lib/hammer_cli/apipie/command.rb +3 -2
- data/lib/hammer_cli/apipie/option_builder.rb +15 -13
- data/lib/hammer_cli/apipie/option_definition.rb +9 -7
- 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/command_extensions.rb +21 -1
- data/lib/hammer_cli/connection.rb +4 -0
- data/lib/hammer_cli/exception_handler.rb +11 -2
- data/lib/hammer_cli/full_help.rb +8 -1
- data/lib/hammer_cli/help/builder.rb +29 -3
- data/lib/hammer_cli/logger_watch.rb +1 -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 +26 -6
- data/lib/hammer_cli/options/option_family.rb +114 -0
- data/lib/hammer_cli/options/predefined.rb +1 -1
- 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 +27 -8
- 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/subcommand.rb +25 -1
- data/lib/hammer_cli/testing/command_assertions.rb +2 -2
- data/lib/hammer_cli/utils.rb +22 -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/test/unit/abstract_test.rb +23 -2
- data/test/unit/apipie/api_connection_test.rb +1 -0
- data/test/unit/apipie/option_builder_test.rb +8 -0
- data/test/unit/bash_test.rb +138 -0
- data/test/unit/command_extensions_test.rb +67 -49
- data/test/unit/exception_handler_test.rb +44 -0
- data/test/unit/help/builder_test.rb +22 -0
- data/test/unit/options/option_family_test.rb +48 -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 +17 -6
- 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: d903c3dbbe33a2411dfd2e23b781609a40b39b4ed29066cabe35af22335042d5
|
4
|
+
data.tar.gz: 25acdf29e7a071a945a4c7c2c4745083e0e11e7d12ce098c662054a7d87caeb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a117c635359bc261f70cb67bf33fc2080f15b909981a98f87d7c64235a2ecf686bf1530b5293e60565e5e52cab2ed9bbf17f604816099ada8e11b11a5b7f064
|
7
|
+
data.tar.gz: 3e296e36f46d6374fc1878a51447cd2fe820104fa5ba191c6bde91a62aff2fd7b76e12743d152ca0eb9457b541e38dd39351da138020501d286c3af071e33b39
|
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/commands_extension.md
CHANGED
@@ -10,6 +10,11 @@ Each command can be easily extended with one ore more `HammerCLI::CommandExtensi
|
|
10
10
|
inheritable true
|
11
11
|
# Simply add a new option to a command is being extended
|
12
12
|
option(option_params)
|
13
|
+
# Add option family to a command
|
14
|
+
option_family(common_options = {}) do
|
15
|
+
parent option_params
|
16
|
+
child option_params
|
17
|
+
end
|
13
18
|
# Extend hash with data returned from server before it is printed
|
14
19
|
before_print do |data|
|
15
20
|
# data modifications
|
@@ -65,6 +70,13 @@ class MyCommandExtensions < HammerCLI::CommandExtensions
|
|
65
70
|
|
66
71
|
option ['--new-option'], 'TYPE', _('Option description')
|
67
72
|
|
73
|
+
option_family(
|
74
|
+
description: _('Common description')
|
75
|
+
) do
|
76
|
+
parent ['--new-option'], 'TYPE', _('Option description')
|
77
|
+
child ['--new-option-ver2'], 'TYPE', _('Option description')
|
78
|
+
end
|
79
|
+
|
68
80
|
before_print do |data|
|
69
81
|
data['results'].each do |result|
|
70
82
|
result['status'] = process_errors(result['errors'])
|
data/doc/creating_commands.md
CHANGED
@@ -173,6 +173,54 @@ Here is the list of predefined options:
|
|
173
173
|
* `:fields` Expects a list with fields to show in output, see [example](creating_commands.md#printing-hash-records).
|
174
174
|
|
175
175
|
|
176
|
+
### Option family
|
177
|
+
Option family is the way to unify options which have the same meaning or purpose,
|
178
|
+
but contain some differences in their definitions (e.g. the name/switch of an option).
|
179
|
+
Mainly serves as a container for options, which purpose is to show less repetitive
|
180
|
+
output in commands' help. Option builders use it by default.
|
181
|
+
|
182
|
+
To define an option family, use the following DSL:
|
183
|
+
```ruby
|
184
|
+
# options is a Hash with options for family/each defined option within it
|
185
|
+
option_family(options = {}) do
|
186
|
+
# parent is the main option. Must be single, option family can have only one parent.
|
187
|
+
parent switches, type, description, options
|
188
|
+
# child is an additional option. Could be none or more than one. Aren't shown in the help output.
|
189
|
+
child switches, type, description, options
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
##### Example
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
option_family(
|
197
|
+
aliased_resource: 'environment',
|
198
|
+
description: _('Puppet environment'),
|
199
|
+
deprecation: _("Use %s instead") % '--puppet-environment[-id]'
|
200
|
+
deprecated: { '--environment' => _("Use %s instead") % '--puppet-environment[-id]',
|
201
|
+
'--environment-id' => _("Use %s instead") % '--puppet-environment[-id]'}
|
202
|
+
) do
|
203
|
+
parent '--environment-id', 'ENVIRONMENT_ID', _(''),
|
204
|
+
format: HammerCLI::Options::Normalizers::Number.new,
|
205
|
+
attribute_name: :option_environment_id
|
206
|
+
child '--environment', 'ENVIRONMENT_NAME', _('Environment name'),
|
207
|
+
attribute_name: :option_environment_name
|
208
|
+
end
|
209
|
+
|
210
|
+
# $ hammer command --help:
|
211
|
+
# ...
|
212
|
+
# Options:
|
213
|
+
# --environment[-id] Puppet environment (Deprecated: Use --puppet-environment[-id] instead)
|
214
|
+
# ...
|
215
|
+
|
216
|
+
# $ hammer full-help:
|
217
|
+
# ...
|
218
|
+
# Options:
|
219
|
+
# --environment ENVIRONMENT_NAME Environment name (--environment is deprecated: Use --puppet-environment[-id] instead)
|
220
|
+
# --environment-id ENVIRONMENT_ID (--environment-id is deprecated: Use --puppet-environment[-id] instead)
|
221
|
+
# ...
|
222
|
+
```
|
223
|
+
|
176
224
|
### Option builders
|
177
225
|
Hammer commands offer option builders that can be used for automatic option generation.
|
178
226
|
See [documentation page](option_builders.md#option-builders) dedicated to this topic for more details.
|
@@ -406,6 +454,31 @@ Options:
|
|
406
454
|
-h, --help print help
|
407
455
|
```
|
408
456
|
|
457
|
+
#### Aliasing subcommands
|
458
|
+
|
459
|
+
Commands can have two or more names, e.g. aliases. To support such functionality
|
460
|
+
simple name addition could be used via `command_name` or `command_names` method:
|
461
|
+
```ruby
|
462
|
+
module HammerCLIHello
|
463
|
+
|
464
|
+
class SayCommand < HammerCLI::AbstractCommand
|
465
|
+
|
466
|
+
class GreetingsCommand < HammerCLI::AbstractCommand
|
467
|
+
command_name 'hello'
|
468
|
+
command_name 'hi'
|
469
|
+
# or use can use other method:
|
470
|
+
command_names 'hello', 'hi'
|
471
|
+
|
472
|
+
desc 'Say Hello World!'
|
473
|
+
# ...
|
474
|
+
end
|
475
|
+
|
476
|
+
autoload_subcommands
|
477
|
+
end
|
478
|
+
|
479
|
+
HammerCLI::MainCommand.subcommand 'say', "Say something", HammerCLIHello::SayCommand
|
480
|
+
end
|
481
|
+
```
|
409
482
|
|
410
483
|
### Conflicting subcommands
|
411
484
|
It can happen that two different plugins define subcommands with the same name by accident.
|
@@ -494,6 +567,33 @@ You first create an _output definition_ that you apply to your data. The result
|
|
494
567
|
is a collection of fields, each having its type. The collection is then passed to an
|
495
568
|
_output adapter_ which handles the actual formatting and printing.
|
496
569
|
|
570
|
+
Adapters support printing by chunks, e.g. if you want to print a large set of
|
571
|
+
data (1000+ records), but you make several calls to the server instead of one,
|
572
|
+
you may want to print received data right away instead of waiting for the rest.
|
573
|
+
This can be achieved via `:current_chunk` option for
|
574
|
+
`print_collection` and `print_data` methods. Allowed values for `:current_chunk`
|
575
|
+
are `:first`, `:another`, `:last`. By default adapters use `:single` value that
|
576
|
+
means only one record will be printed.
|
577
|
+
|
578
|
+
##### Printing by chunks
|
579
|
+
```ruby
|
580
|
+
# ...
|
581
|
+
def execute
|
582
|
+
loop do
|
583
|
+
# ...
|
584
|
+
data = send_request
|
585
|
+
print_data(data, current_chunk: :first)
|
586
|
+
# ...
|
587
|
+
data = send_request
|
588
|
+
print_data(data, current_chunk: :another)
|
589
|
+
# ...
|
590
|
+
data = send_request
|
591
|
+
print_data(data, current_chunk: :last)
|
592
|
+
end
|
593
|
+
end
|
594
|
+
# ...
|
595
|
+
```
|
596
|
+
|
497
597
|
Hammer provides a DSL for defining the output. Next rather complex example will
|
498
598
|
explain how to use it in action.
|
499
599
|
|
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/installation_rpm.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
### Installation from RPMs
|
2
2
|
|
3
|
-
#### Step 1:
|
3
|
+
#### Step 1: set up yum repositories
|
4
4
|
|
5
|
-
For Foreman 1.3 stable the hammer packages are part of your installation repo and you can skip this step.
|
5
|
+
For Foreman 1.3 stable, the hammer packages are part of your installation repo and you can skip this step.
|
6
6
|
|
7
7
|
You can choose from stable or nightly repo. Nightly has more recent version of hammer packages, but it was subject to less testing so there is a higher risk of issues.
|
8
8
|
Add the Foreman yum repository to your yum repo files. For Fedora installations replace 'el6' with 'f18' or 'f19' as appropriate.
|
data/doc/release_notes.md
CHANGED
@@ -1,15 +1,40 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
|
-
###
|
3
|
+
### 2.2.0 (2020-08-11)
|
4
|
+
* Update installation_rpm.md ([PR #333](https://github.com/theforeman/hammer-cli/pull/333))
|
5
|
+
* Clean gem_release.ipynb up
|
6
|
+
* Replace awesome_print with amazing_print ([PR #330](https://github.com/theforeman/hammer-cli/pull/330)), [#29846](http://projects.theforeman.org/issues/29846)
|
7
|
+
* Fix typo: s/filed/feild/ ([PR #331](https://github.com/theforeman/hammer-cli/pull/331))
|
8
|
+
* Bump to 2.2.0-develop
|
9
|
+
|
10
|
+
### 2.1.0 (2020-05-14)
|
11
|
+
* Hammer full-help returns correct output, [#29697](http://projects.theforeman.org/issues/29697)
|
12
|
+
* Add fuzzy subcommand matching, [#29413](http://projects.theforeman.org/issues/29413)
|
13
|
+
* Help contains squeezed options, [#28440](http://projects.theforeman.org/issues/28440)
|
14
|
+
* Keep referenced resource in option options, [#29015](http://projects.theforeman.org/issues/29015)
|
15
|
+
* Bump to 2.1.0-develop
|
16
|
+
|
17
|
+
### 2.0.0 (2020-02-12)
|
18
|
+
* Bump version to 2.0.0
|
19
|
+
* Bump version to 2.0 ([PR #324](https://github.com/theforeman/hammer-cli/pull/324))
|
20
|
+
* Better promts for missing arguments, [#28793](http://projects.theforeman.org/issues/28793)
|
4
21
|
* Allow column max width more than 80, [#28503](http://projects.theforeman.org/issues/28503)
|
22
|
+
* Remove computing sha, [#27728](http://projects.theforeman.org/issues/27728)
|
23
|
+
* Fixed userdata false display in image list, [#28134](http://projects.theforeman.org/issues/28134)
|
24
|
+
* Add new bash completion, [#27728](http://projects.theforeman.org/issues/27728)
|
25
|
+
* Allow adapters print page by page, [#17819](http://projects.theforeman.org/issues/17819)
|
26
|
+
* Add release documentation ([PR #317](https://github.com/theforeman/hammer-cli/pull/317)), [#28149](http://projects.theforeman.org/issues/28149)
|
27
|
+
* Fix pr links in release notes ([PR #318](https://github.com/theforeman/hammer-cli/pull/318)), [#28202](http://projects.theforeman.org/issues/28202)
|
5
28
|
* Extract table generator into reusable component ([PR #314](https://github.com/theforeman/hammer-cli/pull/314)), [#27318](http://projects.theforeman.org/issues/27318)
|
29
|
+
* Better prompts for missing arguments ([PR #313](https://github.com/theforeman/hammer-cli/pull/313)), [#27595](http://projects.theforeman.org/issues/27595)
|
30
|
+
* Bump to 0.20-develop
|
6
31
|
|
7
32
|
### 0.19.0 (2019-10-26)
|
8
|
-
* Allow schema building for custom options ([PR #316](https://github.com/
|
9
|
-
* New lines in text attr dont break output ([PR #300](https://github.com/
|
10
|
-
* Added error to wrong --output ([PR #315](https://github.com/
|
11
|
-
* Pr review checklist ([PR #305](https://github.com/
|
12
|
-
* List items in help with customization ([PR #309](https://github.com/
|
33
|
+
* Allow schema building for custom options ([PR #316](https://github.com/theforeman/hammer-cli/pull/316)), [#27899](http://projects.theforeman.org/issues/27899)
|
34
|
+
* 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)
|
35
|
+
* Added error to wrong --output ([PR #315](https://github.com/theforeman/hammer-cli/pull/315)), [#21590](http://projects.theforeman.org/issues/21590)
|
36
|
+
* Pr review checklist ([PR #305](https://github.com/theforeman/hammer-cli/pull/305)), [#26950](http://projects.theforeman.org/issues/26950)
|
37
|
+
* List items in help with customization ([PR #309](https://github.com/theforeman/hammer-cli/pull/309)), [#27237](http://projects.theforeman.org/issues/27237)
|
13
38
|
|
14
39
|
### 0.18.0 (2019-08-01)
|
15
40
|
* 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
@@ -13,6 +13,7 @@ require 'hammer_cli/options/predefined'
|
|
13
13
|
require 'hammer_cli/help/builder'
|
14
14
|
require 'hammer_cli/help/text_builder'
|
15
15
|
require 'hammer_cli/command_extensions'
|
16
|
+
require 'hammer_cli/options/option_family'
|
16
17
|
require 'logging'
|
17
18
|
|
18
19
|
module HammerCLI
|
@@ -74,6 +75,7 @@ module HammerCLI
|
|
74
75
|
begin
|
75
76
|
begin
|
76
77
|
exit_code = super
|
78
|
+
context.delete(:fields)
|
77
79
|
raise "exit code must be integer" unless exit_code.is_a? Integer
|
78
80
|
rescue => e
|
79
81
|
exit_code = handle_exception(e)
|
@@ -190,10 +192,21 @@ module HammerCLI
|
|
190
192
|
# skip switches that are already defined
|
191
193
|
next if option.nil? or option.switches.any? {|s| find_option(s) }
|
192
194
|
|
195
|
+
if option.respond_to?(:referenced_resource)
|
196
|
+
# Collect options that don't have family, but related to this parent.
|
197
|
+
children = find_options(
|
198
|
+
referenced_resource: option.referenced_resource.to_s,
|
199
|
+
aliased_resource: option.aliased_resource.to_s
|
200
|
+
).select { |o| o.family.nil? || o.family.head.nil? }
|
201
|
+
children.each do |child|
|
202
|
+
option.family.adopt(child) if option.family
|
203
|
+
end
|
204
|
+
end
|
193
205
|
declared_options << option
|
194
206
|
block ||= option.default_conversion_block
|
195
207
|
define_accessors_for(option, &block)
|
196
208
|
extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
|
209
|
+
completion_type_for(option)
|
197
210
|
end
|
198
211
|
end
|
199
212
|
|
@@ -205,6 +218,7 @@ module HammerCLI
|
|
205
218
|
extension.delegatee(self)
|
206
219
|
extension.extend_predefined_options(self)
|
207
220
|
extension.extend_options(self)
|
221
|
+
extension.extend_option_family(self)
|
208
222
|
extension.extend_output(self)
|
209
223
|
extension.extend_help(self)
|
210
224
|
logger('Extensions').info "Applied #{extension.details} on #{self}."
|
@@ -220,6 +234,12 @@ module HammerCLI
|
|
220
234
|
|
221
235
|
protected
|
222
236
|
|
237
|
+
def self.option_family(options = {}, &block)
|
238
|
+
options[:creator] ||= self
|
239
|
+
family = HammerCLI::Options::OptionFamily.new(options)
|
240
|
+
family.instance_eval(&block)
|
241
|
+
end
|
242
|
+
|
223
243
|
def self.find_options(switch_filter, other_filters={})
|
224
244
|
filters = other_filters
|
225
245
|
if switch_filter.is_a? Hash
|
@@ -242,8 +262,8 @@ module HammerCLI
|
|
242
262
|
output.print_record(definition, record)
|
243
263
|
end
|
244
264
|
|
245
|
-
def print_collection(definition, collection)
|
246
|
-
output.print_collection(definition, collection)
|
265
|
+
def print_collection(definition, collection, options = {})
|
266
|
+
output.print_collection(definition, collection, options)
|
247
267
|
end
|
248
268
|
|
249
269
|
def print_message(msg, msg_params = {}, options = {})
|
@@ -283,8 +303,17 @@ module HammerCLI
|
|
283
303
|
end
|
284
304
|
|
285
305
|
def self.command_name(name=nil)
|
286
|
-
@
|
287
|
-
|
306
|
+
if @names && name
|
307
|
+
@names << name if !@names.include?(name)
|
308
|
+
else
|
309
|
+
@names = [name] if name
|
310
|
+
end
|
311
|
+
@names || (superclass.respond_to?(:command_names) ? superclass.command_names : nil)
|
312
|
+
end
|
313
|
+
|
314
|
+
def self.command_names(*names)
|
315
|
+
@names = names unless names.empty?
|
316
|
+
@names || (superclass.respond_to?(:command_names) ? superclass.command_names : nil)
|
288
317
|
end
|
289
318
|
|
290
319
|
def self.warning(message = nil)
|
@@ -314,6 +343,7 @@ module HammerCLI
|
|
314
343
|
declared_options << option
|
315
344
|
block ||= option.default_conversion_block
|
316
345
|
define_accessors_for(option, &block)
|
346
|
+
completion_type_for(option, opts)
|
317
347
|
end
|
318
348
|
extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
|
319
349
|
option
|
@@ -352,6 +382,33 @@ module HammerCLI
|
|
352
382
|
sources
|
353
383
|
end
|
354
384
|
|
385
|
+
def self.completion_map
|
386
|
+
completion = {}
|
387
|
+
# collect options
|
388
|
+
recognised_options.each do |opt|
|
389
|
+
opt.switches.each do |switch|
|
390
|
+
completion[switch] = completion_types.fetch(switch, {})
|
391
|
+
end
|
392
|
+
end
|
393
|
+
# collect subcommands recursively
|
394
|
+
recognised_subcommands.each do |cmd|
|
395
|
+
completion[cmd.names.first] = cmd.subcommand_class.completion_map
|
396
|
+
end
|
397
|
+
# collect params
|
398
|
+
completion[:params] = completion_types[:params] unless completion_types[:params].empty?
|
399
|
+
completion
|
400
|
+
end
|
401
|
+
|
402
|
+
def self.completion_types
|
403
|
+
@completion_types ||= { :params => [] }
|
404
|
+
end
|
405
|
+
|
406
|
+
def self.completion_type_for(option, opts = {})
|
407
|
+
completion_type = opts.delete(:completion)
|
408
|
+
completion_type ||= option.completion_type(opts[:format])
|
409
|
+
[option.switches].flatten(1).each { |s| completion_types[s] = completion_type }
|
410
|
+
end
|
411
|
+
|
355
412
|
private
|
356
413
|
|
357
414
|
def self.inherited_output_definition
|