Permalink
Browse files

Revert conditions. YAGNI.

  • Loading branch information...
1 parent bb7a372 commit 2d9f3e3c4393b2fa6304849a559be76781c9e2c4 @josevalim josevalim committed Jun 20, 2009
Showing with 7 additions and 238 deletions.
  1. +1 −1 lib/thor.rb
  2. +1 −67 lib/thor/group.rb
  3. +5 −41 lib/thor/task.rb
  4. +0 −29 spec/fixtures/conditions.thor
  5. +0 −19 spec/group_spec.rb
  6. +0 −1 spec/spec_helper.rb
  7. +0 −80 spec/task_spec.rb
View
2 lib/thor.rb
@@ -198,7 +198,7 @@ def valid_task?(meth) #:nodoc:
end
def create_task(meth) #:nodoc:
- tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options, nil)
+ tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options)
@usage, @desc, @method_options = nil
end
View
68 lib/thor/group.rb
@@ -22,71 +22,6 @@ def desc(description=nil)
end
end
- # Sets the condition for some task to be executed in the class level. Why
- # is this important? Setting the conditions in the class level allows to
- # an inherited class change the conditions and customize the Thor::Group as
- # it wishes.
- #
- # The conditions given are retrieved from the options hash. Let's suppose
- # that a task is only executed if --test-framework is rspec. You could do
- # this:
- #
- # class_option :test_framework, :type => :string
- #
- # conditions :test_framework => :rspec
- # def create_rspec_files
- # # magic
- # end
- #
- # Later someone creates a framework on top of rspec and need rspec files to
- # generated as well. He could then change the conditions:
- #
- # conditions :test_framework => [ :rspec, :remarkable ], :for => :create_rspec_files
- #
- # He could also use remove_conditions and remove previous set conditions:
- #
- # remove_conditions :test_framework, :for => :create_rspec_files
- #
- # Conditions only work with the class option to be comparead to is a boolean,
- # string or numeric (no array or hash comparisions).
- #
- # ==== Parameters
- # conditions<Hash>:: the conditions for the task. The key is the option name
- # and the value is the condition to be checked. If the
- # condition is an array, it checkes if the current value
- # is included in the array. If a regexp, checks if the
- # value matches, all other values are simply compared (==).
- #
- def conditions(conditions=nil)
- subject = if conditions && conditions[:for]
- find_and_refresh_task(conditions.delete(:for)).conditions
- else
- @conditions ||= {}
- end
-
- subject.merge!(conditions) if conditions
- subject
- end
-
- # Remove a previous specified condition. Check <tt>conditions</tt> above for
- # a complete example.
- #
- # ==== Parameters
- # conditions<Array>:: An array of conditions to be removed.
- # for<Hash>:: A hash with :for as key indicating the task to remove the conditions from.
- #
- # ==== Examples
- #
- # remove_conditions :test_framework, :orm, :for => :create_app_skeleton
- #
- def remove_conditions(*conditions)
- subject = find_and_refresh_task(conditions.pop[:for]).conditions
- conditions.each do |condition|
- subject.delete(condition)
- end
- subject
- end
-
# Start in Thor::Group works differently. It invokes all tasks inside the
# class and does not have to parse task options.
#
@@ -140,8 +75,7 @@ def valid_task?(meth) #:nodoc:
end
def create_task(meth) #:nodoc:
- tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil, @conditions)
- @conditions = nil
+ tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil)
end
end
View
46 lib/thor/task.rb
@@ -1,5 +1,5 @@
class Thor
- class Task < Struct.new(:name, :description, :usage, :options, :conditions)
+ class Task < Struct.new(:name, :description, :usage, :options)
# Creates a dynamic task. Dynamic tasks are created on demand to allow method
# missing calls (since a method missing does not have a task object for it).
@@ -8,24 +8,23 @@ def self.dynamic(name)
new(name, "A dynamically-generated task", name.to_s)
end
- def initialize(name, description, usage, options=nil, conditions=nil)
- super(name.to_s, description, usage, options || {}, conditions || {})
+ def initialize(name, description, usage, options=nil)
+ super(name.to_s, description, usage, options || {})
end
# Dup the options hash on clone.
#
def initialize_copy(other)
super(other)
- self.options = other.options.dup if other.options
- self.conditions = other.conditions.dup if other.conditions
+ self.options = other.options.dup if other.options
end
# By default, a task invokes a method in the thor class. You can change this
# implementation to create custom tasks.
#
def run(instance, args=[])
raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance)
- instance.send(name, *args) if valid_conditions?(instance)
+ instance.send(name, *args)
rescue ArgumentError => e
backtrace = sans_backtrace(e.backtrace, caller)
@@ -91,28 +90,6 @@ def public_method?(instance)
!(collection).include?(name.to_s) && !(collection).include?(name.to_sym) # For Ruby 1.9
end
- # Check if the task conditions are met before invoking.
- #
- def valid_conditions?(instance)
- return true if conditions.empty?
-
- conditions.each do |key, expected|
- actual = stringify!(instance.options[key])
- expected = stringify!(expected)
-
- return false if case expected
- when Regexp
- actual !~ expected
- when Array
- !expected.include?(actual)
- else
- actual != expected
- end
- end
-
- true
- end
-
# Clean everything that comes from the Thor gempath and remove the caller.
#
def sans_backtrace(backtrace, caller)
@@ -121,18 +98,5 @@ def sans_backtrace(backtrace, caller)
saned -= caller
end
- # Receives an object and convert any symbol to string.
- #
- def stringify!(duck)
- case duck
- when Array
- duck.map!{ |i| i.is_a?(Symbol) ? i.to_s : i }
- when Symbol
- duck.to_s
- else
- duck
- end
- end
-
end
end
View
29 spec/fixtures/conditions.thor
@@ -1,29 +0,0 @@
-class Conditional < Thor::Group
- class_option :test_framework, :type => :string
- class_option :with_dispatchers, :type => :boolean, :default => false
-
- conditions :test_framework => :rspec
- def one
- 1
- end
-
- conditions :test_framework => [:rspec, :remarkable]
- def two
- 2
- end
-
- conditions :test_framework => /remarkable/
- def three
- 3
- end
-
- conditions :with_dispatchers => true
- def four
- 4
- end
-end
-
-class Simplified < Conditional
- conditions :test_framework => [:rspec, :remarkable], :for => :one
- remove_conditions :with_dispatchers, :for => :four
-end
View
19 spec/group_spec.rb
@@ -77,23 +77,4 @@
content.must_not =~ /Options/
end
end
-
- describe "#conditions" do
- it "invoke only tasks where conditions met" do
- Conditional.start([]).must == [nil, nil, nil, nil]
- Conditional.start(["--test-framework", "rspec"]).must == [1, 2, nil, nil]
- Conditional.start(["--test-framework", "remarkable"]).must == [nil, 2, 3, nil]
- Conditional.start(["--with-dispatchers"]).must == [nil, nil, nil, 4]
- end
-
- it "when supplied with :for changes the conditions for a previous task" do
- Simplified.start(["--test-framework", "remarkable"]).must == [1, 2, 3, 4]
- end
- end
-
- describe "#remove_conditions" do
- it "removes conditions from a previous specified task" do
- Simplified.start([]).must == [nil, nil, nil, 4]
- end
- end
end
View
1 spec/spec_helper.rb
@@ -12,7 +12,6 @@
load File.join(File.dirname(__FILE__), "fixtures", "group.thor")
load File.join(File.dirname(__FILE__), "fixtures", "script.thor")
load File.join(File.dirname(__FILE__), "fixtures", "invoke.thor")
-load File.join(File.dirname(__FILE__), "fixtures", "conditions.thor")
Kernel.module_eval do
alias_method :must, :should
View
80 spec/task_spec.rb
@@ -48,12 +48,6 @@ def task(options={})
task.dup.options.delete(:foo)
task.options[:foo].must_not be_nil
end
-
- it "dup conditions hash" do
- task = Thor::Task.new("can_has", nil, nil, {}, :foo => true, :bar => :required)
- task.dup.conditions.delete(:foo)
- task.conditions[:foo].must_not be_nil
- end
end
describe "#run" do
@@ -79,78 +73,4 @@ def task(options={})
Thor::Task.new(:task, "I can has cheezburger", "can_has").short_description == "I can has cheezburger"
end
end
-
- describe "#valid_conditions?" do
- def run(instance, conditions={})
- Thor::Task.new(:can_has, "I can has cheezburger", "can_has", nil, conditions).run(instance)
- end
-
- def stub!(options={})
- instance = Object.new
- stub(instance).options{ options }
- instance
- end
-
- it "runs the task if no conditions are given" do
- instance = stub!
- mock(instance).can_has
- run(instance)
- end
-
- it "runs the task if conditions are met" do
- instance = stub!(:with_conditions => true)
- mock(instance).can_has
- run(instance, :with_conditions => true)
- end
-
- it "does not run the task if conditions are not met" do
- instance = stub!(:with_conditions => true)
- dont_allow(instance).can_has
- run(instance, :with_conditions => false)
- end
-
- it "runs the task if symbol is equivalent to the given string" do
- instance = stub!(:framework => :rails)
- mock(instance).can_has
- run(instance, :framework => "rails")
-
- instance = stub!(:framework => "rails")
- mock(instance).can_has
- run(instance, :framework => :rails)
-
- instance = stub!(:framework => :rails)
- mock(instance).can_has
- run(instance, :framework => :rails)
- end
-
- it "does not run the task if strings does not match" do
- instance = stub!(:framework => "merb")
- dont_allow(instance).can_has
- run(instance, :framework => "rails")
- end
-
- it "runs the task if regexp matches" do
- instance = stub!(:framework => "rails")
- mock(instance).can_has
- run(instance, :framework => /rails/)
- end
-
- it "does not run the task if regexp matches" do
- instance = stub!(:framework => "merb")
- dont_allow(instance).can_has
- run(instance, :framework => /rails/)
- end
-
- it "runs the task if value is included in array" do
- instance = stub!(:framework => "rails")
- mock(instance).can_has
- run(instance, :framework => [:rails, :merb])
- end
-
- it "does not run the task if value is not included in array" do
- instance = stub!(:framework => "sinatra")
- dont_allow(instance).can_has
- run(instance, :framework => [:rails, :merb])
- end
- end
end

0 comments on commit 2d9f3e3

Please sign in to comment.