hammer_cli 0.15.1 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/doc/commands_modification.md +82 -0
- data/doc/creating_commands.md +78 -38
- data/doc/developer_docs.md +2 -0
- data/doc/help_modification.md +119 -0
- data/doc/i18n.md +2 -2
- data/doc/installation_rpm.md +3 -3
- data/doc/release_notes.md +9 -1
- data/lib/hammer_cli.rb +0 -1
- data/lib/hammer_cli/abstract.rb +44 -13
- data/lib/hammer_cli/exception_handler.rb +1 -1
- data/lib/hammer_cli/help/definition.rb +55 -0
- data/lib/hammer_cli/help/definition/abstract_item.rb +38 -0
- data/lib/hammer_cli/help/definition/list.rb +53 -0
- data/lib/hammer_cli/help/definition/section.rb +36 -0
- data/lib/hammer_cli/help/definition/text.rb +21 -0
- data/lib/hammer_cli/help/text_builder.rb +26 -49
- data/lib/hammer_cli/i18n.rb +0 -1
- data/lib/hammer_cli/options/option_collector.rb +12 -9
- data/lib/hammer_cli/options/option_processor.rb +17 -0
- data/lib/hammer_cli/options/processor_list.rb +37 -0
- data/lib/hammer_cli/options/sources/base.rb +17 -0
- data/lib/hammer_cli/options/sources/command_line.rb +3 -1
- data/lib/hammer_cli/options/sources/saved_defaults.rb +3 -1
- data/lib/hammer_cli/options/validators/base.rb +20 -0
- data/lib/hammer_cli/options/validators/dsl.rb +160 -0
- data/lib/hammer_cli/options/validators/dsl_block_validator.rb +19 -0
- data/lib/hammer_cli/output/adapter/csv.rb +11 -11
- data/lib/hammer_cli/output/adapter/tree_structure.rb +5 -3
- data/lib/hammer_cli/output/definition.rb +42 -4
- data/lib/hammer_cli/output/dsl.rb +4 -2
- data/lib/hammer_cli/output/fields.rb +9 -2
- data/lib/hammer_cli/testing/messages.rb +6 -6
- data/lib/hammer_cli/utils.rb +15 -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 +70 -5
- data/test/unit/exception_handler_test.rb +1 -1
- data/test/unit/help/definition/abstract_item_test.rb +33 -0
- data/test/unit/help/definition/list_test.rb +17 -0
- data/test/unit/help/definition/section_test.rb +25 -0
- data/test/unit/help/definition/text_test.rb +11 -0
- data/test/unit/help/definition_test.rb +236 -0
- data/test/unit/help/text_builder_test.rb +170 -1
- data/test/unit/options/option_collector_test.rb +18 -9
- data/test/unit/options/processor_list_test.rb +70 -0
- data/test/unit/{validator_test.rb → options/validators/dsl_test.rb} +57 -93
- data/test/unit/output/adapter/abstract_test.rb +3 -0
- data/test/unit/output/adapter/base_test.rb +5 -0
- data/test/unit/output/adapter/csv_test.rb +3 -0
- data/test/unit/output/adapter/json_test.rb +12 -0
- data/test/unit/output/adapter/table_test.rb +5 -0
- data/test/unit/output/adapter/yaml_test.rb +11 -0
- data/test/unit/output/definition_test.rb +221 -1
- data/test/unit/utils_test.rb +23 -0
- metadata +31 -5
- data/lib/hammer_cli/validator.rb +0 -172
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 836795c65ef362f852b3eed29126508d0bf23927
|
4
|
+
data.tar.gz: 8300578ae0b731724817506ee20bda1ea458b71b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 848a8e9636cb5c8e8dea817de554d943f73db10399d897d770d71a7df5cfc66d5c843b351c64587781dd93ae5be81ecd17afe0e2ffa4e0ce7192d55e4d5fd732
|
7
|
+
data.tar.gz: aa6bbeb277ae28f0d1c1626f78773dcfbd64a4b81de89609a5fa64eff4a7a607e582f464fb2b58bc7df30b3770c877b2188b62ed14030992630a21932e0b9cf8
|
@@ -0,0 +1,82 @@
|
|
1
|
+
Modify an existing command
|
2
|
+
-------------------------
|
3
|
+
|
4
|
+
### Modification of output fields
|
5
|
+
|
6
|
+
Each command (as well as each field) might have its own
|
7
|
+
output definition. You can modify the output definition of existing
|
8
|
+
command or a specific field of that command by following output
|
9
|
+
definition interface:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
13
|
+
# Appends fields to the end.
|
14
|
+
# Where:
|
15
|
+
# fields is one or more existing fields
|
16
|
+
# block is block of code with new fields
|
17
|
+
definition.append(fields) do
|
18
|
+
label
|
19
|
+
field
|
20
|
+
collection
|
21
|
+
end
|
22
|
+
# Inserts one or more fields.
|
23
|
+
# Where:
|
24
|
+
# :mode is one of [:before, :after, :replace]
|
25
|
+
# :id is field's id or key. Field's label can be used if field does not
|
26
|
+
# have id
|
27
|
+
# fields is one or more existing fields
|
28
|
+
# block is block of code with new fields
|
29
|
+
definition.insert(:mode, :id, fields) do
|
30
|
+
label
|
31
|
+
field
|
32
|
+
collection
|
33
|
+
end
|
34
|
+
# Returns output definition of the command or field specified with path.
|
35
|
+
# Where:
|
36
|
+
# path = Array of :key or/and :id or/and 'label']
|
37
|
+
definition.at(path)
|
38
|
+
# Returns field from current output definition.
|
39
|
+
definition.find_field(:id)
|
40
|
+
# Deletes all fields from current output definition.
|
41
|
+
definition.clear
|
42
|
+
end
|
43
|
+
```
|
44
|
+
#### Examples
|
45
|
+
```ruby
|
46
|
+
# Append some fields to the end
|
47
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
48
|
+
definition.at(_('Collection Field Label'))
|
49
|
+
.append do
|
50
|
+
field :value3, _('Value 3')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
# Change field's label
|
54
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
55
|
+
definition.at(:path)
|
56
|
+
.find_field(:id).label = _('New label')
|
57
|
+
end
|
58
|
+
# Expand a field with new definition
|
59
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
60
|
+
definition.at([_('some'), :path])
|
61
|
+
.insert(:replace, :not_container_field_id) do
|
62
|
+
field nil, _('Label with new fields'), Fields::Label, id: :now_container_field_id do
|
63
|
+
field :new_field1, _('New field 1')
|
64
|
+
field :new_field2, _('New field 2')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# Insert a new field after specific field
|
69
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
70
|
+
definition.at([_('some'), :path])
|
71
|
+
.insert(:after, :other_field_id, [Fields::Field.new(label: _('My field'), id: :my_field_id)])
|
72
|
+
end
|
73
|
+
# Insert a new field before specific field
|
74
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
75
|
+
definition.insert(:before, :other_field_id,
|
76
|
+
Fields::Field.new(label: _('My field'), id: :my_field_id))
|
77
|
+
end
|
78
|
+
# Remove field
|
79
|
+
HammerCLIForeman::Host::InfoCommand.extend_output_definition do |definition|
|
80
|
+
definition.insert(:replace, :field_id) do; end
|
81
|
+
end
|
82
|
+
```
|
data/doc/creating_commands.md
CHANGED
@@ -169,33 +169,7 @@ In cases when you want to deprecate just one of more possible switches use the e
|
|
169
169
|
Hammer commands offer option builders that can be used for automatic option generation.
|
170
170
|
See [documentation page](option_builders.md#option-builders) dedicated to this topic for more details.
|
171
171
|
|
172
|
-
### Option
|
173
|
-
Hammer provides extended functionality for validating options.
|
174
|
-
|
175
|
-
#### DSL
|
176
|
-
First of all there is a dsl for validating combinations of options:
|
177
|
-
```ruby
|
178
|
-
validate_options do
|
179
|
-
all(:option_name, :option_surname).required # requires all the options
|
180
|
-
option(:option_age).required # requires a single option,
|
181
|
-
# equivalent of :required => true in option declaration
|
182
|
-
any(:option_email, :option_phone).required # requires at least one of the options
|
183
|
-
|
184
|
-
# It is possible to create more complicated constructs.
|
185
|
-
# This example requires either the full address or nothing
|
186
|
-
if any(:option_street, :option_city, :option_zip).exist?
|
187
|
-
all(:option_street, :option_city, :option_zip).required
|
188
|
-
end
|
189
|
-
|
190
|
-
# Here you can reject all address related option when --no-address is passed
|
191
|
-
if option(:option_no_address).exist?
|
192
|
-
all(:option_street, :option_city, :option_zip).rejected
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
```
|
197
|
-
|
198
|
-
#### Option normalizers
|
172
|
+
### Option normalizers
|
199
173
|
Another option-related feature is a set of normalizers for specific option types. They validate and preprocess
|
200
174
|
option values. Each normalizer has a description of the format it accepts. This description is printed
|
201
175
|
in commands' help.
|
@@ -244,24 +218,90 @@ option "--attributes", "ATTRIBUTES", "Values of various attributes",
|
|
244
218
|
|
245
219
|
### Advanced option evaluation
|
246
220
|
|
247
|
-
Sometimes it is necessary to tune the option values based on other parameters given on CLI.
|
221
|
+
Sometimes it is necessary to tune or validate the option values based on other parameters given on CLI.
|
248
222
|
An example could be setting default values based on other options, values lookup in a DB, etc.
|
249
|
-
The right place for this are
|
250
|
-
|
223
|
+
The right place for this are option processors. There are two basic kinds of option processors in hammer:
|
224
|
+
- *option sources* - they provide values for the options, descendants of `HammerCLI::Options::Sources::Base`
|
225
|
+
- *option validators* - they check if the options values are valid, descendants of `HammerCLI::Options::Validators::Base`
|
226
|
+
|
227
|
+
Option sources and validators can be mixed together. For example it's possible to collect options from the command line,
|
228
|
+
do some validation on them and then continue with collecting options from a different source.
|
229
|
+
The whole set of processors is invoked only once per command call. The processing is triggered by a first call
|
230
|
+
to the `options` or `all_options` method, but at latest right after the option validation
|
231
|
+
(before the command's `execute` method is invoked). The order is as follows:
|
232
|
+
1. option parsing
|
233
|
+
1. option normalization
|
234
|
+
1. option processors execution (sources and validators)
|
235
|
+
1. `execute` invocation
|
236
|
+
|
237
|
+
#### Default option sources
|
238
|
+
|
239
|
+
Abstract Hammer command uses two default option sources -
|
240
|
+
`HammerCLI::Options::Sources::CommandLine` responsible for intial population of the options and
|
251
241
|
`HammerCLI::Options::Sources::SavedDefaults` adding defaults managed by the `defaults` command.
|
252
242
|
|
243
|
+
The default option sources are wrapped in `DefaultInputs` processor list so that it's possible to easily place
|
244
|
+
custom sources before or behind all the default ones.
|
245
|
+
The full default hierarchy is:
|
246
|
+
|
247
|
+
```
|
248
|
+
- DefaultInputs
|
249
|
+
- CommandLine
|
250
|
+
- SavedDefaults (present only when defaults are enabled)
|
251
|
+
```
|
252
|
+
|
253
253
|
By overriding `option_sources` method in a command it is possible to add custom option sources
|
254
254
|
for various tasks to the list. The option sources are evaluated one by one each being given output
|
255
255
|
of the previous one as its input so the order in which the sources are listed matters.
|
256
256
|
|
257
|
-
Option
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
257
|
+
#### Option validation
|
258
|
+
Hammer provides extended functionality for validating options.
|
259
|
+
|
260
|
+
First of all there is a DSL for validating combinations of options:
|
261
|
+
```ruby
|
262
|
+
validate_options do
|
263
|
+
all(:option_name, :option_surname).required # requires all the options
|
264
|
+
option(:option_age).required # requires a single option,
|
265
|
+
# equivalent of :required => true in option declaration
|
266
|
+
any(:option_email, :option_phone).required # requires at least one of the options
|
267
|
+
|
268
|
+
# It is possible to create more complicated constructs.
|
269
|
+
# This example requires either the full address or nothing
|
270
|
+
if any(:option_street, :option_city, :option_zip).exist?
|
271
|
+
all(:option_street, :option_city, :option_zip).required
|
272
|
+
end
|
273
|
+
|
274
|
+
# Here you can reject all address related option when --no-address is passed
|
275
|
+
if option(:option_no_address).exist?
|
276
|
+
all(:option_street, :option_city, :option_zip).rejected
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
```
|
281
|
+
|
282
|
+
It's possible to insert a validation block on a certain place in the option processor chain:
|
283
|
+
```ruby
|
284
|
+
validate_options(:after, 'DefaultInputs') do
|
285
|
+
# ...inserts the validation block after DefaultInputs option source
|
286
|
+
end
|
287
|
+
|
288
|
+
validate_options(:prepend) do
|
289
|
+
# ...adds validation to the first place in the queue
|
290
|
+
end
|
291
|
+
|
292
|
+
# Following insert modes can be used:
|
293
|
+
# before, after, append, prepend (the default behavior)
|
294
|
+
```
|
295
|
+
|
296
|
+
Alternatively the functionality can be extracted in a validator object that can be shared by multiple commands:
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
validate_options(:after, 'DefaultInputs', validator: Custom::Validator.new)
|
300
|
+
|
301
|
+
```
|
302
|
+
|
303
|
+
`validate_options` adds validators into a specific command class and they aren't inherited with subclasses.
|
304
|
+
Inheritable validators can be created command's `add_validators` method.
|
265
305
|
|
266
306
|
|
267
307
|
### Adding subcommands
|
data/doc/developer_docs.md
CHANGED
@@ -8,6 +8,8 @@ before creating hammer specific plugins.
|
|
8
8
|
Contents:
|
9
9
|
- [Writing a plugin](writing_a_plugin.md#writing-your-own-hammer-plugin)
|
10
10
|
- [Creating commands](creating_commands.md#create-your-first-command)
|
11
|
+
- [Help modification](help_modification.md#modify-an-existing-help)
|
12
|
+
- [Commands modification](commands_modification.md#modify-an-existing-command)
|
11
13
|
- [Option builders](option_builders.md#option-builders)
|
12
14
|
- [Creating ApiPie commands](creating_apipie_commands.md#creating-commands-for-restful-api-with-apipie)
|
13
15
|
- [Development tips](development_tips.md#development-tips)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
Modify an existing help
|
2
|
+
-------------------------
|
3
|
+
Each command might have its own help definition. This definition is composed of various _help items_, which might contain their own definitions.
|
4
|
+
|
5
|
+
Let's say `hammer host create -h` help string has the following structure:
|
6
|
+
```
|
7
|
+
hammer host create -h
|
8
|
+
+-- Usage
|
9
|
+
+-- Options
|
10
|
+
+-- Additional info
|
11
|
+
| +-- Section(Available keys for --interface:)
|
12
|
+
| | +-- List
|
13
|
+
| | +-- Section
|
14
|
+
| | | +-- List
|
15
|
+
| | +-- Section
|
16
|
+
| | | +-- List
|
17
|
+
| | +-- Section
|
18
|
+
| | | +-- List
|
19
|
+
| +-- Section(Provider specific options:)
|
20
|
+
| | +-- Section
|
21
|
+
| | | +-- Section
|
22
|
+
| | | | +-- List
|
23
|
+
...
|
24
|
+
| | +-- Section(Libvirt:)
|
25
|
+
| | | +-- Section(--compute-attributes:)
|
26
|
+
| | | | +-- List[
|
27
|
+
cpus Number of CPUs
|
28
|
+
memory String, amount of memory, value in bytes
|
29
|
+
start Boolean (expressed as 0 or 1), whether to start the machine or not
|
30
|
+
]
|
31
|
+
...
|
32
|
+
| | | +-- Section
|
33
|
+
| | | | +-- List
|
34
|
+
```
|
35
|
+
Every `Section`, `List` and simple `Text` is _help item_ defined as `HammerCLI::Help::AbstractItem`, so everything might have its own ID now for easier addressing.
|
36
|
+
|
37
|
+
To modify the structure above, you might use the following:
|
38
|
+
```ruby
|
39
|
+
HammerCLIForeman::Host::CreateCommand.extend_help do |h|
|
40
|
+
# Simple addition to the end.
|
41
|
+
h.section
|
42
|
+
h.list
|
43
|
+
h.text
|
44
|
+
|
45
|
+
# Inserts one or more help items.
|
46
|
+
# Where:
|
47
|
+
# :mode is one of [:before, :after, :replace]
|
48
|
+
# :item_id is item's id or label. Item's label can be used if it does not
|
49
|
+
# have an id, e.g. any Section
|
50
|
+
# block is block of code with new items
|
51
|
+
h.insert(:mode, :item_id) do |h|
|
52
|
+
h.section
|
53
|
+
h.list
|
54
|
+
h.text
|
55
|
+
end
|
56
|
+
# Addition to custom path.
|
57
|
+
# Where:
|
58
|
+
# path is Array of :item_id or/and 'item_label'
|
59
|
+
# block is the code block with new help items.
|
60
|
+
h.at(path) do |h|
|
61
|
+
...
|
62
|
+
h.section
|
63
|
+
h.list
|
64
|
+
h.text
|
65
|
+
...
|
66
|
+
end
|
67
|
+
# Returns help item from current definition.
|
68
|
+
h.find_item(:item_id)
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
#### Examples
|
73
|
+
```ruby
|
74
|
+
# Add a new section with list to the end of the Libvirt section.
|
75
|
+
HammerCLIForeman::Host::CreateCommand.extend_help do |h|
|
76
|
+
h.at(['Provider specific options', 'Libvirt']) do |h|
|
77
|
+
h.section('--new-section-with-list', id: :section_with_list) do |h|
|
78
|
+
h.list([
|
79
|
+
['item1', _('Desc1')],
|
80
|
+
['item2'],
|
81
|
+
['item3', _('Desc3')]
|
82
|
+
], id: :list_with_id)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Add important information
|
88
|
+
HammerCLIForeman::Host::CreateCommand.extend_help do |h|
|
89
|
+
h.at(['Provider specific options']) do |h|
|
90
|
+
h.insert(:before, 'EC2') do |h|
|
91
|
+
h.text('Something important for all providers')
|
92
|
+
end
|
93
|
+
h.at(['EC2']) do |h|
|
94
|
+
h.insert(:before, '--compute-attributes') do |h|
|
95
|
+
h.text('Something important for EC2 only')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Delete the Libvirt section from Provider specific options section.
|
102
|
+
HammerCLIForeman::Host::CreateCommand.extend_help do |h|
|
103
|
+
h.at('Provider specific options') do |h|
|
104
|
+
h.insert(:replace, 'Libvirt') do |h|; end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Add more text
|
109
|
+
HammerCLIForeman::Host::CreateCommand.extend_help do |h|
|
110
|
+
h.at('Provider specific options') do |h|
|
111
|
+
h.insert(:before, 'EC2') do |h|
|
112
|
+
h.text('Imagine it already was here', id: :old_text_id)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
h.at(['Provider specific options', :old_text_id]) do |h|
|
116
|
+
h.text('Additional information', id: :additional_text)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
data/doc/i18n.md
CHANGED
@@ -73,8 +73,8 @@ HammerCLI::I18n::FindTask.define(HammerCLIAwesome::I18n::LocaleDomain.new, Hamme
|
|
73
73
|
and create `locale/Makefile` with following content:
|
74
74
|
```make
|
75
75
|
DOMAIN = hammer-cli-awesome
|
76
|
-
VERSION = $(shell bundle exec ruby -e 'require "rubygems"; spec = Gem::Specification::load("../hammer_cli_awesome.gemspec"); puts spec.version')
|
77
|
-
MAIN_MAKEFILE = $(shell bundle exec ruby -e 'require "hammer_cli"; puts HammerCLI::I18n.main_makefile')
|
76
|
+
VERSION = $(shell bundle exec ruby -C ../ -e 'require "rubygems"; spec = Gem::Specification::load("../hammer_cli_awesome.gemspec"); puts spec.version')
|
77
|
+
MAIN_MAKEFILE = $(shell bundle exec ruby -C ../ -e 'require "hammer_cli"; puts HammerCLI::I18n.main_makefile')
|
78
78
|
|
79
79
|
include $(MAIN_MAKEFILE)
|
80
80
|
```
|
data/doc/installation_rpm.md
CHANGED
@@ -32,7 +32,7 @@ On RHEL systems you will also have to add [EPEL repository](https://fedoraprojec
|
|
32
32
|
#### Step 2: install hammer core
|
33
33
|
|
34
34
|
```bash
|
35
|
-
yum install rubygem-hammer_cli
|
35
|
+
yum install tfm-rubygem-hammer_cli
|
36
36
|
```
|
37
37
|
|
38
38
|
#### Step 3: install plugins
|
@@ -41,13 +41,13 @@ Currently, there are two plugins, both available as rpm packages.
|
|
41
41
|
- commands for managing foreman
|
42
42
|
|
43
43
|
```bash
|
44
|
-
yum install rubygem-hammer_cli_foreman
|
44
|
+
yum install tfm-rubygem-hammer_cli_foreman
|
45
45
|
```
|
46
46
|
|
47
47
|
- commands for managing [katello](https://github.com/Katello/katello)
|
48
48
|
|
49
49
|
```bash
|
50
|
-
yum install rubygem-hammer_cli_katello
|
50
|
+
yum install tfm-rubygem-hammer_cli_katello
|
51
51
|
```
|
52
52
|
|
53
53
|
To install any other hammer plugin just make sure the appropriate gem is installed and follow with the [configuration](installation.md#configuration).
|
data/doc/release_notes.md
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
Release notes
|
2
2
|
=============
|
3
|
-
### 0.
|
3
|
+
### 0.16.0 (2019-01-16)
|
4
|
+
* Fixed instructions in i18n docs ([#25724](http://projects.theforeman.org/issues/25724))
|
5
|
+
* Option validators can be mixed with sources ([#22253](http://projects.theforeman.org/issues/22253))
|
6
|
+
* Validator uses options from option collector ([#19574](http://projects.theforeman.org/issues/19574))
|
7
|
+
* Hammer -h does work with --output json, csv, yaml ([#25438](http://projects.theforeman.org/issues/25438))
|
8
|
+
* Update rpm names to use tfm ([PR #296](https://github.com/theforeman/hammer-cli/pull/296))
|
9
|
+
* Allows modification of output fields ([PR #275](https://github.com/theforeman/hammer-cli/pull/275)) ([#21634](http://projects.theforeman.org/issues/21634))
|
10
|
+
* Allow skipping message tests ([PR #292](https://github.com/theforeman/hammer-cli/pull/292)) ([#7451](http://projects.theforeman.org/issues/7451))
|
4
11
|
* Helper for editing text in editor ([PR #294](https://github.com/theforeman/hammer-cli/pull/294)) ([#24489](http://projects.theforeman.org/issues/24489))
|
5
12
|
* Add ability to disable defaults ([PR #293](https://github.com/theforeman/hammer-cli/pull/293)) ([#25307](http://projects.theforeman.org/issues/25307))
|
13
|
+
* Allow modification of additional help texts ([PR #277](https://github.com/theforeman/hammer-cli/pull/277)) ([#21633](http://projects.theforeman.org/issues/21633))
|
6
14
|
|
7
15
|
### 0.15.0 (2018-10-24)
|
8
16
|
* Correct the gemspec ([PR #286](https://github.com/theforeman/hammer-cli/pull/286))
|
data/lib/hammer_cli.rb
CHANGED
@@ -9,7 +9,6 @@ require 'hammer_cli/settings'
|
|
9
9
|
require 'hammer_cli/logger'
|
10
10
|
require 'hammer_cli/ca_cert_manager'
|
11
11
|
require 'hammer_cli/connection'
|
12
|
-
require 'hammer_cli/validator'
|
13
12
|
require 'hammer_cli/output'
|
14
13
|
require 'hammer_cli/options/normalizers'
|
15
14
|
require 'hammer_cli/completer'
|
data/lib/hammer_cli/abstract.rb
CHANGED
@@ -2,14 +2,17 @@ require 'hammer_cli/exception_handler'
|
|
2
2
|
require 'hammer_cli/logger_watch'
|
3
3
|
require 'hammer_cli/options/option_definition'
|
4
4
|
require 'hammer_cli/options/option_collector'
|
5
|
+
require 'hammer_cli/options/processor_list'
|
5
6
|
require 'hammer_cli/options/sources/command_line'
|
6
7
|
require 'hammer_cli/options/sources/saved_defaults'
|
8
|
+
require 'hammer_cli/options/validators/dsl_block_validator'
|
7
9
|
require 'hammer_cli/clamp'
|
8
10
|
require 'hammer_cli/subcommand'
|
9
11
|
require 'hammer_cli/options/matcher'
|
10
12
|
require 'hammer_cli/help/builder'
|
11
13
|
require 'hammer_cli/help/text_builder'
|
12
14
|
require 'logging'
|
15
|
+
|
13
16
|
module HammerCLI
|
14
17
|
|
15
18
|
class AbstractCommand < Clamp::Command
|
@@ -17,6 +20,10 @@ module HammerCLI
|
|
17
20
|
|
18
21
|
class << self
|
19
22
|
attr_accessor :validation_blocks
|
23
|
+
|
24
|
+
def help_extension_blocks
|
25
|
+
@help_extension_blocks ||= []
|
26
|
+
end
|
20
27
|
end
|
21
28
|
|
22
29
|
def adapter
|
@@ -40,7 +47,7 @@ module HammerCLI
|
|
40
47
|
super
|
41
48
|
validate_options
|
42
49
|
logger.info "Called with options: %s" % options.inspect
|
43
|
-
rescue HammerCLI::
|
50
|
+
rescue HammerCLI::Options::Validators::ValidationError => e
|
44
51
|
signal_usage_error e.message
|
45
52
|
end
|
46
53
|
|
@@ -48,15 +55,14 @@ module HammerCLI
|
|
48
55
|
HammerCLI::EX_OK
|
49
56
|
end
|
50
57
|
|
51
|
-
def self.validate_options(&block)
|
58
|
+
def self.validate_options(mode=:append, target_name=nil, validator: nil, &block)
|
59
|
+
validator ||= HammerCLI::Options::Validators::DSLBlockValidator.new(&block)
|
52
60
|
self.validation_blocks ||= []
|
53
|
-
self.validation_blocks <<
|
61
|
+
self.validation_blocks << [mode, target_name, validator]
|
54
62
|
end
|
55
63
|
|
56
64
|
def validate_options
|
57
|
-
|
58
|
-
self.class.validation_blocks.each { |validation_block| validator.run(&validation_block) }
|
59
|
-
end
|
65
|
+
# keep the method for legacy reasons
|
60
66
|
end
|
61
67
|
|
62
68
|
def exception_handler
|
@@ -80,9 +86,16 @@ module HammerCLI
|
|
80
86
|
def self.help(invocation_path, builder = HammerCLI::Help::Builder.new)
|
81
87
|
super(invocation_path, builder)
|
82
88
|
|
83
|
-
|
89
|
+
unless help_extension_blocks.empty?
|
84
90
|
help_extension = HammerCLI::Help::TextBuilder.new(builder.richtext)
|
85
|
-
|
91
|
+
help_extension_blocks.each do |extension_block|
|
92
|
+
begin
|
93
|
+
extension_block.call(help_extension)
|
94
|
+
rescue ArgumentError => e
|
95
|
+
handler = HammerCLI::ExceptionHandler.new
|
96
|
+
handler.handle_exception(e)
|
97
|
+
end
|
98
|
+
end
|
86
99
|
builder.add_text(help_extension.string)
|
87
100
|
end
|
88
101
|
builder.string
|
@@ -90,7 +103,14 @@ module HammerCLI
|
|
90
103
|
|
91
104
|
def self.extend_help(&block)
|
92
105
|
# We save the block for execution on object level, where we can access command's context and check :is_tty? flag
|
93
|
-
|
106
|
+
self.help_extension_blocks << block
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.extend_output_definition(&block)
|
110
|
+
block.call(output_definition)
|
111
|
+
rescue ArgumentError => e
|
112
|
+
handler = HammerCLI::ExceptionHandler.new
|
113
|
+
handler.handle_exception(e)
|
94
114
|
end
|
95
115
|
|
96
116
|
def self.output(definition=nil, &block)
|
@@ -180,8 +200,8 @@ module HammerCLI
|
|
180
200
|
end
|
181
201
|
|
182
202
|
def validator
|
183
|
-
|
184
|
-
@validator ||= HammerCLI::
|
203
|
+
# keep the method for legacy reasons, it's used by validate_options
|
204
|
+
@validator ||= HammerCLI::Options::Validators::DSL.new(self.class.recognised_options, all_options)
|
185
205
|
end
|
186
206
|
|
187
207
|
def handle_exception(e)
|
@@ -240,13 +260,24 @@ module HammerCLI
|
|
240
260
|
end
|
241
261
|
|
242
262
|
def option_collector
|
243
|
-
@option_collector ||= HammerCLI::Options::OptionCollector.new(self.class.recognised_options, option_sources)
|
263
|
+
@option_collector ||= HammerCLI::Options::OptionCollector.new(self.class.recognised_options, add_validators(option_sources))
|
244
264
|
end
|
245
265
|
|
246
266
|
|
247
267
|
def option_sources
|
248
|
-
sources =
|
268
|
+
sources = HammerCLI::Options::ProcessorList.new(name: 'DefaultInputs')
|
269
|
+
sources << HammerCLI::Options::Sources::CommandLine.new(self)
|
249
270
|
sources << HammerCLI::Options::Sources::SavedDefaults.new(context[:defaults], logger) if context[:use_defaults]
|
271
|
+
|
272
|
+
HammerCLI::Options::ProcessorList.new([sources])
|
273
|
+
end
|
274
|
+
|
275
|
+
def add_validators(sources)
|
276
|
+
if self.class.validation_blocks
|
277
|
+
self.class.validation_blocks.each do |validation_block|
|
278
|
+
sources.insert_relative(*validation_block)
|
279
|
+
end
|
280
|
+
end
|
250
281
|
sources
|
251
282
|
end
|
252
283
|
|