hammer_cli 0.12.0 → 0.13.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +1 -0
  3. data/doc/release_notes.md +5 -0
  4. data/lib/hammer_cli.rb +1 -0
  5. data/lib/hammer_cli/apipie/command.rb +8 -0
  6. data/lib/hammer_cli/apipie/option_builder.rb +4 -4
  7. data/lib/hammer_cli/main.rb +7 -0
  8. data/lib/hammer_cli/output/adapter/abstract.rb +5 -0
  9. data/lib/hammer_cli/output/adapter/base.rb +2 -2
  10. data/lib/hammer_cli/output/adapter/csv.rb +1 -1
  11. data/lib/hammer_cli/output/adapter/json.rb +2 -2
  12. data/lib/hammer_cli/output/adapter/table.rb +5 -5
  13. data/lib/hammer_cli/output/adapter/yaml.rb +2 -2
  14. data/lib/hammer_cli/version.rb +1 -1
  15. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  16. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  17. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  18. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  19. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  20. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  21. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  22. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  23. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  24. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  25. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  26. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  27. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/test/unit/apipie/command_test.rb +13 -0
  29. data/test/unit/apipie/option_builder_test.rb +6 -1
  30. data/test/unit/fixtures/apipie/documented.json +10 -1
  31. data/test/unit/output/adapter/base_test.rb +25 -0
  32. data/test/unit/output/adapter/csv_test.rb +24 -0
  33. data/test/unit/output/adapter/json_test.rb +25 -0
  34. data/test/unit/output/adapter/table_test.rb +31 -0
  35. data/test/unit/output/adapter/yaml_test.rb +25 -0
  36. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0aa589ebe2589ead222c05b6b8a1de324f3efdb5
4
- data.tar.gz: 1068b381dbe8685c2a1d7bc0168513f5e48ccce9
3
+ metadata.gz: 4a07530fca2559a9ab75f4e287a46ede2a38d3cd
4
+ data.tar.gz: '0088bd037fda97450755a19d7479e6994549dc96'
5
5
  SHA512:
6
- metadata.gz: c7153a9ebaab813ef8ea1061461efd60c1e357f5445187762203aed5055bb1e38eac86d787f4bec013e5cc78e84afd40fbb3ac81cef8a3b1844732356a7f864f
7
- data.tar.gz: ff4d24d0067d7e500ee573bfb82531637c67f557d1ef9745d4b2587ed31e9edbac0aa6d47eb79778e97658627495f3327b5cac0626d56ea04dfd8a27c7c1b8ba
6
+ metadata.gz: 1b0853ed83f5ceb835fed41d833de7d2abbb789a31ed5b3fff8d35a96c82327bc5d3b2746088d3eb895a61f93ac7da22fc254cf4dfc934455fd3b533a60c62c1
7
+ data.tar.gz: 5c87348a2eebc66ccd5207c0c5aeaa43dbb3c6277a0d977a5e3c8f043e798cee71f2a3a81f57a3af77c6a408fcbe75e63335121402c5de65dd610a76c188f03a
data/bin/hammer CHANGED
@@ -30,6 +30,7 @@ class PreParser < Clamp::Command
30
30
  option ["--csv"], :flag, "Output as CSV (same as --output=csv)"
31
31
  option ["--output"], "ADAPTER", "Set output format"
32
32
  option ["--no-headers"], :flag, "Hide headers from output"
33
+ option ["--output-file"], "OUTPUT_FILE", "Path to custom output file"
33
34
  option ["--csv-separator"], "SEPARATOR", "Character to separate the values"
34
35
  option ["--autocomplete"], "LINE", "Get list of possible endings"
35
36
  option ["--verify-ssl"], "VERIFY_SSL", "Configure SSL verification of remote system" do |value|
@@ -1,5 +1,10 @@
1
1
  Release notes
2
2
  =============
3
+ ### 0.13.0 (2018-05-09)
4
+ * Hammer CSV output saved as a file ([PR #254](https://github.com/theforeman/hammer-cli/pull/254)) ([#11586](http://projects.theforeman.org/issues/11586))
5
+ * correct parsing of enum types ([PR #272](https://github.com/theforeman/hammer-cli/pull/272)) ([#22752](http://projects.theforeman.org/issues/22752))
6
+ * require logger ([PR #273](https://github.com/theforeman/hammer-cli/pull/273)) ([#22906](http://projects.theforeman.org/issues/22906))
7
+ * Better help for unsupported hammer commands ([PR #257](https://github.com/theforeman/hammer-cli/pull/257)) ([#18532](http://projects.theforeman.org/issues/18532))
3
8
 
4
9
  ### 0.12.0 (2018-02-19)
5
10
  * Tests for message formats ([PR #266](https://github.com/theforeman/hammer-cli/pull/266)) ([#7451](http://projects.theforeman.org/issues/7451))
@@ -5,6 +5,7 @@ require 'hammer_cli/version'
5
5
  require 'hammer_cli/modules'
6
6
  require 'hammer_cli/exit_codes'
7
7
  require 'hammer_cli/settings'
8
+ require 'hammer_cli/logger'
8
9
  require 'hammer_cli/ca_cert_manager'
9
10
  require 'hammer_cli/connection'
10
11
  require 'hammer_cli/validator'
@@ -36,6 +36,14 @@ module HammerCLI::Apipie
36
36
  return HammerCLI::EX_OK
37
37
  end
38
38
 
39
+ def help
40
+ help_str = super
41
+ if !resource || (!action.nil? && !resource.has_action?(action))
42
+ help_str << "\n" + _("Unfortunately the server does not support such operation.") + "\n"
43
+ end
44
+ help_str
45
+ end
46
+
39
47
  protected
40
48
 
41
49
  def send_request
@@ -64,14 +64,14 @@ module HammerCLI::Apipie
64
64
  def option_opts(param)
65
65
  opts = {}
66
66
  opts[:required] = true if (param.required? and require_options?)
67
- if param.expected_type.to_s == 'array' || param.validator =~ /Array/i
67
+ if param.expected_type.to_s == 'array'
68
68
  opts[:format] = HammerCLI::Options::Normalizers::List.new
69
- elsif param.expected_type.to_s == 'boolean' || param.validator =~ /Boolean/i
69
+ elsif param.expected_type.to_s == 'boolean' || param.validator.to_s == 'boolean'
70
70
  opts[:format] = HammerCLI::Options::Normalizers::Bool.new
71
- elsif param.validator =~ /Must be one of: (.*)\./
71
+ elsif param.expected_type.to_s == 'string' && param.validator =~ /Must be one of: (.*)\./
72
72
  allowed = $1.split(/,\ ?/).map { |val| val.gsub(/<[^>]*>/i,'') }
73
73
  opts[:format] = HammerCLI::Options::Normalizers::Enum.new(allowed)
74
- elsif param.expected_type.to_s == 'numeric' || param.validator =~ /Number/i || param.validator =~ /Integer/i
74
+ elsif param.expected_type.to_s == 'numeric'
75
75
  opts[:format] = HammerCLI::Options::Normalizers::Number.new
76
76
  end
77
77
  opts[:attribute_name] = HammerCLI.option_accessor_name(param.name)
@@ -44,6 +44,13 @@ module HammerCLI
44
44
  option ["--output"], "ADAPTER", _("Set output format. One of [%s]") %
45
45
  HammerCLI::Output::Output.adapters.keys.join(', '),
46
46
  :context_target => :adapter
47
+ option ["--output-file"], "OUTPUT_FILE", _("Path to custom output file") do |filename|
48
+ begin
49
+ context[:output_file] = File.new(filename, 'w')
50
+ rescue SystemCallError, IOError => e
51
+ raise ArgumentError, e
52
+ end
53
+ end
47
54
  option ["--csv-separator"], "SEPARATOR", _("Character to separate the values"),
48
55
  :context_target => :csv_separator
49
56
 
@@ -64,6 +64,11 @@ module HammerCLI::Output::Adapter
64
64
  Abstract.data_for_field(field, record)
65
65
  end
66
66
 
67
+ def output_stream
68
+ return @context[:output_file] if @context.has_key?(:output_file)
69
+ $stdout
70
+ end
71
+
67
72
  private
68
73
 
69
74
  def filter_formatters(formatters_map)
@@ -14,8 +14,8 @@ module HammerCLI::Output::Adapter
14
14
 
15
15
  def print_collection(fields, collection)
16
16
  collection.each do |data|
17
- puts render_fields(fields, data)
18
- puts
17
+ output_stream.puts render_fields(fields, data)
18
+ output_stream.puts
19
19
  end
20
20
  end
21
21
 
@@ -168,7 +168,7 @@ module HammerCLI::Output::Adapter
168
168
  csv << Cell.values(headers, row)
169
169
  end
170
170
  end
171
- puts csv_string
171
+ output_stream.puts csv_string
172
172
  end
173
173
 
174
174
  def print_message(msg, msg_params={})
@@ -3,12 +3,12 @@ module HammerCLI::Output::Adapter
3
3
 
4
4
  def print_record(fields, record)
5
5
  result = prepare_collection(fields, [record].flatten(1))
6
- puts JSON.pretty_generate(result.first)
6
+ output_stream.puts JSON.pretty_generate(result.first)
7
7
  end
8
8
 
9
9
  def print_collection(fields, collection)
10
10
  result = prepare_collection(fields, collection)
11
- puts JSON.pretty_generate(result)
11
+ output_stream.puts JSON.pretty_generate(result)
12
12
  end
13
13
 
14
14
  def print_message(msg, msg_params={})
@@ -36,21 +36,21 @@ module HammerCLI::Output::Adapter
36
36
 
37
37
  line = hline_bits.join(LINE_SEPARATOR)
38
38
  unless @context[:no_headers]
39
- puts line
40
- puts header_bits.join(COLUMN_SEPARATOR)
41
- puts line
39
+ output_stream.puts line
40
+ output_stream.puts header_bits.join(COLUMN_SEPARATOR)
41
+ output_stream.puts line
42
42
  end
43
43
 
44
44
  formatted_collection.collect do |row|
45
45
  row_bits = fields.map do |f|
46
46
  normalize_column(widths[f.label], row[f.label] || "")
47
47
  end
48
- puts row_bits.join(COLUMN_SEPARATOR)
48
+ output_stream.puts row_bits.join(COLUMN_SEPARATOR)
49
49
  end
50
50
 
51
51
  # print closing line only when the table isn't empty
52
52
  # and there is no --no-headers option
53
- puts line unless formatted_collection.empty? || @context[:no_headers]
53
+ output_stream.puts line unless formatted_collection.empty? || @context[:no_headers]
54
54
 
55
55
  if collection.meta.pagination_set? && collection.count < collection.meta.subtotal
56
56
  pages = (collection.meta.subtotal.to_f/collection.meta.per_page).ceil
@@ -3,12 +3,12 @@ module HammerCLI::Output::Adapter
3
3
 
4
4
  def print_record(fields, record)
5
5
  result = prepare_collection(fields, [record].flatten(1))
6
- puts YAML.dump(result.first)
6
+ output_stream.puts YAML.dump(result.first)
7
7
  end
8
8
 
9
9
  def print_collection(fields, collection)
10
10
  result = prepare_collection(fields, collection)
11
- puts YAML.dump(result)
11
+ output_stream.puts YAML.dump(result)
12
12
  end
13
13
 
14
14
  def print_message(msg, msg_params={})
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.12.0'
3
+ @version ||= Gem::Version.new '0.13.0'
4
4
  end
5
5
  end
@@ -29,11 +29,24 @@ describe HammerCLI::Apipie::Command do
29
29
  class CommandC < CommandA
30
30
  end
31
31
 
32
+ class CommandUnsupp < HammerCLI::Apipie::Command
33
+ resource :architectures, :unsupptest
34
+ end
35
+
32
36
  let(:ctx) { { :adapter => :silent, :interactive => false } }
33
37
  let(:cmd_class) { HammerCLI::Apipie::Command.dup }
34
38
  let(:cmd) { cmd_class.new("", ctx) }
35
39
  let(:cmd_run) { cmd.run([]) }
36
40
 
41
+ context "unsupported commands" do
42
+ let(:cmd_class) { CommandUnsupp.dup }
43
+ let(:cmd) { cmd_class.new("unsupported", ctx) }
44
+ it "should print help for unsupported command" do
45
+ assert_match /.*Unfortunately the server does not support such operation.*/, cmd.help
46
+ end
47
+
48
+ end
49
+
37
50
  context "setting resources" do
38
51
 
39
52
  it "should set resource and action together" do
@@ -90,7 +90,12 @@ describe HammerCLI::Apipie::OptionBuilder do
90
90
  it "should set enum normalizer and handle coded values" do
91
91
  enum_option = options.find {|o| o.attribute_name == HammerCLI.option_accessor_name("coded_enum_param") }
92
92
  enum_option.value_formatter.class.must_equal HammerCLI::Options::Normalizers::Enum
93
- enum_option.value_formatter.allowed_values.sort.must_equal ["tomas", "tereza"].sort
93
+ enum_option.value_formatter.allowed_values.sort.must_equal ["array", "boolean", "hash", "integer", "json", "real", "string", "yaml"].sort
94
+ end
95
+
96
+ it "should set list normalizer for array of nested elements" do
97
+ array_option = options.find {|o| o.attribute_name == HammerCLI.option_accessor_name("nested_elements_param") }
98
+ array_option.value_formatter.class.must_equal HammerCLI::Options::Normalizers::List
94
99
  end
95
100
 
96
101
  it "should set number normalizer" do
@@ -148,11 +148,20 @@
148
148
  "description": "",
149
149
  "required": false
150
150
  },
151
+ {
152
+ "name": "nested_elements_param",
153
+ "full_name": "documented[nested_elements_param]",
154
+ "allow_nil": true,
155
+ "validator": "Must be an Array of nested elements",
156
+ "expected_type": "array",
157
+ "description": "",
158
+ "required": false
159
+ },
151
160
  {
152
161
  "name": "coded_enum_param",
153
162
  "full_name": "documented[coded_enum_param]",
154
163
  "allow_nil": true,
155
- "validator": "Must be one of: <code>tomas</code>, <code>tereza</code>.",
164
+ "validator": "Must be one of: <code>string</code>, <code>boolean</code>, <code>integer</code>, <code>real</code>, <code>array</code>, <code>hash</code>, <code>yaml</code>, <code>json</code>.",
156
165
  "expected_type": "string",
157
166
  "description": "",
158
167
  "required": false
@@ -195,6 +195,31 @@ describe HammerCLI::Output::Adapter::Base do
195
195
 
196
196
  end
197
197
 
198
+ context "output_stream" do
199
+
200
+ let(:tempfile) { Tempfile.new("output_stream_base_test_temp") }
201
+ let(:context) { {:output_file => tempfile} }
202
+
203
+ it "should not print to stdout when --output-file is set" do
204
+ fields = [name]
205
+
206
+ proc { adapter.print_collection(fields, data) }.must_output("")
207
+ end
208
+
209
+ it "should print to file if --output-file is set" do
210
+ fields = [name]
211
+ expected_output = [
212
+ "Name: John",
213
+ "\n"
214
+ ].join("\n")
215
+
216
+ adapter.print_collection(fields, data)
217
+ tempfile.close
218
+ IO.read(tempfile.path).must_equal(expected_output)
219
+ end
220
+
221
+ end
222
+
198
223
  end
199
224
 
200
225
  end
@@ -203,6 +203,30 @@ describe HammerCLI::Output::Adapter::CSValues do
203
203
  out.must_match(/.*NIL.*/)
204
204
  end
205
205
  end
206
+
207
+ context "output_stream" do
208
+
209
+ let(:tempfile) { Tempfile.new("output_stream_csv_test_temp") }
210
+ let(:context) { {:output_file => tempfile} }
211
+ let(:adapter) { HammerCLI::Output::Adapter::CSValues.new(context, HammerCLI::Output::Output.formatters) }
212
+
213
+ it "should not print to stdout when --output-file is set" do
214
+ fields = [field_name]
215
+
216
+ proc { adapter.print_collection(fields, data) }.must_output("")
217
+ end
218
+
219
+ it "should print to file if --output-file is set" do
220
+ fields = [field_name]
221
+ expected_output = "Name\nJohn Doe\n"
222
+
223
+ adapter.print_collection(fields, data)
224
+ tempfile.close
225
+ IO.read(tempfile.path).must_equal(expected_output)
226
+ end
227
+
228
+ end
229
+
206
230
  end
207
231
 
208
232
  context "print message" do
@@ -243,6 +243,31 @@ describe HammerCLI::Output::Adapter::Json do
243
243
 
244
244
  end
245
245
 
246
+ context "output_stream" do
247
+
248
+ let(:tempfile) { Tempfile.new("output_stream_json_test_temp") }
249
+ let(:context) { {:output_file => tempfile} }
250
+
251
+ it "should not print to stdout when --output-file is set" do
252
+ fields = [name]
253
+
254
+ proc { adapter.print_collection(fields, data) }.must_output("")
255
+ end
256
+
257
+ it "should print to file if --output-file is set" do
258
+ fields = [name]
259
+ hash = [{
260
+ 'Name' => 'John'
261
+ }]
262
+ expected_output = JSON.pretty_generate(hash) + "\n"
263
+
264
+ adapter.print_collection(fields, data)
265
+ tempfile.close
266
+ IO.read(tempfile.path).must_equal(expected_output)
267
+ end
268
+
269
+ end
270
+
246
271
  end
247
272
 
248
273
  end
@@ -349,6 +349,37 @@ describe HammerCLI::Output::Adapter::Table do
349
349
  end
350
350
 
351
351
  end
352
+
353
+ context "output_stream" do
354
+
355
+ let(:tempfile) { Tempfile.new("output_stream_table_test_temp") }
356
+ let(:context) { {:output_file => tempfile} }
357
+ let(:adapter) { HammerCLI::Output::Adapter::Table.new(context, HammerCLI::Output::Output.formatters) }
358
+
359
+ it "should not print to stdout when --output-file is set" do
360
+ fields = [field_firstname]
361
+
362
+ proc { adapter.print_collection(fields, data) }.must_output("")
363
+ end
364
+
365
+ it "should print to file if --output-file is set" do
366
+ fields = [field_firstname]
367
+ expected_output = [
368
+ "---------",
369
+ "FIRSTNAME",
370
+ "---------",
371
+ "John ",
372
+ "---------",
373
+ ""
374
+ ].join("\n")
375
+
376
+ adapter.print_collection(fields, data)
377
+ tempfile.close
378
+ IO.read(tempfile.path).must_equal(expected_output)
379
+ end
380
+
381
+ end
382
+
352
383
  end
353
384
 
354
385
  end
@@ -240,6 +240,31 @@ describe HammerCLI::Output::Adapter::Yaml do
240
240
 
241
241
  end
242
242
 
243
+ context "output_stream" do
244
+
245
+ let(:tempfile) { Tempfile.new("output_stream_yaml_test_temp") }
246
+ let(:context) { {:output_file => tempfile} }
247
+
248
+ it "should not print to stdout when --output-file is set" do
249
+ fields = [name]
250
+
251
+ proc { adapter.print_collection(fields, data) }.must_output("")
252
+ end
253
+
254
+ it "should print to file if --output-file is set" do
255
+ fields = [name]
256
+ hash = [{
257
+ 'Name' => 'John'
258
+ }]
259
+ expected_output = YAML.dump(hash)
260
+
261
+ adapter.print_collection(fields, data)
262
+ tempfile.close
263
+ IO.read(tempfile.path).must_equal(expected_output)
264
+ end
265
+
266
+ end
267
+
243
268
  end
244
269
 
245
270
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hammer_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Bačovský
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-19 00:00:00.000000000 Z
12
+ date: 2018-05-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -488,7 +488,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
488
488
  version: '0'
489
489
  requirements: []
490
490
  rubyforge_project:
491
- rubygems_version: 2.6.14
491
+ rubygems_version: 2.6.14.1
492
492
  signing_key:
493
493
  specification_version: 4
494
494
  summary: Universal command-line interface