hammer_cli 0.13.1 → 0.14.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes.md +5 -2
  3. data/lib/hammer_cli/options/normalizers.rb +2 -2
  4. data/lib/hammer_cli/output/adapter/abstract.rb +15 -3
  5. data/lib/hammer_cli/output/adapter/base.rb +2 -8
  6. data/lib/hammer_cli/output/adapter/csv.rb +1 -0
  7. data/lib/hammer_cli/output/adapter/table.rb +2 -1
  8. data/lib/hammer_cli/output/adapter/tree_structure.rb +3 -9
  9. data/lib/hammer_cli/output/fields.rb +12 -6
  10. data/lib/hammer_cli/output/output.rb +6 -0
  11. data/lib/hammer_cli/testing/command_assertions.rb +7 -0
  12. data/lib/hammer_cli/version.rb +1 -1
  13. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  14. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  15. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  16. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  17. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  18. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  19. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  20. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  21. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  22. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  23. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  24. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  25. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  26. data/test/unit/output/adapter/abstract_test.rb +2 -2
  27. data/test/unit/output/adapter/base_test.rb +21 -0
  28. data/test/unit/output/adapter/csv_test.rb +16 -0
  29. data/test/unit/output/adapter/json_test.rb +18 -0
  30. data/test/unit/output/adapter/table_test.rb +31 -1
  31. data/test/unit/output/adapter/yaml_test.rb +18 -0
  32. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e73236442681ea0de600a7331e2d07f94c672269
4
- data.tar.gz: 212fc6f1528868af2162ddacaa47cf1a0e0d57a2
3
+ metadata.gz: fb545eaee547129bde4d51c6ff709f7af30c61bd
4
+ data.tar.gz: 23f8915e5e2c306a2e194ebd7d42162d2f183b95
5
5
  SHA512:
6
- metadata.gz: 6640289dfa481f0bd1061cf14be8a345277887b991476b07177ed8ebe7ebc59811edd45304ebe9e9def94c1c1ace7324bbb2e025ff07b11fc42d6095b00d591f
7
- data.tar.gz: fcbb4cb0d83bdb7d77ef995843c5a83de6bb9f4da34424157ee94ddb5807d0c335832ad5fa2f36d04b522004b143d03a0aaf5e5a4f9497223e0bf1aa8ec77c05
6
+ metadata.gz: 3c9f22f4c7b10e0282f96be42317f0ac2514dba8ad4c2881d46eedeb6ceb01361ba6139c57b51ab382ac255d6a5bc527bde0880ee06d332dc938b7f08317ce4d
7
+ data.tar.gz: cba3583a4dff8bf01a9bf1835eb9393ea99eae965e3156a9bb14dafbb8412e49bd59f2b13b717a24453080ff3faeb2c8151f79a4c91e14f1124e9a0b92c1601d
data/doc/release_notes.md CHANGED
@@ -1,7 +1,10 @@
1
1
  Release notes
2
2
  =============
3
- ### 0.13.1 (2018-08-15)
4
- * restore help building ([PR #280](https://github.com/theforeman/hammer-cli/pull/280)) ([#24488](http://projects.theforeman.org/issues/24488))
3
+ ### 0.14.0 (2018-08-27)
4
+ * Restore help building ([PR #280](https://github.com/theforeman/hammer-cli/pull/280)) ([#24488](http://projects.theforeman.org/issues/24488))
5
+ * Shouldn't translate the bool values in description ([#21381](http://projects.theforeman.org/issues/21381))
6
+ * Allow hiding fields which are missing from api output ([#20607](http://projects.theforeman.org/issues/20607))
7
+ * Add not found error type ([PR #274](https://github.com/theforeman/hammer-cli/pull/274)) ([#20538](http://projects.theforeman.org/issues/20538))
5
8
 
6
9
  ### 0.13.0 (2018-05-09)
7
10
  * Hammer CSV output saved as a file ([PR #254](https://github.com/theforeman/hammer-cli/pull/254)) ([#11586](http://projects.theforeman.org/issues/11586))
@@ -115,7 +115,7 @@ module HammerCLI
115
115
  class Bool < AbstractNormalizer
116
116
 
117
117
  def description
118
- _("One of true/false, yes/no, 1/0")
118
+ _('One of %s.') % ['true/false', 'yes/no', '1/0'].join(', ')
119
119
  end
120
120
 
121
121
  def format(bool)
@@ -125,7 +125,7 @@ module HammerCLI
125
125
  elsif bool.downcase.match(/^(false|f|no|n|0)$/i)
126
126
  return false
127
127
  else
128
- raise ArgumentError, _("Value must be one of true/false, yes/no, 1/0.")
128
+ raise ArgumentError, _('Value must be one of %s.') % ['true/false', 'yes/no', '1/0'].join(', ')
129
129
  end
130
130
  end
131
131
 
@@ -50,12 +50,13 @@ module HammerCLI::Output::Adapter
50
50
  path = field.path
51
51
 
52
52
  path.inject(record) do |record, path_key|
53
- if record && record.kind_of?(Hash) && record.has_key?(path_key.to_sym)
53
+ return nil unless record && record.is_a?(Hash)
54
+ if record.key?(path_key.to_sym)
54
55
  record[path_key.to_sym]
55
- elsif record && record.kind_of?(Hash) && record.has_key?(path_key.to_s)
56
+ elsif record.key?(path_key.to_s)
56
57
  record[path_key.to_s]
57
58
  else
58
- return nil
59
+ HammerCLI::Output::DataMissing.new
59
60
  end
60
61
  end
61
62
  end
@@ -69,6 +70,17 @@ module HammerCLI::Output::Adapter
69
70
  $stdout
70
71
  end
71
72
 
73
+ def displayable_fields(fields, record, compact_only: false)
74
+ fields.select do |field|
75
+ field_data = data_for_field(field, record)
76
+ if compact_only && !field_data.is_a?(HammerCLI::Output::DataMissing)
77
+ true
78
+ else
79
+ field.display?(field_data)
80
+ end
81
+ end
82
+ end
83
+
72
84
  private
73
85
 
74
86
  def filter_formatters(formatters_map)
@@ -27,17 +27,11 @@ module HammerCLI::Output::Adapter
27
27
  HammerCLI::Output::FieldFilter.new(filtered)
28
28
  end
29
29
 
30
- def filter_fields(fields, data)
31
- field_filter.filter(fields).reject do |field|
32
- field_data = data_for_field(field, data)
33
- not field.display?(field_data)
34
- end
35
- end
36
-
37
30
  def render_fields(fields, data)
38
31
  output = ""
39
32
 
40
- fields = filter_fields(fields, data)
33
+ fields = field_filter.filter(fields)
34
+ fields = displayable_fields(fields, data)
41
35
 
42
36
  label_width = label_width(fields)
43
37
 
@@ -157,6 +157,7 @@ module HammerCLI::Output::Adapter
157
157
  end
158
158
 
159
159
  def print_collection(fields, collection)
160
+ fields = displayable_fields(fields, collection.first, compact_only: true)
160
161
  rows = row_data(fields, collection)
161
162
  # get headers using columns heuristic
162
163
  headers = rows.map{ |r| Cell.headers(r, @context) }.max_by{ |headers| headers.size }
@@ -22,6 +22,7 @@ module HammerCLI::Output::Adapter
22
22
 
23
23
  def print_collection(all_fields, collection)
24
24
  fields = field_filter.filter(all_fields)
25
+ fields = displayable_fields(fields, collection.first, compact_only: true)
25
26
 
26
27
  formatted_collection = format_values(fields, collection)
27
28
  # calculate hash of column widths (label -> width)
@@ -52,7 +53,7 @@ module HammerCLI::Output::Adapter
52
53
  # and there is no --no-headers option
53
54
  output_stream.puts line unless formatted_collection.empty? || @context[:no_headers]
54
55
 
55
- if collection.meta.pagination_set? && collection.count < collection.meta.subtotal
56
+ if collection.respond_to?(:meta) && collection.meta.pagination_set? && collection.count < collection.meta.subtotal
56
57
  pages = (collection.meta.subtotal.to_f/collection.meta.per_page).ceil
57
58
  puts _("Page %{page} of %{total} (use --page and --per-page for navigation).") % {:page => collection.meta.page, :total => pages}
58
59
  end
@@ -13,22 +13,16 @@ module HammerCLI::Output::Adapter
13
13
  end
14
14
 
15
15
  protected
16
+
16
17
  def field_filter
17
18
  filtered = []
18
19
  filtered << Fields::Id unless @context[:show_ids]
19
20
  HammerCLI::Output::FieldFilter.new(filtered)
20
21
  end
21
22
 
22
- def filter_fields(fields, data)
23
- field_filter.filter(fields).reject do |field|
24
- field_data = data_for_field(field, data)
25
- not field.display?(field_data)
26
- end
27
- end
28
-
29
23
  def render_fields(fields, data)
30
- fields = filter_fields(fields, data)
31
-
24
+ fields = field_filter.filter(fields)
25
+ fields = displayable_fields(fields, data)
32
26
  fields.reduce({}) do |hash, field|
33
27
  field_data = data_for_field(field, data)
34
28
  next unless field.display?(field_data)
@@ -9,6 +9,7 @@ module Fields
9
9
 
10
10
  def initialize(options={})
11
11
  @hide_blank = options[:hide_blank].nil? ? false : options[:hide_blank]
12
+ @hide_missing = options[:hide_missing].nil? ? true : options[:hide_missing]
12
13
  @path = options[:path] || []
13
14
  @label = options[:label]
14
15
  @options = options
@@ -18,11 +19,15 @@ module Fields
18
19
  @hide_blank
19
20
  end
20
21
 
22
+ def hide_missing?
23
+ @hide_missing
24
+ end
25
+
21
26
  def display?(value)
22
- if not hide_blank?
23
- true
27
+ if value.is_a?(HammerCLI::Output::DataMissing)
28
+ !hide_missing?
24
29
  elsif value.nil?
25
- false
30
+ !hide_blank?
26
31
  else
27
32
  true
28
33
  end
@@ -55,10 +60,10 @@ module Fields
55
60
  end
56
61
 
57
62
  def display?(value)
58
- if not hide_blank?
59
- true
63
+ if value.is_a?(HammerCLI::Output::DataMissing)
64
+ !hide_missing?
60
65
  elsif value.nil? || value.empty?
61
- false
66
+ !hide_blank?
62
67
  else
63
68
  true
64
69
  end
@@ -83,6 +88,7 @@ module Fields
83
88
  class Label < ContainerField
84
89
 
85
90
  def display?(value)
91
+ return false if value.is_a?(HammerCLI::Output::DataMissing) && hide_missing?
86
92
  return true if not hide_blank?
87
93
 
88
94
  !(value.nil? || value.empty?) && fields.any? do |f|
@@ -1,4 +1,10 @@
1
1
  module HammerCLI::Output
2
+ class DataMissing
3
+ def to_s
4
+ ''
5
+ end
6
+ end
7
+
2
8
  class Output
3
9
 
4
10
  def initialize(context={}, options={})
@@ -108,6 +108,13 @@ module HammerCLI
108
108
  expected_result
109
109
  end
110
110
 
111
+ def not_found_error_result(command, message, heading=nil)
112
+ expected_result = CommandExpectation.new
113
+ expected_result.expected_err = common_error(command, message, heading)
114
+ expected_result.expected_exit_code = HammerCLI::EX_NOT_FOUND
115
+ expected_result
116
+ end
117
+
111
118
  def success_result(message)
112
119
  CommandExpectation.new(message)
113
120
  end
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.13.1'
3
+ @version ||= Gem::Version.new '0.14.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
@@ -110,9 +110,9 @@ describe HammerCLI::Output::Adapter::Abstract do
110
110
  assert_nil adapter.send(:data_for_field, field, record)
111
111
  end
112
112
 
113
- it "returns nil, if the data does not exist for the field" do
113
+ it "returns DataMissing instance, if the data does not exist for the field" do
114
114
  record = { :field2 => :value2 }
115
- assert_nil adapter.send(:data_for_field, field, record)
115
+ assert_instance_of HammerCLI::Output::DataMissing, adapter.send(:data_for_field, field, record)
116
116
  end
117
117
 
118
118
  it "returns the value, if data exists for the field" do
@@ -26,6 +26,8 @@ describe HammerCLI::Output::Adapter::Base do
26
26
  let(:params_collection) { Fields::Collection.new(:path => [:params], :label => "Parameters") }
27
27
  let(:param) { Fields::KeyValue.new(:path => nil, :label => nil) }
28
28
  let(:blank) { Fields::Field.new(:path => [:blank], :label => "Blank", :hide_blank => true) }
29
+ let(:login) { Fields::Field.new(:path => [:login], :label => "Login") }
30
+ let(:missing) { Fields::Field.new(:path => [:login], :label => "Missing", :hide_missing => false) }
29
31
 
30
32
  let(:data) { HammerCLI::Output::RecordCollection.new [{
31
33
  :id => 112,
@@ -164,6 +166,25 @@ describe HammerCLI::Output::Adapter::Base do
164
166
  proc { adapter.print_collection(fields, data) }.must_output(expected_output)
165
167
  end
166
168
 
169
+ it "does not print fields which data are missing from api by default" do
170
+ fields = [name, login]
171
+ expected_output = [
172
+ "Name: John",
173
+ "\n"
174
+ ].join("\n")
175
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
176
+ end
177
+
178
+ it "prints fields which data are missing from api when field has hide_missing flag set to false" do
179
+ fields = [name, missing]
180
+ expected_output = [
181
+ "Name: John",
182
+ "Missing:",
183
+ "\n"
184
+ ].join("\n")
185
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
186
+ end
187
+
167
188
  it "should print key -> value" do
168
189
  params_collection.output_definition.append [param]
169
190
  fields = [params_collection]
@@ -12,6 +12,8 @@ describe HammerCLI::Output::Adapter::CSValues do
12
12
 
13
13
  let(:field_name) { Fields::Field.new(:path => [:name], :label => "Name") }
14
14
  let(:field_started_at) { Fields::Field.new(:path => [:started_at], :label => "Started At") }
15
+ let(:field_login) { Fields::Field.new(:path => [:login], :label => "Login") }
16
+ let(:field_missing) { Fields::Field.new(:path => [:missing], :label => "Missing", :hide_missing => false) }
15
17
  let(:fields) {
16
18
  [field_name, field_started_at]
17
19
  }
@@ -32,6 +34,20 @@ describe HammerCLI::Output::Adapter::CSValues do
32
34
  err.must_match //
33
35
  end
34
36
 
37
+ it "does not print fields which data are missing from api by default" do
38
+ fields << field_login
39
+ out, err = capture_io { adapter.print_collection(fields, data) }
40
+ out.wont_match /.*Login.*/
41
+ err.must_match //
42
+ end
43
+
44
+ it "prints fields which data are missing from api when field has hide_missing flag set to false" do
45
+ fields << field_missing
46
+ out, err = capture_io { adapter.print_collection(fields, data) }
47
+ out.must_match /.*Missing.*/
48
+ err.must_match //
49
+ end
50
+
35
51
  context "handle ids" do
36
52
  let(:field_id) { Fields::Id.new(:path => [:some_id], :label => "Id") }
37
53
  let(:fields) {
@@ -58,6 +58,8 @@ describe HammerCLI::Output::Adapter::Json do
58
58
  let(:params_collection) { Fields::Collection.new(:path => [:params], :label => "Parameters") }
59
59
  let(:param) { Fields::KeyValue.new(:path => nil, :label => nil) }
60
60
  let(:blank) { Fields::Field.new(:path => [:blank], :label => "Blank", :hide_blank => true) }
61
+ let(:login) { Fields::Field.new(:path => [:login], :label => "Login") }
62
+ let(:missing) { Fields::Field.new(:path => [:missing], :label => "Missing", :hide_missing => false) }
61
63
 
62
64
  let(:data) { HammerCLI::Output::RecordCollection.new [{
63
65
  :id => 112,
@@ -206,6 +208,22 @@ describe HammerCLI::Output::Adapter::Json do
206
208
  proc { adapter.print_collection(fields, data) }.must_output(expected_output)
207
209
  end
208
210
 
211
+ it "does not print fields which data are missing from api by default" do
212
+ fields = [surname, login]
213
+ hash = [{ 'Surname' => 'Doe' }]
214
+ expected_output = JSON.pretty_generate(hash) + "\n"
215
+
216
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
217
+ end
218
+
219
+ it "prints fields which data are missing from api when field has hide_missing flag set to false" do
220
+ fields = [surname, missing]
221
+ hash = [{ 'Surname' => 'Doe', 'Missing' => '' }]
222
+ expected_output = JSON.pretty_generate(hash) + "\n"
223
+
224
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
225
+ end
226
+
209
227
  it "should print key -> value" do
210
228
  params_collection.output_definition.append [param]
211
229
  fields = [params_collection]
@@ -14,6 +14,8 @@ describe HammerCLI::Output::Adapter::Table do
14
14
  let(:field_firstname) { Fields::Field.new(:path => [:firstname], :label => "Firstname") }
15
15
  let(:field_lastname) { Fields::Field.new(:path => [:lastname], :label => "Lastname") }
16
16
  let(:field_long) { Fields::Field.new(:path => [:long], :label => "Full") }
17
+ let(:field_login) { Fields::Field.new(:path => [:login], :label => "Login") }
18
+ let(:field_missing) { Fields::Field.new(:path => [:missing], :label => "Missing", :hide_missing => false) }
17
19
 
18
20
  let(:fields) {
19
21
  [field_name]
@@ -45,6 +47,34 @@ describe HammerCLI::Output::Adapter::Table do
45
47
  proc { adapter.print_collection(fields, data) }.must_output(/.*John Doe.*/, "")
46
48
  end
47
49
 
50
+ it "does not print fields which data are missing from api by default" do
51
+ fields << field_login
52
+ expected_output = [
53
+ '--------',
54
+ 'NAME ',
55
+ '--------',
56
+ 'John Doe',
57
+ '--------',
58
+ ''
59
+ ].join("\n")
60
+
61
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
62
+ end
63
+
64
+ it "prints fields which data are missing from api when field has hide_missing flag set to false" do
65
+ fields << field_missing
66
+ expected_output = [
67
+ '---------|--------',
68
+ 'NAME | MISSING',
69
+ '---------|--------',
70
+ 'John Doe | ',
71
+ '---------|--------',
72
+ ''
73
+ ].join("\n")
74
+
75
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
76
+ end
77
+
48
78
  context "pagination" do
49
79
  it "should print pagination info if data are not complete" do
50
80
  data = HammerCLI::Output::RecordCollection.new([record], { :total => 2, :page => 1, :per_page => 1, :subtotal => 2 })
@@ -58,7 +88,7 @@ describe HammerCLI::Output::Adapter::Table do
58
88
  end
59
89
 
60
90
  context "handle ids" do
61
- let(:field_id) { Fields::Id.new(:path => [:some_id], :label => "Id") }
91
+ let(:field_id) { Fields::Id.new(:path => [:some_id], :label => "Id", :hide_missing => false) }
62
92
  let(:fields) {
63
93
  [field_name, field_id]
64
94
  }
@@ -56,6 +56,8 @@ describe HammerCLI::Output::Adapter::Yaml do
56
56
  let(:params_collection) { Fields::Collection.new(:path => [:params], :label => "Parameters") }
57
57
  let(:param) { Fields::KeyValue.new(:path => nil, :label => nil) }
58
58
  let(:blank) { Fields::Field.new(:path => [:blank], :label => "Blank", :hide_blank => true) }
59
+ let(:login) { Fields::Field.new(:path => [:login], :label => "Login") }
60
+ let(:missing) { Fields::Field.new(:path => [:missing], :label => "Missing", :hide_missing => false) }
59
61
 
60
62
  let(:data) { HammerCLI::Output::RecordCollection.new [{
61
63
  :id => 112,
@@ -203,6 +205,22 @@ describe HammerCLI::Output::Adapter::Yaml do
203
205
  proc { adapter.print_collection(fields, data) }.must_output(expected_output)
204
206
  end
205
207
 
208
+ it "does not print fields which data are missing from api by default" do
209
+ fields = [surname, login]
210
+ hash = [{ 'Surname' => 'Doe' }]
211
+ expected_output = YAML.dump(hash)
212
+
213
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
214
+ end
215
+
216
+ it "prints fields which data are missing from api when field has hide_missing flag set to false" do
217
+ fields = [surname, missing]
218
+ hash = [{ 'Surname' => 'Doe', 'Missing' => HammerCLI::Output::DataMissing.new }]
219
+ expected_output = YAML.dump(hash)
220
+
221
+ proc { adapter.print_collection(fields, data) }.must_output(expected_output)
222
+ end
223
+
206
224
  it "should print key -> value" do
207
225
  params_collection.output_definition.append [param]
208
226
  fields = [params_collection]
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.13.1
4
+ version: 0.14.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-08-15 00:00:00.000000000 Z
12
+ date: 2018-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp