Don't rely on global callbacks

This commit is contained in:
Chris Eppstein 2011-02-20 10:16:11 -08:00
parent 2142430735
commit 2fe1c17ac4
13 changed files with 139 additions and 128 deletions

View File

@ -350,7 +350,7 @@ to avoid crashing the watcher in the case where the file has been removed.
on_stylesheet_saved do |filename| on_stylesheet_saved do |filename|
Growl.notify { Growl.notify {
self.message "#{filename} updated!" self.message "#{File.basename(filename)} updated!"
self.icon = '/path/to/success.jpg' self.icon = '/path/to/success.jpg'
} }
end end
@ -359,7 +359,7 @@ to avoid crashing the watcher in the case where the file has been removed.
on_stylesheet_error do |filename, message| on_stylesheet_error do |filename, message|
Growl.notify { Growl.notify {
self.message = "#{filename}: #{message}" self.message = "#{File.basename(filename)}: #{message}"
self.icon = '/path/to/fail.jpg' self.icon = '/path/to/fail.jpg'
sticky! sticky!
} }

View File

@ -193,7 +193,7 @@ end
Then /^the following configuration properties are set in ([^ ]+):$/ do |config_file, table| Then /^the following configuration properties are set in ([^ ]+):$/ do |config_file, table|
config = Compass::Configuration::Data.new_from_file(config_file) config = Compass::Configuration::FileData.new_from_file(config_file)
table.hashes.each do |hash| table.hashes.each do |hash|
config.send(hash['property']).should == hash['value'] config.send(hash['property']).should == hash['value']
end end

View File

@ -119,7 +119,7 @@ module Compass
end end
duration = additional_options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : "" duration = additional_options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : ""
write_file(css_filename, css_content, options.merge(:force => true, :extra => duration)) write_file(css_filename, css_content, options.merge(:force => true, :extra => duration))
Compass.configuration.send(:run_stylesheet_saved, File.basename(css_filename)) #run callback Compass.configuration.run_callback(:stylesheet_saved, css_filename)
end end
def should_compile?(sass_filename, css_filename) def should_compile?(sass_filename, css_filename)
@ -140,7 +140,7 @@ module Compass
formatted_error = "(Line #{e.sass_line}: #{e.message})" formatted_error = "(Line #{e.sass_line}: #{e.message})"
file = basename(sass_filename) file = basename(sass_filename)
logger.record :error, file, formatted_error logger.record :error, file, formatted_error
Compass.configuration.send(:run_styesheet_error, file, formatted_error) #run callback Compass.configuration.run_callback(:styesheet_error, sass_filename, formatted_error)
write_file css_filename, error_contents(e, sass_filename), options.merge(:force => true) write_file css_filename, error_contents(e, sass_filename), options.merge(:force => true)
end end

View File

@ -43,6 +43,6 @@ module Compass
end end
end end
['adapters', 'callbacks', 'comments', 'defaults', 'helpers', 'inheritance', 'serialization', 'paths', 'data'].each do |lib| ['adapters', 'comments', 'defaults', 'helpers', 'inheritance', 'serialization', 'paths', 'data', 'file_data'].each do |lib|
require "compass/configuration/#{lib}" require "compass/configuration/#{lib}"
end end

View File

@ -1,25 +0,0 @@
module Compass
module Configuration
module CallbackMethods
extend ::Sass::Callbacks
# on_sprite_generated
# yields the filename
# usage: on_sprite_save {|filename| do_somethign(filename) }
define_callback :sprite_saved
# on_sprite_generated
# yields 'ChunkyPNG::Image'
# usage: on_sprite_generated {|sprite_data| do_something(sprite_data) }
define_callback :sprite_generated
define_callback :stylesheet_saved
define_callback :stylesheet_error
end
class Callbacks
extend CallbackMethods
end
end
end

View File

@ -135,6 +135,16 @@ module Compass
relative_assets || http_images_path == :relative relative_assets || http_images_path == :relative
end end
def run_callback(event, *args)
begin
send(:"run_#{event}", *args)
rescue NoMethodError => e
unless e.message =~ /run_#{event}/
raise
end
end
end
private private
def assert_valid_keys!(attr_hash) def assert_valid_keys!(attr_hash)

View File

@ -0,0 +1,43 @@
module Compass
module Configuration
class FileData < Data
extend Sass::Callbacks
# on_sprite_generated
# yields the filename
# usage: on_sprite_save {|filename| do_somethign(filename) }
define_callback :sprite_saved
# on_sprite_generated
# yields 'ChunkyPNG::Image'
# usage: on_sprite_generated {|sprite_data| do_something(sprite_data) }
define_callback :sprite_generated
# on_stylesheet_saved
# yields the filename
# usage: on_stylesheet_saved {|filename| do_something(filename) }
define_callback :stylesheet_saved
# on_stylesheet_error
# yields the filename & message
# usage: on_stylesheet_error {|filename, message| do_something(filename, message) }
define_callback :stylesheet_error
def self.new_from_file(config_file, defaults = nil)
data = new(config_file)
data.with_defaults(defaults) do
data._parse(config_file)
end
data
end
def self.new_from_string(contents, filename, defaults = nil)
data = new(filename)
data.with_defaults(defaults) do
data.parse_string(contents, filename)
end
data
end
end
end
end

View File

@ -34,11 +34,11 @@ module Compass
config config
elsif config.respond_to?(:read) elsif config.respond_to?(:read)
filename ||= config.to_s if config.is_a?(Pathname) filename ||= config.to_s if config.is_a?(Pathname)
Compass::Configuration::Data.new_from_string(config.read, filename, defaults) Compass::Configuration::FileData.new_from_string(config.read, filename, defaults)
elsif config.is_a?(Hash) elsif config.is_a?(Hash)
Compass::Configuration::Data.new(filename, config) Compass::Configuration::Data.new(filename, config)
elsif config.is_a?(String) elsif config.is_a?(String)
Compass::Configuration::Data.new_from_file(config, defaults) Compass::Configuration::FileData.new_from_file(config, defaults)
elsif config.is_a?(Symbol) elsif config.is_a?(Symbol)
Compass::AppIntegration.lookup(config).configuration Compass::AppIntegration.lookup(config).configuration
else else

View File

@ -144,8 +144,6 @@ module Compass
def method_missing(meth, *args, &block) def method_missing(meth, *args, &block)
if inherited_data if inherited_data
inherited_data.send(meth, *args, &block) inherited_data.send(meth, *args, &block)
elsif Callbacks.respond_to?(meth, true)
Callbacks.send(meth, *args, &block)
else else
raise NoMethodError, meth.to_s raise NoMethodError, meth.to_s
end end

View File

@ -2,100 +2,75 @@ module Compass
module Configuration module Configuration
# The serialization module manages reading and writing the configuration file(s). # The serialization module manages reading and writing the configuration file(s).
module Serialization module Serialization
def self.included(base) def parse(config_file)
base.send(:include, InstanceMethods) raise Compass::Error, "Compass.configuration.parse(filename) has been removed. Please call Compass.add_project_configuration(filename) instead."
base.extend ClassMethods
end end
module ClassMethods # parses a configuration file which is a ruby script
def new_from_file(config_file, defaults = nil) def _parse(config_file)
data = Data.new(config_file) unless File.readable?(config_file)
data.with_defaults(defaults) do raise Compass::Error, "Configuration file, #{config_file}, not found or not readable."
data._parse(config_file)
end
data
end end
open(config_file) do |f|
def new_from_string(contents, filename, defaults = nil) parse_string(f.read, config_file)
data = Data.new(filename)
data.with_defaults(defaults) do
data.parse_string(contents, filename)
end
data
end end
end end
module InstanceMethods def parse_string(contents, filename)
def parse(config_file) bind = binding
raise Compass::Error, "Compass.configuration.parse(filename) has been removed. Please call Compass.add_project_configuration(filename) instead." eval(contents, bind, filename)
ATTRIBUTES.each do |prop|
value = eval(prop.to_s, bind) rescue nil
value = value.to_s if value.is_a?(Pathname)
self.send("#{prop}=", value) unless value.nil?
end end
if @added_import_paths
# parses a configuration file which is a ruby script self.additional_import_paths ||= []
def _parse(config_file) self.additional_import_paths += @added_import_paths
unless File.readable?(config_file)
raise Compass::Error, "Configuration file, #{config_file}, not found or not readable."
end
open(config_file) do |f|
parse_string(f.read, config_file)
end
end end
issue_deprecation_warnings
def parse_string(contents, filename)
bind = binding
eval(contents, bind, filename)
ATTRIBUTES.each do |prop|
value = eval(prop.to_s, bind) rescue nil
value = value.to_s if value.is_a?(Pathname)
self.send("#{prop}=", value) unless value.nil?
end
if @added_import_paths
self.additional_import_paths ||= []
self.additional_import_paths += @added_import_paths
end
issue_deprecation_warnings
end
def serialize
contents = ""
(required_libraries || []).each do |lib|
contents << %Q{require '#{lib}'\n}
end
(loaded_frameworks || []).each do |lib|
contents << %Q{load '#{lib}'\n}
end
(framework_path || []).each do |lib|
contents << %Q{discover '#{lib}'\n}
end
contents << "# Require any additional compass plugins here.\n"
contents << "\n" if (required_libraries || []).any?
ATTRIBUTES.each do |prop|
value = send("#{prop}_without_default")
if value.is_a?(Proc)
$stderr.puts "WARNING: #{prop} is code and cannot be written to a file. You'll need to copy it yourself."
end
if respond_to?("comment_for_#{prop}")
contents << send("comment_for_#{prop}")
end
if block_given? && (to_emit = yield(prop, value))
contents << to_emit
else
contents << serialize_property(prop, value) unless value.nil?
end
end
contents
end
def serialize_property(prop, value)
%Q(#{prop} = #{value.inspect}\n)
end
def issue_deprecation_warnings
if http_images_path == :relative
$stderr.puts "DEPRECATION WARNING: Please set relative_assets = true to enable relative paths."
end
end
end end
def serialize
contents = ""
(required_libraries || []).each do |lib|
contents << %Q{require '#{lib}'\n}
end
(loaded_frameworks || []).each do |lib|
contents << %Q{load '#{lib}'\n}
end
(framework_path || []).each do |lib|
contents << %Q{discover '#{lib}'\n}
end
contents << "# Require any additional compass plugins here.\n"
contents << "\n" if (required_libraries || []).any?
ATTRIBUTES.each do |prop|
value = send("#{prop}_without_default")
if value.is_a?(Proc)
$stderr.puts "WARNING: #{prop} is code and cannot be written to a file. You'll need to copy it yourself."
end
if respond_to?("comment_for_#{prop}")
contents << send("comment_for_#{prop}")
end
if block_given? && (to_emit = yield(prop, value))
contents << to_emit
else
contents << serialize_property(prop, value) unless value.nil?
end
end
contents
end
def serialize_property(prop, value)
%Q(#{prop} = #{value.inspect}\n)
end
def issue_deprecation_warnings
if http_images_path == :relative
$stderr.puts "DEPRECATION WARNING: Please set relative_assets = true to enable relative paths."
end
end
end end
end end
end end

View File

@ -123,8 +123,9 @@ module Compass::SassExtensions::Functions::Sprites
# Generate a sprite image if necessary # Generate a sprite image if necessary
def generate def generate
if generation_required? if generation_required?
save!(construct_sprite) sprite_data = construct_sprite
Compass.configuration.send(:run_sprite_generated, construct_sprite) save!(sprite_data)
Compass.configuration.run_callback(:sprite_generated, sprite_data)
end end
end end
@ -182,7 +183,7 @@ module Compass::SassExtensions::Functions::Sprites
# saves the sprite for later retrieval # saves the sprite for later retrieval
def save!(output_png) def save!(output_png)
saved = output_png.save filename saved = output_png.save filename
Compass.configuration.send(:run_sprite_saved, filename) Compass.configuration.run_callback(:sprite_saved, filename)
saved saved
end end

View File

@ -8,7 +8,8 @@ describe Compass::Sprites do
@images_src_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images') @images_src_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images')
@images_tmp_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images-tmp') @images_tmp_path = File.join(File.dirname(__FILE__), 'test_project', 'public', 'images-tmp')
FileUtils.cp_r @images_src_path, @images_tmp_path FileUtils.cp_r @images_src_path, @images_tmp_path
Compass.configuration.images_path = @images_tmp_path file = StringIO.new("images_path = #{@images_tmp_path.inspect}\n")
Compass.add_configuration(file, "sprite_config")
Compass.configure_sass_plugin! Compass.configure_sass_plugin!
end end

View File

@ -23,8 +23,11 @@ class CompassTest < Test::Unit::TestCase
def test_on_stylesheet_saved_callback def test_on_stylesheet_saved_callback
saved = false saved = false
filepath = nil filepath = nil
Compass.configuration.on_stylesheet_saved {|filepath| path = filepath; saved = true } config = nil
within_project(:blueprint) { } #requires a block but we don't need to pass anything - sdavis before_compile = Proc.new do |config|
config.on_stylesheet_saved {|filepath| path = filepath; saved = true }
end
within_project(:blueprint, before_compile)
assert saved, "Stylesheet callback didn't get called" assert saved, "Stylesheet callback didn't get called"
assert filepath.is_a?(String), "Path is not a string" assert filepath.is_a?(String), "Path is not a string"
end end
@ -122,17 +125,22 @@ private
end end
end end
def within_project(project_name) def within_project(project_name, config_block = nil)
@current_project = project_name @current_project = project_name
Compass.add_configuration(configuration_file(project_name)) if File.exists?(configuration_file(project_name)) Compass.add_configuration(configuration_file(project_name)) if File.exists?(configuration_file(project_name))
Compass.configuration.project_path = project_path(project_name) Compass.configuration.project_path = project_path(project_name)
Compass.configuration.environment = :production Compass.configuration.environment = :production
args = Compass.configuration.to_compiler_arguments(:logger => Compass::NullLogger.new) args = Compass.configuration.to_compiler_arguments(:logger => Compass::NullLogger.new)
if config_block
config_block.call(Compass.configuration)
end
if Compass.configuration.sass_path && File.exists?(Compass.configuration.sass_path) if Compass.configuration.sass_path && File.exists?(Compass.configuration.sass_path)
compiler = Compass::Compiler.new *args compiler = Compass::Compiler.new *args
compiler.run compiler.run
end end
yield Compass.configuration yield Compass.configuration if block_given?
rescue rescue
save_output(project_name) save_output(project_name)
raise raise