Rip out Thor::Shell
This commit is contained in:
parent
9c59f0f357
commit
f519434285
|
@ -9,17 +9,17 @@ begin
|
||||||
env.logger.info("vagrant") { "`vagrant` invoked: #{ARGV.inspect}" }
|
env.logger.info("vagrant") { "`vagrant` invoked: #{ARGV.inspect}" }
|
||||||
|
|
||||||
# Disable color if the proper argument was passed
|
# Disable color if the proper argument was passed
|
||||||
shell = nil
|
ui = nil
|
||||||
if !$stdout.tty? || ARGV.include?("--no-color")
|
if !$stdout.tty? || ARGV.include?("--no-color")
|
||||||
shell = Thor::Shell::Basic.new
|
ui = Vagrant::UI::Colored.new(env)
|
||||||
else
|
else
|
||||||
shell = Thor::Base.shell.new
|
ui = Vagrant::UI::Colored.new(env)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set the UI early in case any errors are raised, and load
|
# Set the UI early in case any errors are raised, and load
|
||||||
# the config immediately, so we gather any new commands from
|
# the config immediately, so we gather any new commands from
|
||||||
# plugins
|
# plugins
|
||||||
env.ui = Vagrant::UI::Shell.new(env, shell)
|
env.ui = ui
|
||||||
env.load!
|
env.load!
|
||||||
|
|
||||||
# Kick start the CLI
|
# Kick start the CLI
|
||||||
|
|
|
@ -1,80 +1,88 @@
|
||||||
module Vagrant
|
module Vagrant
|
||||||
# Vagrant UIs handle communication with the outside world (typically
|
module UI
|
||||||
# through a shell). They must respond to the typically logger methods
|
# Vagrant UIs handle communication with the outside world (typically
|
||||||
# of `warn`, `error`, `info`, and `confirm`.
|
# through a shell). They must respond to the following methods:
|
||||||
class UI
|
#
|
||||||
attr_accessor :env
|
# * `info`
|
||||||
|
# * `warn`
|
||||||
|
# * `error`
|
||||||
|
# * `success`
|
||||||
|
class Interface
|
||||||
|
attr_accessor :env
|
||||||
|
|
||||||
def initialize(env)
|
def initialize(env)
|
||||||
@env = env
|
@env = env
|
||||||
end
|
end
|
||||||
|
|
||||||
[:warn, :error, :info, :confirm].each do |method|
|
[:warn, :error, :info, :success].each do |method|
|
||||||
define_method(method) do |message, *opts|
|
define_method(method) do |message, *opts|
|
||||||
# Log normal console messages
|
# Log normal console messages
|
||||||
env.logger.info("ui") { message }
|
env.logger.info("ui") { message }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[:clear_line, :report_progress].each do |method|
|
||||||
|
# By default do nothing, these aren't logged
|
||||||
|
define_method(method) { |*args| }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
[:clear_line, :report_progress, :ask, :no?, :yes?].each do |method|
|
# This is a UI implementation that outputs color for various types
|
||||||
# By default do nothing, these aren't logged
|
# of messages. This should only be used with a TTY that supports color,
|
||||||
define_method(method) { |*args| }
|
# but is up to the user of the class to verify this is the case.
|
||||||
end
|
class Colored < Interface
|
||||||
|
# Use some light meta-programming to create the various methods to
|
||||||
# A shell UI, which uses a `Thor::Shell` object to talk with
|
# output text to the UI. These all delegate the real functionality
|
||||||
# a terminal.
|
# to `say`.
|
||||||
class Shell < UI
|
[:info, :warn, :error, :success].each do |method|
|
||||||
def initialize(env, shell)
|
|
||||||
super(env)
|
|
||||||
|
|
||||||
@shell = shell
|
|
||||||
end
|
|
||||||
|
|
||||||
[[:warn, :yellow], [:error, :red], [:info, nil], [:confirm, :green]].each do |method, color|
|
|
||||||
class_eval <<-CODE
|
class_eval <<-CODE
|
||||||
def #{method}(message, opts=nil)
|
def #{method}(message, *args)
|
||||||
super(message)
|
super(message)
|
||||||
opts ||= {}
|
say(#{method.inspect}, message, *args)
|
||||||
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
|
end
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is used to output progress reports to the UI.
|
||||||
|
# Send this method progress/total and it will output it
|
||||||
|
# to the UI. Send `clear_line` to clear the line to show
|
||||||
|
# a continuous progress meter.
|
||||||
def report_progress(progress, total, show_parts=true)
|
def report_progress(progress, total, show_parts=true)
|
||||||
percent = (progress.to_f / total.to_f) * 100
|
percent = (progress.to_f / total.to_f) * 100
|
||||||
line = "Progress: #{percent.to_i}%"
|
line = "Progress: #{percent.to_i}%"
|
||||||
line << " (#{progress} / #{total})" if show_parts
|
line << " (#{progress} / #{total})" if show_parts
|
||||||
|
|
||||||
@shell.say(line, nil, false)
|
info(line, :new_line => false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def clear_line
|
def clear_line
|
||||||
@shell.say(line_reset, nil, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def format_message(message, opts=nil)
|
|
||||||
opts = { :prefix => true }.merge(opts || {})
|
|
||||||
message = "[#{env.resource}] #{message}" if opts[:prefix]
|
|
||||||
message
|
|
||||||
end
|
|
||||||
|
|
||||||
def line_reset
|
|
||||||
reset = "\r"
|
reset = "\r"
|
||||||
reset += "\e[0K" unless Util::Platform.windows?
|
reset += "\e[0K" unless Util::Platform.windows?
|
||||||
reset
|
reset
|
||||||
|
|
||||||
|
info(reset, :new_line => false)
|
||||||
|
end
|
||||||
|
|
||||||
|
# This method handles actually outputting a message of a given type
|
||||||
|
# to the console.
|
||||||
|
def say(type, message, opts=nil)
|
||||||
|
defaults = { :new_line => true, :prefix => true }
|
||||||
|
opts = defaults.merge(opts || {})
|
||||||
|
|
||||||
|
# Determine whether we're expecting to output our
|
||||||
|
# own new line or not.
|
||||||
|
printer = opts[:new_line] ? :puts : :print
|
||||||
|
|
||||||
|
# Determine the proper IO channel to send this message
|
||||||
|
# to based on the type of the message
|
||||||
|
channel = type == :error ? $stderr : $stdout
|
||||||
|
|
||||||
|
# Format the message
|
||||||
|
message = "[#{env.resource}] #{message}" if opts[:prefix]
|
||||||
|
|
||||||
|
# Output!
|
||||||
|
# TODO: Color
|
||||||
|
channel.send(printer, message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue