[Compiler] Rewrite of the watch command that adds the following improvements:

1. For robustness, recompile is now based on comparison of corresponding css/sass file timestamps.
2. If a sass file is removed, the corresponding css file is automatically deleted.
3. CSS files will be automatically recompiled if removed. It is no longer necessary to resave the sass file.
4. First time compile is not performed if not necessary.
This commit is contained in:
Chris Eppstein 2009-06-27 18:29:47 -07:00
parent 15ebbfef30
commit 0a232bd922
4 changed files with 51 additions and 33 deletions

View File

@ -73,6 +73,13 @@ module Compass
end
end
def remove(file_name)
if File.exists?(file_name)
File.unlink file_name
logger.record :remove, basename(file_name)
end
end
def basename(file)
relativize(file) {|f| File.basename(file)}
end

View File

@ -21,12 +21,12 @@ module Compass
end
end
def new_compiler_instance(options = {})
def new_compiler_instance(additional_options = {})
Compass::Compiler.new(working_path,
projectize(Compass.configuration.sass_dir),
projectize(Compass.configuration.css_dir),
Compass.sass_engine_options.merge(:quiet => options[:quiet],
:force => options[:force]).merge(options))
:force => options[:force]).merge(additional_options))
end
end

View File

@ -7,45 +7,44 @@ module Compass
module Commands
class WatchProject < UpdateProject
attr_accessor :last_update_time
attr_accessor :last_update_time, :last_sass_files
def perform
puts ">>> Compiling all stylesheets."
super
self.last_update_time = most_recent_update_time
puts ">>> Compass is now watching for changes. Press Ctrl-C to Stop."
loop do
# TODO: Make this efficient by using filesystem monitoring.
begin
sleep 1
rescue Interrupt
Signal.trap("INT") do
puts ""
exit 0
end
file, t = should_update?
if t
puts ">>> Compass is watching for changes. Press Ctrl-C to Stop."
loop do
# TODO: Make this efficient by using filesystem monitoring.
compiler = new_compiler_instance(:quiet => true)
remove_obsolete_css(compiler)
recompile(compiler)
sleep 1
end
end
def remove_obsolete_css(compiler)
sass_files = compiler.sass_files
deleted_sass_files = (last_sass_files || []) - sass_files
deleted_sass_files.each do |deleted_sass_file|
css_file = compiler.corresponding_css_file(deleted_sass_file)
remove(css_file) if File.exists?(css_file)
end
self.last_sass_files = sass_files
end
def recompile(compiler)
if file = compiler.out_of_date?
begin
puts ">>> Change detected to: #{file}"
super
compiler.run
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("#{projectize(Compass.configuration.sass_dir)}/**/*.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("#{projectize(Compass.configuration.sass_dir)}/**/*.sass")).detect {|sass_file| File.stat(sass_file).mtime >= t}
[file, t]
end
end
end
end
end

View File

@ -22,13 +22,25 @@ module Compass
end
def css_files
@css_files ||= sass_files.map{|sass_file| "#{to}/#{stylesheet_name(sass_file)}.css"}
@css_files ||= sass_files.map{|sass_file| corresponding_css_file(sass_file)}
end
def corresponding_css_file(sass_file)
"#{to}/#{stylesheet_name(sass_file)}.css"
end
def target_directories
css_files.map{|css_file| File.dirname(css_file)}.uniq.sort.sort_by{|d| d.length }
end
def out_of_date?
sass_files.zip(css_files).each do |sass_filename, css_filename|
return sass_filename unless File.exists?(css_filename)
return sass_filename if File.stat(sass_filename).mtime > File.stat(css_filename).mtime
end
false
end
def run
Compass.configure_sass_plugin!
target_directories.each do |dir|