From 2fe1c17ac4c8adeb12ce6d9cb5c91e51dad2b91e Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sun, 20 Feb 2011 10:16:11 -0800 Subject: [PATCH] Don't rely on global callbacks --- .../configuration-reference.markdown | 4 +- .../step_definitions/command_line_steps.rb | 2 +- lib/compass/compiler.rb | 4 +- lib/compass/configuration.rb | 2 +- lib/compass/configuration/callbacks.rb | 25 --- lib/compass/configuration/data.rb | 10 ++ lib/compass/configuration/file_data.rb | 43 ++++++ lib/compass/configuration/helpers.rb | 4 +- lib/compass/configuration/inheritance.rb | 2 - lib/compass/configuration/serialization.rb | 145 ++++++++---------- .../sass_extensions/functions/sprites.rb | 7 +- spec/sprites_spec.rb | 3 +- test/compass_test.rb | 16 +- 13 files changed, 139 insertions(+), 128 deletions(-) delete mode 100644 lib/compass/configuration/callbacks.rb create mode 100644 lib/compass/configuration/file_data.rb diff --git a/doc-src/content/help/tutorials/configuration-reference.markdown b/doc-src/content/help/tutorials/configuration-reference.markdown index 0f6475e9..101a0fe4 100644 --- a/doc-src/content/help/tutorials/configuration-reference.markdown +++ b/doc-src/content/help/tutorials/configuration-reference.markdown @@ -350,7 +350,7 @@ to avoid crashing the watcher in the case where the file has been removed. on_stylesheet_saved do |filename| Growl.notify { - self.message "#{filename} updated!" + self.message "#{File.basename(filename)} updated!" self.icon = '/path/to/success.jpg' } 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| Growl.notify { - self.message = "#{filename}: #{message}" + self.message = "#{File.basename(filename)}: #{message}" self.icon = '/path/to/fail.jpg' sticky! } diff --git a/features/step_definitions/command_line_steps.rb b/features/step_definitions/command_line_steps.rb index 26bd9bd1..5127af25 100644 --- a/features/step_definitions/command_line_steps.rb +++ b/features/step_definitions/command_line_steps.rb @@ -193,7 +193,7 @@ end 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| config.send(hash['property']).should == hash['value'] end diff --git a/lib/compass/compiler.rb b/lib/compass/compiler.rb index bccb6489..086e1d3b 100644 --- a/lib/compass/compiler.rb +++ b/lib/compass/compiler.rb @@ -119,7 +119,7 @@ module Compass end duration = additional_options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : "" 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 def should_compile?(sass_filename, css_filename) @@ -140,7 +140,7 @@ module Compass formatted_error = "(Line #{e.sass_line}: #{e.message})" file = basename(sass_filename) 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) end diff --git a/lib/compass/configuration.rb b/lib/compass/configuration.rb index f094570b..3fa3e9ef 100644 --- a/lib/compass/configuration.rb +++ b/lib/compass/configuration.rb @@ -43,6 +43,6 @@ module Compass 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}" end diff --git a/lib/compass/configuration/callbacks.rb b/lib/compass/configuration/callbacks.rb deleted file mode 100644 index 2f034ee9..00000000 --- a/lib/compass/configuration/callbacks.rb +++ /dev/null @@ -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 \ No newline at end of file diff --git a/lib/compass/configuration/data.rb b/lib/compass/configuration/data.rb index 91dec02a..2dcfdca0 100644 --- a/lib/compass/configuration/data.rb +++ b/lib/compass/configuration/data.rb @@ -135,6 +135,16 @@ module Compass relative_assets || http_images_path == :relative end + def run_callback(event, *args) + begin + send(:"run_#{event}", *args) + rescue NoMethodError => e + unless e.message =~ /run_#{event}/ + raise + end + end + end + private def assert_valid_keys!(attr_hash) diff --git a/lib/compass/configuration/file_data.rb b/lib/compass/configuration/file_data.rb new file mode 100644 index 00000000..af628752 --- /dev/null +++ b/lib/compass/configuration/file_data.rb @@ -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 diff --git a/lib/compass/configuration/helpers.rb b/lib/compass/configuration/helpers.rb index 2f037d8a..00afa6e7 100644 --- a/lib/compass/configuration/helpers.rb +++ b/lib/compass/configuration/helpers.rb @@ -34,11 +34,11 @@ module Compass config elsif config.respond_to?(:read) 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) Compass::Configuration::Data.new(filename, config) 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) Compass::AppIntegration.lookup(config).configuration else diff --git a/lib/compass/configuration/inheritance.rb b/lib/compass/configuration/inheritance.rb index 24de6b4d..da12b5bc 100644 --- a/lib/compass/configuration/inheritance.rb +++ b/lib/compass/configuration/inheritance.rb @@ -144,8 +144,6 @@ module Compass def method_missing(meth, *args, &block) if inherited_data inherited_data.send(meth, *args, &block) - elsif Callbacks.respond_to?(meth, true) - Callbacks.send(meth, *args, &block) else raise NoMethodError, meth.to_s end diff --git a/lib/compass/configuration/serialization.rb b/lib/compass/configuration/serialization.rb index afdf4fc5..3e7fcc80 100644 --- a/lib/compass/configuration/serialization.rb +++ b/lib/compass/configuration/serialization.rb @@ -2,100 +2,75 @@ module Compass module Configuration # The serialization module manages reading and writing the configuration file(s). module Serialization - def self.included(base) - base.send(:include, InstanceMethods) - base.extend ClassMethods + def parse(config_file) + raise Compass::Error, "Compass.configuration.parse(filename) has been removed. Please call Compass.add_project_configuration(filename) instead." end - module ClassMethods - def new_from_file(config_file, defaults = nil) - data = Data.new(config_file) - data.with_defaults(defaults) do - data._parse(config_file) - end - data + # parses a configuration file which is a ruby script + def _parse(config_file) + unless File.readable?(config_file) + raise Compass::Error, "Configuration file, #{config_file}, not found or not readable." end - - def new_from_string(contents, filename, defaults = nil) - data = Data.new(filename) - data.with_defaults(defaults) do - data.parse_string(contents, filename) - end - data + open(config_file) do |f| + parse_string(f.read, config_file) end end - module InstanceMethods - def parse(config_file) - raise Compass::Error, "Compass.configuration.parse(filename) has been removed. Please call Compass.add_project_configuration(filename) instead." + 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 - - # parses a configuration file which is a ruby script - def _parse(config_file) - 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 + if @added_import_paths + self.additional_import_paths ||= [] + self.additional_import_paths += @added_import_paths end - - 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 - + 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 end diff --git a/lib/compass/sass_extensions/functions/sprites.rb b/lib/compass/sass_extensions/functions/sprites.rb index 45343df9..d4a2fb8b 100644 --- a/lib/compass/sass_extensions/functions/sprites.rb +++ b/lib/compass/sass_extensions/functions/sprites.rb @@ -123,8 +123,9 @@ module Compass::SassExtensions::Functions::Sprites # Generate a sprite image if necessary def generate if generation_required? - save!(construct_sprite) - Compass.configuration.send(:run_sprite_generated, construct_sprite) + sprite_data = construct_sprite + save!(sprite_data) + Compass.configuration.run_callback(:sprite_generated, sprite_data) end end @@ -182,7 +183,7 @@ module Compass::SassExtensions::Functions::Sprites # saves the sprite for later retrieval def save!(output_png) saved = output_png.save filename - Compass.configuration.send(:run_sprite_saved, filename) + Compass.configuration.run_callback(:sprite_saved, filename) saved end diff --git a/spec/sprites_spec.rb b/spec/sprites_spec.rb index 9f2b2f12..94349518 100644 --- a/spec/sprites_spec.rb +++ b/spec/sprites_spec.rb @@ -8,7 +8,8 @@ describe Compass::Sprites do @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') 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! end diff --git a/test/compass_test.rb b/test/compass_test.rb index ed3b8581..4e1bad00 100644 --- a/test/compass_test.rb +++ b/test/compass_test.rb @@ -23,8 +23,11 @@ class CompassTest < Test::Unit::TestCase def test_on_stylesheet_saved_callback saved = false filepath = nil - Compass.configuration.on_stylesheet_saved {|filepath| path = filepath; saved = true } - within_project(:blueprint) { } #requires a block but we don't need to pass anything - sdavis + config = nil + 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 filepath.is_a?(String), "Path is not a string" end @@ -122,17 +125,22 @@ private end end - def within_project(project_name) + def within_project(project_name, config_block = nil) @current_project = 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.environment = :production 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) compiler = Compass::Compiler.new *args compiler.run end - yield Compass.configuration + yield Compass.configuration if block_given? rescue save_output(project_name) raise