diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 74c35285..13595135 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -14,7 +14,7 @@ require 'active_support/core_ext/integer/inflections' require 'active_support/core_ext/float/rounding' # Simple callback library -require 'vendored-middleman-deps/hooks-0.2.0/lib/hooks' +require 'hooks' # Our custom logger require 'middleman-core/logger' @@ -32,6 +32,7 @@ module Middleman # Uses callbacks include Hooks + include Hooks::InstanceHooks # Before request hook define_hook :before @@ -223,6 +224,12 @@ module Middleman end alias :inspect :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s + # Hooks clones _hooks from the class to the instance. + # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 + # Middleman expects the same list of hooks for class and instance hooks: + def _hooks + self.class._hooks + end end end diff --git a/middleman-core/lib/middleman-more/core_extensions/compass.rb b/middleman-core/lib/middleman-more/core_extensions/compass.rb index cdf2c299..2aa46d47 100644 --- a/middleman-core/lib/middleman-more/core_extensions/compass.rb +++ b/middleman-core/lib/middleman-more/core_extensions/compass.rb @@ -49,7 +49,7 @@ class Middleman::CoreExtensions::Compass < ::Middleman::Extension end # Call hook - app.run_hook :compass_config, ::Compass.configuration + app.run_hook_for :compass_config, app, ::Compass.configuration # Tell Tilt to use it as well (for inline sass blocks) ::Tilt.register 'sass', CompassSassTemplate @@ -73,4 +73,4 @@ class Middleman::CoreExtensions::Compass < ::Middleman::Extension super.merge(::Compass.configuration.to_sass_engine_options) end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile deleted file mode 100644 index 3beea91d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/CHANGES.textile +++ /dev/null @@ -1,9 +0,0 @@ -h2. 0.2.0 - -h3. Changes - * Callback blocks are now executed on the instance using @instance_exec@. If you need to access the class (former context) use @self.class@. - -h2. 0.1.4 - -h3. Bugfixes - * An uninitialized @inheritable_attr@ doesn't crash since it is not cloned anymore. Note that an uncloneable attribute value still causes an exception. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile deleted file mode 100644 index a1b93f3e..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source :rubygems - -gemspec diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc deleted file mode 100644 index 4a209500..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/README.rdoc +++ /dev/null @@ -1,107 +0,0 @@ -= Hooks - -Generic hooks with callbacks for Ruby. - - -== Introduction - -_Hooks_ lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as _you_ run the hook! - -It's almost like ActiveSupport::Callbacks but 76,6% less complex. Instead, it is not more than 60 lines of code, one method compilation, no +method_missing+ and no magic. - -Also, you may pass additional arguments to your callbacks when invoking a hook. - -== Example - -Let's take... a cat. - - require 'hooks' - - class Cat - include Hooks - - define_hook :after_dinner - -Now you can add callbacks to your hook declaratively in your class. - - after_dinner do - puts "Ice cream for #{self}!" - end - - after_dinner :have_a_desert # => refers to Cat#have_a_desert - - def have_a_desert - puts "Hell, yeah!" - end - -This will run the block and #have_a_desert from above. - - cat.run_hook :after_dinner - # => Ice cream for #! - Hell, yeah! - -Callback blocks and methods will be executed with instance context. Note how +self+ in the block refers to the Cat instance. - - -== Inheritance - -Hooks are inherited, here's a complete example to put it all together. - - class Garfield < Cat - - after_dinner :want_some_more - - def want_some_more - puts "Is that all?" - end - end - - - Garfield.new.run_hook :after_dinner - # => Ice cream for #! - Hell, yeah! - Is that all? - -Note how the callbacks are invoked in the order they were inherited. - - -== Options for Callbacks - -You're free to pass any number of arguments to #run_callback, those will be passed to the callbacks. - - cat.run_hook :before_dinner, cat, Time.now - -The callbacks should be ready for receiving parameters. - - before_dinner :wash_pawns - before_dinner do |who, when| - ... - end - - def wash_pawns(who, when) - - -Not sure why a cat should have ice cream for dinner. Beside that, I was tempted naming this gem _hooker_. - - -== Installation - - gem install hooks - - -== Anybody using it? - -* Hooks is already used in [Apotomo:http://github.com/apotonick/apotomo], a hot widget framework for Rails. Look at +lib/apotomo/widget.rb+ for examples and into +lib/apotomo/tree_node.rb+ to learn how modules-driven code might benefit from hooks. - -== Similar libraries - -* http://github.com/nakajima/aspectory -* http://github.com/auser/backcall -* http://github.com/mmcgrana/simple_callbacks - - -== License - -Copyright (c) 2010, Nick Sutterer - -Released under the MIT License. diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Rakefile b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Rakefile deleted file mode 100644 index 4799b87b..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/Rakefile +++ /dev/null @@ -1,12 +0,0 @@ -require 'rake' -require 'rake/testtask' - -desc 'Default: run unit tests.' -task :default => :test - -desc 'Test the hooks plugin.' -Rake::TestTask.new(:test) do |test| - test.libs << 'test' - test.test_files = FileList['test/*_test.rb'] - test.verbose = true -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec deleted file mode 100644 index 326f75c0..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/hooks.gemspec +++ /dev/null @@ -1,22 +0,0 @@ -lib = File.expand_path('../lib/', __FILE__) -$:.unshift lib unless $:.include?(lib) - -require 'hooks' - -Gem::Specification.new do |s| - s.name = "hooks" - s.version = Hooks::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ["Nick Sutterer"] - s.email = ["apotonick@gmail.com"] - s.homepage = "http://nicksda.apotomo.de/tag/hooks" - s.summary = %q{Generic hooks with callbacks for Ruby.} - s.description = %q{Declaratively define hooks, add callbacks and run them with the options you like.} - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.require_paths = ["lib"] - - s.add_development_dependency "shoulda" - s.add_development_dependency "rake" -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb deleted file mode 100644 index 9c4ca879..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks.rb +++ /dev/null @@ -1,109 +0,0 @@ -require File.join(File.dirname(__FILE__), "hooks/inheritable_attribute") - -# Almost like ActiveSupport::Callbacks but 76,6% less complex. -# -# Example: -# -# class CatWidget < Apotomo::Widget -# define_hook :after_dinner -# -# Now you can add callbacks to your hook declaratively in your class. -# -# after_dinner do puts "Ice cream!" end -# after_dinner :have_a_desert # => refers to CatWidget#have_a_desert -# -# Running the callbacks happens on instances. It will run the block and #have_a_desert from above. -# -# cat.run_hook :after_dinner -module Hooks - VERSION = "0.2.0" - - def self.included(base) - base.extend InheritableAttribute - base.extend ClassMethods - end - - module ClassMethods - def define_hook(name) - accessor_name = "_#{name}_callbacks" - - setup_hook_accessors(accessor_name) - define_hook_writer(name, accessor_name) - end - - # Like Hooks#run_hook but for the class. Note that +:callbacks+ must be class methods. - # - # Example: - # - # class Cat - # after_eight :grab_a_beer - # - # def self.grab_a_beer(*) # and so on... - # - # where Cat.run_hook :after_eight will call the class method +grab_a_beer+. - def run_hook(name, *args) - run_hook_for(name, self, *args) - end - - def run_hook_for(name, scope, *args) - callbacks_for_hook(name).each do |callback| - if callback.kind_of? Symbol - scope.send(callback, *args) - else - scope.instance_exec(*args, &callback) - end - end - end - - # Returns the callbacks for +name+. Handy if you want to run the callbacks yourself, say when - # they should be executed in another context. - # - # Example: - # - # def initialize - # self.class.callbacks_for_hook(:after_eight).each do |callback| - # instance_exec(self, &callback) - # end - # - # would run callbacks in the object _instance_ context, passing +self+ as block parameter. - def callbacks_for_hook(name) - send("_#{name}_callbacks") - end - - private - - def define_hook_writer(hook, accessor_name) - self.send(:define_method, hook.to_sym) do |&block| - if self.class.respond_to?(hook) - self.class.send(hook.to_sym, &block) - end - end - - instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{hook}(method=nil, &block) - #{accessor_name} << (block || method) - end - RUBY_EVAL - end - - def setup_hook_accessors(accessor_name) - inheritable_attr(accessor_name) - send("#{accessor_name}=", []) # initialize ivar. - end - end - - # Runs the callbacks (method/block) for the specified hook +name+. Additional arguments will - # be passed to the callback. - # - # Example: - # - # cat.run_hook :after_dinner, "i want ice cream!" - # - # will invoke the callbacks like - # - # desert("i want ice cream!") - # block.call("i want ice cream!") - def run_hook(name, *args) - self.class.run_hook_for(name, self, *args) - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb deleted file mode 100644 index 88f24b4f..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/lib/hooks/inheritable_attribute.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Hooks - module InheritableAttribute - # Creates an inheritable attribute with accessors in the singleton class. Derived classes inherit the - # attributes. This is especially helpful with arrays or hashes that are extended in the inheritance - # chain. Note that you have to initialize the inheritable attribute. - # - # Example: - # - # class Cat - # inheritable_attr :drinks - # self.drinks = ["Becks"] - # - # class Garfield < Cat - # self.drinks << "Fireman's 4" - # - # and then, later - # - # Cat.drinks #=> ["Becks"] - # Garfield.drinks #=> ["Becks", "Fireman's 4"] - def inheritable_attr(name) - instance_eval %Q{ - def #{name}=(v) - @#{name} = v - end - - def #{name} - return @#{name} unless superclass.respond_to?(:#{name}) and value = superclass.#{name} - @#{name} ||= value.clone # only do this once. - end - } - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb deleted file mode 100644 index 83cb24e4..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/hooks_test.rb +++ /dev/null @@ -1,141 +0,0 @@ -require 'test_helper' - -class HooksTest < Test::Unit::TestCase - class TestClass - include Hooks - - def executed - @executed ||= []; - end - end - - - context "Hooks.define_hook" do - setup do - @klass = Class.new(TestClass) - - @mum = @klass.new - @mum.class.define_hook :after_eight - end - - should "provide accessors to the stored callbacks" do - assert_equal [], @klass._after_eight_callbacks - @klass._after_eight_callbacks << :dine - assert_equal [:dine], @klass._after_eight_callbacks - end - - should "respond to Class.callbacks_for_hook" do - assert_equal [], @klass.callbacks_for_hook(:after_eight) - @klass.after_eight :dine - assert_equal [:dine], @klass.callbacks_for_hook(:after_eight) - end - - context "creates a public writer for the hook that" do - should "accepts method names" do - @klass.after_eight :dine - assert_equal [:dine], @klass._after_eight_callbacks - end - - should "accepts blocks" do - @klass.after_eight do true; end - assert @klass._after_eight_callbacks.first.kind_of? Proc - end - - should "be inherited" do - @klass.after_eight :dine - subklass = Class.new(@klass) - - assert_equal [:dine], subklass._after_eight_callbacks - end - end - - context "Hooks#run_hook" do - should "run without parameters" do - @mum.instance_eval do - def a; executed << :a; nil; end - def b; executed << :b; end - - self.class.after_eight :b - self.class.after_eight :a - end - - @mum.run_hook(:after_eight) - - assert_equal [:b, :a], @mum.executed - end - - should "accept arbitrary parameters" do - @mum.instance_eval do - def a(me, arg); executed << arg+1; end - end - @mum.class.after_eight :a - @mum.class.after_eight lambda { |me, arg| me.executed << arg-1 } - - @mum.run_hook(:after_eight, @mum, 1) - - assert_equal [2, 0], @mum.executed - end - - should "execute block callbacks in instance context" do - @mum.class.after_eight { executed << :c } - @mum.run_hook(:after_eight) - assert_equal [:c], @mum.executed - end - end - - context "in class context" do - should "run a callback block" do - executed = [] - @klass.after_eight do - executed << :klass - end - @klass.run_hook :after_eight - - assert_equal [:klass], executed - end - - should "run a class methods" do - executed = [] - @klass.instance_eval do - after_eight :have_dinner - - def have_dinner(executed) - executed << :have_dinner - end - end - @klass.run_hook :after_eight, executed - - assert_equal [:have_dinner], executed - end - end - end - - context "Deriving" do - setup do - @klass = Class.new(TestClass) - - @mum = @klass.new - @mum.class.define_hook :after_eight - end - - should "inherit the hook" do - @klass.class_eval do - after_eight :take_shower - - def take_shower - executed << :take_shower - end - end - - @kid = Class.new(@klass) do - after_eight :have_dinner - - def have_dinner - executed << :have_dinner - end - end.new - - assert_equal [:take_shower, :have_dinner], @kid.run_hook(:after_eight) - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb deleted file mode 100644 index 27e10a2d..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/inheritable_attribute_test.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'test_helper' - -class HooksTest < Test::Unit::TestCase - context "Hooks.define_hook" do - setup do - @klass = Class.new(Object) do - extend Hooks::InheritableAttribute - end - - @mum = @klass.new - @klass.inheritable_attr :drinks - end - - should "provide a reader with empty inherited attributes, already" do - assert_equal nil, @klass.drinks - end - - should "provide a reader with empty inherited attributes in a derived class" do - assert_equal nil, Class.new(@klass).drinks - #@klass.drinks = true - #Class.new(@klass).drinks # TODO: crashes. - end - - should "provide an attribute copy in subclasses" do - @klass.drinks = [] - assert @klass.drinks.object_id != Class.new(@klass).drinks.object_id - end - - should "provide a writer" do - @klass.drinks = [:cabernet] - assert_equal [:cabernet], @klass.drinks - end - - should "inherit attributes" do - @klass.drinks = [:cabernet] - - subklass_a = Class.new(@klass) - subklass_a.drinks << :becks - - subklass_b = Class.new(@klass) - - assert_equal [:cabernet], @klass.drinks - assert_equal [:cabernet, :becks], subklass_a.drinks - assert_equal [:cabernet], subklass_b.drinks - end - - should "not inherit attributes if we set explicitely" do - @klass.drinks = [:cabernet] - subklass = Class.new(@klass) - - subklass.drinks = [:merlot] # we only want merlot explicitely. - assert_equal [:merlot], subklass.drinks # no :cabernet, here - end - end -end diff --git a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb b/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb deleted file mode 100644 index f0b0b3cd..00000000 --- a/middleman-core/lib/vendored-middleman-deps/hooks-0.2.0/test/test_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'rubygems' - -# wycats says... -require 'bundler' -Bundler.setup -require 'test/unit' -require 'shoulda' -require 'hooks' - -$:.unshift File.dirname(__FILE__) # add current dir to LOAD_PATHS diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 954a2325..1d98baa6 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |s| s.add_dependency("bundler", ["~> 1.1"]) s.add_dependency("rack", [">= 1.4.5"]) s.add_dependency("tilt", ["~> 1.4.1"]) + s.add_dependency("hooks", ["~> 0.3"]) # Builder s.add_dependency("rack-test", ["~> 0.6.1"])