Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Simplifying source paths implementation.

  • Loading branch information...
commit f33776b0f7483db0d235c77c62379d9d712bad54 1 parent d7c6b4e
@josevalim josevalim authored
View
54 lib/thor/actions.rb
@@ -28,45 +28,27 @@ def self.included(base) #:nodoc:
end
module ClassMethods
- # Hold source paths used by Thor::Actions.
+ # Hold source paths for one Thor instance. source_paths_for_search is the
+ # method responsible to gather source_paths from this current class,
+ # inherited paths and the source root.
#
def source_paths
- @source_paths ||= from_superclass(:source_paths, [])
+ @source_paths ||= []
end
- # On inheritance, add source root to source paths so dynamic source_root
- # (that depends on the class name, for example) are cached properly.
+ # Returns the source paths in the following order:
#
- def inherited(base) #:nodoc:
- super
- base.source_paths
- if base.respond_to?(:source_root) && !base.source_paths.include?(base.source_root)
- base.source_paths.unshift(base.source_root)
- end
- end
-
- # Deal with source root cache in source_paths. source_paths in the
- # inheritance chain are tricky to implement because:
- #
- # 1) We have to ensure that paths from the parent class appears later in
- # the source paths array.
+ # 1) This class source paths
+ # 2) Source root
+ # 3) Parents source paths
#
- # 2) Whenever source_root is added, it has to be cached because __FILE__
- # in ruby returns relative locations.
- #
- # 3) If someone wants to add source paths dinamically, added paths have
- # to come before the source root.
- #
- # This method basically check if source root was added and put it between
- # the inherited paths and the user added paths.
- #
- def singleton_method_added(method) #:nodoc:
- if method == :source_root
- inherited_paths = from_superclass(:source_paths, [])
-
- self.source_paths.reject!{ |path| inherited_paths.include?(path) }
- self.source_paths.push(*self.source_root)
- self.source_paths.concat(inherited_paths)
+ def source_paths_for_search
+ @source_paths_for_search ||= begin
+ paths = []
+ paths += self.source_paths
+ paths << self.source_root if self.respond_to?(:source_root)
+ paths += from_superclass(:source_paths, [])
+ paths
end
end
end
@@ -132,14 +114,14 @@ def relative_to_original_destination_root(path, remove_dot=true)
#
def find_in_source_paths(file)
relative_root = relative_to_original_destination_root(destination_root, false)
- source_file = nil
+ paths = self.class.source_paths_for_search
- self.class.source_paths.each do |source|
+ paths.each do |source|
source_file = File.expand_path(file, File.join(source, relative_root))
return source_file if File.exists?(source_file)
end
- if self.class.source_paths.empty?
+ if paths.empty?
raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
"you can define a source_root in your class."
else
View
6 spec/actions/directory_spec.rb
@@ -8,11 +8,13 @@
end
def invoker
- @invoker ||= MyCounter.new([1,2], {}, { :destination_root => destination_root })
+ # Use WhinyGenerator since it does not have tweaked source paths.
+ @invoker ||= WhinyGenerator.new([1,2], {}, { :destination_root => destination_root })
end
def revoker
- @revoker ||= MyCounter.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
+ # Use WhinyGenerator since it does not have tweaked source paths.
+ @revoker ||= WhinyGenerator.new([1,2], {}, { :destination_root => destination_root, :behavior => :revoke })
end
def exists_and_identical?(source_path, destination_path)
View
24 spec/actions_spec.rb
@@ -81,24 +81,23 @@ def file
end
end
- describe "#source_paths" do
- it "add source_root to source_paths" do
- MyCounter.source_paths.must == [ File.expand_path("fixtures", File.dirname(__FILE__)) ]
+ describe "#source_paths_for_search" do
+ it "add source_root to source_paths_for_search" do
+ MyCounter.source_paths_for_search.must include(File.expand_path("fixtures", File.dirname(__FILE__)))
end
- it "keeps both parent and current source root in source paths" do
- ClearCounter.source_paths[1].must == File.expand_path("fixtures/bundle", File.dirname(__FILE__))
- ClearCounter.source_paths[2].must == File.expand_path("fixtures", File.dirname(__FILE__))
+ it "keeps only current source root in source paths" do
+ ClearCounter.source_paths_for_search.must include(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
+ ClearCounter.source_paths_for_search.must_not include(File.expand_path("fixtures", File.dirname(__FILE__)))
end
- it "customized source paths should be before after source roots" do
- ClearCounter.source_paths[0].must == File.expand_path("fixtures/doc", File.dirname(__FILE__))
- ClearCounter.source_paths[1].must == File.expand_path("fixtures/bundle", File.dirname(__FILE__))
+ it "customized source paths should be before source roots" do
+ ClearCounter.source_paths_for_search[0].must == File.expand_path("fixtures/doc", File.dirname(__FILE__))
+ ClearCounter.source_paths_for_search[1].must == File.expand_path("fixtures/bundle", File.dirname(__FILE__))
end
- it "should add dynamic source root to source paths" do
- BrokenCounter.source_paths[0].must == File.expand_path("fixtures/doc", File.dirname(__FILE__))
- BrokenCounter.source_paths[1].must == File.expand_path("fixtures/broken", File.dirname(__FILE__))
+ it "keeps inherited source paths at the end" do
+ ClearCounter.source_paths_for_search.last.must == File.expand_path("fixtures/broken", File.dirname(__FILE__))
end
end
end
@@ -116,6 +115,7 @@ def file
new_path = File.join(source_root, "doc")
runner.class.source_paths.unshift(new_path)
+ runner.class.clear_source_paths_for_search
runner.find_in_source_paths("README").must == File.expand_path("README", new_path)
runner.class.source_paths.shift
end
View
15 spec/fixtures/group.thor
@@ -6,12 +6,9 @@ class MyCounter < Thor::Group
end
def self.source_root
- if name =~ /Broken/
- File.expand_path("broken", File.dirname(__FILE__))
- else
- File.expand_path(File.dirname(__FILE__))
- end
+ File.expand_path(File.dirname(__FILE__))
end
+ source_paths << File.expand_path("broken", File.dirname(__FILE__))
argument :first, :type => :numeric
argument :second, :type => :numeric, :default => 2
@@ -41,6 +38,10 @@ FOO
super
base.source_paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "doc")))
end
+
+ def self.clear_source_paths_for_search
+ @source_paths_for_search = nil
+ end
end
class ClearCounter < MyCounter
@@ -74,8 +75,10 @@ class BrokenCounter < MyCounter
end
class WhinyGenerator < Thor::Group
+ include Thor::Actions
+
def self.source_root
- File.join(File.dirname(__FILE__), 'doc')
+ File.expand_path(File.dirname(__FILE__))
end
def wrong_arity(required)
Please sign in to comment.
Something went wrong with that request. Please try again.