hammer_cli 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -5
- data/config/cli_config.template.yml +12 -3
- data/doc/creating_apipie_commands.md +53 -56
- data/doc/creating_commands.md +25 -19
- data/doc/developer_docs.md +3 -2
- data/doc/development_tips.md +3 -3
- data/doc/i18n.md +3 -3
- data/doc/installation.md +24 -207
- data/doc/installation_deb.md +48 -0
- data/doc/installation_gem.md +30 -0
- data/doc/installation_rpm.md +53 -0
- data/doc/installation_source.md +31 -0
- data/doc/option_builders.md +77 -0
- data/doc/option_normalizers.md +5 -5
- data/doc/writing_a_plugin.md +9 -9
- data/lib/hammer_cli.rb +1 -0
- data/lib/hammer_cli/abstract.rb +21 -8
- data/lib/hammer_cli/apipie.rb +1 -2
- data/lib/hammer_cli/apipie/command.rb +37 -64
- data/lib/hammer_cli/apipie/option_builder.rb +69 -0
- data/lib/hammer_cli/apipie/options.rb +1 -61
- data/lib/hammer_cli/clamp.rb +15 -0
- data/lib/hammer_cli/i18n.rb +14 -2
- data/lib/hammer_cli/logger.rb +1 -1
- data/lib/hammer_cli/option_builder.rb +43 -0
- data/lib/hammer_cli/options/option_definition.rb +6 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +2 -2
- data/lib/hammer_cli/output/adapter/base.rb +6 -3
- data/lib/hammer_cli/output/adapter/table.rb +19 -2
- data/lib/hammer_cli/output/definition.rb +4 -0
- data/lib/hammer_cli/output/fields.rb +9 -0
- data/lib/hammer_cli/output/formatters.rb +20 -8
- data/lib/hammer_cli/utils.rb +1 -1
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/hammer-cli.pot +103 -79
- data/test/unit/abstract_test.rb +62 -0
- data/test/unit/apipie/command_test.rb +12 -197
- data/test/unit/apipie/option_builder_test.rb +110 -0
- data/test/unit/i18n_test.rb +50 -0
- data/test/unit/option_builder_test.rb +33 -0
- data/test/unit/output/adapter/abstract_test.rb +26 -3
- data/test/unit/output/adapter/base_test.rb +20 -3
- data/test/unit/output/adapter/csv_test.rb +2 -2
- data/test/unit/output/adapter/table_test.rb +24 -1
- data/test/unit/output/definition_test.rb +13 -0
- data/test/unit/output/formatters_test.rb +17 -1
- data/test/unit/utils_test.rb +1 -1
- metadata +101 -88
- data/lib/hammer_cli/apipie/read_command.rb +0 -41
- data/lib/hammer_cli/apipie/write_command.rb +0 -49
- data/test/unit/apipie/read_command_test.rb +0 -37
- data/test/unit/apipie/write_command_test.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 290f41e5f2227f4e71ffbaf977f02ba0cf8b1601
|
4
|
+
data.tar.gz: 14502a8f77396925e426d8e1384f73e77fd6288a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05159163a04fb707dbdfcd1292bd2d9b845742643b3d39fde9d422a060dab9cd4d8d8a3cd82b957427c01ca7629444eee63834d8afff2c649d917509acb12105
|
7
|
+
data.tar.gz: 238d88468d9fc4e74c209d991a6b1cde091eb14f5cb0f31e7c5ad7e5932a8f2a5d9f6e67999eb982b2b40ac81e22ff38c85e495e42be42190f4ed5b25331ec02
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
Hammer - the CLI tool (not only) for Foreman
|
2
2
|
============================================
|
3
3
|
|
4
|
-
|
5
4
|
Hammer is a generic [clamp-based](https://github.com/mdub/clamp) CLI framework.
|
6
5
|
Hammer-cli provides just the core functionality. The core is extensible using plugins that contain application-specific commands.
|
7
6
|
|
@@ -16,22 +15,31 @@ You also can easily add custom commands for your specific use, such as bulk acti
|
|
16
15
|
|
17
16
|
Installation
|
18
17
|
------------
|
19
|
-
We build rpms, debs and gems. Alternatively you can install hammer form a git checkout.
|
18
|
+
We build rpms, debs and gems. Alternatively you can install hammer form a git checkout.
|
19
|
+
See our [installation and configuration instuctions](doc/installation.md#installation).
|
20
|
+
|
21
|
+
|
22
|
+
Having issues?
|
23
|
+
--------------
|
24
|
+
If one of hammer commands doesn't work as you would expect, you can run `hammer -d ...` to get
|
25
|
+
full debug output from the loggers. It should give you an idea what went wrong.
|
26
|
+
|
27
|
+
If you have questions, don't hesitate to contact us on `foreman-users@googlegroups.com` or
|
28
|
+
`FreeNode#foreman` irc channel.
|
20
29
|
|
21
30
|
|
22
31
|
Further reading
|
23
32
|
---------------
|
24
33
|
If you're interested in hammer and want to develop some plugins for Foreman
|
25
|
-
or use it as a base for your own
|
34
|
+
or use it as a base for your own CLI, read
|
26
35
|
[the developer docs](doc/developer_docs.md#hammer-development-docs).
|
27
36
|
|
37
|
+
|
28
38
|
License
|
29
39
|
-------
|
30
|
-
|
31
40
|
This project is licensed under the GPLv3+.
|
32
41
|
|
33
42
|
|
34
43
|
Acknowledgements
|
35
44
|
----------------
|
36
|
-
|
37
45
|
Thanks to Brian Gupta for the initial work and a great name.
|
@@ -1,15 +1,24 @@
|
|
1
|
+
# User interface related settings
|
1
2
|
:ui:
|
3
|
+
# Enable interactive queries?
|
2
4
|
:interactive: true
|
5
|
+
# Number of records listed per page
|
3
6
|
:per_page: 20
|
7
|
+
# Location of shell history file
|
4
8
|
:history_file: '~/.hammer/history'
|
5
9
|
|
6
10
|
|
7
|
-
#
|
11
|
+
# Enable/disable color output of logger in Clamp commands
|
8
12
|
:watch_plain: false
|
9
13
|
|
14
|
+
# Directory where the logs are stored. The default is /var/log/hammer/ and the log file is named hammer.log
|
10
15
|
:log_dir: '~/.hammer/log'
|
16
|
+
|
17
|
+
# Logging level. One of debug, info, warning, error, fatal
|
11
18
|
:log_level: 'error'
|
12
|
-
|
19
|
+
|
13
20
|
#:log_owner: 'foreman'
|
14
21
|
#:log_group: 'foreman'
|
15
|
-
|
22
|
+
|
23
|
+
# Maximum log size in bytes. Log rotates when the value gets exceeded
|
24
|
+
#:log_size: 5 #in MB
|
@@ -1,76 +1,69 @@
|
|
1
1
|
Creating commands for RESTful API with ApiPie
|
2
2
|
---------------------------------------------
|
3
3
|
|
4
|
-
CLIs
|
4
|
+
CLIs bound to a REST API do simillar things for most of the resources. Typically there are
|
5
5
|
CRUD actions that appear for nearly every resource. Actions differ with parameters
|
6
6
|
accross resources but the operations remain the same.
|
7
7
|
|
8
8
|
Hammer is optimised for usage with [ApiPie](https://github.com/Pajk/apipie-rails)
|
9
|
-
and generated
|
9
|
+
and generated API bindings and tries to reduce the effort neccessary for a command creation.
|
10
10
|
|
11
11
|
|
12
12
|
### ApiPie and bindings
|
13
13
|
|
14
14
|
[ApiPie](https://github.com/Pajk/apipie-rails) is a documentation library for RESTful APIs.
|
15
|
-
Unlike traditional tools ApiPie uses DSL for
|
15
|
+
Unlike traditional tools ApiPie uses DSL for API descriptions. This brings many advantages. See its
|
16
16
|
documentation for details.
|
17
17
|
|
18
18
|
Foreman comes with [ruby bindings](https://github.com/theforeman/foreman_api) automatically generated
|
19
19
|
from the information provided by ApiPie. Every resource (eg. Architecture, User) has it's own
|
20
|
-
class with methods for each available action (
|
21
|
-
Apart from that it contains also full
|
22
|
-
This
|
23
|
-
and reduce the amount of custom code per CLI action.
|
20
|
+
class with methods for each available action (e.g. create, show, index, destroy).
|
21
|
+
Apart from that it contains also full API documentation with parameters for the actions.
|
22
|
+
This allows to reuse the documentation on the client side for automatic option definition
|
23
|
+
and to reduce the amount of custom code per CLI action.
|
24
24
|
|
25
25
|
|
26
26
|
### ApiPie commands in Hammer
|
27
27
|
|
28
|
-
Hammer
|
28
|
+
Hammer provides `HammerCLI::Apipie::Command` base class for apipie actions.
|
29
|
+
The command class is single resource related and expect the resource and an action to be defined.
|
29
30
|
|
30
|
-
- __ReadCommand__
|
31
|
-
- should be used for actions that print records
|
32
|
-
- retrieves the data and prints them in given format (uses output definition)
|
33
|
-
- typical actions in rails terminology: _index, show_
|
34
|
-
|
35
|
-
- __WriteCommand__
|
36
|
-
- should used for actions that modify records
|
37
|
-
- sends modifying request and prints the result
|
38
|
-
- typical actions in rails terminology: _create, update, destroy_
|
39
|
-
|
40
|
-
Both command classes are single resource related and expect the resource and an action to be defined.
|
41
31
|
There's a simple DSL for that:
|
42
32
|
|
43
33
|
```ruby
|
44
|
-
class ListCommand < HammerCLI::Apipie::
|
34
|
+
class ListCommand < HammerCLI::Apipie::Command
|
45
35
|
# define resource and the action together
|
46
|
-
resource
|
36
|
+
resource :architectures, :index
|
47
37
|
end
|
48
38
|
|
49
39
|
# or
|
50
40
|
|
51
|
-
class ListCommand2 < HammerCLI::Apipie::
|
41
|
+
class ListCommand2 < HammerCLI::Apipie::Command
|
52
42
|
# define them separately
|
53
|
-
resource
|
43
|
+
resource :architectures
|
54
44
|
action :index
|
55
45
|
end
|
56
46
|
```
|
57
47
|
|
58
48
|
#### Options definition
|
59
49
|
|
60
|
-
When the resource-action pair is defined we can take
|
61
|
-
There's
|
50
|
+
When the resource-action pair is defined we can take advantage of automatic option definition.
|
51
|
+
There's an [option builder](https://github.com/theforeman/hammer-cli/blob/master/lib/hammer_cli/apipie/option_builder.rb)
|
52
|
+
for apipie parameters pre-set in the apipie command's base class.
|
53
|
+
You can read details about the option builder principles [here](option_builders.md#option-builders).
|
54
|
+
|
62
55
|
|
63
56
|
```ruby
|
64
|
-
class ListCommand < HammerCLI::Apipie::
|
65
|
-
resource
|
57
|
+
class ListCommand < HammerCLI::Apipie::Command
|
58
|
+
resource :architectures, :index
|
66
59
|
|
67
|
-
|
60
|
+
build_options
|
68
61
|
end
|
69
62
|
```
|
70
63
|
|
71
64
|
If we plug the command into an existing command tree and check the help we will see there
|
72
65
|
are four parameters defined from the ApiPie docs. Compare the result with
|
73
|
-
[online
|
66
|
+
[online API documentation](http://www.theforeman.org/api/apidoc/architectures/index.html).
|
74
67
|
```
|
75
68
|
$ hammer architecture list -h
|
76
69
|
Usage:
|
@@ -85,14 +78,18 @@ Options:
|
|
85
78
|
```
|
86
79
|
|
87
80
|
It is possible to combine apipie options with custom ones. If the generated options
|
88
|
-
|
81
|
+
don't suit your needs for any reason, you can always redefine them by hand or just skip them.
|
82
|
+
|
89
83
|
See following example.
|
90
84
|
```ruby
|
91
|
-
class ListCommand < HammerCLI::Apipie::
|
92
|
-
resource
|
85
|
+
class ListCommand < HammerCLI::Apipie::Command
|
86
|
+
resource :architectures, :index
|
93
87
|
|
94
|
-
|
88
|
+
# first created option takes precedence
|
95
89
|
option '--search', 'QUERY', "search query"
|
90
|
+
|
91
|
+
# use option :without to define what options should be skipped
|
92
|
+
build_options :without => [:order]
|
96
93
|
end
|
97
94
|
```
|
98
95
|
|
@@ -109,16 +106,16 @@ Options:
|
|
109
106
|
```
|
110
107
|
Note that the `--search` description has changed and `--order` disappeared.
|
111
108
|
|
112
|
-
|
109
|
+
Automaticaly generated options reflect:
|
113
110
|
- parameter names and descriptions
|
114
111
|
- required parameters
|
115
112
|
- parameter types - the only supported type is array, which is translated to option normalizer `List`
|
116
113
|
|
117
|
-
####
|
114
|
+
#### Status messages
|
118
115
|
|
119
|
-
|
116
|
+
Some commands are expected to print result of the API action. There are
|
120
117
|
two class methods for setting success and failure messages. Messages are
|
121
|
-
printed according to the
|
118
|
+
printed according to the HTTP status code the API returned.
|
122
119
|
|
123
120
|
```ruby
|
124
121
|
success_message "The user has been created"
|
@@ -129,14 +126,14 @@ failure_message "Could not create the user"
|
|
129
126
|
#### Example 1: Create an architecture
|
130
127
|
|
131
128
|
```ruby
|
132
|
-
class CreateCommand < HammerCLI::Apipie::
|
129
|
+
class CreateCommand < HammerCLI::Apipie::Command
|
133
130
|
command_name "create"
|
134
|
-
resource
|
131
|
+
resource :architectures, :create
|
135
132
|
|
136
133
|
success_message "Architecture created"
|
137
134
|
failure_message "Could not create the architecture"
|
138
135
|
|
139
|
-
|
136
|
+
build_options
|
140
137
|
end
|
141
138
|
```
|
142
139
|
|
@@ -174,12 +171,12 @@ Could not create the architecture:
|
|
174
171
|
#### Example 2: Show an architecture
|
175
172
|
|
176
173
|
```ruby
|
177
|
-
class InfoCommand < HammerCLI::Apipie::
|
174
|
+
class InfoCommand < HammerCLI::Apipie::Command
|
178
175
|
command_name "info"
|
179
|
-
resource
|
176
|
+
resource :architectures, :show
|
180
177
|
|
181
178
|
# It's a good practice to reuse output definition from list commands
|
182
|
-
# and add more details.
|
179
|
+
# and add more details. This helps avoiding duplicities.
|
183
180
|
output ListCommand.output_definition do
|
184
181
|
from "architecture" do
|
185
182
|
field :operatingsystem_ids, "OS ids", Fields::List
|
@@ -188,7 +185,7 @@ class InfoCommand < HammerCLI::Apipie::ReadCommand
|
|
188
185
|
end
|
189
186
|
end
|
190
187
|
|
191
|
-
|
188
|
+
build_options
|
192
189
|
end
|
193
190
|
```
|
194
191
|
|
@@ -214,7 +211,7 @@ Updated at: 2013/06/08 19:17:43
|
|
214
211
|
|
215
212
|
#### Tips
|
216
213
|
|
217
|
-
When you define more
|
214
|
+
When you define more commands like we've shown above you find yourself repeating
|
218
215
|
`resource ...` in every one of them. As the commands are usually grouped by
|
219
216
|
the resource it is handy to extract the resource definition one level up to
|
220
217
|
the encapsulating command.
|
@@ -222,15 +219,15 @@ the encapsulating command.
|
|
222
219
|
```ruby
|
223
220
|
class Architecture < HammerCLI::Apipie::Command
|
224
221
|
|
225
|
-
resource
|
222
|
+
resource :architectures
|
226
223
|
|
227
|
-
class ListCommand < HammerCLI::Apipie::
|
224
|
+
class ListCommand < HammerCLI::Apipie::Command
|
228
225
|
action :index
|
229
226
|
# ...
|
230
227
|
end
|
231
228
|
|
232
229
|
|
233
|
-
class InfoCommand < HammerCLI::Apipie::
|
230
|
+
class InfoCommand < HammerCLI::Apipie::Command
|
234
231
|
action :show
|
235
232
|
# ...
|
236
233
|
end
|
@@ -245,20 +242,20 @@ the resource of the parent command is used at runtime. This is useful for contex
|
|
245
242
|
shared commands.
|
246
243
|
|
247
244
|
The following example shows a common subcommand that can be attached to
|
248
|
-
any parent
|
249
|
-
is fictitious. There
|
245
|
+
any parent which has a resource implementing the method `add_tag`. Please note that this example
|
246
|
+
is fictitious. There are no tags in Foreman's architectures and users.
|
250
247
|
```ruby
|
251
248
|
module Tags
|
252
249
|
class AddTag < HammerCLI::Apipie::WriteCommand
|
253
250
|
option '--id', 'ID', 'ID of the resource'
|
254
251
|
option '--tag', 'TAG', 'Name of the tag to add'
|
255
252
|
action :add_tag
|
256
|
-
command_name '
|
253
|
+
command_name 'add-tag'
|
257
254
|
end
|
258
255
|
end
|
259
256
|
|
260
257
|
class Architecture < HammerCLI::Apipie::Command
|
261
|
-
resource
|
258
|
+
resource :architectures
|
262
259
|
# ...
|
263
260
|
include Tags
|
264
261
|
autoload_subcommands
|
@@ -273,9 +270,9 @@ end
|
|
273
270
|
```
|
274
271
|
|
275
272
|
```
|
276
|
-
$ hammer architecture
|
273
|
+
$ hammer architecture add-tag -h
|
277
274
|
Usage:
|
278
|
-
hammer architecture
|
275
|
+
hammer architecture add-tag [OPTIONS]
|
279
276
|
|
280
277
|
Options:
|
281
278
|
--id ID ID of the resource
|
@@ -284,9 +281,9 @@ Options:
|
|
284
281
|
```
|
285
282
|
|
286
283
|
```
|
287
|
-
$ hammer user
|
284
|
+
$ hammer user add-tag -h
|
288
285
|
Usage:
|
289
|
-
hammer user
|
286
|
+
hammer user add-tag [OPTIONS]
|
290
287
|
|
291
288
|
Options:
|
292
289
|
--id ID ID of the resource
|
data/doc/creating_commands.md
CHANGED
@@ -13,7 +13,7 @@ touch ./lib/hammer_cli_hello/hello_world.rb
|
|
13
13
|
# ./lib/hammer_cli_hello/hello_world.rb
|
14
14
|
require 'hammer_cli'
|
15
15
|
|
16
|
-
# it's a good
|
16
|
+
# it's a good practice to nest commands into modules
|
17
17
|
module HammerCLIHello
|
18
18
|
|
19
19
|
# hammer commands must be descendants of AbstractCommand
|
@@ -97,7 +97,7 @@ for the full list of available exit codes.
|
|
97
97
|
Our new command has only one option so far. It's `-h` which is built in for every command by default.
|
98
98
|
Option declaration is the same as in clamp so please read it's
|
99
99
|
[documentation](https://github.com/mdub/clamp/#declaring-options)
|
100
|
-
on that topic. However unlike in Clamp, the option accessors in Hammer are created with prefix 'option_', to avoid
|
100
|
+
on that topic. However, unlike in Clamp, the option accessors in Hammer are created with prefix 'option_', to avoid
|
101
101
|
conflict with methods of the commands. So to access value of an `--name` option you have to call `option_name()`
|
102
102
|
|
103
103
|
|
@@ -129,6 +129,9 @@ $ hammer hello --name 'Foreman'
|
|
129
129
|
Hello Foreman!
|
130
130
|
```
|
131
131
|
|
132
|
+
### Option builders
|
133
|
+
Hammer commands offer option builders that can be used for automatic option generation.
|
134
|
+
See [documentation page](option_builders.md#option-builders) dedicated to this topic for more details.
|
132
135
|
|
133
136
|
### Option validation
|
134
137
|
Hammer provides extended functionality for validating options.
|
@@ -139,10 +142,10 @@ First of all there is a dsl for validating combinations of options:
|
|
139
142
|
validate_options do
|
140
143
|
all(:option_name, :option_surname).required # requires all the options
|
141
144
|
option(:option_age).required # requires a single option,
|
142
|
-
|
145
|
+
# equivalent of :required => true in option declaration
|
143
146
|
any(:option_email, :option_phone).required # requires at least one of the options
|
144
147
|
|
145
|
-
#
|
148
|
+
# It is possible to create more complicated constructs.
|
146
149
|
# This example requires either the full address or nothing
|
147
150
|
if any(:option_street, :option_city, :option_zip).exist?
|
148
151
|
all(:option_street, :option_city, :option_zip).required
|
@@ -204,7 +207,7 @@ option "--attributes", "ATTRIBUTES", "Values of various attributes",
|
|
204
207
|
`--attributes="material=unoptanium,thickness=3"` -> `{'material' => 'unoptanium', 'thickness' => '3'}`
|
205
208
|
|
206
209
|
### Adding subcommands
|
207
|
-
Commands in the
|
210
|
+
Commands in the CLI can be structured into a tree of parent commands (nodes) and subcommands (leaves).
|
208
211
|
Neither the number of subcommands nor the nesting is limited. Please note that no parent command
|
209
212
|
can perform any action and therefore it's useless to define `execute` method for them. This limit
|
210
213
|
comes from Clamp's implementation of the command hierarchy.
|
@@ -247,7 +250,7 @@ Hello World!
|
|
247
250
|
This is very typical usage of subcommands. When you create more of them it may feel a bit
|
248
251
|
duplicit to always define the subcommand structure at the end of the class definition.
|
249
252
|
Hammer provides utility methods for subcommand autoloading. This is handy especially
|
250
|
-
when you have growing number of subcommands. See how it works in the following example:
|
253
|
+
when you have a growing number of subcommands. See how it works in the following example:
|
251
254
|
|
252
255
|
```ruby
|
253
256
|
module HammerCLIHello
|
@@ -307,7 +310,7 @@ a message in a log for debugging purposes.
|
|
307
310
|
|
308
311
|
|
309
312
|
### Removing subcommands
|
310
|
-
If your plugin needs to disable existing subcommand, you can use `remove_subcommand` for this.
|
313
|
+
If your plugin needs to disable an existing subcommand, you can use `remove_subcommand` for this.
|
311
314
|
|
312
315
|
```ruby
|
313
316
|
HammerCLI::MainCommand.remove_subcommand 'say'
|
@@ -337,13 +340,13 @@ print_message(msg)
|
|
337
340
|
```
|
338
341
|
|
339
342
|
#### Printing hash records
|
340
|
-
Typical usage of a
|
341
|
-
some records returned by the
|
343
|
+
Typical usage of a CLI is interaction with some API. In many cases it's listing
|
344
|
+
some records returned by the API.
|
342
345
|
|
343
346
|
Hammer comes with support for selecting and formatting of hash record fields.
|
344
|
-
You first create
|
345
|
-
is a collection of fields each having its type. The collection is then passed to
|
346
|
-
_output adapter_ which handles the
|
347
|
+
You first create a _output definition_ that you apply to your data. The result
|
348
|
+
is a collection of fields, each having its type. The collection is then passed to an
|
349
|
+
_output adapter_ which handles the actual formatting and printing.
|
347
350
|
|
348
351
|
Hammer provides a DSL for defining the output. Next rather complex example will
|
349
352
|
explain how to use it in action.
|
@@ -380,7 +383,7 @@ We can create an output definition that selects and formats some of the fields:
|
|
380
383
|
class Command < HammerCLI::AbstractCommand
|
381
384
|
|
382
385
|
output do
|
383
|
-
# Simple field with a label. The first parameter is key in the printed hash.
|
386
|
+
# Simple field with a label. The first parameter is the key in the printed hash.
|
384
387
|
field :id, 'ID'
|
385
388
|
|
386
389
|
# Fields can have types. The type determines how the field is printed.
|
@@ -403,7 +406,7 @@ class Command < HammerCLI::AbstractCommand
|
|
403
406
|
|
404
407
|
def execute
|
405
408
|
records = retrieve_data
|
406
|
-
|
409
|
+
print_record( # <- printing utility of AbstractCommand
|
407
410
|
output_definition, # <- method for accessing fields defined in the block 'output'
|
408
411
|
records # <- the data to print
|
409
412
|
)
|
@@ -432,7 +435,7 @@ Contacts:
|
|
432
435
|
Created At: 2012/12/18 15:25:00
|
433
436
|
```
|
434
437
|
|
435
|
-
You can optionally use output definition from another command as a base and extend it with
|
438
|
+
You can optionally use the output definition from another command as a base and extend it with
|
436
439
|
additional fields. This is helpful when there are two commands, one listing brief data and
|
437
440
|
another one showing details. Typically it's list and show.
|
438
441
|
```ruby
|
@@ -455,7 +458,7 @@ All Hammer field types are:
|
|
455
458
|
* __KeyValue__ - Formats hashes containing `:name` and `:value`
|
456
459
|
* __Collection__ - Enables to render subcollections. Takes a block with another output definition.
|
457
460
|
|
458
|
-
The default adapter for every command is Base adapter. It is possible to override
|
461
|
+
The default adapter for every command is the Base adapter. It is possible to override
|
459
462
|
the default one by redefining command's method `adapter`.
|
460
463
|
|
461
464
|
```ruby
|
@@ -523,7 +526,7 @@ require 'hammer_cli_hello/hello_world'
|
|
523
526
|
```
|
524
527
|
|
525
528
|
Centralized exception handling implies that you should raise exceptions on error states in your command
|
526
|
-
rather than handle it and return error codes. This approach
|
529
|
+
rather than handle it and return error codes. This approach guarantees that error messages are logged and
|
527
530
|
printed consistently and correct exit codes are returned.
|
528
531
|
|
529
532
|
|
@@ -532,7 +535,7 @@ Values form config files are accesible via class `HammerCLI::Settings`.
|
|
532
535
|
It's method `get` returns either the value or nil when it's not found.
|
533
536
|
|
534
537
|
Config values belonging to a specific plugin must be nested under
|
535
|
-
the plugin's name in config files.
|
538
|
+
the plugin's name (without the prefix 'hammer_cli_') in config files.
|
536
539
|
|
537
540
|
```yaml
|
538
541
|
#cli_config.yml
|
@@ -546,6 +549,9 @@ HammerCLI::Settings.get(:log_dir) # get a value
|
|
546
549
|
HammerCLI::Settings.get(:hello_world, :name) # get a nested value
|
547
550
|
```
|
548
551
|
|
549
|
-
There
|
552
|
+
There are more ways where to place your config file for hammer.
|
553
|
+
The best practice is to place module's configuration into a separate file named by
|
554
|
+
the module. In this example it would be `~/.hammer/cli.modules.d/hello_world.yml`.
|
555
|
+
|
550
556
|
Read more in [the settings howto](https://github.com/theforeman/hammer-cli#configuration).
|
551
557
|
|