Skip to content

Commit

Permalink
Merge pull request #878 from takmar/fix/find-class-and-command-name
Browse files Browse the repository at this point in the history
Correctly identify hyphenated and alias command names
  • Loading branch information
rafaelfranca authored Aug 28, 2024
2 parents 8f897d5 + 3821657 commit f2e243d
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 1 deletion.
11 changes: 11 additions & 0 deletions lib/thor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,17 @@ def disable_required_check?(command) #:nodoc:
command && disable_required_check.include?(command.name.to_sym)
end

# Checks if a specified command exists.
#
# ==== Parameters
# command_name<String>:: The name of the command to check for existence.
#
# ==== Returns
# Boolean:: +true+ if the command exists, +false+ otherwise.
def command_exists?(command_name) #:nodoc:
commands.keys.include?(normalize_command_name(command_name))
end

protected

# Returns this class exclusive options array set.
Expand Down
11 changes: 11 additions & 0 deletions lib/thor/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ def handle_argument_error(command, error, _args, arity) #:nodoc:
raise error, msg
end

# Checks if a specified command exists.
#
# ==== Parameters
# command_name<String>:: The name of the command to check for existence.
#
# ==== Returns
# Boolean:: +true+ if the command exists, +false+ otherwise.
def command_exists?(command_name) #:nodoc:
commands.keys.include?(command_name)
end

protected

# The method responsible for dispatching given the args.
Expand Down
2 changes: 1 addition & 1 deletion lib/thor/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def find_class_and_command_by_namespace(namespace, fallback = true)
*pieces, command = namespace.split(":")
namespace = pieces.join(":")
namespace = "default" if namespace.empty?
klass = Thor::Base.subclasses.detect { |thor| thor.namespace == namespace && thor.commands.keys.include?(command) }
klass = Thor::Base.subclasses.detect { |thor| thor.namespace == namespace && thor.command_exists?(command) }
end
unless klass # look for a Thor::Group with the right name
klass = Thor::Util.find_by_namespace(namespace)
Expand Down
3 changes: 3 additions & 0 deletions spec/fixtures/script.thor
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,15 @@ end
class Apple < Thor
namespace :fruits
desc 'apple', 'apple'; def apple; end
desc 'rotten-apple', 'rotten apple'; def rotten_apple; end
map "ra" => :rotten_apple
end

class Pear < Thor
namespace :fruits
desc 'pear', 'pear'; def pear; end
end

class MyClassOptionScript < Thor
class_option :free

Expand Down
10 changes: 10 additions & 0 deletions spec/group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@
end
end

describe "#command_exists?" do
it "returns true for a command that is defined in the class" do
expect(MyCounter.command_exists?("one")).to be true
end

it "returns false for a command that is not defined in the class" do
expect(MyCounter.command_exists?("zero")).to be false
end
end

describe "edge-cases" do
it "can handle boolean options followed by arguments" do
klass = Class.new(Thor::Group) do
Expand Down
12 changes: 12 additions & 0 deletions spec/thor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,18 @@ def self.exit_on_failure?
end
end

describe "#command_exists?" do
it "returns true for a command that is defined in the class" do
expect(MyScript.command_exists?("zoo")).to be true
expect(MyScript.command_exists?("name-with-dashes")).to be true
expect(MyScript.command_exists?("animal_prison")).to be true
end

it "returns false for a command that is not defined in the class" do
expect(MyScript.command_exists?("animal_heaven")).to be false
end
end

describe "#map" do
it "calls the alias of a method if one is provided" do
expect(MyScript.start(%w(-T fish))).to eq(%w(fish))
Expand Down
8 changes: 8 additions & 0 deletions spec/util_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ def self.clear_user_home!
expect(Thor::Util.find_class_and_command_by_namespace("fruits:apple")).to eq([Apple, "apple"])
expect(Thor::Util.find_class_and_command_by_namespace("fruits:pear")).to eq([Pear, "pear"])
end

it "returns correct Thor class and the command name with hypen when shared namespaces" do
expect(Thor::Util.find_class_and_command_by_namespace("fruits:rotten-apple")).to eq([Apple, "rotten-apple"])
end

it "returns correct Thor class and the associated alias command name when shared namespaces" do
expect(Thor::Util.find_class_and_command_by_namespace("fruits:ra")).to eq([Apple, "ra"])
end
end

describe "#thor_classes_in" do
Expand Down

0 comments on commit f2e243d

Please sign in to comment.