core: use cleaner UI abstractions
This commit is contained in:
parent
fc86a10796
commit
a32e154e6e
|
@ -96,7 +96,7 @@ module Vagrant
|
||||||
@provider_config = provider_config
|
@provider_config = provider_config
|
||||||
@provider_name = provider_name
|
@provider_name = provider_name
|
||||||
@provider_options = provider_options
|
@provider_options = provider_options
|
||||||
@ui = @env.ui.scope(@name)
|
@ui = Vagrant::UI::Prefixed.new(@env.ui, @name)
|
||||||
|
|
||||||
# Read the ID, which is usually in local storage
|
# Read the ID, which is usually in local storage
|
||||||
@id = nil
|
@id = nil
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require "delegate"
|
||||||
require "thread"
|
require "thread"
|
||||||
|
|
||||||
require "log4r"
|
require "log4r"
|
||||||
|
@ -43,15 +44,6 @@ module Vagrant
|
||||||
def machine(type, *data)
|
def machine(type, *data)
|
||||||
@logger.info("Machine: #{type} #{data.inspect}")
|
@logger.info("Machine: #{type} #{data.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a new UI class that is scoped to the given resource name.
|
|
||||||
# Subclasses can then use this scope name to do whatever they please.
|
|
||||||
#
|
|
||||||
# @param [String] scope_name
|
|
||||||
# @return [Interface]
|
|
||||||
def scope(scope_name)
|
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is a UI implementation that does nothing.
|
# This is a UI implementation that does nothing.
|
||||||
|
@ -99,10 +91,6 @@ module Vagrant
|
||||||
safe_puts("#{Time.now.utc.to_i},#{target},#{type},#{data.join(",")}")
|
safe_puts("#{Time.now.utc.to_i},#{target},#{type},#{data.join(",")}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def scope(scope_name)
|
|
||||||
BasicScope.new(self, scope_name)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is a UI implementation that outputs the text as is. It
|
# This is a UI implementation that outputs the text as is. It
|
||||||
|
@ -110,9 +98,6 @@ module Vagrant
|
||||||
class Basic < Interface
|
class Basic < Interface
|
||||||
include Util::SafePuts
|
include Util::SafePuts
|
||||||
|
|
||||||
# The prefix for `output` messages.
|
|
||||||
OUTPUT_PREFIX = "==> "
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
|
|
||||||
|
@ -194,17 +179,64 @@ module Vagrant
|
||||||
# do this.
|
# do this.
|
||||||
Thread.new do
|
Thread.new do
|
||||||
@lock.synchronize do
|
@lock.synchronize do
|
||||||
safe_puts(format_message(type, message, opts),
|
safe_puts(format_message(type, message, **opts),
|
||||||
:io => channel, :printer => printer)
|
:io => channel, :printer => printer)
|
||||||
end
|
end
|
||||||
end.join
|
end.join
|
||||||
end
|
end
|
||||||
|
|
||||||
def scope(scope_name)
|
def format_message(type, message, **opts)
|
||||||
BasicScope.new(self, scope_name)
|
message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prefixed wraps an existing UI and adds a prefix to it.
|
||||||
|
class Prefixed < Interface
|
||||||
|
# The prefix for `output` messages.
|
||||||
|
OUTPUT_PREFIX = "==> "
|
||||||
|
|
||||||
|
def initialize(ui, prefix)
|
||||||
|
super()
|
||||||
|
|
||||||
|
@prefix = prefix
|
||||||
|
@ui = ui
|
||||||
|
end
|
||||||
|
|
||||||
|
# Use some light meta-programming to create the various methods to
|
||||||
|
# output text to the UI. These all delegate the real functionality
|
||||||
|
# to `say`.
|
||||||
|
[:ask, :detail, :info, :warn, :error, :output, :success].each do |method|
|
||||||
|
class_eval <<-CODE
|
||||||
|
def #{method}(message, *args, **opts)
|
||||||
|
super(message)
|
||||||
|
opts[:bold] = #{method.inspect} != :detail if !opts.has_key?(:bold)
|
||||||
|
@ui.#{method}(format_message(#{method.inspect}, message, **opts), *args, **opts)
|
||||||
|
end
|
||||||
|
CODE
|
||||||
|
end
|
||||||
|
|
||||||
|
[:clear_line, :report_progress].each do |method|
|
||||||
|
# By default do nothing, these aren't formatted
|
||||||
|
define_method(method) { |*args| @ui.send(method, *args) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# For machine-readable output, set the prefix in the
|
||||||
|
# options hash and continue it on.
|
||||||
|
def machine(type, *data)
|
||||||
|
opts = {}
|
||||||
|
opts = data.pop if data.last.is_a?(Hash)
|
||||||
|
opts[:scope] = @prefix
|
||||||
|
data << opts
|
||||||
|
@ui.machine(type, *data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return the parent's opts.
|
||||||
|
#
|
||||||
|
# @return [Hash]
|
||||||
|
def opts
|
||||||
|
@ui.opts
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is called by `say` to format the message for output.
|
|
||||||
def format_message(type, message, **opts)
|
def format_message(type, message, **opts)
|
||||||
prefix = ""
|
prefix = ""
|
||||||
if !opts.has_key?(:prefix) || opts[:prefix]
|
if !opts.has_key?(:prefix) || opts[:prefix]
|
||||||
|
@ -216,7 +248,9 @@ module Vagrant
|
||||||
return message if prefix.empty?
|
return message if prefix.empty?
|
||||||
|
|
||||||
# Otherwise, make sure to prefix every line properly
|
# Otherwise, make sure to prefix every line properly
|
||||||
message.split("\n").map { |line| "#{prefix}#{line}" }.join("\n")
|
message.split("\n").map do |line|
|
||||||
|
"#{prefix}#{@prefix}: #{line}"
|
||||||
|
end.join("\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -231,13 +265,6 @@ module Vagrant
|
||||||
@scope = scope
|
@scope = scope
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return the parent's opts.
|
|
||||||
#
|
|
||||||
# @return [Hash]
|
|
||||||
def opts
|
|
||||||
@ui.opts
|
|
||||||
end
|
|
||||||
|
|
||||||
[:ask, :detail, :warn, :error, :info, :output, :success].each do |method|
|
[:ask, :detail, :warn, :error, :info, :output, :success].each do |method|
|
||||||
define_method(method) do |message, opts=nil|
|
define_method(method) do |message, opts=nil|
|
||||||
opts ||= {}
|
opts ||= {}
|
||||||
|
@ -288,9 +315,6 @@ module Vagrant
|
||||||
|
|
||||||
opts = @opts.merge(opts)
|
opts = @opts.merge(opts)
|
||||||
|
|
||||||
# Default the bold option if its not given
|
|
||||||
opts[:bold] = type == :output if !opts.has_key?(:bold)
|
|
||||||
|
|
||||||
# Special case some colors for certain message types
|
# Special case some colors for certain message types
|
||||||
opts[:color] = :red if type == :error
|
opts[:color] = :red if type == :error
|
||||||
opts[:color] = :yellow if type == :warn
|
opts[:color] = :yellow if type == :warn
|
||||||
|
|
|
@ -58,58 +58,11 @@ describe Vagrant::UI::Basic do
|
||||||
subject.error("foo")
|
subject.error("foo")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#detail" do
|
|
||||||
it "prefixes with spaces" do
|
|
||||||
subject.should_receive(:safe_puts).with(" foo", anything)
|
|
||||||
subject.detail("foo")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't prefix if told not to" do
|
|
||||||
subject.should_receive(:safe_puts).with("foo", anything)
|
|
||||||
subject.detail("foo", prefix: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "prefixes every line" do
|
|
||||||
subject.should_receive(:safe_puts).with(" foo\n bar", anything)
|
|
||||||
subject.detail("foo\nbar")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#output" do
|
|
||||||
it "prefixes with ==>" do
|
|
||||||
subject.should_receive(:safe_puts).with("==> foo", anything)
|
|
||||||
subject.output("foo")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "doesn't prefix if told not to" do
|
|
||||||
subject.should_receive(:safe_puts).with("foo", anything)
|
|
||||||
subject.output("foo", prefix: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "prefixes every line" do
|
|
||||||
subject.should_receive(:safe_puts).with("==> foo\n==> bar", anything)
|
|
||||||
subject.output("foo\nbar")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#scope" do
|
|
||||||
it "creates a basic scope" do
|
|
||||||
scope = subject.scope("foo")
|
|
||||||
expect(scope.scope).to eql("foo")
|
|
||||||
expect(scope.ui).to be(subject)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Vagrant::UI::Colored do
|
describe Vagrant::UI::Colored do
|
||||||
include_context "unit"
|
include_context "unit"
|
||||||
|
|
||||||
before do
|
|
||||||
# We don't want any prefixes on anything...
|
|
||||||
subject.opts[:prefix] = false
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#detail" do
|
describe "#detail" do
|
||||||
it "colors output nothing by default" do
|
it "colors output nothing by default" do
|
||||||
subject.should_receive(:safe_puts).with("foo", anything)
|
subject.should_receive(:safe_puts).with("foo", anything)
|
||||||
|
@ -147,7 +100,7 @@ describe Vagrant::UI::Colored do
|
||||||
subject.opts[:color] = :red
|
subject.opts[:color] = :red
|
||||||
|
|
||||||
subject.should_receive(:safe_puts).with do |message, *args|
|
subject.should_receive(:safe_puts).with do |message, *args|
|
||||||
expect(message).to start_with("\033[1;31m")
|
expect(message).to start_with("\033[0;31m")
|
||||||
expect(message).to end_with("\033[0m")
|
expect(message).to end_with("\033[0m")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -158,22 +111,22 @@ describe Vagrant::UI::Colored do
|
||||||
subject.opts[:color] = :red
|
subject.opts[:color] = :red
|
||||||
|
|
||||||
subject.should_receive(:safe_puts).with do |message, *args|
|
subject.should_receive(:safe_puts).with do |message, *args|
|
||||||
expect(message).to start_with("\033[1;32m")
|
expect(message).to start_with("\033[0;32m")
|
||||||
expect(message).to end_with("\033[0m")
|
expect(message).to end_with("\033[0m")
|
||||||
end
|
end
|
||||||
|
|
||||||
subject.output("foo", color: :green)
|
subject.output("foo", color: :green)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't bold the output if specified" do
|
it "bolds the output if specified" do
|
||||||
subject.opts[:color] = :red
|
subject.opts[:color] = :red
|
||||||
|
|
||||||
subject.should_receive(:safe_puts).with do |message, *args|
|
subject.should_receive(:safe_puts).with do |message, *args|
|
||||||
expect(message).to start_with("\033[0;31m")
|
expect(message).to start_with("\033[1;31m")
|
||||||
expect(message).to end_with("\033[0m")
|
expect(message).to end_with("\033[0m")
|
||||||
end
|
end
|
||||||
|
|
||||||
subject.output("foo", bold: false)
|
subject.output("foo", bold: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -189,20 +142,37 @@ describe Vagrant::UI::Colored do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Vagrant::UI::BasicScope do
|
describe Vagrant::UI::Prefixed do
|
||||||
let(:scope) { "foo" }
|
let(:prefix) { "foo" }
|
||||||
let(:ui) { double("ui") }
|
let(:ui) { Vagrant::UI::Basic.new }
|
||||||
|
|
||||||
subject { described_class.new(ui, scope) }
|
subject { described_class.new(ui, prefix) }
|
||||||
|
|
||||||
|
describe "#detail" do
|
||||||
|
it "prefixes with spaces and the message" do
|
||||||
|
ui.should_receive(:safe_puts).with(" #{prefix}: foo", anything)
|
||||||
|
subject.detail("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prefixes every line" do
|
||||||
|
ui.should_receive(:detail).with(" #{prefix}: foo\n #{prefix}: bar", bold: false)
|
||||||
|
subject.detail("foo\nbar")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't prefix if requestsed" do
|
||||||
|
ui.should_receive(:detail).with("foo", prefix: false, bold: false)
|
||||||
|
subject.detail("foo", prefix: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#machine" do
|
describe "#machine" do
|
||||||
it "sets the scope option" do
|
it "sets the scope option" do
|
||||||
ui.should_receive(:machine).with(:foo, scope: scope)
|
ui.should_receive(:machine).with(:foo, scope: prefix)
|
||||||
subject.machine(:foo)
|
subject.machine(:foo)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "preserves existing options" do
|
it "preserves existing options" do
|
||||||
ui.should_receive(:machine).with(:foo, :bar, foo: :bar, scope: scope)
|
ui.should_receive(:machine).with(:foo, :bar, foo: :bar, scope: prefix)
|
||||||
subject.machine(:foo, :bar, foo: :bar)
|
subject.machine(:foo, :bar, foo: :bar)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -215,24 +185,23 @@ describe Vagrant::UI::BasicScope do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#output" do
|
describe "#output" do
|
||||||
it "prefixes with the scope" do
|
it "prefixes with an arrow and the message" do
|
||||||
ui.should_receive(:output).with("#{scope}: foo", anything)
|
ui.should_receive(:output).with("==> #{prefix}: foo", anything)
|
||||||
subject.output("foo")
|
subject.output("foo")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not prefix if told not to" do
|
|
||||||
ui.should_receive(:output).with("foo", anything)
|
|
||||||
subject.output("foo", prefix: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "prefixes every line" do
|
it "prefixes every line" do
|
||||||
ui.should_receive(:output).with(
|
ui.should_receive(:output).with("==> #{prefix}: foo\n==> #{prefix}: bar", anything)
|
||||||
"#{scope}: foo\n#{scope}: bar", anything)
|
|
||||||
subject.output("foo\nbar")
|
subject.output("foo\nbar")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "puts the scope into the options hash" do
|
it "doesn't prefix if requestsed" do
|
||||||
ui.should_receive(:output).with(anything, scope: scope)
|
ui.should_receive(:output).with("foo", prefix: false, bold: true)
|
||||||
|
subject.output("foo", prefix: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "requests bolding" do
|
||||||
|
ui.should_receive(:output).with("==> #{prefix}: foo", bold: true)
|
||||||
subject.output("foo")
|
subject.output("foo")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue