Added a compass command-line option to watch a project and automatically recompile when it changes. Use compass --watch.
This commit is contained in:
parent
d66f659d9a
commit
3fe8f6a675
42
lib/compass/commands/watch_project.rb
Normal file
42
lib/compass/commands/watch_project.rb
Normal 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
|
@ -6,6 +6,30 @@ module Compass
|
||||
module Exec
|
||||
class ExecError < StandardError
|
||||
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
|
||||
|
||||
attr_accessor :args, :options, :opts
|
||||
@ -24,12 +48,7 @@ module Compass
|
||||
if e.is_a?(ExecError) || e.is_a?(OptionParser::ParseError)
|
||||
$stderr.puts e.message
|
||||
else
|
||||
$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
|
||||
::Compass::Exec.report_error(e, @options)
|
||||
end
|
||||
exit 1
|
||||
end
|
||||
@ -73,6 +92,10 @@ END
|
||||
self.options[:command] = :update_project
|
||||
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|
|
||||
self.options[:framework] = framework
|
||||
end
|
||||
@ -121,18 +144,6 @@ 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)
|
||||
require File.join(File.dirname(__FILE__), 'commands', command.to_s)
|
||||
command_class_name = command.to_s.split(/_/).map{|p| p.capitalize}.join('')
|
||||
|
Loading…
Reference in New Issue
Block a user