wavefront-cli 2.18.0 → 3.0.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +4 -5
  5. data/HISTORY.md +20 -1
  6. data/README.md +79 -29
  7. data/lib/wavefront-cli/base.rb +26 -2
  8. data/lib/wavefront-cli/commands/alert.rb +10 -10
  9. data/lib/wavefront-cli/commands/base.rb +15 -2
  10. data/lib/wavefront-cli/commands/cloudintegration.rb +3 -3
  11. data/lib/wavefront-cli/commands/config.rb +2 -1
  12. data/lib/wavefront-cli/commands/dashboard.rb +8 -6
  13. data/lib/wavefront-cli/commands/derivedmetric.rb +5 -5
  14. data/lib/wavefront-cli/commands/event.rb +3 -3
  15. data/lib/wavefront-cli/commands/integration.rb +5 -5
  16. data/lib/wavefront-cli/commands/link.rb +3 -3
  17. data/lib/wavefront-cli/commands/message.rb +2 -2
  18. data/lib/wavefront-cli/commands/metric.rb +1 -1
  19. data/lib/wavefront-cli/commands/notificant.rb +3 -3
  20. data/lib/wavefront-cli/commands/proxy.rb +3 -3
  21. data/lib/wavefront-cli/commands/query.rb +3 -3
  22. data/lib/wavefront-cli/commands/savedsearch.rb +3 -3
  23. data/lib/wavefront-cli/commands/settings.rb +22 -0
  24. data/lib/wavefront-cli/commands/source.rb +3 -3
  25. data/lib/wavefront-cli/commands/user.rb +4 -4
  26. data/lib/wavefront-cli/commands/usergroup.rb +5 -8
  27. data/lib/wavefront-cli/commands/webhook.rb +3 -3
  28. data/lib/wavefront-cli/commands/window.rb +3 -3
  29. data/lib/wavefront-cli/commands/write.rb +6 -4
  30. data/lib/wavefront-cli/config.rb +14 -0
  31. data/lib/wavefront-cli/controller.rb +2 -0
  32. data/lib/wavefront-cli/dashboard.rb +133 -14
  33. data/lib/wavefront-cli/display/base.rb +28 -7
  34. data/lib/wavefront-cli/display/dashboard.rb +32 -8
  35. data/lib/wavefront-cli/display/distribution.rb +4 -1
  36. data/lib/wavefront-cli/display/printer/long.rb +149 -140
  37. data/lib/wavefront-cli/display/printer/terse.rb +19 -42
  38. data/lib/wavefront-cli/display/query.rb +6 -0
  39. data/lib/wavefront-cli/display/settings.rb +21 -0
  40. data/lib/wavefront-cli/display/write.rb +12 -5
  41. data/lib/wavefront-cli/event.rb +1 -1
  42. data/lib/wavefront-cli/exception.rb +1 -0
  43. data/lib/wavefront-cli/settings.rb +37 -0
  44. data/lib/wavefront-cli/stdlib/array.rb +20 -0
  45. data/lib/wavefront-cli/stdlib/string.rb +8 -0
  46. data/lib/wavefront-cli/user.rb +1 -1
  47. data/lib/wavefront-cli/version.rb +1 -1
  48. data/lib/wavefront-cli/write.rb +310 -10
  49. data/spec/.rubocop.yml +3 -0
  50. data/spec/spec_helper.rb +81 -1
  51. data/spec/wavefront-cli/alert_spec.rb +1 -0
  52. data/spec/wavefront-cli/cloudintegration_spec.rb +1 -0
  53. data/spec/wavefront-cli/dashboard_spec.rb +47 -4
  54. data/spec/wavefront-cli/derivedmetric_spec.rb +1 -0
  55. data/spec/wavefront-cli/display/base_spec.rb +16 -9
  56. data/spec/wavefront-cli/display/printer/long_spec.rb +75 -106
  57. data/spec/wavefront-cli/display/printer/terse_spec.rb +33 -21
  58. data/spec/wavefront-cli/event_spec.rb +1 -0
  59. data/spec/wavefront-cli/externallink_spec.rb +1 -0
  60. data/spec/wavefront-cli/integration_spec.rb +1 -0
  61. data/spec/wavefront-cli/maintenancewindow_spec.rb +1 -0
  62. data/spec/wavefront-cli/proxy_spec.rb +2 -0
  63. data/spec/wavefront-cli/query_spec.rb +9 -0
  64. data/spec/wavefront-cli/resources/display/alert-human-long +24 -0
  65. data/spec/wavefront-cli/resources/display/alert-input.json +37 -0
  66. data/spec/wavefront-cli/resources/display/alerts-human-terse +9 -0
  67. data/spec/wavefront-cli/resources/display/alerts-input.json +1 -0
  68. data/spec/wavefront-cli/resources/display/user-human-long +19 -0
  69. data/spec/wavefront-cli/resources/display/user-human-long-no_sep +18 -0
  70. data/spec/wavefront-cli/resources/display/user-input.json +1 -0
  71. data/spec/wavefront-cli/resources/responses/README.md +2 -0
  72. data/spec/wavefront-cli/resources/responses/alert-list.json +1 -0
  73. data/spec/wavefront-cli/resources/responses/backups.json +1 -0
  74. data/spec/wavefront-cli/resources/responses/cloudintegration-list.json +1 -0
  75. data/spec/wavefront-cli/resources/responses/dashboard-list.json +1 -0
  76. data/spec/wavefront-cli/resources/responses/derivedmetric-list.json +1 -0
  77. data/spec/wavefront-cli/resources/responses/event-list.json +1 -0
  78. data/spec/wavefront-cli/resources/responses/integration-list.json +1 -0
  79. data/spec/wavefront-cli/resources/responses/link-list.json +1 -0
  80. data/spec/wavefront-cli/resources/responses/notificant-list.json +1 -0
  81. data/spec/wavefront-cli/resources/responses/proxy-list.json +1 -0
  82. data/spec/wavefront-cli/resources/responses/query-cpu.json +1 -0
  83. data/spec/wavefront-cli/resources/responses/savedsearch-list.json +1 -0
  84. data/spec/wavefront-cli/resources/responses/user-list.json +1 -0
  85. data/spec/wavefront-cli/resources/responses/usergroup-list.json +1 -0
  86. data/spec/wavefront-cli/resources/responses/webhook-list.json +1 -0
  87. data/spec/wavefront-cli/resources/responses/window-list.json +1 -0
  88. data/spec/wavefront-cli/savedsearch_spec.rb +1 -0
  89. data/spec/wavefront-cli/settings_spec.rb +19 -0
  90. data/spec/wavefront-cli/stdlib/array_spec.rb +20 -0
  91. data/spec/wavefront-cli/stdlib/string_spec.rb +13 -1
  92. data/spec/wavefront-cli/user_spec.rb +1 -0
  93. data/spec/wavefront-cli/usergroup_spec.rb +1 -0
  94. data/spec/wavefront-cli/webhook_spec.rb +1 -0
  95. data/spec/wavefront-cli/write_spec.rb +167 -0
  96. data/wavefront-cli.gemspec +3 -4
  97. metadata +65 -31
  98. data/.gitlab-ci.yml +0 -16
  99. data/lib/wavefront-cli/base_write.rb +0 -298
  100. data/lib/wavefront-cli/commands/report.rb +0 -37
  101. data/lib/wavefront-cli/display/printer/base.rb +0 -24
  102. data/lib/wavefront-cli/display/report.rb +0 -17
  103. data/lib/wavefront-cli/report.rb +0 -18
  104. data/spec/wavefront-cli/display/printer/base_spec.rb +0 -20
@@ -29,7 +29,7 @@ module WavefrontDisplay
29
29
  raw_response
30
30
  end
31
31
 
32
- @data = data.is_a?(Map) ? Map(put_id_first(data)) : data
32
+ @data = prioritize_keys(data, priority_keys)
33
33
  @options = options
34
34
  end
35
35
 
@@ -95,10 +95,31 @@ module WavefrontDisplay
95
95
  exit 1
96
96
  end
97
97
 
98
- # If the data contains an 'id' key, move it to the start.
98
+ # Keys which we wish to float to the top of descriptions and
99
+ # long listing objects. Subclasses may define their own.
99
100
  #
100
- def put_id_first(data)
101
- data.key?(:id) ? { id: data[:id] }.merge(data) : data
101
+ def priority_keys
102
+ %i[id name]
103
+ end
104
+
105
+ def prioritize_keys(data, keys)
106
+ return _prioritize_keys(data, keys) unless data.is_a?(Array)
107
+ data.map { |e| _prioritize_keys(e, keys) }
108
+ end
109
+
110
+ # Move the given fields to the start of a Hash or Map
111
+ # @param data [Hash, Map]
112
+ # @param keys [Array[Symbol]] keys to float
113
+ # @return [Hash, Map]
114
+ #
115
+ def _prioritize_keys(data, keys)
116
+ keys.each.with_object(data.is_a?(Map) ? Map.new : {}) do |k, a|
117
+ next unless data.key?(k)
118
+ a[k] = data[k]
119
+ data.delete(k)
120
+ end.merge(data)
121
+ rescue NoMethodError
122
+ data
102
123
  end
103
124
 
104
125
  # Default display method for 'describe' and long-list methods.
@@ -112,7 +133,7 @@ module WavefrontDisplay
112
133
  # modified_data means that any fields parameter is ignored.
113
134
  #
114
135
  def long_output(fields = nil, modified_data = nil)
115
- if data.empty? || (modified_data && modified_data.empty?)
136
+ if data.empty? || modified_data&.empty?
116
137
  puts 'No data.'
117
138
  else
118
139
  require_relative 'printer/long'
@@ -123,7 +144,7 @@ module WavefrontDisplay
123
144
 
124
145
  def multicolumn(*columns)
125
146
  require_relative 'printer/terse'
126
- puts WavefrontDisplayPrinter::Terse.new(data, *columns)
147
+ puts WavefrontDisplayPrinter::Terse.new(data, columns)
127
148
  pagination_line
128
149
  end
129
150
 
@@ -133,7 +154,7 @@ module WavefrontDisplay
133
154
  def pagination_line
134
155
  return unless raw.respond_to?(:moreItems) && raw.moreItems == true
135
156
 
136
- enditem = raw.limit > 0 ? raw.offset + raw.limit - 1 : 0
157
+ enditem = raw.limit.positive? ? raw.offset + raw.limit - 1 : 0
137
158
  puts format('List shows items %d to %d. Use -o and -L for more.',
138
159
  raw.offset, enditem)
139
160
  rescue StandardError
@@ -6,14 +6,12 @@ module WavefrontDisplay
6
6
  #
7
7
  class Dashboard < Base
8
8
  def do_list
9
- long_output %i[id minutes target status tags hostsUsed
10
- condition displayExpression severity
11
- additionalInformation]
9
+ long_output
12
10
  end
13
11
 
14
12
  def do_describe
15
13
  drop_fields(:parameterDetails)
16
- readable_time(:updatedEpochMillis)
14
+ readable_time(:createdEpochMillis, :updatedEpochMillis)
17
15
  data[:sections] = data[:sections].map { |s| s[:name] }
18
16
  long_output
19
17
  end
@@ -27,12 +25,38 @@ module WavefrontDisplay
27
25
  end
28
26
  end
29
27
 
30
- def do_fav
31
- puts "Added #{options[:'<id>']} to favourites."
28
+ def do_favs
29
+ if data.empty?
30
+ puts 'No favourites.'
31
+ else
32
+ multicolumn(:id)
33
+ end
34
+ end
35
+
36
+ alias do_fav do_favs
37
+ alias do_unfav do_favs
38
+
39
+ def do_acls
40
+ data.each do |dash|
41
+ display_acl('view and modify', dash[:modifyAcl])
42
+ display_acl('view', dash[:viewAcl])
43
+ end
32
44
  end
33
45
 
34
- def do_unfav
35
- puts "Removed #{options[:'<id>']} from favourites."
46
+ alias do_acl_grant do_acls
47
+ alias do_acl_revoke do_acls
48
+ alias do_acl_clear do_acls
49
+
50
+ private
51
+
52
+ def display_acl(title, acl_data)
53
+ puts title
54
+
55
+ if acl_data.empty?
56
+ puts ' <none>'
57
+ else
58
+ acl_data.each { |e| puts format(' %<name>s (%<id>s)', e) }
59
+ end
36
60
  end
37
61
  end
38
62
  end
@@ -6,7 +6,10 @@ module WavefrontDisplay
6
6
  class Distribution < Write
7
7
  # rubocop:disable Metrics/AbcSize
8
8
  def do_distribution
9
- report unless options[:quiet] || (data[:unsent] + data[:rejected] > 0)
9
+ unless options[:quiet] || (data[:unsent] + data[:rejected].positive?)
10
+ report
11
+ end
12
+
10
13
  exit(data.rejected.zero? && data.unsent.zero? ? 0 : 1)
11
14
  end
12
15
  # rubocop:enable Metrics/AbcSize
@@ -1,58 +1,45 @@
1
- require_relative 'base'
2
- require_relative '../../stdlib/string'
3
-
4
1
  module WavefrontDisplayPrinter
5
2
  #
6
3
  # Print the long indented descriptions of things
7
4
  #
8
- class Long < Base
9
- attr_reader :indent, :indent_str, :indent_step, :kw, :hide_blank
10
-
11
- def initialize(data, fields = nil, modified_data = nil)
12
- @out = []
13
- @indent = 0
14
- @indent_step = 2
15
- @hide_blank = true
16
- _two_columns(modified_data || data, nil, fields)
5
+ class Long
6
+ attr_reader :opts, :list, :kw
7
+ #
8
+ # @param data [Hash] of data to display
9
+ # @param fields [Array[Symbol]] requred fields
10
+ # @param modified_data [Hash] an override for @data
11
+ # @param options [Hash] keys can be
12
+ # indent: [Integer] by how many spaces nested objects should indent
13
+ # padding: [Integer] number of spaces between columns
14
+ # separator: [Bool] whether or not to print a line of dashes
15
+ # between objects in an array of objects
16
+ # none [Bool] whether or not to put '<none>' for empty arrays
17
+ #
18
+ def initialize(data, fields = nil, modified_data = nil, options = {})
19
+ @opts = default_opts.merge(options)
20
+ data = preened_data(data, fields)
21
+ @list = make_list(modified_data || data)
22
+ @kw = longest_key_col(list)
17
23
  end
18
24
 
19
- # A recursive function which displays a key-value hash in two
20
- # columns. The key column width is automatically calculated.
21
- # Multiple-value 'v's are printed one per line. Hashes are nested.
22
- #
23
- # @param data [Array] and array of objects to display. Each object
24
- # should be a hash.
25
- # @param indent [Integer] how many characters to indent the current
26
- # data.
27
- # @kw [Integer] the width of the first (key) column.
28
- # @returns [Nil]
25
+ # Default options. Can all be overridden by passing them in the
26
+ # initializer options hash.
29
27
  #
30
- # rubocop:disable Metrics/AbcSize
31
- def _two_columns(data, key_col_width = nil, fields = nil)
32
- [data].flatten.each do |item|
33
- preen_fields(item, fields)
34
- key_col_width ||= key_width(item)
35
- @kw ||= key_col_width
36
- mk_indent(indent)
37
- item.each { |k, v| parse_line(k, v) }
38
- add_line(nil) if indent.zero?
39
- end
40
-
41
- @indent -= indent_step if indent > 0
42
- @kw += 2
43
- mk_indent(indent)
28
+ def default_opts
29
+ { indent: 2,
30
+ padding: 2,
31
+ separator: true,
32
+ none: true }
44
33
  end
45
- # rubocop:enable Metrics/AbcSize
46
34
 
47
- # Drop any fields not required.
48
- #
49
- # @param item [Hash, Map] the raw data
50
- # @param fields [Array[Symbol]] the fields we wish to keep
51
- # @return [Hash, Map]
35
+ # @param data [Hash] raw data
36
+ # @param fields [Array, Nil] fields to keep in @data. Nil means
37
+ # everything
38
+ # @return [Hash]
52
39
  #
53
- def preen_fields(item, fields = nil)
54
- return item unless fields
55
- item.keep_if { |k, _v| fields.include?(k.to_sym) }
40
+ def preened_data(data, fields = nil)
41
+ return data if fields.nil?
42
+ data.map { |d| d.select { |k| fields.include?(k.to_sym) }.to_h }
56
43
  end
57
44
 
58
45
  # Remove HTML and stuff
@@ -60,131 +47,153 @@ module WavefrontDisplayPrinter
60
47
  # @param [String] raw value
61
48
  # @return [String] value with all HTML stripped out
62
49
  #
63
- def preen_value(value)
50
+ def preened_value(value)
64
51
  return value unless value.is_a?(String) && value =~ /<.*>/
65
52
  value.gsub(%r{<\/?[^>]*>}, '').delete("\n")
66
53
  end
67
54
 
68
- # Return true if this line is blank and we don't want to print
69
- # blank lines
70
- #
71
- # @param value [Object] thing to check
72
- # @return [Boolean]
73
- #
74
- def blank?(value)
75
- value.respond_to?(:empty?) && value.empty? && hide_blank
55
+ # A recursive function which takes a structure, most likely a
56
+ # hash, and turns it into an array of arrays. This output is
57
+ # easily formatted into nicely laid-out columns by #to_s. Most of
58
+ # the parameters are used by the function itself.
59
+ # @param data [Object] the thing you wish to present
60
+ # @param aggr [Array] aggregates the output array. Don't set this
61
+ # yourself
62
+ # @param depth [Integer] how many layers of indentation are
63
+ # required. Don't set this yourself.
64
+ # @param last_key [String, Nil] a memo used for printing arrays.
65
+ # Don't set this yourself.
66
+ # @return [Array[Array]] where each sub-array is of the form
67
+ # [key, value, depth]
68
+ #
69
+ # Make an array of hashes: { key, value, depth }
70
+ #
71
+ def make_list(data, aggr = [], depth = 0, last_key = nil)
72
+ if data.is_a?(Hash)
73
+ append_hash(data, aggr, depth)
74
+ elsif data.is_a?(Array)
75
+ append_array(data, aggr, depth, last_key)
76
+ else
77
+ aggr.<< ['', preened_value(data), depth]
78
+ end
79
+ end
80
+
81
+ def smart_value(val)
82
+ val.to_s.empty? && opts[:none] ? '<none>' : preened_value(val)
76
83
  end
77
84
 
78
- # Parse a line and add it to the output or pass it on to another
79
- # method which knows how to add it to the output.
85
+ # Works out what the width of the left-hand (key) column needs to
86
+ # be. This considers indentation and padding.
87
+ # @param data [Array] of the form returned by #make_list
88
+ # @return [Integer]
80
89
  #
81
- # @param key [String] a key
82
- # @param value [Object] the value: could be anything
83
- # @return [Nil]
90
+ def longest_key_col(data)
91
+ data.map { |d| d[0].size + opts[:padding] + opts[:indent] * d[2] }.max
92
+ end
93
+
94
+ # Turn the list made by #make_list into user output
95
+ # @return [String]
84
96
  #
85
- def parse_line(key, value)
86
- return if blank?(value)
97
+ # rubocop:disable Metrics/AbcSize
98
+ def to_s
99
+ list.map do |e|
100
+ indent = ' ' * opts[:indent] * e.last
101
+ key_str = (indent + e.first.to_s + ' ' * kw)[0..kw]
102
+ val = e[1] == :separator ? '-' * (TW - key_str.length) : e[1]
103
+ line(key_str, val)
104
+ end.join("\n")
105
+ end
106
+ # rubocop:enable Metrics/AbcSize
87
107
 
88
- value = preen_value(value)
108
+ def line(key, val)
109
+ line_length = key.to_s.size + val.to_s.size
89
110
 
90
- if value.is_a?(Hash)
91
- add_hash(key, value)
92
- elsif value.is_a?(Array)
93
- add_array(key, value)
94
- else
95
- add_line(key, value)
111
+ if line_length > TW && val.is_a?(String)
112
+ val = val.value_fold(key.to_s.size)
96
113
  end
114
+
115
+ format('%s%s', key, val).rstrip
97
116
  end
98
117
 
99
- # Add a key-value pair to the output when value is an array. It
100
- # will put the key and the first value element on the first
101
- # line, with subsequent value elements aligned at the same
102
- # offset, but with no key. If any value element is a hash, it is
103
- # handled by a separate method. For instance:
104
- #
105
- # key value1
106
- # value2
107
- # value3
118
+ private
119
+
120
+ # Part of the #make_list recursion. Deals with a hash.
108
121
  #
109
- # @param key [String] the key
110
- # @param value_arr [Array] an array of values
111
- # @return [Nil]
122
+ # @param data [Hash]
123
+ # @param aggr [Array[Array]]
124
+ # @param depth [Integer]
125
+ # @return [Array[Array]]
112
126
  #
113
- def add_array(key, value_arr)
114
- value_arr.each_with_index do |element, index|
115
- if element.is_a?(Hash)
116
- add_hash(key, element, value_arr.size, index)
127
+ def append_hash(data, aggr, depth)
128
+ data.each_pair do |k, v|
129
+ if v.is_a?(Hash)
130
+ aggr = append_hash_values(k, v, aggr, depth)
131
+ elsif v.is_a?(Array)
132
+ aggr = append_array_values(k, v, aggr, depth)
117
133
  else
118
- add_line(index.zero? ? key : nil, element)
134
+ aggr.<< [k, smart_value(v), depth]
119
135
  end
120
136
  end
121
- end
122
-
123
- # Add a hash to the output. It will put the key on a line on its
124
- # own, followed by other keys indented. All values are aligned
125
- # to the same point. If this hash is a member of an array, we
126
- # are able to print a horizontal rule at the end of it. We don't
127
- # do this if it is the final member of the array.
128
- #
129
- # For instance:
130
- #
131
- # key
132
- # subkey1 value1
133
- # subkey2 value2
134
- #
135
- # @param key [String] the key
136
- # @param value [Hash] hash of values to display
137
- # @param size [Integer] the size of the parent array, if there
138
- # is one
139
- # @param index [Integer] the index of this element in parent
140
- # array, if there is one.
141
- # @return [Nil]
142
- #
143
- def add_hash(key, value, arr_size = 0, arr_index = 0)
144
- add_line(key) if arr_index.zero?
145
- @indent += indent_step
146
- @kw -= 2
147
- _two_columns([value], kw - indent_step)
148
- add_rule(kw) if arr_index + 1 < arr_size
149
- end
150
137
 
151
- # Add a horizontal rule, from the start of the second column to
152
- # just shy of the end of the terminal
153
- #
154
- def add_rule(key_col_width)
155
- add_line(nil, '-' * (TW - key_col_width - 4))
138
+ aggr
156
139
  end
157
140
 
158
- # Make the string which is prepended to each line. Stepping is
159
- # controlled by @indent_step.
141
+ # Part of the #make_list recursion. Deals with arrays.
160
142
  #
161
- # @param indent [Integer] how many characters to indent by.
143
+ # @param data [Array]
144
+ # @param aggr [Array[Array]]
145
+ # @param depth [Integer]
146
+ # @return [Array[Array]]
162
147
  #
163
- def mk_indent(indent)
164
- @indent_str = ' ' * indent
148
+ def append_array(data, aggr, depth, last_key)
149
+ data.each.with_index(1) do |element, i|
150
+ aggr = make_list(element, aggr, depth, last_key)
151
+
152
+ if opts[:separator] && element.is_a?(Hash) && i < data.size
153
+ aggr.<< ['', :separator, depth]
154
+ end
155
+ end
156
+
157
+ aggr
165
158
  end
166
159
 
167
- # Print a single line of output, handling the necessary
168
- # indentation and tabulation.
160
+ # Part of the #make_list recursion. Appends the key name of a
161
+ # hash. May be paired with '<none>' if the hash is empty,
162
+ # otherwise indent another level and go back into the recursive
163
+ # loop with the values.
169
164
  #
170
- # @param key [String] what to print in the first (key) column.
171
- # Make this an empty string to print
172
- # @param val [String, Numeric] what to print in the second column
173
- # @param tw [Integer] terminal width
165
+ # @param key [String] key of hash
166
+ # @param values [Hash] values of hash
167
+ # @param depth [Integer]
168
+ # @return [Array[Array]]
174
169
  #
175
- # rubocop:disable Metrics/AbcSize
176
- def mk_line(key, value = '', term_width = TW)
177
- return indent_str + ' ' * kw + value if !key || key.empty?
178
-
179
- indent_str + format("%-#{kw}s%s", key, value)
180
- .fold(term_width, kw + indent_str.size, '').rstrip
170
+ def append_hash_values(key, values, aggr, depth)
171
+ if values.empty? && opts[:none]
172
+ aggr.<< [key, '<none>', depth]
173
+ else
174
+ aggr.<< [key, nil, depth]
175
+ make_list(values, aggr, depth + 1)
176
+ end
181
177
  end
182
- # rubocop:enable Metrics/AbcSize
183
178
 
184
- # Add a line, prepped by #mk_line() to the out array.
179
+ # Part of the #make_list recursion.
180
+ #
181
+ # @param data [Hash]
182
+ # @param aggr [Array[Array]]
183
+ # @param depth [Integer]
184
+ # @return [Array[Array]]
185
185
  #
186
- def add_line(*args)
187
- @out.<< mk_line(*args)
186
+ def append_array_values(key, values, aggr, depth)
187
+ if values.empty? && opts[:none]
188
+ aggr.<< [key, '<none>', depth]
189
+ elsif values.all? { |w| w.is_a?(String) }
190
+ values.sort!
191
+ aggr.<< [key, preened_value(values.shift), depth]
192
+ make_list(values, aggr, depth, key)
193
+ else
194
+ aggr.<< [key, nil, depth]
195
+ make_list(values, aggr, depth + 1, key)
196
+ end
188
197
  end
189
198
  end
190
199
  end