class 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
Public Class Methods
Instantiates 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
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
# 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.respond_to?(:key?) && 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.is_a?(Array) && data.respond_to?(:to_hash) ) ? data.to_hash : data end
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" unless defined?(YAML) YAML.dump(data) when :pp require "stringio" unless defined?(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
# 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] = {} 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(&:size).max + 2 versions_by_cookbook.sort.map do |cookbook, versions| "#{cookbook.ljust(key_length)} #{versions.join(" ")}" end end end
# 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
# 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
# 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
# File lib/chef/knife/core/generic_presenter.rb, line 179 def formatting_subset_of_data? config[:attribute] || config[:run_list] end
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
# 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
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 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
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