hammer_cli 0.13.1 → 0.14.0

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