From afbed7e8164f8bf5dc2b5665dbbc46c005781b85 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 11:02:12 -0800 Subject: [PATCH 01/10] core: add output/detail methods to Ui, prefix with arrows --- bin/vagrant | 2 +- lib/vagrant/ui.rb | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bin/vagrant b/bin/vagrant index 631b35f3b..21c22fedb 100755 --- a/bin/vagrant +++ b/bin/vagrant @@ -124,7 +124,7 @@ begin if !Vagrant.in_installer? # If we're not in the installer, warn. - env.ui.warn(I18n.t("vagrant.general.not_in_installer") + "\n") + env.ui.warn(I18n.t("vagrant.general.not_in_installer") + "\n", prefix: false) end begin diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index d7f11dd04..96bd8a6d7 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -19,7 +19,7 @@ module Vagrant @logger = Log4r::Logger.new("vagrant::ui::interface") end - [:ask, :warn, :error, :info, :success].each do |method| + [:ask, :detail, :warn, :error, :info, :output, :success].each do |method| define_method(method) do |message, *opts| # Log normal console messages @logger.info { "#{method}: #{message}" } @@ -104,6 +104,9 @@ module Vagrant class Basic < Interface include Util::SafePuts + # The prefix for `output` messages. + OUTPUT_PREFIX = "==> " + def initialize super @@ -113,7 +116,7 @@ module Vagrant # Use some light meta-programming to create the various methods to # output text to the UI. These all delegate the real functionality # to `say`. - [:info, :warn, :error, :success].each do |method| + [:detail, :info, :warn, :error, :output, :success].each do |method| class_eval <<-CODE def #{method}(message, *args) super(message) @@ -196,10 +199,14 @@ module Vagrant end # This is called by `say` to format the message for output. - def format_message(type, message, opts=nil) - opts ||= {} - message = "[#{opts[:scope]}] #{message}" if opts[:scope] && opts[:prefix] - message + def format_message(type, message, **opts) + prefix = "" + if !opts.has_key?(:prefix) || opts[:prefix] + prefix = OUTPUT_PREFIX + prefix = " " * OUTPUT_PREFIX.length if type == :detail + end + + prefix + message end end @@ -212,10 +219,11 @@ module Vagrant @scope = scope end - [:ask, :warn, :error, :info, :success].each do |method| + [:ask, :detail, :warn, :error, :info, :output, :success].each do |method| define_method(method) do |message, opts=nil| opts ||= {} opts[:scope] = @scope + message = "#{@scope}: #{message}" if !opts.has_key?(:prefix) || opts[:prefix] @ui.send(method, message, opts) end end From f3d102e0691524172ddfa123f1f464547aad76a4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 17:58:09 -0800 Subject: [PATCH 02/10] core: colorize VM output for each VM in a command --- lib/vagrant/plugin/v2/command.rb | 7 +++++ lib/vagrant/ui.rb | 49 ++++++++++++++++++-------------- lib/vagrant/util/platform.rb | 1 + 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/lib/vagrant/plugin/v2/command.rb b/lib/vagrant/plugin/v2/command.rb index ebee926e3..9a634b7d1 100644 --- a/lib/vagrant/plugin/v2/command.rb +++ b/lib/vagrant/plugin/v2/command.rb @@ -188,7 +188,14 @@ module Vagrant machines.reverse! if options[:reverse] # Go through each VM and yield it! + color_order = [:green, :cyan, :magenta, :yellow, :blue] + color_index = 0 + machines.each do |machine| + # Set the machine color + machine.ui.opts[:color] = color_order[color_index % color_order.length] + color_index += 1 + @logger.info("With machine: #{machine.name} (#{machine.provider.inspect})") yield machine end diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 96bd8a6d7..03c75ce1d 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -15,8 +15,13 @@ module Vagrant # * `error` # * `success` class Interface + # Opts can be used to set some options. These options are implementation + # specific. See the implementation for more docs. + attr_accessor :opts + def initialize @logger = Log4r::Logger.new("vagrant::ui::interface") + @opts = {} end [:ask, :detail, :warn, :error, :info, :output, :success].each do |method| @@ -219,6 +224,13 @@ module Vagrant @scope = scope end + # Return the parent's opts. + # + # @return [Hash] + def opts + @ui.opts + end + [:ask, :detail, :warn, :error, :info, :output, :success].each do |method| define_method(method) do |message, opts=nil| opts ||= {} @@ -248,34 +260,29 @@ module Vagrant class Colored < Basic # Terminal colors COLORS = { - :clear => "\e[0m", - :red => "\e[31m", - :green => "\e[32m", - :yellow => "\e[33m" - } - - # Mapping between type of message and the color to output - COLOR_MAP = { - :warn => COLORS[:yellow], - :error => COLORS[:red], - :success => COLORS[:green] + red: 31, + green: 32, + yellow: 33, + blue: 34, + magenta: 35, + cyan: 36, } # This is called by `say` to format the message for output. - def format_message(type, message, opts=nil) + def format_message(type, message, **opts) # Get the format of the message before adding color. message = super - # Colorize the message if there is a color for this type of message, - # either specified by the options or via the default color map. - if opts.has_key?(:color) - color = COLORS[opts[:color]] - message = "#{color}#{message}#{COLORS[:clear]}" - else - message = "#{COLOR_MAP[type]}#{message}#{COLORS[:clear]}" if COLOR_MAP[type] - end + opts = @opts.merge(opts) + return message if !opts.has_key?(:color) - message + # If it is a detail, it is not bold. Every other message type + # is bolded. + bold = type != :detail + color = COLORS[opts[:color]] + + # Color the message and make sure to reset the color at the end + "\033[#{bold ? 1 : 0};#{color}m#{message}\033[0m" end end end diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index ac3f8ecf3..53da7df0a 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -110,6 +110,7 @@ module Vagrant if windows? return true if ENV.has_key?("ANSICON") return true if cygwin? + return true if ENV["TERM"] == "cygwin" return false end From b557ee56253485b583d9cf86a1bcef6c25d5c416 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 18:04:32 -0800 Subject: [PATCH 03/10] core: align text and make sure its all lined up with prefixes --- lib/vagrant/ui.rb | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 03c75ce1d..50b9ca3ae 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -211,7 +211,11 @@ module Vagrant prefix = " " * OUTPUT_PREFIX.length if type == :detail end - prefix + message + # Fast-path if there is no prefix + return message if prefix.empty? + + # Otherwise, make sure to prefix every line properly + message.split("\n").map { |line| "#{prefix}#{line}" }.join("\n") end end @@ -235,7 +239,16 @@ module Vagrant define_method(method) do |message, opts=nil| opts ||= {} opts[:scope] = @scope - message = "#{@scope}: #{message}" if !opts.has_key?(:prefix) || opts[:prefix] + if !opts.has_key?(:prefix) || opts[:prefix] + first = true + prefix = "#{@scope}: " + prefix_blank = " " * prefix.length + message = message.split("\n").map do |line| + scope = first ? prefix : prefix_blank + first = false + "#{scope}#{line}" + end.join("\n") + end @ui.send(method, message, opts) end end From 5b449c800085c5cd849ae23ac8452bfedd32b99d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 18:15:52 -0800 Subject: [PATCH 04/10] providers/virtualbox: many `detail` level output --- lib/vagrant/ui.rb | 6 +----- .../virtualbox/action/check_guest_additions.rb | 6 ++++-- plugins/providers/virtualbox/action/forward_ports.rb | 6 +++--- plugins/providers/virtualbox/action/network.rb | 11 ++++++++++- templates/locales/en.yml | 6 +++++- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 50b9ca3ae..6f22bde70 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -240,13 +240,9 @@ module Vagrant opts ||= {} opts[:scope] = @scope if !opts.has_key?(:prefix) || opts[:prefix] - first = true prefix = "#{@scope}: " - prefix_blank = " " * prefix.length message = message.split("\n").map do |line| - scope = first ? prefix : prefix_blank - first = false - "#{scope}#{line}" + "#{prefix}#{line}" end.join("\n") end @ui.send(method, message, opts) diff --git a/plugins/providers/virtualbox/action/check_guest_additions.rb b/plugins/providers/virtualbox/action/check_guest_additions.rb index 77552699d..d6a388ece 100644 --- a/plugins/providers/virtualbox/action/check_guest_additions.rb +++ b/plugins/providers/virtualbox/action/check_guest_additions.rb @@ -7,11 +7,13 @@ module VagrantPlugins end def call(env) + env[:ui].output(I18n.t("vagrant.virtualbox.checking_guest_additions")) + # Use the raw interface for now, while the virtualbox gem # doesn't support guest properties (due to cross platform issues) version = env[:machine].provider.driver.read_guest_additions_version if !version - env[:ui].warn I18n.t("vagrant.actions.vm.check_guest_additions.not_detected") + env[:ui].detail(I18n.t("vagrant.actions.vm.check_guest_additions.not_detected")) else # Read the versions versions = [version, env[:machine].provider.driver.version] @@ -29,7 +31,7 @@ module VagrantPlugins vb_version = versions[1] if guest_version != vb_version - env[:ui].warn(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch", + env[:ui].detail(I18n.t("vagrant.actions.vm.check_guest_additions.version_mismatch", :guest_version => version, :virtualbox_version => vb_version)) end diff --git a/plugins/providers/virtualbox/action/forward_ports.rb b/plugins/providers/virtualbox/action/forward_ports.rb index 705c0a135..b45f074eb 100644 --- a/plugins/providers/virtualbox/action/forward_ports.rb +++ b/plugins/providers/virtualbox/action/forward_ports.rb @@ -25,7 +25,7 @@ module VagrantPlugins end end - env[:ui].info I18n.t("vagrant.actions.vm.forward_ports.forwarding") + env[:ui].output(I18n.t("vagrant.actions.vm.forward_ports.forwarding")) forward_ports @app.call(env) @@ -47,7 +47,7 @@ module VagrantPlugins # because the VM is using Virtualbox NAT networking. Host-only # bridged networking don't require port-forwarding and establishing # forwarded ports on these attachment types has uncertain behaviour. - @env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", + @env[:ui].detail(I18n.t("vagrant.actions.vm.forward_ports.forwarding_entry", message_attributes)) # Verify we have the network interface to attach to @@ -61,7 +61,7 @@ module VagrantPlugins # Port forwarding requires the network interface to be a NAT interface, # so verify that that is the case. if interfaces[fp.adapter][:type] != :nat - @env[:ui].info(I18n.t("vagrant.actions.vm.forward_ports.non_nat", + @env[:ui].detail(I18n.t("vagrant.actions.vm.forward_ports.non_nat", message_attributes)) next end diff --git a/plugins/providers/virtualbox/action/network.rb b/plugins/providers/virtualbox/action/network.rb index 171ad734a..961947370 100644 --- a/plugins/providers/virtualbox/action/network.rb +++ b/plugins/providers/virtualbox/action/network.rb @@ -104,7 +104,16 @@ module VagrantPlugins if !adapters.empty? # Enable the adapters @logger.info("Enabling adapters...") - env[:ui].info I18n.t("vagrant.actions.vm.network.preparing") + env[:ui].output(I18n.t("vagrant.actions.vm.network.preparing")) + adapters.each do |adapter| + env[:ui].detail(I18n.t( + "vagrant.virtualbox.network_adapter", + adapter: adapter[:adapter].to_s, + type: adapter[:type].to_s, + extra: "", + )) + end + env[:machine].provider.driver.enable_adapters(adapters) end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index b6b0f90a8..ae6acd861 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -124,6 +124,10 @@ en: The 'run_file' specified could not be found. virtualbox: + checking_guest_additions: |- + Checking for guest additions in VM... + network_adapter: |- + Adapter %{adapter}: %{type}%{extra} config: id_in_pre_import: |- The ':id' parameter is not available in "pre-import" customizations. @@ -1114,7 +1118,7 @@ en: Fixed port collision for %{guest_port} => %{host_port}. Now on port %{new_port}. forwarding: Forwarding ports... forwarding_entry: |- - -- %{guest_port} => %{host_port} (adapter %{adapter}) + %{guest_port} => %{host_port} (adapter %{adapter}) non_nat: |- VirtualBox adapter #%{adapter} not configured as "NAT". Skipping port forwards on this adapter. From ea77194384fcd7316f968e2d2629b105cfb7b053 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 18:21:55 -0800 Subject: [PATCH 05/10] providers/virtualbox: more detailed output --- plugins/providers/virtualbox/action/set_name.rb | 4 ++-- plugins/providers/virtualbox/synced_folder.rb | 11 ++++++----- templates/locales/en.yml | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/providers/virtualbox/action/set_name.rb b/plugins/providers/virtualbox/action/set_name.rb index 649b08d27..e75670846 100644 --- a/plugins/providers/virtualbox/action/set_name.rb +++ b/plugins/providers/virtualbox/action/set_name.rb @@ -35,8 +35,8 @@ module VagrantPlugins if vms.has_key?(name) @logger.info("Not setting the name because our name is already set.") else - @logger.info("Setting the name of the VM: #{name}") - env[:ui].info(I18n.t("vagrant.actions.vm.set_name.setting_name")) + env[:ui].info(I18n.t( + "vagrant.actions.vm.set_name.setting_name", name: name)) env[:machine].provider.driver.set_name(name) end diff --git a/plugins/providers/virtualbox/synced_folder.rb b/plugins/providers/virtualbox/synced_folder.rb index 419b70a54..dfd8251dc 100644 --- a/plugins/providers/virtualbox/synced_folder.rb +++ b/plugins/providers/virtualbox/synced_folder.rb @@ -35,12 +35,13 @@ module VagrantPlugins end # Go through each folder and mount - machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting")) + machine.ui.output(I18n.t("vagrant.actions.vm.share_folders.mounting")) folders.each do |id, data| if data[:guestpath] # Guest path specified, so mount the folder to specified point - machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.mounting_entry", - :guest_path => data[:guestpath])) + machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.mounting_entry", + guestpath: data[:guestpath], + hostpath: data[:hostpath])) # Dup the data so we can pass it to the guest API data = data.dup @@ -55,8 +56,8 @@ module VagrantPlugins :mount_virtualbox_shared_folder, id, data[:guestpath], data) else # If no guest path is specified, then automounting is disabled - machine.ui.info(I18n.t("vagrant.actions.vm.share_folders.nomount_entry", - :host_path => data[:hostpath])) + machine.ui.detail(I18n.t("vagrant.actions.vm.share_folders.nomount_entry", + :hostpath => data[:hostpath])) end end end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index ae6acd861..03b376c8a 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1189,11 +1189,11 @@ en: share_folders: creating: Creating shared folders metadata... mounting: Mounting shared folders... - mounting_entry: "-- %{guest_path}" - nomount_entry: "-- Automounting disabled: %{host_path}" + mounting_entry: "%{guestpath} => %{hostpath}" + nomount_entry: "Automounting disabled: %{hostpath}" set_name: setting_name: |- - Setting the name of the VM... + Setting the name of the VM: %{name} suspend: suspending: Saving VM state and suspending execution... From f713e43b003cb1fd5850a4254ef50dbe7acd3fb0 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 18:28:23 -0800 Subject: [PATCH 06/10] Fix tests for new UI methods --- test/unit/vagrant/plugin/v2/command_test.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/unit/vagrant/plugin/v2/command_test.rb b/test/unit/vagrant/plugin/v2/command_test.rb index d4e28587c..a5b9da1ad 100644 --- a/test/unit/vagrant/plugin/v2/command_test.rb +++ b/test/unit/vagrant/plugin/v2/command_test.rb @@ -75,9 +75,11 @@ describe Vagrant::Plugin::V2::Command do it "should yield every VM in order is no name is given" do foo_vm = double("foo") foo_vm.stub(:name => "foo", :provider => :foobarbaz) + foo_vm.stub(ui: Vagrant::UI::Silent.new) bar_vm = double("bar") bar_vm.stub(:name => "bar", :provider => :foobarbaz) + bar_vm.stub(ui: Vagrant::UI::Silent.new) environment.stub(:machine_names => [:foo, :bar]) environment.stub(:machine).with(:foo, default_provider).and_return(foo_vm) @@ -102,6 +104,7 @@ describe Vagrant::Plugin::V2::Command do it "yields the given VM if a name is given" do foo_vm = double("foo") foo_vm.stub(:name => "foo", :provider => :foobarbaz) + foo_vm.stub(ui: Vagrant::UI::Silent.new) environment.stub(:machine).with(:foo, default_provider).and_return(foo_vm) @@ -115,6 +118,7 @@ describe Vagrant::Plugin::V2::Command do provider = :foobarbaz foo_vm.stub(:name => "foo", :provider => provider) + foo_vm.stub(ui: Vagrant::UI::Silent.new) environment.stub(:machine).with(:foo, provider).and_return(foo_vm) vms = [] @@ -138,6 +142,7 @@ describe Vagrant::Plugin::V2::Command do environment.stub(:active_machines => [[name, provider]]) environment.stub(:machine).with(name, provider).and_return(vmware_vm) vmware_vm.stub(:name => name, :provider => provider) + vmware_vm.stub(ui: Vagrant::UI::Silent.new) vms = [] instance.with_target_vms(name.to_s) { |vm| vms << vm } @@ -151,7 +156,7 @@ describe Vagrant::Plugin::V2::Command do environment.stub(:active_machines => [[name, provider]]) environment.stub(:machine).with(name, provider).and_return(vmware_vm) - vmware_vm.stub(:name => name, :provider => provider) + vmware_vm.stub(:name => name, :provider => provider, ui: Vagrant::UI::Silent.new) vms = [] instance.with_target_vms(name.to_s, :provider => provider) { |vm| vms << vm } @@ -164,6 +169,7 @@ describe Vagrant::Plugin::V2::Command do environment.stub(:machine).with(name, default_provider).and_return(machine) machine.stub(:name => name, :provider => default_provider) + machine.stub(ui: Vagrant::UI::Silent.new) results = [] instance.with_target_vms(name.to_s) { |m| results << m } @@ -180,6 +186,7 @@ describe Vagrant::Plugin::V2::Command do environment.stub(:machine_names => []) environment.stub(:primary_machine_name => name) vmware_vm.stub(:name => name, :provider => provider) + vmware_vm.stub(ui: Vagrant::UI::Silent.new) vms = [] instance.with_target_vms(nil, :single_target => true) { |vm| vms << vm } @@ -195,6 +202,7 @@ describe Vagrant::Plugin::V2::Command do environment.stub(:machine_names => []) environment.stub(:primary_machine_name => name) machine.stub(:name => name, :provider => default_provider) + machine.stub(ui: Vagrant::UI::Silent.new) vms = [] instance.with_target_vms(nil, :single_target => true) { |vm| vms << machine } From 1b8f1a3864b318fccc5a77a0184a6f301bdc6153 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 20:34:25 -0800 Subject: [PATCH 07/10] core: convert more output to `output` method --- lib/vagrant/action/builtin/wait_for_communicator.rb | 4 ++-- lib/vagrant/plugin/v2/communicator.rb | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/vagrant/action/builtin/wait_for_communicator.rb b/lib/vagrant/action/builtin/wait_for_communicator.rb index c30127659..c69784629 100644 --- a/lib/vagrant/action/builtin/wait_for_communicator.rb +++ b/lib/vagrant/action/builtin/wait_for_communicator.rb @@ -50,7 +50,7 @@ module Vagrant end # Wait for a result or an interrupt - env[:ui].info I18n.t("vagrant.boot_waiting") + env[:ui].output(I18n.t("vagrant.boot_waiting")) while ready_thr.alive? && states_thr.alive? sleep 1 return if env[:interrupted] @@ -72,7 +72,7 @@ module Vagrant raise Errors::VMBootTimeout end - env[:ui].info I18n.t("vagrant.boot_completed") + env[:ui].output(I18n.t("vagrant.boot_completed")) # Make sure our threads are all killed ready_thr.kill diff --git a/lib/vagrant/plugin/v2/communicator.rb b/lib/vagrant/plugin/v2/communicator.rb index 1ac8ef1bb..ebe704918 100644 --- a/lib/vagrant/plugin/v2/communicator.rb +++ b/lib/vagrant/plugin/v2/communicator.rb @@ -49,6 +49,10 @@ module Vagrant # wait_for_ready waits until the communicator is ready, blocking # until then. It will wait up to the given duration or raise an # exception if something goes wrong. + # + # @param [Fixnum] duration Timeout in seconds. + # @return [Boolean] Will return true on successful connection + # or false on timeout. def wait_for_ready(duration) # By default, we implement a naive solution. begin From ac2ca2537dbf3a71300434b1358d10da677d0689 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 20:41:17 -0800 Subject: [PATCH 08/10] core: Ui color should be red on errors, yellow on warnings --- lib/vagrant/ui.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 6f22bde70..2796720b0 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -285,6 +285,10 @@ module Vagrant opts = @opts.merge(opts) return message if !opts.has_key?(:color) + # Special case some colors for certain message types + opts[:color] = :red if type == :error + opts[:color] = :yellow if type == :warn + # If it is a detail, it is not bold. Every other message type # is bolded. bold = type != :detail From 0eec9aa599e0577417c7b219e7caf15581b65e81 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 21:31:07 -0800 Subject: [PATCH 09/10] core: extensive tests for Vagrant::UI classes --- lib/vagrant/ui.rb | 10 +- test/unit/vagrant/ui_test.rb | 228 +++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 test/unit/vagrant/ui_test.rb diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 2796720b0..6d1a4faf2 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -175,9 +175,9 @@ module Vagrant # This method handles actually outputting a message of a given type # to the console. - def say(type, message, opts=nil) + def say(type, message, **opts) defaults = { :new_line => true, :prefix => true } - opts = defaults.merge(opts || {}) + opts = defaults.merge(@opts).merge(opts) # Determine whether we're expecting to output our # own new line or not. @@ -221,6 +221,8 @@ module Vagrant # This implements a scope for the {Basic} UI. class BasicScope < Interface + attr_reader :scope, :ui + def initialize(ui, scope) super() @@ -283,12 +285,14 @@ module Vagrant message = super opts = @opts.merge(opts) - return message if !opts.has_key?(:color) # Special case some colors for certain message types opts[:color] = :red if type == :error opts[:color] = :yellow if type == :warn + # If there is no color specified, exit early + return message if !opts.has_key?(:color) + # If it is a detail, it is not bold. Every other message type # is bolded. bold = type != :detail diff --git a/test/unit/vagrant/ui_test.rb b/test/unit/vagrant/ui_test.rb new file mode 100644 index 000000000..50ded7798 --- /dev/null +++ b/test/unit/vagrant/ui_test.rb @@ -0,0 +1,228 @@ +require File.expand_path("../../base", __FILE__) + +describe Vagrant::UI::Basic do + context "in general" do + it "outputs within the a new thread" do + current = Thread.current.object_id + + subject.should_receive(:safe_puts).with do |*args| + expect(Thread.current.object_id).to_not eq(current) + true + end + + subject.output("foo") + end + + it "outputs using `puts` by default" do + subject.should_receive(:safe_puts).with do |message, **opts| + expect(opts[:printer]).to eq(:puts) + true + end + + subject.output("foo") + end + + it "outputs using `print` if new_line is false" do + subject.should_receive(:safe_puts).with do |message, **opts| + expect(opts[:printer]).to eq(:print) + true + end + + subject.output("foo", new_line: false) + end + + it "outputs using `print` if new_line is false" do + subject.should_receive(:safe_puts).with do |message, **opts| + expect(opts[:printer]).to eq(:print) + true + end + + subject.output("foo", new_line: false) + end + + it "outputs to stdout" do + subject.should_receive(:safe_puts).with do |message, **opts| + expect(opts[:io]).to be($stdout) + true + end + + subject.output("foo") + end + + it "outputs to stderr for errors" do + subject.should_receive(:safe_puts).with do |message, **opts| + expect(opts[:io]).to be($stderr) + true + end + + subject.error("foo") + 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 + +describe Vagrant::UI::Colored do + include_context "unit" + + before do + # We don't want any prefixes on anything... + subject.opts[:prefix] = false + end + + describe "#detail" do + it "colors output nothing by default" do + subject.should_receive(:safe_puts).with("foo", anything) + subject.detail("foo") + end + + it "does not bold by default with a color" do + subject.should_receive(:safe_puts).with do |message, *args| + expect(message).to start_with("\033[0;31m") + expect(message).to end_with("\033[0m") + end + + subject.detail("foo", color: :red) + end + end + + describe "#error" do + it "colors red" do + subject.should_receive(:safe_puts).with do |message, *args| + expect(message).to start_with("\033[1;31m") + expect(message).to end_with("\033[0m") + end + + subject.error("foo") + end + end + + describe "#output" do + it "colors output nothing by default" do + subject.should_receive(:safe_puts).with("foo", anything) + subject.output("foo") + end + + it "colors output to color specified in global opts" do + subject.opts[:color] = :red + + subject.should_receive(:safe_puts).with do |message, *args| + expect(message).to start_with("\033[1;31m") + expect(message).to end_with("\033[0m") + end + + subject.output("foo") + end + + it "colors output to specified color over global opts" do + subject.opts[:color] = :red + + subject.should_receive(:safe_puts).with do |message, *args| + expect(message).to start_with("\033[1;32m") + expect(message).to end_with("\033[0m") + end + + subject.output("foo", color: :green) + end + end + + describe "#warn" do + it "colors yellow" do + subject.should_receive(:safe_puts).with do |message, *args| + expect(message).to start_with("\033[1;33m") + expect(message).to end_with("\033[0m") + end + + subject.warn("foo") + end + end +end + +describe Vagrant::UI::BasicScope do + let(:scope) { "foo" } + let(:ui) { double("ui") } + + subject { described_class.new(ui, scope) } + + describe "#machine" do + it "sets the scope option" do + ui.should_receive(:machine).with(:foo, scope: scope) + subject.machine(:foo) + end + + it "preserves existing options" do + ui.should_receive(:machine).with(:foo, :bar, foo: :bar, scope: scope) + subject.machine(:foo, :bar, foo: :bar) + end + end + + describe "#opts" do + it "is the parent's opts" do + ui.stub(opts: Object.new) + expect(subject.opts).to be(ui.opts) + end + end + + describe "#output" do + it "prefixes with the scope" do + ui.should_receive(:output).with("#{scope}: foo", anything) + subject.output("foo") + 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 + ui.should_receive(:output).with( + "#{scope}: foo\n#{scope}: bar", anything) + subject.output("foo\nbar") + end + + it "puts the scope into the options hash" do + ui.should_receive(:output).with(anything, scope: scope) + subject.output("foo") + end + end +end From 3f62addac2db97bae77c91c8e238dfe75dddf4df Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 17 Jan 2014 21:53:17 -0800 Subject: [PATCH 10/10] core: make output white for now --- lib/vagrant/plugin/v2/command.rb | 2 +- lib/vagrant/ui.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/vagrant/plugin/v2/command.rb b/lib/vagrant/plugin/v2/command.rb index 9a634b7d1..146e502ac 100644 --- a/lib/vagrant/plugin/v2/command.rb +++ b/lib/vagrant/plugin/v2/command.rb @@ -188,7 +188,7 @@ module Vagrant machines.reverse! if options[:reverse] # Go through each VM and yield it! - color_order = [:green, :cyan, :magenta, :yellow, :blue] + color_order = [:white] color_index = 0 machines.each do |machine| diff --git a/lib/vagrant/ui.rb b/lib/vagrant/ui.rb index 6d1a4faf2..b24f427b1 100644 --- a/lib/vagrant/ui.rb +++ b/lib/vagrant/ui.rb @@ -277,6 +277,7 @@ module Vagrant blue: 34, magenta: 35, cyan: 36, + white: 37, } # This is called by `say` to format the message for output.