class Chef::Knife::UI
Chef::Knife::UI¶ ↑
The User Interaction class used by knife.
Attributes
Public Class Methods
# File lib/chef/knife/core/ui.rb, line 46 def initialize(stdout, stderr, stdin, config) @stdout, @stderr, @stdin, @config = stdout, stderr, stdin, config @presenter = Chef::Knife::Core::GenericPresenter.new(self, config) end
Public Instance Methods
# File lib/chef/knife/core/ui.rb, line 118 def ask(*args, &block) highline.ask(*args, &block) end
# File lib/chef/knife/core/ui.rb, line 139 def ask_question(question, opts={}) question = question + "[#{opts[:default]}] " if opts[:default] if opts[:default] and config[:defaults] opts[:default] else stdout.print question a = stdin.readline.strip if opts[:default] a.empty? ? opts[:default] : a else a end end end
# File lib/chef/knife/core/ui.rb, line 103 def color(string, *colors) if color? highline.color(string, *colors) else string end end
Should colored output be used? For output to a terminal, this is determined by the value of `config`. When output is not to a terminal, colored output is never used
# File lib/chef/knife/core/ui.rb, line 114 def color? Chef::Config[:color] && stdout.tty? && !Chef::Platform.windows? end
Not the ideal signature for a function but we need to stick with this for now until we get a chance to break our API in Chef 12.
question => Question to print before asking for confirmation append_instructions => Should print '? (Y/N)' as instructions default_choice => Set to true for 'Y', and false for 'N' as default answer
# File lib/chef/knife/core/ui.rb, line 258 def confirm(question, append_instructions=true, default_choice=nil) unless confirm_without_exit(question, append_instructions, default_choice) exit 3 end true end
See confirm method for argument information
# File lib/chef/knife/core/ui.rb, line 220 def confirm_without_exit(question, append_instructions=true, default_choice=nil) return true if config[:yes] stdout.print question stdout.print confirmation_instructions(default_choice) if append_instructions answer = stdin.readline answer.chomp! case answer when "Y", "y" true when "N", "n" self.msg("You said no, so I'm done here.") false when "" unless default_choice.nil? default_choice else self.msg("I have no idea what to do with '#{answer}'") self.msg("Just say Y or N, please.") confirm_without_exit(question, append_instructions, default_choice) end else self.msg("I have no idea what to do with '#{answer}'") self.msg("Just say Y or N, please.") confirm_without_exit(question, append_instructions, default_choice) end end
# File lib/chef/knife/core/ui.rb, line 208 def confirmation_instructions(default_choice) case default_choice when true '? (Y/n)' when false '? (y/N)' else '? (Y/N)' end end
# File lib/chef/knife/core/ui.rb, line 165 def edit_data(data, parse_output=true) output = Chef::JSONCompat.to_json_pretty(data) if (!config[:disable_editing]) Tempfile.open([ 'knife-edit-', '.json' ]) do |tf| tf.sync = true tf.puts output tf.close raise "Please set EDITOR environment variable" unless system("#{config[:editor]} #{tf.path}") output = IO.read(tf.path) end end parse_output ? Chef::JSONCompat.from_json(output) : output end
# File lib/chef/knife/core/ui.rb, line 182 def edit_object(klass, name) object = klass.load(name) output = edit_data(object) # Only make the save if the user changed the object. # # Output JSON for the original (object) and edited (output), then parse # them without reconstituting the objects into real classes # (create_additions=false). Then, compare the resulting simple objects, # which will be Array/Hash/String/etc. # # We wouldn't have to do these shenanigans if all the editable objects # implemented to_hash, or if to_json against a hash returned a string # with stable key order. object_parsed_again = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(object), :create_additions => false) output_parsed_again = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(output), :create_additions => false) if object_parsed_again != output_parsed_again output.save self.msg("Saved #{output}") else self.msg("Object unchanged, not saving") end output(format_for_display(object)) if config[:print_after] end
Prints a msg to stderr. Used for warn, error, and fatal.
# File lib/chef/knife/core/ui.rb, line 79 def err(message) begin stderr.puts message rescue Errno::EPIPE => e raise e if @config[:verbosity] >= 2 exit 0 end end
Print an error message
# File lib/chef/knife/core/ui.rb, line 94 def error(message) err("#{color('ERROR:', :red, :bold)} #{message}") end
Print a message describing a fatal error.
# File lib/chef/knife/core/ui.rb, line 99 def fatal(message) err("#{color('FATAL:', :red, :bold)} #{message}") end
# File lib/chef/knife/core/ui.rb, line 58 def highline @highline ||= begin require 'highline' HighLine.new end end
Determines if the output format is a data interchange format, i.e., JSON or YAML
# File lib/chef/knife/core/ui.rb, line 135 def interchange? @presenter.interchange? end
# File lib/chef/knife/core/ui.rb, line 122 def list(*args) highline.list(*args) end
Prints a message to stdout. Aliased as info
for compatibility
with the logger API.
# File lib/chef/knife/core/ui.rb, line 67 def msg(message) begin stdout.puts message rescue Errno::EPIPE => e raise e if @config[:verbosity] >= 2 exit 0 end end
Formats data
using the configured presenter and outputs the
result via msg
. Formatting can be customized by configuring a
different presenter. See use_presenter
# File lib/chef/knife/core/ui.rb, line 129 def output(data) msg @presenter.format(data) end
# File lib/chef/knife/core/ui.rb, line 156 def pretty_print(data) begin stdout.puts data rescue Errno::EPIPE => e raise e if @config[:verbosity] >= 2 exit 0 end end
Creates a new presenter_class
object and uses it to format
structured data for display. By default, a Chef::Knife::Core::GenericPresenter
object is used.
# File lib/chef/knife/core/ui.rb, line 54 def use_presenter(presenter_class) @presenter = presenter_class.new(self, config) end
Print a warning message
# File lib/chef/knife/core/ui.rb, line 89 def warn(message) err("#{color('WARNING:', :yellow, :bold)} #{message}") end