diff --git a/lib/puppet/feature/ansicolor.rb b/lib/puppet/feature/ansicolor.rb deleted file mode 100644 index 74ec1a49c..000000000 --- a/lib/puppet/feature/ansicolor.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'puppet/util/feature' - -Puppet.features.rubygems? -Puppet.features.add(:ansicolor, - Puppet.features.microsoft_windows? ? { :libs => 'win32console' } : {} ) diff --git a/lib/puppet/util/colors.rb b/lib/puppet/util/colors.rb index ab57fa2a6..60196bece 100644 --- a/lib/puppet/util/colors.rb +++ b/lib/puppet/util/colors.rb @@ -1,102 +1,125 @@ module Puppet::Util::Colors BLACK = {:console => "\e[0;30m", :html => "color: #FFA0A0" } RED = {:console => "\e[0;31m", :html => "color: #FFA0A0" } GREEN = {:console => "\e[0;32m", :html => "color: #00CD00" } YELLOW = {:console => "\e[0;33m", :html => "color: #FFFF60" } BLUE = {:console => "\e[0;34m", :html => "color: #80A0FF" } MAGENTA = {:console => "\e[0;35m", :html => "color: #FFA500" } CYAN = {:console => "\e[0;36m", :html => "color: #40FFFF" } WHITE = {:console => "\e[0;37m", :html => "color: #FFFFFF" } HBLACK = {:console => "\e[1;30m", :html => "color: #FFA0A0" } HRED = {:console => "\e[1;31m", :html => "color: #FFA0A0" } HGREEN = {:console => "\e[1;32m", :html => "color: #00CD00" } HYELLOW = {:console => "\e[1;33m", :html => "color: #FFFF60" } HBLUE = {:console => "\e[1;34m", :html => "color: #80A0FF" } HMAGENTA = {:console => "\e[1;35m", :html => "color: #FFA500" } HCYAN = {:console => "\e[1;36m", :html => "color: #40FFFF" } HWHITE = {:console => "\e[1;37m", :html => "color: #FFFFFF" } BG_RED = {:console => "\e[0;41m", :html => "background: #FFA0A0"} BG_GREEN = {:console => "\e[0;42m", :html => "background: #00CD00"} BG_YELLOW = {:console => "\e[0;43m", :html => "background: #FFFF60"} BG_BLUE = {:console => "\e[0;44m", :html => "background: #80A0FF"} BG_MAGENTA = {:console => "\e[0;45m", :html => "background: #FFA500"} BG_CYAN = {:console => "\e[0;46m", :html => "background: #40FFFF"} BG_WHITE = {:console => "\e[0;47m", :html => "background: #FFFFFF"} BG_HRED = {:console => "\e[1;41m", :html => "background: #FFA0A0"} BG_HGREEN = {:console => "\e[1;42m", :html => "background: #00CD00"} BG_HYELLOW = {:console => "\e[1;43m", :html => "background: #FFFF60"} BG_HBLUE = {:console => "\e[1;44m", :html => "background: #80A0FF"} BG_HMAGENTA = {:console => "\e[1;45m", :html => "background: #FFA500"} BG_HCYAN = {:console => "\e[1;46m", :html => "background: #40FFFF"} BG_HWHITE = {:console => "\e[1;47m", :html => "background: #FFFFFF"} RESET = {:console => "\e[0m", :html => "" } Colormap = { :debug => WHITE, :info => GREEN, :notice => CYAN, :warning => YELLOW, :err => HMAGENTA, :alert => RED, :emerg => HRED, :crit => HRED, :black => BLACK, :red => RED, :green => GREEN, :yellow => YELLOW, :blue => BLUE, :magenta => MAGENTA, :cyan => CYAN, :white => WHITE, :hblack => HBLACK, :hred => HRED, :hgreen => HGREEN, :hyellow => HYELLOW, :hblue => HBLUE, :hmagenta => HMAGENTA, :hcyan => HCYAN, :hwhite => HWHITE, :bg_red => BG_RED, :bg_green => BG_GREEN, :bg_yellow => BG_YELLOW, :bg_blue => BG_BLUE, :bg_magenta => BG_MAGENTA, :bg_cyan => BG_CYAN, :bg_white => BG_WHITE, :bg_hred => BG_HRED, :bg_hgreen => BG_HGREEN, :bg_hyellow => BG_HYELLOW, :bg_hblue => BG_HBLUE, :bg_hmagenta => BG_HMAGENTA, :bg_hcyan => BG_HCYAN, :bg_hwhite => BG_HWHITE, :reset => { :console => "\e[m", :html => "" } } + # This is how you test for windows without pulling in Puppet.features, which + # we want to avoid for now since this module is used in logging and may be + # needed before feature are initialized + if File::ALT_SEPARATOR + # We're on windows, need win32console for color to work + begin + require 'win32console' + rescue LoadError + def console_has_color? + false + end + else + def console_has_color? + true + end + end + else + # On a posix system we can just enable it + def console_has_color? + true + end + end + def colorize(color, str) case Puppet[:color] when true, :ansi, "ansi", "yes" - if Puppet.features.ansicolor? + if console_has_color? console_color(color, str) else str end when :html, "html" html_color(color, str) else str end end def console_color(color, str) Colormap[color][:console] + str.gsub(RESET[:console], Colormap[color][:console]) + RESET[:console] end def html_color(color, str) span = '' % Colormap[color][:html] "#{span}%s" % str.gsub(//, "\\0#{span}") end end diff --git a/spec/unit/util/colors_spec.rb b/spec/unit/util/colors_spec.rb index 86a062729..f114894da 100755 --- a/spec/unit/util/colors_spec.rb +++ b/spec/unit/util/colors_spec.rb @@ -1,69 +1,69 @@ #!/usr/bin/env ruby require 'spec_helper' describe Puppet::Util::Colors do include Puppet::Util::Colors let (:message) { 'a message' } let (:color) { :black } let (:subject) { self } describe ".console_color" do it { should respond_to :console_color } it "should generate ANSI escape sequences" do subject.console_color(color, message).should == "\e[0;30m#{message}\e[0m" end end describe ".html_color" do it { should respond_to :html_color } it "should generate an HTML span element and style attribute" do subject.html_color(color, message).should =~ /#{message}<\/span>/ end end describe ".colorize" do it { should respond_to :colorize } context "ansicolor supported" do before :each do - Puppet.features.stubs(:ansicolor?).returns(true) + subject.stubs(:console_has_color?).returns(true) end it "should colorize console output" do Puppet[:color] = true subject.expects(:console_color).with(color, message) subject.colorize(:black, message) end it "should not colorize unknown color schemes" do Puppet[:color] = :thisisanunknownscheme subject.colorize(:black, message).should == message end end context "ansicolor not supported" do before :each do - Puppet.features.stubs(:ansicolor?).returns(false) + subject.stubs(:console_has_color?).returns(false) end it "should not colorize console output" do Puppet[:color] = true subject.expects(:console_color).never subject.colorize(:black, message).should == message end it "should colorize html output" do Puppet[:color] = :html subject.expects(:html_color).with(color, message) subject.colorize(color, message) end end end end diff --git a/spec/unit/util/log/destinations_spec.rb b/spec/unit/util/log/destinations_spec.rb index 3017333b5..bbe9b0d9e 100755 --- a/spec/unit/util/log/destinations_spec.rb +++ b/spec/unit/util/log/destinations_spec.rb @@ -1,164 +1,166 @@ #!/usr/bin/env ruby -S rspec require 'spec_helper' require 'puppet/util/log' describe Puppet::Util::Log.desttypes[:report] do before do @dest = Puppet::Util::Log.desttypes[:report] end it "should require a report at initialization" do @dest.new("foo").report.should == "foo" end it "should send new messages to the report" do report = mock 'report' dest = @dest.new(report) report.expects(:<<).with("my log") dest.handle "my log" end end describe Puppet::Util::Log.desttypes[:file] do before do File.stubs(:open) # prevent actually creating the file @class = Puppet::Util::Log.desttypes[:file] end it "should default to automatically flush log output" do @class.new('/tmp/log').autoflush.should == true end describe "when matching" do shared_examples_for "file destination" do it "should match an absolute path" do @class.match?(abspath).should be_true end it "should not match a relative path" do @class.match?(relpath).should be_false end end describe "on POSIX systems", :as_platform => :posix do let (:abspath) { '/tmp/log' } let (:relpath) { 'log' } it_behaves_like "file destination" end describe "on Windows systems", :as_platform => :windows do let (:abspath) { 'C:\\temp\\log.txt' } let (:relpath) { 'log.txt' } it_behaves_like "file destination" end end end describe Puppet::Util::Log.desttypes[:syslog] do let (:klass) { Puppet::Util::Log.desttypes[:syslog] } # these tests can only be run when syslog is present, because # we can't stub the top-level Syslog module describe "when syslog is available", :if => Puppet.features.syslog? do before :each do Syslog.stubs(:opened?).returns(false) Syslog.stubs(:const_get).returns("LOG_KERN").returns(0) Syslog.stubs(:open) end it "should open syslog" do Syslog.expects(:open) klass.new end it "should close syslog" do Syslog.expects(:close) dest = klass.new dest.close end it "should send messages to syslog" do syslog = mock 'syslog' syslog.expects(:info).with("don't panic") Syslog.stubs(:open).returns(syslog) msg = Puppet::Util::Log.new(:level => :info, :message => "don't panic") dest = klass.new dest.handle(msg) end end describe "when syslog is unavailable" do it "should not be a suitable log destination" do Puppet.features.stubs(:syslog?).returns(false) klass.suitable?(:syslog).should be_false end end end describe Puppet::Util::Log.desttypes[:console] do describe "when color is available" do before :each do - Puppet.features.stubs(:ansicolor?).returns(true) + subject.stubs(:console_has_color?).returns(true) end + it "should support color output" do Puppet[:color] = true subject.colorize(:red, 'version').should == "\e[0;31mversion\e[0m" end it "should withhold color output when not appropriate" do Puppet[:color] = false subject.colorize(:red, 'version').should == "version" end it "should handle multiple overlapping colors in a stack-like way" do Puppet[:color] = true vstring = subject.colorize(:red, 'version') subject.colorize(:green, "(#{vstring})").should == "\e[0;32m(\e[0;31mversion\e[0;32m)\e[0m" end it "should handle resets in a stack-like way" do Puppet[:color] = true vstring = subject.colorize(:reset, 'version') subject.colorize(:green, "(#{vstring})").should == "\e[0;32m(\e[mversion\e[0;32m)\e[0m" end end end describe Puppet::Util::Log.desttypes[:telly_prototype_console] do describe "when color is available" do before :each do - Puppet.features.stubs(:ansicolor?).returns(true) + subject.stubs(:console_has_color?).returns(true) end + it "should support color output" do Puppet[:color] = true subject.colorize(:red, 'version').should == "\e[0;31mversion\e[0m" end it "should withhold color output when not appropriate" do Puppet[:color] = false subject.colorize(:red, 'version').should == "version" end it "should handle multiple overlapping colors in a stack-like way" do Puppet[:color] = true vstring = subject.colorize(:red, 'version') subject.colorize(:green, "(#{vstring})").should == "\e[0;32m(\e[0;31mversion\e[0;32m)\e[0m" end it "should handle resets in a stack-like way" do Puppet[:color] = true vstring = subject.colorize(:reset, 'version') subject.colorize(:green, "(#{vstring})").should == "\e[0;32m(\e[mversion\e[0;32m)\e[0m" end end end