Skip to content

Commit

Permalink
[Compiler] Rewrite of the watch command that adds the following impro…
Browse files Browse the repository at this point in the history
…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 0a232bd
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 31 deletions.
7 changes: 7 additions & 0 deletions lib/compass/actions.rb
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions lib/compass/commands/update_project.rb
Expand Up @@ -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
Expand Down
55 changes: 27 additions & 28 deletions lib/compass/commands/watch_project.rb
Expand Up @@ -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
14 changes: 13 additions & 1 deletion lib/compass/compiler.rb
Expand Up @@ -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|
Expand Down

0 comments on commit 0a232bd

Please sign in to comment.