diff --git a/lib/compass/actions.rb b/lib/compass/actions.rb index 10fd7c5f..95b9b06b 100644 --- a/lib/compass/actions.rb +++ b/lib/compass/actions.rb @@ -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 diff --git a/lib/compass/commands/update_project.rb b/lib/compass/commands/update_project.rb index 821a94ed..e00e7a8f 100644 --- a/lib/compass/commands/update_project.rb +++ b/lib/compass/commands/update_project.rb @@ -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 diff --git a/lib/compass/commands/watch_project.rb b/lib/compass/commands/watch_project.rb index 698d9be9..97eb2fe9 100644 --- a/lib/compass/commands/watch_project.rb +++ b/lib/compass/commands/watch_project.rb @@ -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. + 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 - 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 + puts ">>> Change detected to: #{file}" + compiler.run + rescue StandardError => e + ::Compass::Exec.report_error(e, options) 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 \ No newline at end of file diff --git a/lib/compass/compiler.rb b/lib/compass/compiler.rb index 9134553e..84fb3945 100644 --- a/lib/compass/compiler.rb +++ b/lib/compass/compiler.rb @@ -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|