Skip to content

Commit 3c5a459

Browse files
author
José Valim
committed
Allow calling private methods on template names
This is an expected feature from Thor. When rendering files, Thor behaves like Sinatra. It works as if the file was embedded in the current Thor class. Therefore, restricting the filename to be just public methods is a wrong limitation that does not fit with how Thor is meant to be used.
1 parent 1c7cb62 commit 3c5a459

File tree

3 files changed

+13
-34
lines changed

3 files changed

+13
-34
lines changed

lib/thor/actions/empty_directory.rb

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,12 @@ def destination=(destination)
9797
#
9898
# user.rb
9999
#
100-
# The method referenced by %-string SHOULD be public. Otherwise you
101-
# get the exception with the corresponding error message.
100+
# The method referenced can be either public or private.
102101
#
103102
def convert_encoded_instructions(filename)
104103
filename.gsub(/%(.*?)%/) do |initial_string|
105-
call_public_method($1.strip) or initial_string
106-
end
107-
end
108-
109-
# Calls `base`'s public method `sym`.
110-
# Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
111-
# `base`
112-
# Raises:: Thor::PrivateMethodEncodedError if `sym` references
113-
# a private method.
114-
def call_public_method(sym)
115-
if base.respond_to?(sym)
116-
base.send(sym)
117-
elsif base.respond_to?(sym, true)
118-
raise Thor::PrivateMethodEncodedError,
119-
"Method #{base.class}##{sym} should be public, not private"
120-
else
121-
nil
104+
method = $1.strip
105+
base.respond_to?(method, true) ? base.send(method) : initial_string
122106
end
123107
end
124108

lib/thor/error.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,4 @@ class RequiredArgumentMissingError < InvocationError
2525

2626
class MalformattedArgumentError < InvocationError
2727
end
28-
29-
# Raised when a user tries to call a private method encoded in templated filename.
30-
class PrivateMethodEncodedError < Error
31-
end
3228
end

spec/actions/empty_directory_spec.rb

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,23 @@ def base
107107
expect(@action.send(:convert_encoded_instructions, "%file_name%.txt")).to eq("expected.txt")
108108
end
109109

110+
it "accepts and executes a private %\w+% encoded instruction" do
111+
@action.base.extend Module.new {
112+
private
113+
def private_file_name
114+
"expected"
115+
end
116+
}
117+
expect(@action.send(:convert_encoded_instructions, "%private_file_name%.txt")).to eq("expected.txt")
118+
end
119+
110120
it "ignores an 'illegal' %\w+% encoded instruction" do
111121
expect(@action.send(:convert_encoded_instructions, "%some_name%.txt")).to eq("%some_name%.txt")
112122
end
113123

114124
it "ignores incorrectly encoded instruction" do
115125
expect(@action.send(:convert_encoded_instructions, "%some.name%.txt")).to eq("%some.name%.txt")
116126
end
117-
118-
it "raises an error if the instruction refers to a private method" do
119-
module PrivExt
120-
private
121-
def private_file_name
122-
"something_hidden"
123-
end
124-
end
125-
@action.base.extend(PrivExt)
126-
expect { @action.send(:convert_encoded_instructions, "%private_file_name%.txt") }.to raise_error Thor::PrivateMethodEncodedError
127-
end
128127
end
129128
end
130129
end

0 commit comments

Comments
 (0)