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.
- checksums.yaml +4 -4
- data/bin/hammer +4 -9
- data/config/cli_config.template.yml +12 -6
- data/doc/creating_commands.md +38 -0
- data/doc/i18n.md +33 -2
- data/doc/option_normalizers.md +2 -0
- data/doc/release_notes.md +18 -0
- data/lib/hammer_cli/abstract.rb +7 -2
- data/lib/hammer_cli/apipie/option_builder.rb +1 -1
- data/lib/hammer_cli/ca_cert_fetcher.rb +8 -8
- data/lib/hammer_cli/clamp.rb +9 -9
- data/lib/hammer_cli/context.rb +2 -1
- data/lib/hammer_cli/defaults.rb +12 -14
- data/lib/hammer_cli/defaults_commands.rb +2 -2
- data/lib/hammer_cli/exception_handler.rb +1 -1
- data/lib/hammer_cli/help/builder.rb +2 -1
- data/lib/hammer_cli/i18n/find_task.rb +41 -0
- data/lib/hammer_cli/i18n.rb +4 -0
- data/lib/hammer_cli/logger.rb +1 -1
- data/lib/hammer_cli/main.rb +12 -11
- data/lib/hammer_cli/modules.rb +5 -8
- data/lib/hammer_cli/options/normalizers.rb +15 -11
- data/lib/hammer_cli/options/option_collector.rb +17 -3
- data/lib/hammer_cli/options/option_definition.rb +36 -21
- data/lib/hammer_cli/output/adapter/csv.rb +1 -1
- data/lib/hammer_cli/output/adapter/table.rb +8 -6
- data/lib/hammer_cli/settings.rb +1 -6
- data/lib/hammer_cli/shell.rb +2 -2
- data/lib/hammer_cli/ssloptions.rb +5 -5
- data/lib/hammer_cli/subcommand.rb +51 -26
- data/lib/hammer_cli/testing/command_assertions.rb +2 -2
- data/lib/hammer_cli/testing/messages.rb +54 -0
- data/lib/hammer_cli/validator.rb +9 -9
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
- data/man/hammer.1.gz +0 -0
- data/test/functional/defaults_test.rb +3 -12
- data/test/functional/help_test.rb +1 -1
- data/test/functional/nil_values_test.rb +75 -0
- data/test/functional/test_helper.rb +10 -0
- data/test/reports/TEST-Fields-ContainerField-display-.xml +7 -0
- data/test/reports/TEST-Fields-ContainerField-display-blank-is-allowed.xml +15 -0
- data/test/reports/TEST-Fields-ContainerField-display-blank-is-not-allowed.xml +15 -0
- data/test/reports/TEST-Fields-ContainerField.xml +7 -0
- data/test/reports/TEST-Fields-Field-display-.xml +7 -0
- data/test/reports/TEST-Fields-Field-display-blank-is-allowed.xml +11 -0
- data/test/reports/TEST-Fields-Field-display-blank-is-not-allowed.xml +11 -0
- data/test/reports/TEST-Fields-Field-hide-blank-.xml +11 -0
- data/test/reports/TEST-Fields-Field-parameters.xml +9 -0
- data/test/reports/TEST-Fields-Field.xml +13 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-build-options.xml +15 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-exception-handler.xml +13 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-logging.xml +21 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-option-builder.xml +11 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-options.xml +11 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-output.xml +19 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-remove-subcommand.xml +11 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand-.xml +13 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior-subcommand.xml +11 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand-subcommand-behavior.xml +7 -0
- data/test/reports/TEST-HammerCLI-AbstractCommand.xml +11 -0
- data/test/reports/TEST-HammerCLI-Apipie-Command-options.xml +11 -0
- data/test/reports/TEST-HammerCLI-Apipie-Command-resource-defined.xml +9 -0
- data/test/reports/TEST-HammerCLI-Apipie-Command-setting-resources.xml +19 -0
- data/test/reports/TEST-HammerCLI-Apipie-Command.xml +9 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-aliasing-resources.xml +13 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-filtering-options.xml +15 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-required-options.xml +11 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-setting-correct-normalizers.xml +9 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-hash-params.xml +11 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder-with-one-simple-param.xml +15 -0
- data/test/reports/TEST-HammerCLI-Apipie-OptionBuilder.xml +7 -0
- data/test/reports/TEST-HammerCLI-Completer-command-completion.xml +29 -0
- data/test/reports/TEST-HammerCLI-Completer-option-value-completion.xml +17 -0
- data/test/reports/TEST-HammerCLI-Completer-subcommand-completion.xml +19 -0
- data/test/reports/TEST-HammerCLI-Completer.xml +7 -0
- data/test/reports/TEST-HammerCLI-CompleterLine-line-complete.xml +25 -0
- data/test/reports/TEST-HammerCLI-CompleterLine-splitting-words.xml +29 -0
- data/test/reports/TEST-HammerCLI-CompleterLine.xml +7 -0
- data/test/reports/TEST-HammerCLI-CompleterWord-complete-.xml +23 -0
- data/test/reports/TEST-HammerCLI-CompleterWord-quote.xml +15 -0
- data/test/reports/TEST-HammerCLI-CompleterWord-quoted-.xml +13 -0
- data/test/reports/TEST-HammerCLI-CompleterWord.xml +7 -0
- data/test/reports/TEST-HammerCLI-Connection.xml +21 -0
- data/test/reports/TEST-HammerCLI-ExceptionHandler.xml +21 -0
- data/test/reports/TEST-HammerCLI-I18n.xml +11 -0
- data/test/reports/TEST-HammerCLI-MainCommand-loading-context-password.xml +11 -0
- data/test/reports/TEST-HammerCLI-MainCommand-loading-context-username.xml +11 -0
- data/test/reports/TEST-HammerCLI-MainCommand-loading-context-verbose.xml +9 -0
- data/test/reports/TEST-HammerCLI-MainCommand-loading-context.xml +7 -0
- data/test/reports/TEST-HammerCLI-MainCommand.xml +7 -0
- data/test/reports/TEST-HammerCLI-Modules-find-by-name.xml +13 -0
- data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-not-found.xml +13 -0
- data/test/reports/TEST-HammerCLI-Modules-load-a-module-module-runtime-exception.xml +13 -0
- data/test/reports/TEST-HammerCLI-Modules-load-a-module-success.xml +15 -0
- data/test/reports/TEST-HammerCLI-Modules-load-a-module.xml +7 -0
- data/test/reports/TEST-HammerCLI-Modules-load-all-modules.xml +9 -0
- data/test/reports/TEST-HammerCLI-Modules-names.xml +13 -0
- data/test/reports/TEST-HammerCLI-Modules.xml +7 -0
- data/test/reports/TEST-HammerCLI-OptionBuilderContainer.0.xml +7 -0
- data/test/reports/TEST-HammerCLI-OptionBuilderContainer.xml +11 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-abstract.xml +9 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-bool.xml +31 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-datetime.xml +17 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-enum.xml +15 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-enumlist.xml +21 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-json-input.xml +15 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-key-value-list.xml +17 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers-list.xml +15 -0
- data/test/reports/TEST-HammerCLI-Options-Normalizers.xml +7 -0
- data/test/reports/TEST-HammerCLI-Options-OptionDefinition-context.xml +9 -0
- data/test/reports/TEST-HammerCLI-Options-OptionDefinition-formatters.xml +11 -0
- data/test/reports/TEST-HammerCLI-Options-OptionDefinition.xml +7 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-error-messages.xml +15 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-messages.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract-test-data-for-field.xml +15 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Abstract.xml +17 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection-show-ids.xml +9 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Base-print-collection.xml +27 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Base.xml +7 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-formatters.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-collections.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-fields-with-containers.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection-handle-ids.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-collection.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues-print-message.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-CSValues.xml +7 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-column-width.xml +15 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-formatters.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-handle-ids.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection-sort-columns.xml +9 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table-print-collection.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Adapter-Table.xml +7 -0
- data/test/reports/TEST-HammerCLI-Output-Definition-empty-.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Definition.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl-collection.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl-custom-fields.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl-fields.xml +15 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl-label.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl-path-definition.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Dsl.xml +9 -0
- data/test/reports/TEST-HammerCLI-Output-FieldFilter.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-BooleanFormatter.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-ColorFormatter.xml +9 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-DateFormatter.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-FieldFormatter.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterContainer.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-FormatterLibrary.xml +11 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-KeyValueFormatter.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-ListFormatter.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Formatters-LongTextFormatter.xml +13 -0
- data/test/reports/TEST-HammerCLI-Output-Output-adapters.xml +17 -0
- data/test/reports/TEST-HammerCLI-Output-Output-data.xml +15 -0
- data/test/reports/TEST-HammerCLI-Output-Output-formatters.xml +9 -0
- data/test/reports/TEST-HammerCLI-Output-Output-messages.xml +19 -0
- data/test/reports/TEST-HammerCLI-Output-Output.xml +7 -0
- data/test/reports/TEST-HammerCLI-Output-RecordCollection.xml +13 -0
- data/test/reports/TEST-HammerCLI-Settings-load-from-paths.xml +15 -0
- data/test/reports/TEST-HammerCLI-Settings.xml +25 -0
- data/test/reports/TEST-HammerCLI-ShellHistory-loading-old-history.xml +11 -0
- data/test/reports/TEST-HammerCLI-ShellHistory-saving-history.xml +15 -0
- data/test/reports/TEST-HammerCLI-ShellHistory.xml +7 -0
- data/test/reports/TEST-MiniTest-Spec.xml +7 -0
- data/test/reports/TEST-String-camelize.xml +11 -0
- data/test/reports/TEST-String-formatting.xml +17 -0
- data/test/reports/TEST-String-indent.xml +11 -0
- data/test/reports/TEST-String-interactive-.xml +13 -0
- data/test/reports/TEST-String.xml +7 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint-exist-.xml +13 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-AllConstraint.xml +7 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint-exist-.xml +13 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-AnyConstraint.xml +7 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-exist-.xml +9 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-rejected.xml +13 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint-required.xml +13 -0
- data/test/reports/TEST-constraints-HammerCLI-Validator-BaseConstraint.xml +7 -0
- data/test/reports/TEST-constraints.xml +7 -0
- data/test/unit/abstract_test.rb +10 -1
- data/test/unit/apipie/option_builder_test.rb +6 -0
- data/test/unit/defaults_test.rb +12 -5
- data/test/unit/exception_handler_test.rb +1 -1
- data/test/unit/fixtures/apipie/documented.json +10 -1
- data/test/unit/help/builder_test.rb +16 -1
- data/test/unit/messages_test.rb +7 -0
- data/test/unit/modules_test.rb +4 -15
- data/test/unit/options/normalizers_test.rb +21 -1
- data/test/unit/options/option_collector_test.rb +10 -4
- data/test/unit/output/adapter/csv_test.rb +29 -0
- data/test/unit/output/adapter/table_test.rb +27 -0
- data/test/unit/validator_test.rb +4 -4
- 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, _("
|
|
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, _("
|
|
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, _("
|
|
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 = _("
|
|
189
|
+
msg = _("Value must be %s.") % quoted_values
|
|
186
190
|
else
|
|
187
|
-
msg = _("
|
|
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, _("
|
|
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
|
|
12
|
-
@
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
|
data/lib/hammer_cli/settings.rb
CHANGED
|
@@ -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
|
data/lib/hammer_cli/shell.rb
CHANGED
|
@@ -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
|
|
6
|
+
class Definition < Clamp::Subcommand::Definition
|
|
7
7
|
|
|
8
|
-
def initialize(names, description,
|
|
8
|
+
def initialize(names, description, subcommand_class, options = {})
|
|
9
9
|
@names = Array(names)
|
|
10
10
|
@description = description
|
|
11
|
-
@
|
|
12
|
-
@
|
|
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 = @
|
|
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, _("
|
|
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
|
-
|
|
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
|
data/lib/hammer_cli/validator.rb
CHANGED
|
@@ -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
|
|
data/lib/hammer_cli/version.rb
CHANGED
|
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
|
-
|
|
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, "
|
|
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)
|