5

I have a ruby script (Guardfile) that executes a rake command.

guard :shell do

  watch(%r{^manifests\/.+\.pp$}) do |m|
    spec = `rake spec`
    retval = $?.to_i
    case retval
    when 0
       if spec.length > 0 then
          puts spec
          n "#{m[0]} Tests Failed!", 'Rake Spec', :pending         
       else
          puts spec
          n "#{m[0]} Tests Passed!", 'Rake Spec', :pending

       end
    end
end

When I run a 'rake spec' from the command line, outputs are colorized. How could I make it so the output of the ruby script is also colorized?

From command line:

enter image description here

From ruby script:

enter image description here

Update

I was able to sort-of work around the problem by using script

bash command preserve color when piping

spec = `script -q /dev/null rake spec`

This still has the downside of not scrolling the text in real time. While it does preserve the colors, it does not output anything until the very end.

Is there a more native way to do this that will allow for scrolling?

Community
  • 1
  • 1
spuder
  • 17,437
  • 19
  • 87
  • 153

2 Answers2

2

First, rake spec --color won't work, because you're passing --color to rake, and not rspec.

Jay Mitchell's suggestion for color should work - by putting this in your .rspec file:

--color

As for having "live" output, guard-shell has an eager command for this:

https://github.com/guard/guard-shell/blob/master/lib/guard/shell.rb#L37-L51

Unfortunately, guard-shell has 2 important shortcomings:

  • it doesn't give you access to the exit code

  • it doesn't properly report failures in Guard (which causes other tasks to run)

So the eager method of Guard::Shell is useless for our needs here.

Instead, the following should work:

# a version of Guard::Shell's 'eager()' which returns the result
class InPty
  require 'pty'

  def self.run(command)
    PTY.spawn(command) do |r, w, pid|
      begin
        $stdout.puts
        r.each {|line| $stdout.print line }
      rescue Errno::EIO
      end
      Process.wait(pid)
    end

    $?.success?
  rescue PTY::ChildExited
  end
end

# A hack so that Guard::Shell properly throws :task_has_failed
class ProperGuardPluginFailure
  def to_s
    throw :task_has_failed
  end
end

guard :shell, any_return: true do
  watch(%r{^manifests\/.+\.pp$}) do |m|
    ok = InPty.run('rake spec')
    status, type = ok ? ['Passed', :success] : ['Failed', :failed]
    n "#{m[0]} Tests #{status}!", 'Rake Spec', type
    ok ? nil : ProperGuardPluginFailure.new
  end
end

The above looks ideal for a new guard plugin - good idea?

Cezary Baginski
  • 2,077
  • 15
  • 14
-1

I am unfamiliar with Guardfiles. Can you use gems? The colorize gem is great.

https://github.com/fazibear/colorize

Install it:

$ sudo gem install colorize

Use it:

require 'colorize'

puts "Tests failed!".red
puts "Tests passed!".green
Darren Stone
  • 2,008
  • 13
  • 16