hammer_cli 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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)