[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:
parent
15ebbfef30
commit
0a232bd922
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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|
|
||||
|
Loading…
Reference in New Issue
Block a user