Class: Chef::Knife::Core::GenericPresenter

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/knife/core/generic_presenter.rb

Overview

Chef::Knife::Core::GenericPresenter

The base presenter class for displaying structured data in knife commands. This is not an abstract base class, and it is suitable for displaying most kinds of objects that knife needs to display.

Direct Known Subclasses

NodePresenter

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ui, config) ⇒ GenericPresenter

Instaniates a new GenericPresenter. This is generally handled by the Chef::Knife::UI object, though you need to match the signature of this method if you intend to use your own presenter instead.



37
38
39
# File 'lib/chef/knife/core/generic_presenter.rb', line 37

def initialize(ui, config)
  @ui, @config = ui, config
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



32
33
34
# File 'lib/chef/knife/core/generic_presenter.rb', line 32

def config
  @config
end

#uiObject (readonly)

Returns the value of attribute ui.



31
32
33
# File 'lib/chef/knife/core/generic_presenter.rb', line 31

def ui
  @ui
end

Instance Method Details

#extract_nested_value(data, nested_value_spec) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/chef/knife/core/generic_presenter.rb', line 161

def extract_nested_value(data, nested_value_spec)
  nested_value_spec.split(".").each do |attr|
    if data.nil?
      nil # don't get no method error on nil
    elsif data.respond_to?(attr.to_sym)
      data = data.send(attr.to_sym)
    elsif data.respond_to?(:[])
      data = data[attr]
    else
      data = begin
        data.send(attr.to_sym)
      rescue NoMethodError
        nil
      end
    end
  end
  ( !data.kind_of?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data
end

#format(data) ⇒ Object

Returns a String representation of data that is suitable for output to a terminal or perhaps for data interchange with another program. The representation of the data depends on the value of the ‘config` setting.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/chef/knife/core/generic_presenter.rb', line 58

def format(data)
  case parse_format_option
  when :summary
    summarize(data)
  when :text
    text_format(data)
  when :json
    Chef::JSONCompat.to_json_pretty(data)
  when :yaml
    require 'yaml'
    YAML::dump(data)
  when :pp
    require 'stringio'
    # If you were looking for some attribute and there is only one match
    # just dump the attribute value
    if config[:attribute] and data.length == 1
      data.values[0]
    else
      out = StringIO.new
      PP.pp(data, out)
      out.string
    end
  end
end

#format_cookbook_list_for_display(item) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/chef/knife/core/generic_presenter.rb', line 180

def format_cookbook_list_for_display(item)
  if config[:with_uri]
    item.inject({}) do |collected, (cookbook, versions)|
      collected[cookbook] = Hash.new
      versions['versions'].each do |ver|
        collected[cookbook][ver['version']] = ver['url']
      end
      collected
    end
  else
    versions_by_cookbook = item.inject({}) do |collected, ( cookbook, versions )|
      collected[cookbook] = versions["versions"].map {|v| v['version']}
      collected
    end
    key_length = versions_by_cookbook.empty? ? 0 : versions_by_cookbook.keys.map {|name| name.size }.max + 2
    versions_by_cookbook.sort.map do |cookbook, versions|
      "#{cookbook.ljust(key_length)} #{versions.join('  ')}"
    end
  end
end

#format_data_subset_for_display(data) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/chef/knife/core/generic_presenter.rb', line 135

def format_data_subset_for_display(data)
  subset = if config[:attribute]
    result = {}
    Array(config[:attribute]).each do |nested_value_spec|
      nested_value = extract_nested_value(data, nested_value_spec)
      result[nested_value_spec] = nested_value
    end
    result
  elsif config[:run_list]
    run_list = data.run_list.run_list
    { "run_list" => run_list }
  else
    raise ArgumentError, "format_data_subset_for_display requires attribute, run_list, or id_only config option to be set"
  end
  {name_or_id_for(data) => subset }
end

#format_for_display(data) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/chef/knife/core/generic_presenter.rb', line 123

def format_for_display(data)
  if formatting_subset_of_data?
    format_data_subset_for_display(data)
  elsif config[:id_only]
    name_or_id_for(data)
  elsif config[:environment] && data.respond_to?(:chef_environment)
    {"chef_environment" => data.chef_environment}
  else
    data
  end
end

#format_list_for_display(list) ⇒ Object



119
120
121
# File 'lib/chef/knife/core/generic_presenter.rb', line 119

def format_list_for_display(list)
  config[:with_uri] ? list : list.keys.sort { |a,b| a <=> b }
end

#formatting_subset_of_data?Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/chef/knife/core/generic_presenter.rb', line 156

def formatting_subset_of_data?
  config[:attribute] || config[:run_list]
end

#interchange?Boolean

Is the selected output format a data interchange format? Returns true if the selected output format is json or yaml, false otherwise. Knife search uses this to adjust its data output so as not to produce invalid JSON output.

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
# File 'lib/chef/knife/core/generic_presenter.rb', line 45

def interchange?
  case parse_format_option
  when :json, :yaml
    true
  else
    false
  end
end

#name_or_id_for(data) ⇒ Object



152
153
154
# File 'lib/chef/knife/core/generic_presenter.rb', line 152

def name_or_id_for(data)
  data.respond_to?(:name) ? data.name : data["id"]
end

#parse_format_optionObject

Converts the user-supplied value of ‘config` to a Symbol representing the desired output format.

Returns

returns one of :summary, :text, :json, :yaml, or :pp

Raises

Raises an ArgumentError if the desired output format could not be determined from the value of ‘config`



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/chef/knife/core/generic_presenter.rb', line 90

def parse_format_option
  case config[:format]
  when "summary", /^s/, nil
    :summary
  when "text", /^t/
    :text
  when "json", /^j/
    :json
  when "yaml", /^y/
    :yaml
  when "pp", /^p/
    :pp
  else
    raise ArgumentError, "Unknown output format #{config[:format]}"
  end
end

#summarize(data) ⇒ Object

Summarize the data. Defaults to text format output, which may not be very summary-like



109
110
111
# File 'lib/chef/knife/core/generic_presenter.rb', line 109

def summarize(data)
  text_format(data)
end

#text_format(data) ⇒ Object

Converts the data to a String in the text format. Uses Chef::Knife::Core::TextFormatter



115
116
117
# File 'lib/chef/knife/core/generic_presenter.rb', line 115

def text_format(data)
  TextFormatter.new(data, ui).formatted_data
end