Added a compass command-line option to watch a project and automatically recompile when it changes. Use compass --watch.

This commit is contained in:
Chris Eppstein 2008-11-04 11:55:57 -08:00
parent d66f659d9a
commit 3fe8f6a675
2 changed files with 71 additions and 18 deletions

View File

@ -0,0 +1,42 @@
require 'rubygems'
require 'sass'
require 'fileutils'
require 'pathname'
require File.join(File.dirname(__FILE__), 'base')
require File.join(File.dirname(__FILE__), 'update_project')
module Compass
module Commands
class WatchProject < UpdateProject
attr_accessor :last_update_time
def perform
super
self.last_update_time = most_recent_update_time
loop do
# TODO: Make this efficient by using filesystem monitoring.
sleep 1
file, t = should_update?
if t
begin
puts ">>> Change detected to #{file} <<<"
super
rescue StandardError => e
::Compass::Exec.report_error(e, options)
end
self.last_update_time = t
end
end
end
def most_recent_update_time
Dir.glob(separate("#{project_directory}/src/**/*.sass")).map {|sass_file| File.stat(sass_file).mtime}.max
end
def should_update?
t = most_recent_update_time
if t > last_update_time
file = Dir.glob(separate("#{project_directory}/src/**/*.sass")).detect {|sass_file| File.stat(sass_file).mtime >= t}
[file, t]
end
end
end
end
end

View File

@ -6,6 +6,30 @@ module Compass
module Exec module Exec
class ExecError < StandardError class ExecError < StandardError
end end
def report_error(e, options)
$stderr.puts "#{e.class} on line #{get_line e} of #{get_file e}: #{e.message}"
if options[:trace]
e.backtrace[1..-1].each { |t| $stderr.puts " #{t}" }
else
$stderr.puts "Run with --trace to see the full backtrace"
end
end
def get_file(exception)
exception.backtrace[0].split(/:/, 2)[0]
end
def get_line(exception)
# SyntaxErrors have weird line reporting
# when there's trailing whitespace,
# which there is for Haml documents.
return exception.message.scan(/:(\d+)/)[0] if exception.is_a?(::Haml::SyntaxError)
exception.backtrace[0].scan(/:(\d+)/)[0]
end
module_function :report_error, :get_file, :get_line
class Compass class Compass
attr_accessor :args, :options, :opts attr_accessor :args, :options, :opts
@ -24,12 +48,7 @@ module Compass
if e.is_a?(ExecError) || e.is_a?(OptionParser::ParseError) if e.is_a?(ExecError) || e.is_a?(OptionParser::ParseError)
$stderr.puts e.message $stderr.puts e.message
else else
$stderr.puts "#{e.class} on line #{get_line e} of #{get_file e}: #{e.message}" ::Compass::Exec.report_error(e, @options)
if @options[:trace]
e.backtrace[1..-1].each { |t| $stderr.puts " #{t}" }
else
$stderr.puts "Run with --trace to see the full backtrace"
end
end end
exit 1 exit 1
end end
@ -73,6 +92,10 @@ END
self.options[:command] = :update_project self.options[:command] = :update_project
end end
opts.on('-w', '--watch', :NONE, 'Monitor the current project for changes and update') do
self.options[:command] = :watch_project
end
opts.on('-f FRAMEWORK', '--framework FRAMEWORK', [:compass, :blueprint], 'Set up a new project using the selected framework. Legal values: compass (default), blueprint') do |framework| opts.on('-f FRAMEWORK', '--framework FRAMEWORK', [:compass, :blueprint], 'Set up a new project using the selected framework. Legal values: compass (default), blueprint') do |framework|
self.options[:framework] = framework self.options[:framework] = framework
end end
@ -121,18 +144,6 @@ END
end end
end end
def get_file(exception)
exception.backtrace[0].split(/:/, 2)[0]
end
def get_line(exception)
# SyntaxErrors have weird line reporting
# when there's trailing whitespace,
# which there is for Haml documents.
return exception.message.scan(/:(\d+)/)[0] if exception.is_a?(::Haml::SyntaxError)
exception.backtrace[0].scan(/:(\d+)/)[0]
end
def do_command(command) def do_command(command)
require File.join(File.dirname(__FILE__), 'commands', command.to_s) require File.join(File.dirname(__FILE__), 'commands', command.to_s)
command_class_name = command.to_s.split(/_/).map{|p| p.capitalize}.join('') command_class_name = command.to_s.split(/_/).map{|p| p.capitalize}.join('')