Permalink
Browse files

[Compiler] Rewrite of the watch command that adds the following impro…

…vements:

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.
  • Loading branch information...
chriseppstein committed Jun 28, 2009
1 parent 15ebbfe commit 0a232bd922695f6f659fac9f90466745d4425839
Showing with 49 additions and 31 deletions.
  1. +7 −0 lib/compass/actions.rb
  2. +2 −2 lib/compass/commands/update_project.rb
  3. +27 −28 lib/compass/commands/watch_project.rb
  4. +13 −1 lib/compass/compiler.rb
View
@@ -73,6 +73,13 @@ def compile(sass_filename, css_filename, options)
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
@@ -21,12 +21,12 @@ def perform
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
@@ -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."
Signal.trap("INT") do
puts ""
exit 0
end
puts ">>> Compass is watching for changes. Press Ctrl-C to Stop."
loop do
# TODO: Make this efficient by using filesystem monitoring.
begin
sleep 1
rescue Interrupt
puts ""
exit 0
end
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
compiler = new_compiler_instance(:quiet => true)
remove_obsolete_css(compiler)
recompile(compiler)
sleep 1
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
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 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]
def recompile(compiler)
if file = compiler.out_of_date?
begin
puts ">>> Change detected to: #{file}"
compiler.run
rescue StandardError => e
::Compass::Exec.report_error(e, options)
end
end
end
end
end
end
View
@@ -22,13 +22,25 @@ def stylesheet_name(sass_file)
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|

0 comments on commit 0a232bd

Please sign in to comment.