Permalink
Browse files

Allow default namespace tasks to be invoked without a colon

  • Loading branch information...
1 parent 852190a commit 8a4e9ca919b95319ebbb2cd499aab4aef8ed5c73 @indirect indirect committed with Brian Donovan Mar 9, 2010
Showing with 47 additions and 37 deletions.
  1. +1 −1 lib/thor/invocation.rb
  2. +2 −2 lib/thor/runner.rb
  3. +7 −13 lib/thor/util.rb
  4. +8 −1 spec/fixtures/group.thor
  5. +8 −3 spec/fixtures/script.thor
  6. +3 −3 spec/group_spec.rb
  7. +15 −7 spec/runner_spec.rb
  8. +3 −7 spec/util_spec.rb
View
2 lib/thor/invocation.rb
@@ -11,7 +11,7 @@ module ClassMethods
def prepare_for_invocation(key, name) #:nodoc:
case name
when Symbol, String
- Thor::Util.find_class_and_task_by_namespace(name.to_s)
+ Thor::Util.find_class_and_task_by_namespace(name.to_s, !key)
else
name
end
View
4 lib/thor/runner.rb
@@ -16,7 +16,7 @@ class Thor::Runner < Thor #:nodoc:
def help(meth=nil)
if meth && !self.respond_to?(meth)
initialize_thorfiles(meth)
- klass, task = Thor::Util.find_class_and_task_by_namespace!(meth)
+ klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
klass.start(["-h", task].compact, :shell => self.shell)
else
super
@@ -29,7 +29,7 @@ def help(meth=nil)
def method_missing(meth, *args)
meth = meth.to_s
initialize_thorfiles(meth)
- klass, task = Thor::Util.find_class_and_task_by_namespace!(meth)
+ klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
args.unshift(task) if task
klass.start(args, :shell => self.shell)
end
View
20 lib/thor/util.rb
@@ -128,25 +128,19 @@ def self.camel_case(str)
# ==== Parameters
# namespace<String>
#
- def self.find_class_and_task_by_namespace(namespace)
- if namespace.include?(?:)
+ def self.find_class_and_task_by_namespace(namespace, fallback = true)
+ if namespace.include?(?:) # look for a namespaced task
pieces = namespace.split(":")
task = pieces.pop
klass = Thor::Util.find_by_namespace(pieces.join(":"))
end
-
- unless klass
+ unless klass # look for a Thor::Group with the right name
klass, task = Thor::Util.find_by_namespace(namespace), nil
end
-
- return klass, task
- end
-
- # The same as namespace_to_thor_class_and_task!, but raises an error if a klass
- # could not be found.
- def self.find_class_and_task_by_namespace!(namespace)
- klass, task = find_class_and_task_by_namespace(namespace)
- raise Error, "Could not find namespace or task #{namespace.inspect}." unless klass
+ if !klass && fallback # try a task in the default namespace
+ task = namespace
+ klass = Thor::Util.find_by_namespace('')
+ end
return klass, task
end
View
9 spec/fixtures/group.thor
@@ -20,7 +20,7 @@ class MyCounter < Thor::Group
desc <<-FOO
Description:
- This generator run three tasks: one, two and three.
+ This generator runs three tasks: one, two and three.
FOO
def one
@@ -81,3 +81,10 @@ class WhinyGenerator < Thor::Group
def wrong_arity(required)
end
end
+
+class TaskConflict < Thor::Group
+ desc "A group with the same name as a default task"
+ def group
+ puts "group"
+ end
+end
View
11 spec/fixtures/script.thor
@@ -127,9 +127,14 @@ module Scripts
class MyDefaults < Thor
namespace :default
- desc "test", "prints 'test'"
- def test
- puts "test"
+ desc "cow", "prints 'moo'"
+ def cow
+ puts "moo"
+ end
+
+ desc "task_conflict", "only gets called when prepended with a colon"
+ def task_conflict
+ puts "task"
end
end
View
6 spec/group_spec.rb
@@ -36,11 +36,11 @@
describe "#desc" do
it "sets the description for a given class" do
- MyCounter.desc.must == "Description:\n This generator run three tasks: one, two and three.\n"
+ MyCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
end
it "can be inherited" do
- BrokenCounter.desc.must == "Description:\n This generator run three tasks: one, two and three.\n"
+ BrokenCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
end
it "can be nil" do
@@ -59,7 +59,7 @@
it "shows description" do
@content.must =~ /Description:/
- @content.must =~ /This generator run three tasks: one, two and three./
+ @content.must =~ /This generator runs three tasks: one, two and three./
end
it "shows options information" do
View
22 spec/runner_spec.rb
@@ -30,9 +30,8 @@
end
it "raises error if a class/task cannot be found" do
- Thor::Runner.should_receive(:exit).with(1)
content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
- content.strip.must == 'Could not find namespace or task "unknown".'
+ content.strip.must == 'Could not find task "unknown" in "default" namespace.'
end
end
@@ -68,10 +67,9 @@
end
it "raises an error if class/task can't be found" do
- Thor::Runner.should_receive(:exit).with(1)
ARGV.replace ["unknown"]
content = capture(:stderr){ Thor::Runner.start }
- content.strip.must == 'Could not find namespace or task "unknown".'
+ content.strip.must == 'Could not find task "unknown" in "default" namespace.'
end
it "does not swallow NoMethodErrors that occur inside the called method" do
@@ -145,12 +143,22 @@
it "presents tasks in the default namespace with an empty namespace" do
ARGV.replace ["list"]
- capture(:stdout) { Thor::Runner.start }.must =~ /^thor :test\s+# prints 'test'/m
+ capture(:stdout) { Thor::Runner.start }.must =~ /^thor :cow\s+# prints 'moo'/m
end
it "runs tasks with an empty namespace from the default namespace" do
- ARGV.replace [":test"]
- capture(:stdout) { Thor::Runner.start }.must == "test\n"
+ ARGV.replace [":task_conflict"]
+ capture(:stdout) { Thor::Runner.start }.must == "task\n"
+ end
+
+ it "runs groups even when there is a task with the same name" do
+ ARGV.replace ["task_conflict"]
+ capture(:stdout) { Thor::Runner.start }.must == "group\n"
+ end
+
+ it "runs tasks with no colon in the default namespace" do
+ ARGV.replace ["cow"]
+ capture(:stdout) { Thor::Runner.start }.must == "moo\n"
end
end
View
10 spec/util_spec.rb
@@ -100,18 +100,14 @@ def self.clear_user_home!
Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
end
- it "fallbacks in the namespace:task look up even if a full namespace does not match" do
+ it "falls back in the namespace:task look up even if a full namespace does not match" do
Thor.const_set(:Help, Module.new)
Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
Thor.send :remove_const, :Help
end
- describe 'errors' do
- it "raises an error if the Thor class or task can't be found" do
- lambda {
- Thor::Util.find_class_and_task_by_namespace!("foobar")
- }.must raise_error(Thor::Error, 'Could not find namespace or task "foobar".')
- end
+ it "falls back on the default namespace class if nothing else matches" do
+ Thor::Util.find_class_and_task_by_namespace("test").must == [Scripts::MyDefaults, "test"]
end
end

0 comments on commit 8a4e9ca

Please sign in to comment.