Skip to content

Commit

Permalink
Merge 3c5a459 into 08265a3
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Mar 26, 2013
2 parents 08265a3 + 3c5a459 commit e9ed94a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 41 deletions.
22 changes: 3 additions & 19 deletions lib/thor/actions/empty_directory.rb
Expand Up @@ -97,28 +97,12 @@ def destination=(destination)
#
# user.rb
#
# The method referenced by %-string SHOULD be public. Otherwise you
# get the exception with the corresponding error message.
# The method referenced can be either public or private.
#
def convert_encoded_instructions(filename)
filename.gsub(/%(.*?)%/) do |initial_string|
call_public_method($1.strip) or initial_string
end
end

# Calls `base`'s public method `sym`.
# Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
# `base`
# Raises:: Thor::PrivateMethodEncodedError if `sym` references
# a private method.
def call_public_method(sym)
if base.respond_to?(sym)
base.send(sym)
elsif base.respond_to?(sym, true)
raise Thor::PrivateMethodEncodedError,
"Method #{base.class}##{sym} should be public, not private"
else
nil
method = $1.strip
base.respond_to?(method, true) ? base.send(method) : initial_string
end
end

Expand Down
15 changes: 12 additions & 3 deletions lib/thor/base.rb
Expand Up @@ -119,6 +119,18 @@ def register_klass_file(klass) #:nodoc:
end

module ClassMethods
def attr_reader(*) #:nodoc:
no_commands { super }
end

def attr_writer(*) #:nodoc:
no_commands { super }
end

def attr_accessor(*) #:nodoc:
no_commands { super }
end

# If you want to raise an error for unknown options, call check_unknown_options!
# This is disabled by default to allow dynamic invocations.
def check_unknown_options!
Expand Down Expand Up @@ -578,9 +590,6 @@ def method_added(meth)
# Return if it's not a public instance method
return unless public_method_defined?(meth.to_sym)

# Return if attr_* added the method
return if caller.first.to_s[/`attr_(reader|writer|accessor)'/]

return if @no_commands || !create_command(meth)

is_thor_reserved_word?(meth, :command)
Expand Down
4 changes: 0 additions & 4 deletions lib/thor/error.rb
Expand Up @@ -25,8 +25,4 @@ class RequiredArgumentMissingError < InvocationError

class MalformattedArgumentError < InvocationError
end

# Raised when a user tries to call a private method encoded in templated filename.
class PrivateMethodEncodedError < Error
end
end
21 changes: 10 additions & 11 deletions spec/actions/empty_directory_spec.rb
Expand Up @@ -107,24 +107,23 @@ def base
expect(@action.send(:convert_encoded_instructions, "%file_name%.txt")).to eq("expected.txt")
end

it "accepts and executes a private %\w+% encoded instruction" do
@action.base.extend Module.new {
private
def private_file_name
"expected"
end
}
expect(@action.send(:convert_encoded_instructions, "%private_file_name%.txt")).to eq("expected.txt")
end

it "ignores an 'illegal' %\w+% encoded instruction" do
expect(@action.send(:convert_encoded_instructions, "%some_name%.txt")).to eq("%some_name%.txt")
end

it "ignores incorrectly encoded instruction" do
expect(@action.send(:convert_encoded_instructions, "%some.name%.txt")).to eq("%some.name%.txt")
end

it "raises an error if the instruction refers to a private method" do
module PrivExt
private
def private_file_name
"something_hidden"
end
end
@action.base.extend(PrivExt)
expect { @action.send(:convert_encoded_instructions, "%private_file_name%.txt") }.to raise_error Thor::PrivateMethodEncodedError
end
end
end
end
4 changes: 0 additions & 4 deletions spec/base_spec.rb
Expand Up @@ -287,9 +287,5 @@ def hello
expect(capture(:stderr){ MyScript.start(["some_attribute"]) }).to match(/Could not find/)
expect(capture(:stderr){ MyScript.start(["some_attribute=", "foo"]) }).to match(/Could not find/)
end

it "respects visibility" do
expect(MyScript.public_instance_methods).to_not include(:private_attribute)
end
end
end

0 comments on commit e9ed94a

Please sign in to comment.