Class: WavefrontDisplay::Base

Inherits:
Object
  • Object
show all
Includes:
WavefrontCli::Constants
Defined in:
lib/wavefront-cli/display/base.rb

Overview

Print human-friendly output. If a command requires a dedicated handler to format its output, define a method with the same name as that which fetches the data, in a WavefrontDisplay class, extending this one.

We provide #long_output() and #multicolumn() methods to solve standard formatting problems. To use them, define a do_() method but rather than printing the output, have it call the method.

Constant Summary

Constants included from WavefrontCli::Constants

WavefrontCli::Constants::DEFAULT_OPTS, WavefrontCli::Constants::HUMAN_TIME_FORMAT, WavefrontCli::Constants::HUMAN_TIME_FORMAT_MS

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, options = {}) ⇒ Base

Returns a new instance of Base.

Parameters:

  • data (Map, Hash, Array)

    the data returned by the SDK response.

  • options (Hash) (defaults to: {})

    options from docopt



23
24
25
26
# File 'lib/wavefront-cli/display/base.rb', line 23

def initialize(data, options = {})
  @data = data.is_a?(Map) ? Map(put_id_first(data)) : data
  @options = options
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



17
18
19
# File 'lib/wavefront-cli/display/base.rb', line 17

def data
  @data
end

#optionsObject (readonly)

Returns the value of attribute options.



17
18
19
# File 'lib/wavefront-cli/display/base.rb', line 17

def options
  @options
end

Instance Method Details

#do_deleteObject



147
148
149
# File 'lib/wavefront-cli/display/base.rb', line 147

def do_delete
  puts "Deleted #{friendly_name} '#{options[:'<id>']}'."
end

#do_importObject



142
143
144
145
# File 'lib/wavefront-cli/display/base.rb', line 142

def do_import
  puts "Imported #{friendly_name}."
  long_output
end

#do_listObject

The following do_ methods are default handlers called following their namesake operation in the corresponding WavefrontCli class. They can be overriden in the inheriting class.



134
135
136
# File 'lib/wavefront-cli/display/base.rb', line 134

def do_list
  long_output
end

#do_list_briefObject



138
139
140
# File 'lib/wavefront-cli/display/base.rb', line 138

def do_list_brief
  multicolumn(:id, :name)
end

#do_searchObject



167
168
169
170
171
172
173
# File 'lib/wavefront-cli/display/base.rb', line 167

def do_search
  if data.empty?
    puts 'No matches.'
  else
    long_output
  end
end

#do_search_briefObject



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/wavefront-cli/display/base.rb', line 155

def do_search_brief
  display_keys = ([:id] + options[:'<condition>'].map do |c|
    c.split(/\W/, 2).first.to_sym
  end).uniq

  if data.empty?
    puts 'No matches.'
  else
    multicolumn(*display_keys)
  end
end

#do_tag_addObject



175
176
177
# File 'lib/wavefront-cli/display/base.rb', line 175

def do_tag_add
  puts "Tagged #{friendly_name} '#{options[:'<id>']}'."
end

#do_tag_clearObject



183
184
185
# File 'lib/wavefront-cli/display/base.rb', line 183

def do_tag_clear
  puts "Cleared tags on #{friendly_name} '#{options[:'<id>']}'."
end

#do_tag_deleteObject



179
180
181
# File 'lib/wavefront-cli/display/base.rb', line 179

def do_tag_delete
  puts "Deleted tag from #{friendly_name} '#{options[:'<id>']}'."
end

#do_tag_setObject



187
188
189
# File 'lib/wavefront-cli/display/base.rb', line 187

def do_tag_set
  puts "Set tags on #{friendly_name} '#{options[:'<id>']}'."
end

#do_tagsObject



191
192
193
194
195
196
197
# File 'lib/wavefront-cli/display/base.rb', line 191

def do_tags
  if data.empty?
    puts "No tags set on #{friendly_name} '#{options[:'<id>']}'."
  else
    data.sort.each { |t| puts t }
  end
end

#do_undeleteObject



151
152
153
# File 'lib/wavefront-cli/display/base.rb', line 151

def do_undelete
  puts "Undeleted #{friendly_name} '#{options[:'<id>']}'."
end

#drop_fields(*keys) ⇒ Nil

Modify, in-place, the data structure to remove fields which we deem not of interest to the user.

Parameters:

  • keys (Symbol)

    keys you do not wish to be shown.

Returns:

  • (Nil)


205
206
207
208
209
210
211
# File 'lib/wavefront-cli/display/base.rb', line 205

def drop_fields(*keys)
  if data.is_a?(Array)
    data.each { |i| i.delete_if { |k, _v| keys.include?(k.to_sym) } }
  else
    data.delete_if { |k, _v| keys.include?(k.to_sym) }
  end
end

#friendly_nameObject

return [String] the name of the thing we’re operating on, like

'alert' or 'dashboard'.


124
125
126
127
# File 'lib/wavefront-cli/display/base.rb', line 124

def friendly_name
  self.class.name.split('::').last.gsub(/([a-z])([A-Z])/, '\\1 \\2')
      .downcase
end

#human_time(t, force_utc = false) ⇒ Object

Make a time human-readable. Automatically deals with epoch seconds and epoch milliseconds

param t [Integer, String] a timestamp. If it’s a string, it is

converted to an int.

param force_utc [Boolean] force output in UTC. Currently only

used for unit tests.

return [String] a human-readable timestamp

Raises:

  • (ArgumentError)


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/wavefront-cli/display/base.rb', line 234

def human_time(t, force_utc = false)
  raise ArgumentError unless t.is_a?(Numeric) || t.is_a?(String)
  str = t.to_s

  if str =~ /^\d{13}$/
    fmt = '%Q'
    out_fmt = HUMAN_TIME_FORMAT_MS
  elsif str =~ /^\d{10}$/
    fmt = '%s'
    out_fmt = HUMAN_TIME_FORMAT
  else
    raise ArgumentError
  end

  ret = DateTime.strptime(str, fmt).to_time
  ret = ret.utc if force_utc
  ret.strftime(out_fmt)
end

#key_width(hash = {}, pad = 2) ⇒ Integer

Give it a key-value hash, and it will return the size of the first column to use when formatting that data.

Parameters:

  • hash (Hash) (defaults to: {})

    the data for which you need a column width

  • pad (Integer) (defaults to: 2)

    the number of spaces you want between columns

Returns:

  • (Integer)

    length of longest key + pad



116
117
118
119
# File 'lib/wavefront-cli/display/base.rb', line 116

def key_width(hash = {}, pad = 2)
  return 0 if hash.keys.empty?
  hash.keys.map(&:size).max + pad
end

#long_output(fields = nil, modified_data = nil) ⇒ Object

Default display method for ‘describe’ and long-list methods. Wraps around #_two_columns() giving you the chance to modify

Parameters:

  • fields (Array[Symbol]) (defaults to: nil)

    a list of fields you wish to display. If this is nil, all fields are displayed.

  • modified_data (Hash, Array) (defaults to: nil)

    lets you modify @data in-line. If this is truthy, it is used. Passing modified_data means that any fields parameter is ignored.



95
96
97
98
99
100
101
102
# File 'lib/wavefront-cli/display/base.rb', line 95

def long_output(fields = nil, modified_data = nil)
  if data.empty? || (modified_data && modified_data.empty?)
    puts 'No data.'
  else
    require_relative 'printer/long'
    puts WavefrontDisplayPrinter::Long.new(data, fields, modified_data)
  end
end

#multicolumn(*columns) ⇒ Object



104
105
106
107
# File 'lib/wavefront-cli/display/base.rb', line 104

def multicolumn(*columns)
  require_relative 'printer/terse'
  puts WavefrontDisplayPrinter::Terse.new(data, *columns)
end

#put_id_first(data) ⇒ Object

If the data contains an ‘id’ key, move it to the start.



81
82
83
# File 'lib/wavefront-cli/display/base.rb', line 81

def put_id_first(data)
  data.key?(:id) ? { id: data[:id] }.merge(data) : data
end

#readable_time(*keys) ⇒ Object

Modify, in-place, the data structure to make times human-readable. Automatically handles second and millisecond epoch times. Currently only operates on top-level keys.

param keys [Symbol, Array] the keys you wish to be

turned into readable times.

return [Nil]



221
222
223
# File 'lib/wavefront-cli/display/base.rb', line 221

def readable_time(*keys)
  keys.each { |k| data[k] = human_time(data[k]) if data.key?(k) }
end

#run(method) ⇒ Object

find the correct method to deal with the output of the user’s command.



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/wavefront-cli/display/base.rb', line 31

def run(method)
  if method == 'do_list'
    run_list
  elsif method == 'do_search'
    run_search
  elsif respond_to?("#{method}_brief")
    send("#{method}_brief")
  elsif respond_to?(method)
    send(method)
  else
    long_output
  end
end

#run_error(method) ⇒ Object

Display classes can provide a do_method_code() method, which handles <code> errors when running do_method(). (Code is 404 etc.)

Parameters:

  • method (Symbol)

    the error method we wish to call



73
74
75
76
77
# File 'lib/wavefront-cli/display/base.rb', line 73

def run_error(method)
  return unless respond_to?(method)
  send(method)
  exit 1
end

#run_listObject

Choose the correct list handler. The user can specifiy a long listing with the –long options.



48
49
50
51
52
53
54
# File 'lib/wavefront-cli/display/base.rb', line 48

def run_list
  if options[:long]
    do_list
  else
    do_list_brief
  end
end

#run_searchObject

Choose the correct search handler. The user can specifiy a long listing with the –long options.



59
60
61
62
63
64
65
# File 'lib/wavefront-cli/display/base.rb', line 59

def run_search
  if options[:long]
    do_search
  else
    do_search_brief
  end
end