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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -5
  3. data/config/cli_config.template.yml +12 -3
  4. data/doc/creating_apipie_commands.md +53 -56
  5. data/doc/creating_commands.md +25 -19
  6. data/doc/developer_docs.md +3 -2
  7. data/doc/development_tips.md +3 -3
  8. data/doc/i18n.md +3 -3
  9. data/doc/installation.md +24 -207
  10. data/doc/installation_deb.md +48 -0
  11. data/doc/installation_gem.md +30 -0
  12. data/doc/installation_rpm.md +53 -0
  13. data/doc/installation_source.md +31 -0
  14. data/doc/option_builders.md +77 -0
  15. data/doc/option_normalizers.md +5 -5
  16. data/doc/writing_a_plugin.md +9 -9
  17. data/lib/hammer_cli.rb +1 -0
  18. data/lib/hammer_cli/abstract.rb +21 -8
  19. data/lib/hammer_cli/apipie.rb +1 -2
  20. data/lib/hammer_cli/apipie/command.rb +37 -64
  21. data/lib/hammer_cli/apipie/option_builder.rb +69 -0
  22. data/lib/hammer_cli/apipie/options.rb +1 -61
  23. data/lib/hammer_cli/clamp.rb +15 -0
  24. data/lib/hammer_cli/i18n.rb +14 -2
  25. data/lib/hammer_cli/logger.rb +1 -1
  26. data/lib/hammer_cli/option_builder.rb +43 -0
  27. data/lib/hammer_cli/options/option_definition.rb +6 -0
  28. data/lib/hammer_cli/output/adapter/abstract.rb +2 -2
  29. data/lib/hammer_cli/output/adapter/base.rb +6 -3
  30. data/lib/hammer_cli/output/adapter/table.rb +19 -2
  31. data/lib/hammer_cli/output/definition.rb +4 -0
  32. data/lib/hammer_cli/output/fields.rb +9 -0
  33. data/lib/hammer_cli/output/formatters.rb +20 -8
  34. data/lib/hammer_cli/utils.rb +1 -1
  35. data/lib/hammer_cli/version.rb +1 -1
  36. data/locale/hammer-cli.pot +103 -79
  37. data/test/unit/abstract_test.rb +62 -0
  38. data/test/unit/apipie/command_test.rb +12 -197
  39. data/test/unit/apipie/option_builder_test.rb +110 -0
  40. data/test/unit/i18n_test.rb +50 -0
  41. data/test/unit/option_builder_test.rb +33 -0
  42. data/test/unit/output/adapter/abstract_test.rb +26 -3
  43. data/test/unit/output/adapter/base_test.rb +20 -3
  44. data/test/unit/output/adapter/csv_test.rb +2 -2
  45. data/test/unit/output/adapter/table_test.rb +24 -1
  46. data/test/unit/output/definition_test.rb +13 -0
  47. data/test/unit/output/formatters_test.rb +17 -1
  48. data/test/unit/utils_test.rb +1 -1
  49. metadata +101 -88
  50. data/lib/hammer_cli/apipie/read_command.rb +0 -41
  51. data/lib/hammer_cli/apipie/write_command.rb +0 -49
  52. data/test/unit/apipie/read_command_test.rb +0 -37
  53. 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: 83ee93e64de515a960acf80a4ed0452d700fb5cd
4
- data.tar.gz: fb55752f1a394e1261a342bf3d8e9a68ed98386f
3
+ metadata.gz: 290f41e5f2227f4e71ffbaf977f02ba0cf8b1601
4
+ data.tar.gz: 14502a8f77396925e426d8e1384f73e77fd6288a
5
5
  SHA512:
6
- metadata.gz: 772c2a0849cde3c134977dfe3856cd4e6deb4b3cdbaa0568eb7656e64c9a9d722b11ba00a61a65a99e75978fd377e069f2aa9b4adb9e1fe7f8535dc4cc1edb19
7
- data.tar.gz: dff56f16e56b6632e1e82e5327f1c0ae7fd39e218ce6aaaf5d0d4c30643b12dc3864e83fd9279066e504f0c740de9b666fe103498eeaf086caf11633ecf62bba
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. See our [installation instructions](doc/installation.md#installation) for details.
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 cli, read
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
- # enable/disable color output of logger in Clamp commands
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
- :log_api_calls: false
19
+
13
20
  #:log_owner: 'foreman'
14
21
  #:log_group: 'foreman'
15
- #:log_size: 5 #MB
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 binded to a rest api do simillar things for most of the resources. Typically it's
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 api bindings and tries to reduce the effort neccessary for a command creation.
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 api description. This brings many advantages. See its
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 (eg. create, show, index, destroy).
21
- Apart from that it contains also full api documentation with parameters for the actions.
22
- This enables to reuse the documentation on client side for automatic option definition
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 identifies two basic types of ApiPie commands:
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::ReadCommand
34
+ class ListCommand < HammerCLI::Apipie::Command
45
35
  # define resource and the action together
46
- resource ForemanApi::Resources::Architecture, :index
36
+ resource :architectures, :index
47
37
  end
48
38
 
49
39
  # or
50
40
 
51
- class ListCommand2 < HammerCLI::Apipie::ReadCommand
41
+ class ListCommand2 < HammerCLI::Apipie::Command
52
42
  # define them separately
53
- resource ForemanApi::Resources::Architecture
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 the advantage of automatic option definition.
61
- There's a class method `apipie_options` for this purpose.
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::ReadCommand
65
- resource ForemanApi::Resources::Architecture, :index
57
+ class ListCommand < HammerCLI::Apipie::Command
58
+ resource :architectures, :index
66
59
 
67
- apipie_options
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 api documentation](http://www.theforeman.org/api/apidoc/architectures/index.html).
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
- doesn't suit your needs for any reason, you can always skip and redefine them by hand.
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::ReadCommand
92
- resource ForemanApi::Resources::Architecture, :index
85
+ class ListCommand < HammerCLI::Apipie::Command
86
+ resource :architectures, :index
93
87
 
94
- apipie_options :without => [:search, :order]
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
- Automatic options reflect:
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
- #### Write commands
114
+ #### Status messages
118
115
 
119
- Write commands are expected to print result of the api action. There are
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 http status code the api returned.
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::WriteCommand
129
+ class CreateCommand < HammerCLI::Apipie::Command
133
130
  command_name "create"
134
- resource ForemanApi::Resources::Architecture, :create
131
+ resource :architectures, :create
135
132
 
136
133
  success_message "Architecture created"
137
134
  failure_message "Could not create the architecture"
138
135
 
139
- apipie_options
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::ReadCommand
174
+ class InfoCommand < HammerCLI::Apipie::Command
178
175
  command_name "info"
179
- resource ForemanApi::Resources::Architecture, :show
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. It helps avoiding duplicities.
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
- apipie_options
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 command like we've shown above you find yourself repeating
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 ForemanApi::Resources::Architecture
222
+ resource :architectures
226
223
 
227
- class ListCommand < HammerCLI::Apipie::ReadCommand
224
+ class ListCommand < HammerCLI::Apipie::Command
228
225
  action :index
229
226
  # ...
230
227
  end
231
228
 
232
229
 
233
- class InfoCommand < HammerCLI::Apipie::ReadCommand
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 of which resource implements method `add_tag`. Please note that this example
249
- is fictitious. There's no tags in Foreman's architectures and users.
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 'add_tag'
253
+ command_name 'add-tag'
257
254
  end
258
255
  end
259
256
 
260
257
  class Architecture < HammerCLI::Apipie::Command
261
- resource ForemanApi::Resources::Architecture
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 add_tag -h
273
+ $ hammer architecture add-tag -h
277
274
  Usage:
278
- hammer architecture add_tag [OPTIONS]
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 add_tag -h
284
+ $ hammer user add-tag -h
288
285
  Usage:
289
- hammer user add_tag [OPTIONS]
286
+ hammer user add-tag [OPTIONS]
290
287
 
291
288
  Options:
292
289
  --id ID ID of the resource
@@ -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 practise to nest commands into modules
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
- # equivalent of :required => true in option declaration
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
- # Tt is possible to create more complicated constructs.
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 cli can be structured into a tree of parent commands (nodes) and subcommands (leaves).
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 cli is interaction with some api. In many cases it's listing
341
- some records returned by the api.
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 so called _output definition_ that you apply on your data. The result
345
- is a collection of fields each having its type. The collection is then passed to some
346
- _output adapter_ which handles the actuall formatting and printing.
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
- print_records( # <- printing utility of AbstractCommand
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 guarrantees that error messages are logged and
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's more ways where to place your config file for hammer.
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