hammer_cli 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/bin/hammer +6 -0
  4. data/config/cli_config.template.yml +3 -0
  5. data/doc/creating_commands.md +19 -0
  6. data/doc/i18n.md +15 -0
  7. data/doc/installation.md +1 -1
  8. data/doc/release_notes.md +61 -0
  9. data/lib/hammer_cli/abstract.rb +10 -37
  10. data/lib/hammer_cli/apipie/command.rb +10 -6
  11. data/lib/hammer_cli/apipie/option_builder.rb +26 -13
  12. data/lib/hammer_cli/apipie/options.rb +12 -10
  13. data/lib/hammer_cli/completer.rb +2 -2
  14. data/lib/hammer_cli/exception_handler.rb +5 -4
  15. data/lib/hammer_cli/exceptions.rb +1 -0
  16. data/lib/hammer_cli/i18n.rb +41 -0
  17. data/lib/hammer_cli/main.rb +2 -2
  18. data/lib/hammer_cli/options/normalizers.rb +31 -0
  19. data/lib/hammer_cli/output/adapter/abstract.rb +5 -1
  20. data/lib/hammer_cli/output/adapter/csv.rb +140 -12
  21. data/lib/hammer_cli/shell.rb +6 -6
  22. data/lib/hammer_cli/subcommand.rb +82 -0
  23. data/lib/hammer_cli/utils.rb +13 -0
  24. data/lib/hammer_cli/version.rb +1 -1
  25. data/locale/Makefile +11 -10
  26. data/locale/README.md +18 -0
  27. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/locale/en/hammer-cli.po +227 -0
  29. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  30. data/locale/en_GB/hammer-cli.po +274 -0
  31. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  32. data/locale/es/hammer-cli.po +275 -0
  33. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  34. data/locale/fr/hammer-cli.po +276 -0
  35. data/locale/hammer-cli.pot +158 -93
  36. data/test/reports/TEST-Fields-ContainerField-display-.xml +7 -0
  37. data/test/reports/TEST-Fields-ContainerField-display-blank-is-allowed.xml +15 -0
  38. data/test/reports/TEST-Fields-ContainerField-display-blank-is-not-allowed.xml +15 -0
  39. data/test/reports/TEST-Fields-ContainerField.xml +7 -0
  40. data/test/reports/TEST-Fields-Field-display-.xml +7 -0
  41. data/test/reports/TEST-Fields-Field-display-blank-is-allowed.xml +11 -0
  42. data/test/reports/TEST-Fields-Field-display-blank-is-not-allowed.xml +11 -0
  43. data/test/reports/TEST-Fields-Field-hide-blank-.xml +11 -0
  44. data/test/reports/TEST-Fields-Field-parameters.xml +9 -0
  45. data/test/reports/TEST-Fields-Field.xml +13 -0
  46. data/test/reports/TEST-HammerCLI-AbstractCommand-build-options.xml +15 -0
  47. data/test/reports/TEST-HammerCLI-AbstractCommand-exception-handler.xml +13 -0
  48. data/test/reports/TEST-HammerCLI-AbstractCommand-logging.xml +21 -0
  49. data/test/reports/TEST-HammerCLI-AbstractCommand-option-builder.xml +11 -0
  50. data/test/reports/TEST-HammerCLI-AbstractCommand-options.xml +11 -0
  51. data/test/reports/TEST-HammerCLI-AbstractCommand-output.xml +19 -0
  52. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-remove-subcommand.xml +11 -0
  53. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand-.xml +13 -0
  54. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand.xml +11 -0
  55. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior.xml +7 -0
  56. data/test/reports/TEST-HammerCLI-AbstractCommand.xml +11 -0
  57. data/test/reports/TEST-HammerCLI-Apipie-Command-options.xml +11 -0
  58. data/test/reports/TEST-HammerCLI-Apipie-Command-resource-defined.xml +9 -0
  59. data/test/reports/TEST-HammerCLI-Apipie-Command-setting-resources.xml +19 -0
  60. data/test/reports/TEST-HammerCLI-Apipie-Command.xml +9 -0
  61. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-aliasing-resources.xml +13 -0
  62. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-filtering-options.xml +15 -0
  63. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-required-options.xml +11 -0
  64. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-setting-correct-normalizers.xml +9 -0
  65. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-hash-params.xml +11 -0
  66. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-one-simple-param.xml +15 -0
  67. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder.xml +7 -0
  68. data/test/reports/TEST-HammerCLI-Completer-command-completion.xml +29 -0
  69. data/test/reports/TEST-HammerCLI-Completer-option-value-completion.xml +17 -0
  70. data/test/reports/TEST-HammerCLI-Completer-subcommand-completion.xml +19 -0
  71. data/test/reports/TEST-HammerCLI-Completer.xml +7 -0
  72. data/test/reports/TEST-HammerCLI-CompleterLine-line-complete.xml +25 -0
  73. data/test/reports/TEST-HammerCLI-CompleterLine-splitting-words.xml +29 -0
  74. data/test/reports/TEST-HammerCLI-CompleterLine.xml +7 -0
  75. data/test/reports/TEST-HammerCLI-CompleterWord-complete-.xml +23 -0
  76. data/test/reports/TEST-HammerCLI-CompleterWord-quote.xml +15 -0
  77. data/test/reports/TEST-HammerCLI-CompleterWord-quoted-.xml +13 -0
  78. data/test/reports/TEST-HammerCLI-CompleterWord.xml +7 -0
  79. data/test/reports/TEST-HammerCLI-Connection.xml +21 -0
  80. data/test/reports/TEST-HammerCLI-ExceptionHandler.xml +21 -0
  81. data/test/reports/TEST-HammerCLI-I18n.xml +11 -0
  82. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-password.xml +11 -0
  83. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-username.xml +11 -0
  84. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-verbose.xml +9 -0
  85. data/test/reports/TEST-HammerCLI-MainCommand-loading-context.xml +7 -0
  86. data/test/reports/TEST-HammerCLI-MainCommand.xml +7 -0
  87. data/test/reports/TEST-HammerCLI-Modules-find-by-name.xml +13 -0
  88. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-not-found.xml +13 -0
  89. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-runtime-exception.xml +13 -0
  90. data/test/reports/TEST-HammerCLI-Modules-load-a-module-success.xml +15 -0
  91. data/test/reports/TEST-HammerCLI-Modules-load-a-module.xml +7 -0
  92. data/test/reports/TEST-HammerCLI-Modules-load-all-modules.xml +9 -0
  93. data/test/reports/TEST-HammerCLI-Modules-names.xml +13 -0
  94. data/test/reports/TEST-HammerCLI-Modules.xml +7 -0
  95. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.0.xml +7 -0
  96. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.xml +11 -0
  97. data/test/reports/TEST-HammerCLI-Options-Normalizers-abstract.xml +9 -0
  98. data/test/reports/TEST-HammerCLI-Options-Normalizers-bool.xml +31 -0
  99. data/test/reports/TEST-HammerCLI-Options-Normalizers-datetime.xml +17 -0
  100. data/test/reports/TEST-HammerCLI-Options-Normalizers-enum.xml +15 -0
  101. data/test/reports/TEST-HammerCLI-Options-Normalizers-enumlist.xml +21 -0
  102. data/test/reports/TEST-HammerCLI-Options-Normalizers-json-input.xml +15 -0
  103. data/test/reports/TEST-HammerCLI-Options-Normalizers-key-value-list.xml +17 -0
  104. data/test/reports/TEST-HammerCLI-Options-Normalizers-list.xml +15 -0
  105. data/test/reports/TEST-HammerCLI-Options-Normalizers.xml +7 -0
  106. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-context.xml +9 -0
  107. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-formatters.xml +11 -0
  108. data/test/reports/TEST-HammerCLI-Options-OptionDefinition.xml +7 -0
  109. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-error-messages.xml +15 -0
  110. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-messages.xml +11 -0
  111. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-test-data-for-field.xml +15 -0
  112. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract.xml +17 -0
  113. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection-show-ids.xml +9 -0
  114. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection.xml +27 -0
  115. data/test/reports/TEST-HammerCLI-Output-Adapter-Base.xml +7 -0
  116. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-formatters.xml +11 -0
  117. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-collections.xml +13 -0
  118. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-containers.xml +11 -0
  119. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-ids.xml +11 -0
  120. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection.xml +11 -0
  121. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-message.xml +11 -0
  122. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues.xml +7 -0
  123. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-column-width.xml +15 -0
  124. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-formatters.xml +11 -0
  125. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-handle-ids.xml +11 -0
  126. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-sort-columns.xml +9 -0
  127. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection.xml +11 -0
  128. data/test/reports/TEST-HammerCLI-Output-Adapter-Table.xml +7 -0
  129. data/test/reports/TEST-HammerCLI-Output-Definition-empty-.xml +11 -0
  130. data/test/reports/TEST-HammerCLI-Output-Definition.xml +11 -0
  131. data/test/reports/TEST-HammerCLI-Output-Dsl-collection.xml +13 -0
  132. data/test/reports/TEST-HammerCLI-Output-Dsl-custom-fields.xml +11 -0
  133. data/test/reports/TEST-HammerCLI-Output-Dsl-fields.xml +15 -0
  134. data/test/reports/TEST-HammerCLI-Output-Dsl-label.xml +13 -0
  135. data/test/reports/TEST-HammerCLI-Output-Dsl-path-definition.xml +13 -0
  136. data/test/reports/TEST-HammerCLI-Output-Dsl.xml +9 -0
  137. data/test/reports/TEST-HammerCLI-Output-FieldFilter.xml +13 -0
  138. data/test/reports/TEST-HammerCLI-Output-Formatters-BooleanFormatter.xml +11 -0
  139. data/test/reports/TEST-HammerCLI-Output-Formatters-ColorFormatter.xml +9 -0
  140. data/test/reports/TEST-HammerCLI-Output-Formatters-DateFormatter.xml +11 -0
  141. data/test/reports/TEST-HammerCLI-Output-Formatters-FieldFormatter.xml +13 -0
  142. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterContainer.xml +13 -0
  143. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterLibrary.xml +11 -0
  144. data/test/reports/TEST-HammerCLI-Output-Formatters-KeyValueFormatter.xml +13 -0
  145. data/test/reports/TEST-HammerCLI-Output-Formatters-ListFormatter.xml +13 -0
  146. data/test/reports/TEST-HammerCLI-Output-Formatters-LongTextFormatter.xml +13 -0
  147. data/test/reports/TEST-HammerCLI-Output-Output-adapters.xml +17 -0
  148. data/test/reports/TEST-HammerCLI-Output-Output-data.xml +15 -0
  149. data/test/reports/TEST-HammerCLI-Output-Output-formatters.xml +9 -0
  150. data/test/reports/TEST-HammerCLI-Output-Output-messages.xml +19 -0
  151. data/test/reports/TEST-HammerCLI-Output-Output.xml +7 -0
  152. data/test/reports/TEST-HammerCLI-Output-RecordCollection.xml +13 -0
  153. data/test/reports/TEST-HammerCLI-Settings-load-from-paths.xml +15 -0
  154. data/test/reports/TEST-HammerCLI-Settings.xml +25 -0
  155. data/test/reports/TEST-HammerCLI-ShellHistory-loading-old-history.xml +11 -0
  156. data/test/reports/TEST-HammerCLI-ShellHistory-saving-history.xml +15 -0
  157. data/test/reports/TEST-HammerCLI-ShellHistory.xml +7 -0
  158. data/test/reports/TEST-MiniTest-Spec.xml +7 -0
  159. data/test/reports/TEST-String-camelize.xml +11 -0
  160. data/test/reports/TEST-String-formatting.xml +17 -0
  161. data/test/reports/TEST-String-indent.xml +11 -0
  162. data/test/reports/TEST-String-interactive-.xml +13 -0
  163. data/test/reports/TEST-String.xml +7 -0
  164. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint-exist-.xml +13 -0
  165. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint.xml +7 -0
  166. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint-exist-.xml +13 -0
  167. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint.xml +7 -0
  168. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-exist-.xml +9 -0
  169. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-rejected.xml +13 -0
  170. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-required.xml +13 -0
  171. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint.xml +7 -0
  172. data/test/reports/TEST-constraints.xml +7 -0
  173. data/test/unit/abstract_test.rb +15 -11
  174. data/test/unit/apipie/command_test.rb +29 -1
  175. data/test/unit/apipie/option_builder_test.rb +22 -0
  176. data/test/unit/fixtures/apipie/documented.json +44 -0
  177. data/test/unit/options/normalizers_test.rb +35 -0
  178. data/test/unit/output/adapter/csv_test.rb +104 -4
  179. data/test/unit/utils_test.rb +58 -0
  180. metadata +292 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 290f41e5f2227f4e71ffbaf977f02ba0cf8b1601
4
- data.tar.gz: 14502a8f77396925e426d8e1384f73e77fd6288a
3
+ metadata.gz: 9e93c3909bae5e1ce10cef180e409f5046ac7207
4
+ data.tar.gz: 23865ff20011788a464be2f5e61775311f787aa2
5
5
  SHA512:
6
- metadata.gz: 05159163a04fb707dbdfcd1292bd2d9b845742643b3d39fde9d422a060dab9cd4d8d8a3cd82b957427c01ca7629444eee63834d8afff2c649d917509acb12105
7
- data.tar.gz: 238d88468d9fc4e74c209d991a6b1cde091eb14f5cb0f31e7c5ad7e5932a8f2a5d9f6e67999eb982b2b40ac81e22ff38c85e495e42be42190f4ed5b25331ec02
6
+ metadata.gz: 5d3984b23d9f786da504884d19b1ce39b1043c36bb9c340b7ecdeebd11c3f2567213c7fbed67c661627374d5f76f9c2aeaef9451c9c6609c6c2bda51604a16a8
7
+ data.tar.gz: 907a881b80c1269b0cbcb87ee70dab37865a29ab14b2304f9d642413d42901eb88b96bdbf8e49372dae34b1548492e4a4ad155fd4527dc6b404fb9c0bf94c378
data/README.md CHANGED
@@ -12,10 +12,11 @@ Available plugins are currently:
12
12
 
13
13
  You also can easily add custom commands for your specific use, such as bulk actions or admin tasks.
14
14
 
15
+ Check out the [release notes](doc/release_notes.md#release-notes) to see what's new in the latest version.
15
16
 
16
17
  Installation
17
18
  ------------
18
- We build rpms, debs and gems. Alternatively you can install hammer form a git checkout.
19
+ We build rpms, debs and gems. Alternatively you can install hammer from a git checkout.
19
20
  See our [installation and configuration instuctions](doc/installation.md#installation).
20
21
 
21
22
 
@@ -25,7 +26,7 @@ If one of hammer commands doesn't work as you would expect, you can run `hammer
25
26
  full debug output from the loggers. It should give you an idea what went wrong.
26
27
 
27
28
  If you have questions, don't hesitate to contact us on `foreman-users@googlegroups.com` or
28
- `FreeNode#foreman` irc channel.
29
+ the `Freenode#theforeman` IRC channel.
29
30
 
30
31
 
31
32
  Further reading
data/bin/hammer CHANGED
@@ -16,6 +16,7 @@ class PreParser < Clamp::Command
16
16
  option ["-c", "--config"], "CFG_FILE", _("path to custom config file")
17
17
  option ["-u", "--username"], "USERNAME", _("username to access the remote system")
18
18
  option ["-p", "--password"], "PASSWORD", _("password to access the remote system")
19
+ option ["-s", "--server"], "SERVER", _("remote system address")
19
20
  option ["--interactive"], "INTERACTIVE", _("Explicitly turn interactive mode on/off") do |value|
20
21
  bool_normalizer = HammerCLI::Options::Normalizers::Bool.new
21
22
  bool_normalizer.format(value)
@@ -54,10 +55,15 @@ HammerCLI::Settings.load({
54
55
  :_params => {
55
56
  :username => preparser.username,
56
57
  :password => preparser.password,
58
+ :host => preparser.server,
57
59
  :interactive => preparser.interactive,
58
60
  :verbose => preparser.verbose? || preparser.debug?
59
61
  }})
60
62
 
63
+ if HammerCLI::Settings.get(:mark_translated)
64
+ include HammerCLI::I18n::Debug
65
+ end
66
+
61
67
  # setup logging
62
68
  require 'hammer_cli/logger'
63
69
  logger = Logging.logger['Init']
@@ -22,3 +22,6 @@
22
22
 
23
23
  # Maximum log size in bytes. Log rotates when the value gets exceeded
24
24
  #:log_size: 5 #in MB
25
+
26
+ # Mark translated strings with X characters (for developers)
27
+ #:mark_translated: false
@@ -319,6 +319,25 @@ If your plugin needs to disable an existing subcommand, you can use `remove_subc
319
319
  Call to this action is automatically logged.
320
320
 
321
321
 
322
+ ### Lazy-loaded subcommands
323
+ In some cases it's beneficial to load the command classes lazily at the time when they
324
+ are really needed. It can save some time in CLIs containing many commands with time-consuming
325
+ initialization.
326
+
327
+ Such commands have to be placed in a separate file (`hammer_cli_hello/say.rb` in our case).
328
+ Following construct registers the command as lazy-loaded. CLI then requires the file
329
+ when it needs the command class for the first time.
330
+
331
+ ```ruby
332
+ HammerCLI::MainCommand.lazy_subcommand(
333
+ 'say', # command's name
334
+ 'Say something', # description
335
+ 'HammerCLIHello::SayCommand', # command's class in a string
336
+ 'hammer_cli_hello/say' # require path of the file
337
+ )
338
+ ```
339
+
340
+
322
341
  ### Printing some output
323
342
  We've mentioned above that it's not recommended practice to print output
324
343
  directly with `puts` in Hammer. The reason is we separate definition
data/doc/i18n.md CHANGED
@@ -83,3 +83,18 @@ puts _("Hello %s, it is %s" % [name, day])
83
83
  # CORRECT
84
84
  puts _("Hello %{name}, it is %{day}") % {:name => name, :day => day}
85
85
  ```
86
+
87
+
88
+ 3) Don't use newlines in the gettext function. Strings with newlines are not extracted correctly.
89
+ ```ruby
90
+ # WRONG
91
+ puts _("TODO: \n - make dishes\n - do shopping")
92
+ # CORRECT
93
+ puts _("TODO:") +
94
+ "\n - " + _("make dishes") +
95
+ "\n - " + _("do shopping")
96
+ ```
97
+
98
+
99
+ 4) Try setting `:mark_translated: true` to identify gaps in your translations.
100
+ This will wrap all translated strings with angle brackets '>message<'.
data/doc/installation.md CHANGED
@@ -60,7 +60,7 @@ Plugins are disabled by default. To enable plugin create configuration file in `
60
60
  Plugin specific configuration must be nested under plugin's name (without the ```hammer_cli_``` prefix).
61
61
 
62
62
  In the example we assume the gem ```hammer_cli_foreman``` with the Foreman plugin is installed. Then the plugin configuration
63
- in ```~/.hammer/cli.plugins.d/foreman.yml``` should look as follows:
63
+ in ```~/.hammer/cli.modules.d/foreman.yml``` should look as follows:
64
64
 
65
65
  ```yaml
66
66
  :foreman:
@@ -0,0 +1,61 @@
1
+ Release notes
2
+ =============
3
+
4
+ ### 0.1.2
5
+ * Allow override of request options, e.g. :response => :raw
6
+ * Lazy loaded subcommands ([#6761](http://projects.theforeman.org/issues/6761))
7
+ * I18n - fixed error message + docs
8
+ * I18n - fix apipie warning string to be properly extracted
9
+ * I18n - add mark_translated to highlight extracted strings
10
+ * I18n - add en_GB locale
11
+ * I18n - extracting new, pulling from tx
12
+ * Project-Id-Version is fixed after tx pull
13
+ * Restrict ci_reporter gem to less than 2.0.0 to fix CI ([#6779](http://projects.theforeman.org/issues/6779))
14
+ * Fixed dependency on simplecov
15
+ * Parameters are not wrapped ([#6343](http://projects.theforeman.org/issues/6343))
16
+ * Rest-client > 1.7 does not support ruby 1.8 ([#6534](http://projects.theforeman.org/issues/6534))
17
+ * Exit cleanly when EOF/ctrl+d given in shell ([#6148](http://projects.theforeman.org/issues/6148))
18
+ * Fix incorrect --server help text ([#6219](http://projects.theforeman.org/issues/6219))
19
+ * Fixed wrong config file path in installation docs
20
+ * Empty list in csv adapter does not work ([#6238](http://projects.theforeman.org/issues/6238))
21
+ * Resource name mapping ([#6092](http://projects.theforeman.org/issues/6092))
22
+ * Tests for EnumList normalizer, fixed missing quotes in description
23
+ * ListEnum normalizer
24
+ * Add --server cli option ([#6219](http://projects.theforeman.org/issues/6219))
25
+ * CSV handles collection or container ([#5111](http://projects.theforeman.org/issues/5111))
26
+ * build_options configurable with block ([#5747](http://projects.theforeman.org/issues/5747))
27
+ * Add pkg:generate_source task to generate gem ([#5793](http://projects.theforeman.org/issues/5793))
28
+
29
+
30
+ ### 0.1.1
31
+ * Removed `log_api_calls` setting
32
+ * Updated documentation
33
+ * String#format fixed to behave consistently with %
34
+ * Fix for ignoring cases where output record is null ([#5605](http://projects.theforeman.org/issues/5605))
35
+ * Messages for clamp translated ([#4475](http://projects.theforeman.org/issues/4475))
36
+ * Read and write commands merged ([#4311](http://projects.theforeman.org/issues/4311))
37
+ * Introduced option builders ([#4311](http://projects.theforeman.org/issues/4311))
38
+ * Add support for boolean fields ([#5025](http://projects.theforeman.org/issues/5025))
39
+ * Skip missing translation domains ([#4916](http://projects.theforeman.org/issues/4916))
40
+
41
+
42
+ ### 0.1.0
43
+ * Updated documentation
44
+ * Fixes command description issues ([#4791](http://projects.theforeman.org/issues/4791), [#4556](http://projects.theforeman.org/issues/4556))
45
+ * Added option for debugging output ([#4861](http://projects.theforeman.org/issues/4861))
46
+ * Runs with log level 'debug' in verbose ([#4835](http://projects.theforeman.org/issues/4835))
47
+ * Loads configuration form /etc/hammer ([#4792](http://projects.theforeman.org/issues/4792))
48
+ * Numbered collections in output ([#4676](http://projects.theforeman.org/issues/4676))
49
+ * Dynamic API bindings ([#3897](http://projects.theforeman.org/issues/3897))
50
+ * Fixes subnet info in csv mode errors out ([#4531](http://projects.theforeman.org/issues/4531))
51
+ * i18n support ([#4472](http://projects.theforeman.org/issues/4472))
52
+ * shell - temporarily disable command completion on ruby 1.8
53
+ * Enable setting width to columns in table output adapter ([#4384](http://projects.theforeman.org/issues/4384))
54
+ * Enable skipping blank values in base output adapter ([#4231](http://projects.theforeman.org/issues/4231))
55
+ * Adds support for output fields containing multiline text
56
+ * Fixes --interactive=false still prompts ([#4378](http://projects.theforeman.org/issues/4378))
57
+ * Fixes completion of quoted values ([#4182](http://projects.theforeman.org/issues/4182))
58
+ * Main commands are now sorted in the help output ([#4112](http://projects.theforeman.org/issues/4112))
59
+ * Persistent history in shell ([#3883](http://projects.theforeman.org/issues/3883))
60
+ * Stores option -v into context ([#3633](http://projects.theforeman.org/issues/3633))
61
+ * Adds JSONInput formalizer ([#4246](http://projects.theforeman.org/issues/4246))
@@ -2,13 +2,13 @@ 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/clamp'
5
+ require 'hammer_cli/subcommand'
5
6
  require 'logging'
6
7
 
7
8
  module HammerCLI
8
9
 
9
- class CommandConflict < StandardError; end
10
-
11
10
  class AbstractCommand < Clamp::Command
11
+ include HammerCLI::Subcommand
12
12
 
13
13
  class << self
14
14
  attr_accessor :validation_block
@@ -62,31 +62,6 @@ module HammerCLI
62
62
  context[:path][-2]
63
63
  end
64
64
 
65
- def self.remove_subcommand(name)
66
- self.recognised_subcommands.delete_if do |sc|
67
- if sc.is_called?(name)
68
- logger.info "subcommand #{name} (#{sc.subcommand_class}) was removed."
69
- true
70
- else
71
- false
72
- end
73
- end
74
- end
75
-
76
- def self.subcommand!(name, description, subcommand_class = self, &block)
77
- remove_subcommand(name)
78
- self.subcommand(name, description, subcommand_class, &block)
79
- logger.info "subcommand #{name} (#{subcommand_class}) was created."
80
- end
81
-
82
- def self.subcommand(name, description, subcommand_class = self, &block)
83
- existing = find_subcommand(name)
84
- if existing
85
- raise HammerCLI::CommandConflict, "can't replace subcommand #{name} (#{existing.subcommand_class}) with #{name} (#{subcommand_class})"
86
- end
87
- super
88
- end
89
-
90
65
  class SortedBuilder < Clamp::Help::Builder
91
66
  def add_list(heading, items)
92
67
  items.sort! do |a, b|
@@ -135,16 +110,13 @@ module HammerCLI
135
110
  end
136
111
 
137
112
  def self.option_builder
138
- @option_builder ||= OptionBuilderContainer.new
139
- @option_builder.builders = custom_option_builders
113
+ @option_builder ||= create_option_builder
140
114
  @option_builder
141
115
  end
142
116
 
143
- def self.custom_option_builders
144
- []
145
- end
146
-
147
117
  def self.build_options(builder_params={})
118
+ builder_params = yield(builder_params) if block_given?
119
+
148
120
  option_builder.build(builder_params).each do |option|
149
121
  # skip switches that are already defined
150
122
  next if option.nil? or option.switches.any? {|s| find_option(s) }
@@ -157,6 +129,10 @@ module HammerCLI
157
129
 
158
130
  protected
159
131
 
132
+ def self.create_option_builder
133
+ OptionBuilderContainer.new
134
+ end
135
+
160
136
  def print_record(definition, record)
161
137
  output.print_record(definition, record)
162
138
  end
@@ -190,10 +166,7 @@ module HammerCLI
190
166
 
191
167
  def exception_handler_class
192
168
  #search for exception handler class in parent modules/classes
193
- module_list = self.class.name.to_s.split('::').inject([Object]) do |mod, class_name|
194
- mod << mod[-1].const_get(class_name)
195
- end
196
- module_list.reverse.each do |mod|
169
+ HammerCLI.constant_path(self.class.name.to_s).reverse.each do |mod|
197
170
  return mod.send(:exception_handler_class) if mod.respond_to? :exception_handler_class
198
171
  end
199
172
  return HammerCLI::ExceptionHandler
@@ -17,12 +17,12 @@ module HammerCLI::Apipie
17
17
  " "
18
18
  end
19
19
 
20
- def self.custom_option_builders
21
- builders = super
22
- builders += [
20
+ def self.create_option_builder
21
+ builder = super
22
+ builder.builders += [
23
23
  OptionBuilder.new(resource.action(action), :require_options => false)
24
24
  ] if resource_defined?
25
- builders
25
+ builder
26
26
  end
27
27
 
28
28
  def self.apipie_options(*args)
@@ -39,7 +39,7 @@ module HammerCLI::Apipie
39
39
 
40
40
  def send_request
41
41
  if resource && resource.has_action?(action)
42
- resource.call(action, request_params, request_headers)
42
+ resource.call(action, request_params, request_headers, request_options)
43
43
  else
44
44
  raise HammerCLI::OperationNotSupportedError, "The server does not support such operation."
45
45
  end
@@ -49,8 +49,12 @@ module HammerCLI::Apipie
49
49
  {}
50
50
  end
51
51
 
52
+ def request_options
53
+ {}
54
+ end
55
+
52
56
  def request_params
53
- method_options
57
+ method_options(options)
54
58
  end
55
59
 
56
60
  def print_data(data)
@@ -1,7 +1,7 @@
1
1
 
2
2
  module HammerCLI::Apipie
3
3
 
4
- class OptionBuilder
4
+ class OptionBuilder < HammerCLI::AbstractOptionBuilder
5
5
 
6
6
  def initialize(action, options={})
7
7
  @action = action
@@ -10,8 +10,9 @@ module HammerCLI::Apipie
10
10
 
11
11
  def build(builder_params={})
12
12
  filter = Array(builder_params[:without])
13
+ resource_name_map = builder_params[:resource_mapping] || {}
13
14
 
14
- options_for_params(@action.params, filter)
15
+ options_for_params(@action.params, filter, resource_name_map)
15
16
  end
16
17
 
17
18
  attr_writer :require_options
@@ -21,34 +22,34 @@ module HammerCLI::Apipie
21
22
 
22
23
  protected
23
24
 
24
- def options_for_params(params, filter)
25
+ def options_for_params(params, filter, resource_name_map)
25
26
  opts = []
26
27
  params.each do |p|
27
28
  next if filter.include?(p.name) || filter.include?(p.name.to_sym)
28
29
  if p.expected_type == :hash
29
- opts += options_for_params(p.params, filter)
30
+ opts += options_for_params(p.params, filter, resource_name_map)
30
31
  else
31
- opts << create_option(p)
32
+ opts << create_option(p, resource_name_map)
32
33
  end
33
34
  end
34
35
  opts
35
36
  end
36
37
 
37
- def create_option(param)
38
- HammerCLI::Options::OptionDefinition.new(
39
- option_switch(param),
40
- option_type(param),
38
+ def create_option(param, resource_name_map)
39
+ option(
40
+ option_switch(param, resource_name_map),
41
+ option_type(param, resource_name_map),
41
42
  option_desc(param),
42
43
  option_opts(param)
43
44
  )
44
45
  end
45
46
 
46
- def option_switch(param)
47
- '--' + param.name.gsub('_', '-')
47
+ def option_switch(param, resource_name_map)
48
+ '--' + optionamize(aliased(param.name, resource_name_map))
48
49
  end
49
50
 
50
- def option_type(param)
51
- param.name.upcase.gsub('-', '_')
51
+ def option_type(param, resource_name_map)
52
+ aliased(param.name, resource_name_map).upcase.gsub('-', '_')
52
53
  end
53
54
 
54
55
  def option_desc(param)
@@ -61,9 +62,21 @@ module HammerCLI::Apipie
61
62
  # FIXME: There is a bug in apipie, it does not produce correct expected type for Arrays
62
63
  # When it's fixed, we should test param["expected_type"] == "array"
63
64
  opts[:format] = HammerCLI::Options::Normalizers::List.new if param.validator.include? "Array"
65
+ opts[:attribute_name] = HammerCLI.option_accessor_name(param.name)
64
66
  return opts
65
67
  end
66
68
 
69
+ def aliased(name, resource_name_map)
70
+ resource_name = name.gsub(/_id[s]?$/, "")
71
+ resource_name = resource_name_map[resource_name.to_s] || resource_name_map[resource_name.to_sym] || resource_name
72
+ if name.end_with?("_id")
73
+ return "#{resource_name}_id"
74
+ elsif name.end_with?("_ids")
75
+ return "#{resource_name}_ids"
76
+ else
77
+ return name
78
+ end
79
+ end
67
80
 
68
81
  end
69
82
  end
@@ -2,25 +2,27 @@
2
2
  module HammerCLI::Apipie
3
3
  module Options
4
4
 
5
- def all_method_options
6
- method_options_for_params(resource.action(action).params, true)
5
+ def method_options(options)
6
+ method_options_for_params(resource.action(action).params, options)
7
7
  end
8
8
 
9
- def method_options
10
- method_options_for_params(resource.action(action).params, false)
11
- end
12
-
13
- def method_options_for_params(params, include_nil=true)
9
+ def method_options_for_params(params, options)
14
10
  opts = {}
11
+
15
12
  params.each do |p|
16
13
  if p.expected_type == :hash
17
- opts[p.name] = method_options_for_params(p.params, include_nil)
14
+ opts[p.name] = method_options_for_params(p.params, options)
18
15
  else
19
- opts[p.name] = get_option_value(p.name)
16
+ p_name = HammerCLI.option_accessor_name(p.name)
17
+ if options.has_key?(p_name)
18
+ opts[p.name] = options[p_name]
19
+ elsif respond_to?(p_name, true)
20
+ opt = send(p_name)
21
+ opts[p.name] = opt unless opt.nil?
22
+ end
20
23
  end
21
24
  end
22
25
 
23
- opts.reject! {|key, value| value.nil? } unless include_nil
24
26
  opts
25
27
  end
26
28
 
@@ -189,7 +189,7 @@ module HammerCLI
189
189
  unless word.start_with?('-')
190
190
  break unless subcommands.has_key? word
191
191
 
192
- cmd = subcommands[word]
192
+ cmd = subcommands[word].subcommand_class
193
193
  cmd_idx = idx+1
194
194
  subcommands = sub_command_map(cmd)
195
195
  end
@@ -229,7 +229,7 @@ module HammerCLI
229
229
  def sub_command_map(cmd_class)
230
230
  cmd_class.recognised_subcommands.inject({}) do |cmd_map, cmd|
231
231
  cmd.names.each do |name|
232
- cmd_map.update(name => cmd.subcommand_class)
232
+ cmd_map.update(name => cmd)
233
233
  end
234
234
  cmd_map
235
235
  end
@@ -63,7 +63,8 @@ module HammerCLI
63
63
  end
64
64
 
65
65
  def handle_usage_exception(e)
66
- print_error _("Error: %{message}\n\nSee: '%{path} --help'") % {:message => e.message, :path => e.command.invocation_path}
66
+ print_error (_("Error: %{message}") + "\n\n" +
67
+ _("See: '%{path} --help'")) % {:message => e.message, :path => e.command.invocation_path}
67
68
  log_full_error e
68
69
  HammerCLI::EX_USAGE
69
70
  end
@@ -87,9 +88,9 @@ module HammerCLI
87
88
 
88
89
  def handle_apipie_docloading_error(e)
89
90
  rake_command = "rake apipie:cache"
90
- print_error _("Could not load API description from the server\n"\
91
- " - is your server down?\n"\
92
- " - was \"#{rake_command}\" run on the server when using apipie cache? (typical production settings))\n")
91
+ print_error _("Could not load the API description from the server") + "\n - " +
92
+ _("is the server down?") + "\n - " +
93
+ _("was '%s' run on the server when using apipie cache? (typical production settings)") % rake_command
93
94
  log_full_error e
94
95
  HammerCLI::EX_CONFIG
95
96
  end
@@ -1,5 +1,6 @@
1
1
  module HammerCLI
2
2
 
3
+ class CommandConflict < StandardError; end
3
4
  class OperationNotSupportedError < StandardError; end
4
5
  class ModuleLoadingError < StandardError; end
5
6
 
@@ -22,6 +22,47 @@ module HammerCLI
22
22
  end
23
23
  end
24
24
 
25
+ # include this module to see translations highlighted
26
+ module Debug
27
+ DL = '>'
28
+ DR = '<'
29
+
30
+ # slightly modified copy of fast_gettext D_* method
31
+ def _(key)
32
+ FastGettext.translation_repositories.each_key do |domain|
33
+ result = FastGettext::TranslationMultidomain.d_(domain, key) {nil}
34
+ return DL + result + DR unless result.nil?
35
+ end
36
+ DL + key + DR
37
+ end
38
+
39
+ # slightly modified copy of fast_gettext D_* method
40
+ def n_(*keys)
41
+ FastGettext.translation_repositories.each_key do |domain|
42
+ result = FastGettext::TranslationMultidomain.dn_(domain, *keys) {nil}
43
+ return DL + result + DR unless result.nil?
44
+ end
45
+ DL + keys[-3].split(keys[-2]||FastGettext::NAMESPACE_SEPARATOR).last + DR
46
+ end
47
+
48
+ # slightly modified copy of fast_gettext D_* method
49
+ def s_(key, separator=nil)
50
+ FastGettext.translation_repositories.each_key do |domain|
51
+ result = FastGettext::TranslationMultidomain.ds_(domain, key, separator) {nil}
52
+ return DL + result + DR unless result.nil?
53
+ end
54
+ DL + key.split(separator||FastGettext::NAMESPACE_SEPARATOR).last + DR
55
+ end
56
+
57
+ # slightly modified copy of fast_gettext D_* method
58
+ def ns_(*keys)
59
+ FastGettext.translation_repositories.each_key do |domain|
60
+ result = FastGettext::TranslationMultidomain.dns_(domain, *keys) {nil}
61
+ return DL + result + DR unless result.nil?
62
+ end
63
+ DL + keys[-2].split(FastGettext::NAMESPACE_SEPARATOR).last + DR
64
+ end
65
+ end
25
66
 
26
67
  class AbstractLocaleDomain
27
68
 
@@ -12,6 +12,8 @@ module HammerCLI
12
12
  :context_target => :username
13
13
  option ["-p", "--password"], "PASSWORD", _("password to access the remote system"),
14
14
  :context_target => :password
15
+ option ["-s", "--server"], "SERVER", _("remote system address"),
16
+ :context_target => :uri
15
17
 
16
18
  option "--version", :flag, _("show version") do
17
19
  puts "hammer (%s)" % HammerCLI.version
@@ -53,6 +55,4 @@ module HammerCLI
53
55
 
54
56
  end
55
57
 
56
- # extend MainCommand
57
- require 'hammer_cli/shell'
58
58
 
@@ -154,7 +154,38 @@ module HammerCLI
154
154
  end
155
155
  end
156
156
 
157
+ class EnumList < AbstractNormalizer
157
158
 
159
+ def initialize(allowed_values)
160
+ @allowed_values = allowed_values
161
+ end
162
+
163
+ def description
164
+ _("Any combination (comma separated list) of '%s'") % quoted_values
165
+ end
166
+
167
+ def format(value)
168
+ value.is_a?(String) ? parse(value) : []
169
+ end
170
+
171
+ def complete(value)
172
+ Completer::finalize_completions(@allowed_values)
173
+ end
174
+
175
+ private
176
+
177
+ def quoted_values
178
+ @allowed_values.map { |v| "'#{v}'" }.join(', ')
179
+ end
180
+
181
+ def parse(arr)
182
+ arr.split(",").uniq.tap do |values|
183
+ unless values.inject(true) { |acc, cur| acc & (@allowed_values.include? cur) }
184
+ raise ArgumentError, _("value must be a combination of '%s'") % quoted_values
185
+ end
186
+ end
187
+ end
188
+ end
158
189
  end
159
190
  end
160
191
  end
@@ -41,7 +41,7 @@ module HammerCLI::Output::Adapter
41
41
  HammerCLI::Output::FieldFilter.new
42
42
  end
43
43
 
44
- def data_for_field(field, record)
44
+ def self.data_for_field(field, record)
45
45
  path = field.path
46
46
 
47
47
  path.inject(record) do |record, path_key|
@@ -55,6 +55,10 @@ module HammerCLI::Output::Adapter
55
55
  end
56
56
  end
57
57
 
58
+ def data_for_field(field, record)
59
+ Abstract.data_for_field(field, record)
60
+ end
61
+
58
62
  private
59
63
 
60
64
  def filter_formatters(formatters_map)