module Veewee # Vagrant UIs handle communication with the outside world (typically # through a shell). They must respond to the typically logger methods # of `warn`, `error`, `info`, and `success`. class UI attr_accessor :env attr_accessor :resource def initialize(env) @env = env end [:warn, :error, :info, :success].each do |method| define_method(method) do |message, *argv| opts, *argv = argv opts ||= {} # Log normal console messages env.logger.info("ui") { message } end end [:clear_line, :report_progress, :ask, :no?, :yes?].each do |method| # By default do nothing, these aren't logged define_method(method) { |*args| } end # A shell UI, which uses a `Thor::Shell` object to talk with # a terminal. class Shell < UI def initialize(env, shell) super(env) @shell = shell end [[:warn, :yellow], [:error, :red], [:info, nil], [:success, :green]].each do |method, color| class_eval <<-CODE def #{method}(message, opts = nil) super(message) opts ||= {} opts[:new_line] = true if !opts.has_key?(:new_line) @shell.say("\#{format_message(message, opts)}", #{color.inspect}, opts[:new_line]) end CODE end [:ask, :no?, :yes?].each do |method| class_eval <<-CODE def #{method}(message, opts = nil) super(message) opts ||= {} @shell.send(#{method.inspect}, format_message(message, opts), opts[:color]) end CODE end def report_progress(progress, total, show_parts = true) percent = (progress.to_f / total.to_f) * 100 line = "Progress: #{percent.to_i}%" line << " (#{progress} / #{total})" if show_parts @shell.say(line, nil, false) end def clear_line @shell.say(line_reset, nil, false) end protected def format_message(message, opts = nil) opts = { :prefix => true }.merge(opts || {}) opts[:prefix] = false if env.resource == "veewee" opts[:prefix] = false if env.resource == "vagrant" message = "[#{env.resource}] #{message}" if opts[:prefix] message end def line_reset reset = "\r" reset += "\e[0K" unless Util::Platform.windows? reset end end end end