class Chef::Knife::Core::GenericPresenter

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.

Attributes

config[R]
ui[R]

Public Class Methods

new(ui, config) click to toggle source

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.

# File lib/chef/knife/core/generic_presenter.rb, line 60
def initialize(ui, config)
  @ui, @config = ui, config
end

Public Instance Methods

attribute_field_separator() click to toggle source

GenericPresenter is used in contexts where MultiAttributeReturnOption is not, so we need to set the default value here rather than as part of the CLI option.

# File lib/chef/knife/core/generic_presenter.rb, line 186
def attribute_field_separator
  config[:field_separator] || "."
end
extract_nested_value(data, nested_value_spec) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 190
def extract_nested_value(data, nested_value_spec)
  nested_value_spec.split(attribute_field_separator).each do |attr|
    data =
      if data.is_a?(Array)
        data[attr.to_i]
      elsif data.respond_to?(:[], false) && data.key?(attr)
        data[attr]
      elsif data.respond_to?(attr.to_sym, false)
        # handles -a chef_environment and other things that hang of the node and aren't really attributes
        data.public_send(attr.to_sym)
      else
        nil
      end
  end
  # necessary (?) for coercing objects (the run_list object?) to hashes
  ( !data.kind_of?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data
end
format(data) click to toggle source

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.

# File lib/chef/knife/core/generic_presenter.rb, line 81
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] && 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) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 208
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) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 158
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) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 146
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) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 142
def format_list_for_display(list)
  config[:with_uri] ? list : list.keys.sort { |a, b| a <=> b }
end
formatting_subset_of_data?() click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 179
def formatting_subset_of_data?
  config[:attribute] || config[:run_list]
end
interchange?() click to toggle source

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.

# File lib/chef/knife/core/generic_presenter.rb, line 68
def interchange?
  case parse_format_option
  when :json, :yaml
    true
  else
    false
  end
end
name_or_id_for(data) click to toggle source
# File lib/chef/knife/core/generic_presenter.rb, line 175
def name_or_id_for(data)
  data.respond_to?(:name) ? data.name : data["id"]
end
parse_format_option() click to toggle source

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`

# File lib/chef/knife/core/generic_presenter.rb, line 113
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) click to toggle source

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

# File lib/chef/knife/core/generic_presenter.rb, line 132
def summarize(data)
  text_format(data)
end
text_format(data) click to toggle source

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

# File lib/chef/knife/core/generic_presenter.rb, line 138
def text_format(data)
  TextFormatter.new(data, ui).formatted_data
end