Class: Chef::Knife::UI

Inherits:
Object show all
Extended by:
Forwardable
Defined in:
lib/chef/knife/core/ui.rb

Overview

Chef::Knife::UI

The User Interaction class used by knife.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout, stderr, stdin, config) ⇒ UI

Returns a new instance of UI.



46
47
48
49
# 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

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



38
39
40
# File 'lib/chef/knife/core/ui.rb', line 38

def config
  @config
end

#presenterObject (readonly)

Returns the value of attribute presenter.



40
41
42
# File 'lib/chef/knife/core/ui.rb', line 40

def presenter
  @presenter
end

#stderrObject (readonly)

Returns the value of attribute stderr.



36
37
38
# File 'lib/chef/knife/core/ui.rb', line 36

def stderr
  @stderr
end

#stdinObject (readonly)

Returns the value of attribute stdin.



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

def stdin
  @stdin
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



35
36
37
# File 'lib/chef/knife/core/ui.rb', line 35

def stdout
  @stdout
end

Instance Method Details

#ask(*args, &block) ⇒ Object



118
119
120
# File 'lib/chef/knife/core/ui.rb', line 118

def ask(*args, &block)
  highline.ask(*args, &block)
end

#ask_question(question, opts = {}) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# 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

#color(string, *colors) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/chef/knife/core/ui.rb', line 103

def color(string, *colors)
  if color?
    highline.color(string, *colors)
  else
    string
  end
end

#color?Boolean

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

Returns:

  • (Boolean)


114
115
116
# File 'lib/chef/knife/core/ui.rb', line 114

def color?
  Chef::Config[:color] && stdout.tty? && !Chef::Platform.windows?
end

#confirm(question, append_instructions = true) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/chef/knife/core/ui.rb', line 208

def confirm(question, append_instructions=true)
  return true if config[:yes]

  stdout.print question
  stdout.print "? (Y/N) " 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.")
    exit 3
  else
    self.msg("I have no idea what to do with #{answer}")
    self.msg("Just say Y or N, please.")
    confirm(question)
  end
end

#edit_data(data, parse_output = true) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# 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

#edit_object(klass, name) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# 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

#err(message) ⇒ Object

Prints a msg to stderr. Used for warn, error, and fatal.



79
80
81
82
83
84
85
86
# 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

#error(message) ⇒ Object

Print an error message



94
95
96
# File 'lib/chef/knife/core/ui.rb', line 94

def error(message)
  err("#{color('ERROR:', :red, :bold)} #{message}")
end

#fatal(message) ⇒ Object

Print a message describing a fatal error.



99
100
101
# File 'lib/chef/knife/core/ui.rb', line 99

def fatal(message)
  err("#{color('FATAL:', :red, :bold)} #{message}")
end

#highlineObject



58
59
60
61
62
63
# File 'lib/chef/knife/core/ui.rb', line 58

def highline
  @highline ||= begin
    require 'highline'
    HighLine.new
  end
end

#interchange?Boolean

Determines if the output format is a data interchange format, i.e., JSON or YAML

Returns:

  • (Boolean)


135
136
137
# File 'lib/chef/knife/core/ui.rb', line 135

def interchange?
  @presenter.interchange?
end

#list(*args) ⇒ Object



122
123
124
# File 'lib/chef/knife/core/ui.rb', line 122

def list(*args)
  highline.list(*args)
end

#msg(message) ⇒ Object Also known as: info

Prints a message to stdout. Aliased as info for compatibility with the logger API.



67
68
69
70
71
72
73
74
# 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

#output(data) ⇒ Object

Formats data using the configured presenter and outputs the result via msg. Formatting can be customized by configuring a different presenter. See use_presenter



129
130
131
# File 'lib/chef/knife/core/ui.rb', line 129

def output(data)
  msg @presenter.format(data)
end

#pretty_print(data) ⇒ Object



156
157
158
159
160
161
162
163
# 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

#use_presenter(presenter_class) ⇒ Object

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.



54
55
56
# File 'lib/chef/knife/core/ui.rb', line 54

def use_presenter(presenter_class)
  @presenter = presenter_class.new(self, config)
end

#warn(message) ⇒ Object

Print a warning message



89
90
91
# File 'lib/chef/knife/core/ui.rb', line 89

def warn(message)
  err("#{color('WARNING:', :yellow, :bold)} #{message}")
end