hammer_cli 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +4 -9
  3. data/config/cli_config.template.yml +12 -6
  4. data/doc/creating_commands.md +38 -0
  5. data/doc/i18n.md +33 -2
  6. data/doc/option_normalizers.md +2 -0
  7. data/doc/release_notes.md +18 -0
  8. data/lib/hammer_cli/abstract.rb +7 -2
  9. data/lib/hammer_cli/apipie/option_builder.rb +1 -1
  10. data/lib/hammer_cli/ca_cert_fetcher.rb +8 -8
  11. data/lib/hammer_cli/clamp.rb +9 -9
  12. data/lib/hammer_cli/context.rb +2 -1
  13. data/lib/hammer_cli/defaults.rb +12 -14
  14. data/lib/hammer_cli/defaults_commands.rb +2 -2
  15. data/lib/hammer_cli/exception_handler.rb +1 -1
  16. data/lib/hammer_cli/help/builder.rb +2 -1
  17. data/lib/hammer_cli/i18n/find_task.rb +41 -0
  18. data/lib/hammer_cli/i18n.rb +4 -0
  19. data/lib/hammer_cli/logger.rb +1 -1
  20. data/lib/hammer_cli/main.rb +12 -11
  21. data/lib/hammer_cli/modules.rb +5 -8
  22. data/lib/hammer_cli/options/normalizers.rb +15 -11
  23. data/lib/hammer_cli/options/option_collector.rb +17 -3
  24. data/lib/hammer_cli/options/option_definition.rb +36 -21
  25. data/lib/hammer_cli/output/adapter/csv.rb +1 -1
  26. data/lib/hammer_cli/output/adapter/table.rb +8 -6
  27. data/lib/hammer_cli/settings.rb +1 -6
  28. data/lib/hammer_cli/shell.rb +2 -2
  29. data/lib/hammer_cli/ssloptions.rb +5 -5
  30. data/lib/hammer_cli/subcommand.rb +51 -26
  31. data/lib/hammer_cli/testing/command_assertions.rb +2 -2
  32. data/lib/hammer_cli/testing/messages.rb +54 -0
  33. data/lib/hammer_cli/validator.rb +9 -9
  34. data/lib/hammer_cli/version.rb +1 -1
  35. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  36. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  37. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  38. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  39. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  40. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  41. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  42. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  43. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  44. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  45. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  46. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  47. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  48. data/man/hammer.1.gz +0 -0
  49. data/test/functional/defaults_test.rb +3 -12
  50. data/test/functional/help_test.rb +1 -1
  51. data/test/functional/nil_values_test.rb +75 -0
  52. data/test/functional/test_helper.rb +10 -0
  53. data/test/reports/TEST-Fields-ContainerField-display-.xml +7 -0
  54. data/test/reports/TEST-Fields-ContainerField-display-blank-is-allowed.xml +15 -0
  55. data/test/reports/TEST-Fields-ContainerField-display-blank-is-not-allowed.xml +15 -0
  56. data/test/reports/TEST-Fields-ContainerField.xml +7 -0
  57. data/test/reports/TEST-Fields-Field-display-.xml +7 -0
  58. data/test/reports/TEST-Fields-Field-display-blank-is-allowed.xml +11 -0
  59. data/test/reports/TEST-Fields-Field-display-blank-is-not-allowed.xml +11 -0
  60. data/test/reports/TEST-Fields-Field-hide-blank-.xml +11 -0
  61. data/test/reports/TEST-Fields-Field-parameters.xml +9 -0
  62. data/test/reports/TEST-Fields-Field.xml +13 -0
  63. data/test/reports/TEST-HammerCLI-AbstractCommand-build-options.xml +15 -0
  64. data/test/reports/TEST-HammerCLI-AbstractCommand-exception-handler.xml +13 -0
  65. data/test/reports/TEST-HammerCLI-AbstractCommand-logging.xml +21 -0
  66. data/test/reports/TEST-HammerCLI-AbstractCommand-option-builder.xml +11 -0
  67. data/test/reports/TEST-HammerCLI-AbstractCommand-options.xml +11 -0
  68. data/test/reports/TEST-HammerCLI-AbstractCommand-output.xml +19 -0
  69. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-remove-subcommand.xml +11 -0
  70. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand-.xml +13 -0
  71. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand.xml +11 -0
  72. data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior.xml +7 -0
  73. data/test/reports/TEST-HammerCLI-AbstractCommand.xml +11 -0
  74. data/test/reports/TEST-HammerCLI-Apipie-Command-options.xml +11 -0
  75. data/test/reports/TEST-HammerCLI-Apipie-Command-resource-defined.xml +9 -0
  76. data/test/reports/TEST-HammerCLI-Apipie-Command-setting-resources.xml +19 -0
  77. data/test/reports/TEST-HammerCLI-Apipie-Command.xml +9 -0
  78. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-aliasing-resources.xml +13 -0
  79. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-filtering-options.xml +15 -0
  80. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-required-options.xml +11 -0
  81. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-setting-correct-normalizers.xml +9 -0
  82. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-hash-params.xml +11 -0
  83. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-one-simple-param.xml +15 -0
  84. data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder.xml +7 -0
  85. data/test/reports/TEST-HammerCLI-Completer-command-completion.xml +29 -0
  86. data/test/reports/TEST-HammerCLI-Completer-option-value-completion.xml +17 -0
  87. data/test/reports/TEST-HammerCLI-Completer-subcommand-completion.xml +19 -0
  88. data/test/reports/TEST-HammerCLI-Completer.xml +7 -0
  89. data/test/reports/TEST-HammerCLI-CompleterLine-line-complete.xml +25 -0
  90. data/test/reports/TEST-HammerCLI-CompleterLine-splitting-words.xml +29 -0
  91. data/test/reports/TEST-HammerCLI-CompleterLine.xml +7 -0
  92. data/test/reports/TEST-HammerCLI-CompleterWord-complete-.xml +23 -0
  93. data/test/reports/TEST-HammerCLI-CompleterWord-quote.xml +15 -0
  94. data/test/reports/TEST-HammerCLI-CompleterWord-quoted-.xml +13 -0
  95. data/test/reports/TEST-HammerCLI-CompleterWord.xml +7 -0
  96. data/test/reports/TEST-HammerCLI-Connection.xml +21 -0
  97. data/test/reports/TEST-HammerCLI-ExceptionHandler.xml +21 -0
  98. data/test/reports/TEST-HammerCLI-I18n.xml +11 -0
  99. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-password.xml +11 -0
  100. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-username.xml +11 -0
  101. data/test/reports/TEST-HammerCLI-MainCommand-loading-context-verbose.xml +9 -0
  102. data/test/reports/TEST-HammerCLI-MainCommand-loading-context.xml +7 -0
  103. data/test/reports/TEST-HammerCLI-MainCommand.xml +7 -0
  104. data/test/reports/TEST-HammerCLI-Modules-find-by-name.xml +13 -0
  105. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-not-found.xml +13 -0
  106. data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-runtime-exception.xml +13 -0
  107. data/test/reports/TEST-HammerCLI-Modules-load-a-module-success.xml +15 -0
  108. data/test/reports/TEST-HammerCLI-Modules-load-a-module.xml +7 -0
  109. data/test/reports/TEST-HammerCLI-Modules-load-all-modules.xml +9 -0
  110. data/test/reports/TEST-HammerCLI-Modules-names.xml +13 -0
  111. data/test/reports/TEST-HammerCLI-Modules.xml +7 -0
  112. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.0.xml +7 -0
  113. data/test/reports/TEST-HammerCLI-OptionBuilderContainer.xml +11 -0
  114. data/test/reports/TEST-HammerCLI-Options-Normalizers-abstract.xml +9 -0
  115. data/test/reports/TEST-HammerCLI-Options-Normalizers-bool.xml +31 -0
  116. data/test/reports/TEST-HammerCLI-Options-Normalizers-datetime.xml +17 -0
  117. data/test/reports/TEST-HammerCLI-Options-Normalizers-enum.xml +15 -0
  118. data/test/reports/TEST-HammerCLI-Options-Normalizers-enumlist.xml +21 -0
  119. data/test/reports/TEST-HammerCLI-Options-Normalizers-json-input.xml +15 -0
  120. data/test/reports/TEST-HammerCLI-Options-Normalizers-key-value-list.xml +17 -0
  121. data/test/reports/TEST-HammerCLI-Options-Normalizers-list.xml +15 -0
  122. data/test/reports/TEST-HammerCLI-Options-Normalizers.xml +7 -0
  123. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-context.xml +9 -0
  124. data/test/reports/TEST-HammerCLI-Options-OptionDefinition-formatters.xml +11 -0
  125. data/test/reports/TEST-HammerCLI-Options-OptionDefinition.xml +7 -0
  126. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-error-messages.xml +15 -0
  127. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-messages.xml +11 -0
  128. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-test-data-for-field.xml +15 -0
  129. data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract.xml +17 -0
  130. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection-show-ids.xml +9 -0
  131. data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection.xml +27 -0
  132. data/test/reports/TEST-HammerCLI-Output-Adapter-Base.xml +7 -0
  133. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-formatters.xml +11 -0
  134. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-collections.xml +13 -0
  135. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-containers.xml +11 -0
  136. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-ids.xml +11 -0
  137. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection.xml +11 -0
  138. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-message.xml +11 -0
  139. data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues.xml +7 -0
  140. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-column-width.xml +15 -0
  141. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-formatters.xml +11 -0
  142. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-handle-ids.xml +11 -0
  143. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-sort-columns.xml +9 -0
  144. data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection.xml +11 -0
  145. data/test/reports/TEST-HammerCLI-Output-Adapter-Table.xml +7 -0
  146. data/test/reports/TEST-HammerCLI-Output-Definition-empty-.xml +11 -0
  147. data/test/reports/TEST-HammerCLI-Output-Definition.xml +11 -0
  148. data/test/reports/TEST-HammerCLI-Output-Dsl-collection.xml +13 -0
  149. data/test/reports/TEST-HammerCLI-Output-Dsl-custom-fields.xml +11 -0
  150. data/test/reports/TEST-HammerCLI-Output-Dsl-fields.xml +15 -0
  151. data/test/reports/TEST-HammerCLI-Output-Dsl-label.xml +13 -0
  152. data/test/reports/TEST-HammerCLI-Output-Dsl-path-definition.xml +13 -0
  153. data/test/reports/TEST-HammerCLI-Output-Dsl.xml +9 -0
  154. data/test/reports/TEST-HammerCLI-Output-FieldFilter.xml +13 -0
  155. data/test/reports/TEST-HammerCLI-Output-Formatters-BooleanFormatter.xml +11 -0
  156. data/test/reports/TEST-HammerCLI-Output-Formatters-ColorFormatter.xml +9 -0
  157. data/test/reports/TEST-HammerCLI-Output-Formatters-DateFormatter.xml +11 -0
  158. data/test/reports/TEST-HammerCLI-Output-Formatters-FieldFormatter.xml +13 -0
  159. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterContainer.xml +13 -0
  160. data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterLibrary.xml +11 -0
  161. data/test/reports/TEST-HammerCLI-Output-Formatters-KeyValueFormatter.xml +13 -0
  162. data/test/reports/TEST-HammerCLI-Output-Formatters-ListFormatter.xml +13 -0
  163. data/test/reports/TEST-HammerCLI-Output-Formatters-LongTextFormatter.xml +13 -0
  164. data/test/reports/TEST-HammerCLI-Output-Output-adapters.xml +17 -0
  165. data/test/reports/TEST-HammerCLI-Output-Output-data.xml +15 -0
  166. data/test/reports/TEST-HammerCLI-Output-Output-formatters.xml +9 -0
  167. data/test/reports/TEST-HammerCLI-Output-Output-messages.xml +19 -0
  168. data/test/reports/TEST-HammerCLI-Output-Output.xml +7 -0
  169. data/test/reports/TEST-HammerCLI-Output-RecordCollection.xml +13 -0
  170. data/test/reports/TEST-HammerCLI-Settings-load-from-paths.xml +15 -0
  171. data/test/reports/TEST-HammerCLI-Settings.xml +25 -0
  172. data/test/reports/TEST-HammerCLI-ShellHistory-loading-old-history.xml +11 -0
  173. data/test/reports/TEST-HammerCLI-ShellHistory-saving-history.xml +15 -0
  174. data/test/reports/TEST-HammerCLI-ShellHistory.xml +7 -0
  175. data/test/reports/TEST-MiniTest-Spec.xml +7 -0
  176. data/test/reports/TEST-String-camelize.xml +11 -0
  177. data/test/reports/TEST-String-formatting.xml +17 -0
  178. data/test/reports/TEST-String-indent.xml +11 -0
  179. data/test/reports/TEST-String-interactive-.xml +13 -0
  180. data/test/reports/TEST-String.xml +7 -0
  181. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint-exist-.xml +13 -0
  182. data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint.xml +7 -0
  183. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint-exist-.xml +13 -0
  184. data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint.xml +7 -0
  185. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-exist-.xml +9 -0
  186. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-rejected.xml +13 -0
  187. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-required.xml +13 -0
  188. data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint.xml +7 -0
  189. data/test/reports/TEST-constraints.xml +7 -0
  190. data/test/unit/abstract_test.rb +10 -1
  191. data/test/unit/apipie/option_builder_test.rb +6 -0
  192. data/test/unit/defaults_test.rb +12 -5
  193. data/test/unit/exception_handler_test.rb +1 -1
  194. data/test/unit/fixtures/apipie/documented.json +10 -1
  195. data/test/unit/help/builder_test.rb +16 -1
  196. data/test/unit/messages_test.rb +7 -0
  197. data/test/unit/modules_test.rb +4 -15
  198. data/test/unit/options/normalizers_test.rb +21 -1
  199. data/test/unit/options/option_collector_test.rb +10 -4
  200. data/test/unit/output/adapter/csv_test.rb +29 -0
  201. data/test/unit/output/adapter/table_test.rb +27 -0
  202. data/test/unit/validator_test.rb +4 -4
  203. metadata +353 -53
@@ -5,7 +5,6 @@ module HammerCLI
5
5
  module Options
6
6
  module Normalizers
7
7
 
8
-
9
8
  class AbstractNormalizer
10
9
  def description
11
10
  ""
@@ -20,6 +19,11 @@ module HammerCLI
20
19
  end
21
20
  end
22
21
 
22
+ class Default < AbstractNormalizer
23
+ def format(value)
24
+ value
25
+ end
26
+ end
23
27
 
24
28
  class KeyValueList < AbstractNormalizer
25
29
 
@@ -27,7 +31,7 @@ module HammerCLI
27
31
  FULL_RE = "^((%s)[,]?)+$" % PAIR_RE
28
32
 
29
33
  def description
30
- _("Comma-separated list of key=value.")
34
+ _("Comma-separated list of key=value")
31
35
  end
32
36
 
33
37
  def format(val)
@@ -41,7 +45,7 @@ module HammerCLI
41
45
  formatter = JSONInput.new
42
46
  formatter.format(val)
43
47
  rescue ArgumentError
44
- raise ArgumentError, _("value must be defined as a comma-separated list of key=value or valid JSON")
48
+ raise ArgumentError, _("Value must be defined as a comma-separated list of key=value or valid JSON.")
45
49
  end
46
50
  end
47
51
  end
@@ -97,7 +101,7 @@ module HammerCLI
97
101
  if numeric?(val)
98
102
  val.to_i
99
103
  else
100
- raise ArgumentError, _("numeric value is required")
104
+ raise ArgumentError, _("Numeric value is required.")
101
105
  end
102
106
  end
103
107
 
@@ -111,7 +115,7 @@ module HammerCLI
111
115
  class Bool < AbstractNormalizer
112
116
 
113
117
  def description
114
- _("One of true/false, yes/no, 1/0.")
118
+ _("One of true/false, yes/no, 1/0")
115
119
  end
116
120
 
117
121
  def format(bool)
@@ -121,7 +125,7 @@ module HammerCLI
121
125
  elsif bool.downcase.match(/^(false|f|no|n|0)$/i)
122
126
  return false
123
127
  else
124
- raise ArgumentError, _("value must be one of true/false, yes/no, 1/0")
128
+ raise ArgumentError, _("Value must be one of true/false, yes/no, 1/0.")
125
129
  end
126
130
  end
127
131
 
@@ -160,7 +164,7 @@ module HammerCLI
160
164
  ::JSON.parse(json_string)
161
165
 
162
166
  rescue ::JSON::ParserError => e
163
- raise ArgumentError, _("Unable to parse JSON input")
167
+ raise ArgumentError, _("Unable to parse JSON input.")
164
168
  end
165
169
 
166
170
  end
@@ -182,9 +186,9 @@ module HammerCLI
182
186
  value
183
187
  else
184
188
  if allowed_values.count == 1
185
- msg = _("value must be %s") % quoted_values
189
+ msg = _("Value must be %s.") % quoted_values
186
190
  else
187
- msg = _("value must be one of %s") % quoted_values
191
+ msg = _("Value must be one of %s.") % quoted_values
188
192
  end
189
193
  raise ArgumentError, msg
190
194
  end
@@ -212,7 +216,7 @@ module HammerCLI
212
216
  raise ArgumentError unless date
213
217
  ::DateTime.parse(date).to_s
214
218
  rescue ArgumentError
215
- raise ArgumentError, _("'%s' is not a valid date") % date
219
+ raise ArgumentError, _("'%s' is not a valid date.") % date
216
220
  end
217
221
  end
218
222
 
@@ -243,7 +247,7 @@ module HammerCLI
243
247
  def parse(arr)
244
248
  arr.split(",").uniq.tap do |values|
245
249
  unless values.inject(true) { |acc, cur| acc & (@allowed_values.include? cur) }
246
- raise ArgumentError, _("value must be a combination of '%s'") % quoted_values
250
+ raise ArgumentError, _("Value must be a combination of '%s'.") % quoted_values
247
251
  end
248
252
  end
249
253
  end
@@ -8,14 +8,28 @@ module HammerCLI
8
8
  @option_sources = option_sources
9
9
  end
10
10
 
11
- def all_options
12
- @all_options ||= @option_sources.inject({}) do |all_options, source|
11
+ def all_options_raw
12
+ @all_options_raw ||= @option_sources.inject({}) do |all_options, source|
13
13
  source.get_options(@recognised_options, all_options)
14
14
  end
15
15
  end
16
16
 
17
+ def all_options
18
+ @all_options ||= translate_nils(all_options_raw)
19
+ end
20
+
17
21
  def options
18
- @options ||= all_options.reject {|key, value| value.nil? }
22
+ @options ||= all_options.reject { |key, value| value.nil? && all_options_raw[key].nil? }
23
+ end
24
+
25
+ private
26
+
27
+ def translate_nils(opts)
28
+ Hash[ opts.map { |k,v| [k, translate_nil(v)] } ]
29
+ end
30
+
31
+ def translate_nil(value)
32
+ value == HammerCLI::NilValue ? nil : value
19
33
  end
20
34
  end
21
35
  end
@@ -2,6 +2,8 @@ require 'clamp'
2
2
 
3
3
  module HammerCLI
4
4
 
5
+ class NilValue; end
6
+
5
7
  def self.option_accessor_name(*name)
6
8
  if name.length > 1
7
9
  name.map { |n| _option_accessor_name(n) }
@@ -16,6 +18,8 @@ module HammerCLI
16
18
 
17
19
  module Options
18
20
 
21
+ NIL_SUBST = 'NIL'
22
+
19
23
  class OptionDefinition < Clamp::Option::Definition
20
24
 
21
25
  attr_accessor :value_formatter
@@ -23,18 +27,14 @@ module HammerCLI
23
27
  attr_accessor :deprecated_switches
24
28
 
25
29
  def initialize(switches, type, description, options = {})
26
- self.value_formatter = options.delete(:format)
30
+ self.value_formatter = options.delete(:format) || HammerCLI::Options::Normalizers::Default.new
27
31
  self.context_target = options.delete(:context_target)
28
32
  self.deprecated_switches = options.delete(:deprecated)
29
33
  super
30
34
  end
31
35
 
32
36
  def complete(value)
33
- if value_formatter.nil?
34
- []
35
- else
36
- value_formatter.complete(value)
37
- end
37
+ value_formatter.complete(value)
38
38
  end
39
39
 
40
40
  def help_lhs
@@ -84,11 +84,7 @@ module HammerCLI
84
84
  end
85
85
 
86
86
  def format_description
87
- if value_formatter.nil?
88
- ""
89
- else
90
- value_formatter.description
91
- end
87
+ value_formatter.description
92
88
  end
93
89
 
94
90
  def value_description
@@ -98,26 +94,45 @@ module HammerCLI
98
94
  ].compact
99
95
 
100
96
  str = ""
101
- str += _("Can be specified multiple times. ") if multivalued?
102
- str += _("Default: ") + default_sources.join(_(", or ")) unless default_sources.empty?
97
+ if multivalued?
98
+ str += _("Can be specified multiple times.")
99
+ str += " "
100
+ end
101
+ unless default_sources.empty?
102
+ sep = _(", or")
103
+ sep += " "
104
+ str += _("Default:")
105
+ str += " "
106
+ str += default_sources.join(sep)
107
+ end
103
108
  str
104
109
  end
105
110
 
106
111
  def default_conversion_block
107
- if !value_formatter.nil?
108
- value_formatter.method(:format)
109
- elsif flag?
112
+ if flag?
110
113
  Clamp.method(:truthy?)
114
+ else
115
+ self.method(:format_value)
116
+ end
117
+ end
118
+
119
+ def format_value(value)
120
+ if value == nil_subst
121
+ HammerCLI::NilValue
122
+ else
123
+ value_formatter.format(value)
111
124
  end
112
125
  end
113
126
 
127
+ def nil_subst
128
+ nil_subst = ENV['HAMMER_NIL'] || HammerCLI::Options::NIL_SUBST
129
+ raise _('Environment variable HAMMER_NIL can not be empty.') if nil_subst.empty?
130
+ nil_subst
131
+ end
132
+
114
133
  def default_value
115
134
  if defined?(@default_value)
116
- if value_formatter
117
- value_formatter.format(@default_value)
118
- else
119
- @default_value
120
- end
135
+ value_formatter.format(@default_value)
121
136
  elsif multivalued?
122
137
  []
123
138
  end
@@ -163,7 +163,7 @@ module HammerCLI::Output::Adapter
163
163
  # or use headers from output definition
164
164
  headers ||= default_headers(fields)
165
165
  csv_string = generate do |csv|
166
- csv << headers if headers
166
+ csv << headers if headers && !@context[:no_headers]
167
167
  rows.each do |row|
168
168
  csv << Cell.values(headers, row)
169
169
  end
@@ -35,10 +35,11 @@ module HammerCLI::Output::Adapter
35
35
  end
36
36
 
37
37
  line = hline_bits.join(LINE_SEPARATOR)
38
-
39
- puts line
40
- puts header_bits.join(COLUMN_SEPARATOR)
41
- puts line
38
+ unless @context[:no_headers]
39
+ puts line
40
+ puts header_bits.join(COLUMN_SEPARATOR)
41
+ puts line
42
+ end
42
43
 
43
44
  formatted_collection.collect do |row|
44
45
  row_bits = fields.map do |f|
@@ -48,11 +49,12 @@ module HammerCLI::Output::Adapter
48
49
  end
49
50
 
50
51
  # print closing line only when the table isn't empty
51
- puts line unless formatted_collection.empty?
52
+ # and there is no --no-headers option
53
+ puts line unless formatted_collection.empty? || @context[:no_headers]
52
54
 
53
55
  if collection.meta.pagination_set? && collection.count < collection.meta.subtotal
54
56
  pages = (collection.meta.subtotal.to_f/collection.meta.per_page).ceil
55
- puts _("Page %{page} of %{total} (use --page and --per-page for navigation)") % {:page => collection.meta.page, :total => pages}
57
+ puts _("Page %{page} of %{total} (use --page and --per-page for navigation).") % {:page => collection.meta.page, :total => pages}
56
58
  end
57
59
  end
58
60
 
@@ -23,11 +23,6 @@ module HammerCLI
23
23
  Dir.glob(File.join(full_path, 'cli.modules.d/*.yml')).sort.each do |f|
24
24
  load_from_file(f)
25
25
  end
26
- Dir.glob(File.join(full_path, 'hammer.modules.d/*.yml')).sort.each do |f|
27
- warn _("Warning: location hammer.modules.d is deprecated, move your module configurations to cli.modules.d")
28
- warn " #{f} -> #{f.gsub('hammer.modules.d', 'cli.modules.d')}"
29
- load_from_file(f)
30
- end
31
26
  end
32
27
  end
33
28
  end
@@ -41,7 +36,7 @@ module HammerCLI
41
36
  path_history << file_path
42
37
  end
43
38
  rescue Exception => e
44
- warn _("Warning: Couldn't load configuration file %{path}: %{message}") % { path: file_path, message: e.message }
39
+ warn _("Warning: Couldn't load configuration file %{path}: %{message}.") % { path: file_path, message: e.message }
45
40
  end
46
41
  end
47
42
  end
@@ -113,8 +113,8 @@ module HammerCLI
113
113
  end
114
114
 
115
115
  def print_welcome_message
116
- print_message(_("Welcome to the hammer interactive shell"))
117
- print_message(_("Type 'help' for usage information"))
116
+ print_message(_("Welcome to the hammer interactive shell."))
117
+ print_message(_("Type 'help' for usage information."))
118
118
  end
119
119
 
120
120
  def common_prefix(results)
@@ -55,11 +55,11 @@ module HammerCLI
55
55
  options
56
56
  elsif options[:ssl_client_cert] || options[:ssl_client_key]
57
57
  if options[:ssl_client_cert]
58
- warn _("SSL client certificate is set but the key is not")
58
+ warn _("SSL client certificate is set but the key is not.")
59
59
  elsif options[:ssl_client_key]
60
- warn _("SSL client key is set but the certificate is not")
60
+ warn _("SSL client key is set but the certificate is not.")
61
61
  end
62
- warn _("SSL client authentication disabled")
62
+ warn _("SSL client authentication disabled.")
63
63
  {}
64
64
  else
65
65
  {}
@@ -69,13 +69,13 @@ module HammerCLI
69
69
  def read_certificate(path)
70
70
  OpenSSL::X509::Certificate.new(File.read(path)) unless path.nil?
71
71
  rescue SystemCallError => e
72
- warn _("Could't read SSL client certificate %s") % path
72
+ warn _("Could't read SSL client certificate %s.") % path
73
73
  end
74
74
 
75
75
  def read_key(path)
76
76
  OpenSSL::PKey::RSA.new(File.read(path)) unless path.nil?
77
77
  rescue SystemCallError => e
78
- warn _("Could't read SSL client key %s") % path
78
+ warn _("Could't read SSL client key %s.") % path
79
79
  end
80
80
  end
81
81
  end
@@ -3,14 +3,34 @@ module HammerCLI
3
3
 
4
4
  module Subcommand
5
5
 
6
- class LazyDefinition < Clamp::Subcommand::Definition
6
+ class Definition < Clamp::Subcommand::Definition
7
7
 
8
- def initialize(names, description, subcommand_class_name, path)
8
+ def initialize(names, description, subcommand_class, options = {})
9
9
  @names = Array(names)
10
10
  @description = description
11
- @subcommand_class_name = subcommand_class_name
12
- @path = path
11
+ @subcommand_class = subcommand_class
12
+ @hidden = options[:hidden]
13
+ @warning = options[:warning]
14
+ end
15
+
16
+ def hidden?
17
+ @hidden
18
+ end
19
+
20
+ def subcommand_class
21
+ warn(@warning) if @warning
22
+ @subcommand_class
23
+ end
24
+
25
+ attr_reader :warning
26
+ end
27
+
28
+ class LazyDefinition < Definition
29
+
30
+ def initialize(names, description, subcommand_class_name, path, options = {})
31
+ super(names, description, subcommand_class_name, options)
13
32
  @loaded = false
33
+ @path = path
14
34
  end
15
35
 
16
36
  def loaded?
@@ -18,20 +38,22 @@ module HammerCLI
18
38
  end
19
39
 
20
40
  def subcommand_class
41
+ warn(@warning) if @warning
21
42
  if !@loaded
22
43
  require @path
23
44
  @loaded = true
24
- @constantized_class = @subcommand_class_name.constantize
45
+ @constantized_class = @subcommand_class.constantize
25
46
  end
26
47
  @constantized_class
27
48
  end
28
-
29
49
  end
30
50
 
31
51
  def self.included(base)
32
52
  base.extend(ClassMethods)
33
53
  end
34
54
 
55
+
56
+
35
57
  module ClassMethods
36
58
  def remove_subcommand(name)
37
59
  self.recognised_subcommands.delete_if do |sc|
@@ -44,38 +66,41 @@ module HammerCLI
44
66
  end
45
67
  end
46
68
 
47
- def subcommand!(name, description, subcommand_class = self, &block)
69
+ def subcommand!(name, description, subcommand_class = self, options = {}, &block)
48
70
  remove_subcommand(name)
49
- subcommand(name, description, subcommand_class, &block)
71
+ subcommand(name, description, subcommand_class, options, &block)
50
72
  logger.info "subcommand #{name} (#{subcommand_class}) was created."
51
73
  end
52
74
 
53
- def subcommand(name, description, subcommand_class = self, &block)
75
+ def subcommand(name, description, subcommand_class = self, options = {}, &block)
76
+ definition = Definition.new(name, description, subcommand_class, options)
77
+ define_subcommand(name, subcommand_class, definition, &block)
78
+ end
79
+
80
+ def lazy_subcommand(name, description, subcommand_class_name, path, options = {})
81
+ definition = LazyDefinition.new(name, description, subcommand_class_name, path, options)
82
+ define_subcommand(name, Class, definition)
83
+ end
84
+
85
+ def lazy_subcommand!(name, description, subcommand_class_name, path, options = {})
86
+ remove_subcommand(name)
87
+ self.lazy_subcommand(name, description, subcommand_class_name, path, options)
88
+ logger.info "subcommand #{name} (#{subcommand_class_name}) was created."
89
+ end
90
+
91
+ def define_subcommand(name, subcommand_class, definition, &block)
54
92
  existing = find_subcommand(name)
55
93
  if existing
56
- raise HammerCLI::CommandConflict, _("can't replace subcommand %<name>s (%<existing_class>s) with %<name>s (%<new_class>s)") % {
94
+ raise HammerCLI::CommandConflict, _("Can't replace subcommand %<name>s (%<existing_class>s) with %<name>s (%<new_class>s).") % {
57
95
  :name => name,
58
96
  :existing_class => existing.subcommand_class,
59
97
  :new_class => subcommand_class
60
98
  }
61
99
  end
62
- super
100
+ subcommand_class = Class.new(subcommand_class, &block) if block
101
+ declare_subcommand_parameters unless has_subcommands?
102
+ recognised_subcommands << definition
63
103
  end
64
-
65
- def lazy_subcommand(name, description, subcommand_class, path)
66
- # call original subcommand to ensure command's parameters are set correctly
67
- # (hammer command SUBCOMMAND [ARGS] ...)
68
- subcommand(name, description, Class)
69
- # replace last subcommand definition with correct lazy-loaded one
70
- recognised_subcommands[-1] = LazyDefinition.new(name, description, subcommand_class, path)
71
- end
72
-
73
- def lazy_subcommand!(name, description, subcommand_class, path)
74
- remove_subcommand(name)
75
- self.lazy_subcommand(name, description, subcommand_class, path)
76
- logger.info "subcommand #{name} (#{subcommand_class}) was created."
77
- end
78
-
79
104
  end
80
105
 
81
106
  end
@@ -71,13 +71,13 @@ module HammerCLI
71
71
  if heading.nil?
72
72
  ["Error: #{message}",
73
73
  "",
74
- "See: '#{command} --help'",
74
+ "See: '#{command} --help'.",
75
75
  ""].join("\n")
76
76
  else
77
77
  ["#{heading}:",
78
78
  " Error: #{message}",
79
79
  " ",
80
- " See: '#{command} --help'",
80
+ " See: '#{command} --help'.",
81
81
  ""].join("\n")
82
82
  end
83
83
  end
@@ -0,0 +1,54 @@
1
+ module HammerCLI
2
+ module Testing
3
+ module Messages
4
+ def get_subcommands(cmd)
5
+ return [] unless cmd.respond_to? :recognised_subcommands
6
+ cmd.recognised_subcommands.map { |c| c.subcommand_class }
7
+ end
8
+
9
+ def all_subcommands(cmd, parent=HammerCLI::AbstractCommand)
10
+ result = []
11
+ get_subcommands(cmd).each do |klass|
12
+ if klass < parent
13
+ result << klass
14
+ result += all_subcommands(klass, parent)
15
+ end
16
+ end
17
+ result
18
+ end
19
+
20
+ def assert_msg_period(cmd, method_name)
21
+ if cmd.respond_to?(method_name) && !cmd.send(method_name).nil?
22
+ assert(cmd.send(method_name).end_with?('.'), "#{cmd}.#{method_name} doesn't end with '.'")
23
+ end
24
+ end
25
+
26
+ def refute_msg_period(cmd, method_name)
27
+ if cmd.respond_to?(method_name) && !cmd.send(method_name).nil?
28
+ refute(cmd.send(method_name).end_with?('.'), "#{cmd}.#{method_name} ends with '.'")
29
+ end
30
+ end
31
+
32
+ def check_option_description(cmd, opt)
33
+ refute opt.description.end_with?('.'), "Description for option #{opt.long_switch} in #{cmd} ends with '.'"
34
+ end
35
+
36
+ def check_command_messages(cmd)
37
+ cmd.recognised_options.each do |opt|
38
+ check_option_description(cmd, opt)
39
+ end
40
+ refute_msg_period(cmd, :desc)
41
+ assert_msg_period(cmd, :success_message)
42
+ refute_msg_period(cmd, :failure_message)
43
+ end
44
+
45
+ def check_all_command_messages(main_cmd, parent=HammerCLI::AbstractCommand)
46
+ all_subcommands(main_cmd, parent).each do |cmd|
47
+ it "test messages of #{cmd}" do
48
+ check_command_messages(cmd)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -38,7 +38,7 @@ module HammerCLI
38
38
 
39
39
  def get_option(name)
40
40
  name = name.to_s
41
- raise _("Unknown option name '%s'") % name unless @options.has_key? name
41
+ raise _("Unknown option name '%s'.") % name unless @options.has_key? name
42
42
  @options[name]
43
43
  end
44
44
 
@@ -69,8 +69,8 @@ module HammerCLI
69
69
 
70
70
  def initialize(options, to_check)
71
71
  super(options, to_check)
72
- @rejected_msg = _("You can't set all options %s at one time")
73
- @required_msg = _("Options %s are required")
72
+ @rejected_msg = _("You can't set all options %s at one time.")
73
+ @required_msg = _("Options %s are required.")
74
74
  end
75
75
 
76
76
  def exist?
@@ -84,8 +84,8 @@ module HammerCLI
84
84
  class OneOptionConstraint < AllConstraint
85
85
  def initialize(options, to_check)
86
86
  super(options, [to_check])
87
- @rejected_msg = _("You can't set option %s")
88
- @required_msg = _("Option %s is required")
87
+ @rejected_msg = _("You can't set option %s.")
88
+ @required_msg = _("Option %s is required.")
89
89
  end
90
90
 
91
91
  def value
@@ -97,8 +97,8 @@ module HammerCLI
97
97
 
98
98
  def initialize(options, to_check)
99
99
  super(options, to_check)
100
- @rejected_msg = _("You can't set any of options %s")
101
- @required_msg = _("At least one of options %s is required")
100
+ @rejected_msg = _("You can't set any of options %s.")
101
+ @required_msg = _("At least one of options %s is required.")
102
102
  end
103
103
 
104
104
  def exist?
@@ -123,11 +123,11 @@ module HammerCLI
123
123
  def required_msg
124
124
  case count_present_options
125
125
  when 0
126
- _("One of options %s is required")
126
+ _("One of options %s is required.")
127
127
  when 1
128
128
  ''
129
129
  else
130
- _("Only one of options %s can be set")
130
+ _("Only one of options %s can be set.")
131
131
  end
132
132
  end
133
133
 
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.11.0'
3
+ @version ||= Gem::Version.new '0.12.0'
4
4
  end
5
5
  end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/man/hammer.1.gz CHANGED
Binary file
@@ -15,18 +15,9 @@ describe 'commands' do
15
15
  end
16
16
  end
17
17
 
18
- let(:defaults_path) { File.join(File.dirname(__FILE__), '../unit/fixtures/defaults/defaults.yml') }
19
-
20
18
  before do
21
- settings = load_yaml(defaults_path)
22
-
23
- @defaults = HammerCLI::Defaults.new(settings[:defaults], defaults_path)
24
- @defaults.stubs(:write_to_file).returns true
25
- @defaults.stubs(:providers).returns({ 'foreman' => TestProvider.new() })
26
-
27
- @context = {
28
- :defaults => @defaults
29
- }
19
+ @defaults = defaults_mock({ 'foreman' => TestProvider.new() })
20
+ @context = { :defaults => @defaults }
30
21
  end
31
22
 
32
23
  describe 'defaults list' do
@@ -142,7 +133,7 @@ describe 'commands' do
142
133
  it 'reports missing parameter name' do
143
134
  options = ['--param-value=83']
144
135
 
145
- expected_result = usage_error_result(cmd, "option '--param-name' is required")
136
+ expected_result = usage_error_result(cmd, "Option '--param-name' is required.")
146
137
 
147
138
  result = run_cmd(cmd + options, @context)
148
139
  assert_cmd(expected_result, result)