thor 0.13.4 → 0.13.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/lib/thor/actions.rb +12 -4
- data/lib/thor/actions/file_manipulation.rb +1 -1
- data/lib/thor/invocation.rb +1 -1
- data/lib/thor/runner.rb +4 -4
- data/lib/thor/util.rb +7 -13
- data/lib/thor/version.rb +1 -1
- data/spec/actions_spec.rb +1 -1
- data/spec/fixtures/group.thor +8 -1
- data/spec/fixtures/script.thor +8 -3
- data/spec/group_spec.rb +3 -3
- data/spec/runner_spec.rb +15 -7
- data/spec/util_spec.rb +3 -7
- metadata +12 -5
data/README.rdoc
CHANGED
@@ -270,7 +270,7 @@ argument for our generator to run.
|
|
270
270
|
|
271
271
|
The <tt>create_lib_file</tt> uses an ERB template. This is what it looks like:
|
272
272
|
|
273
|
-
class <%= name.
|
273
|
+
class <%= name.capitalize %>
|
274
274
|
end
|
275
275
|
|
276
276
|
The arguments that you set in your generator will automatically be passed in
|
data/lib/thor/actions.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'uri'
|
2
3
|
require 'thor/core_ext/file_binary_read'
|
3
4
|
|
4
5
|
Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action|
|
@@ -115,7 +116,7 @@ class Thor
|
|
115
116
|
@source_paths ||= self.class.source_paths_for_search
|
116
117
|
end
|
117
118
|
|
118
|
-
# Receives a file or directory and search for it in the source paths.
|
119
|
+
# Receives a file or directory and search for it in the source paths.
|
119
120
|
#
|
120
121
|
def find_in_source_paths(file)
|
121
122
|
relative_root = relative_to_original_destination_root(destination_root, false)
|
@@ -129,7 +130,7 @@ class Thor
|
|
129
130
|
raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
|
130
131
|
"you can define a source_root in your class."
|
131
132
|
else
|
132
|
-
raise Error, "Could not find #{file.inspect} in source paths."
|
133
|
+
raise Error, "Could not find #{file.inspect} in source paths: \n#{source_paths.join("\n")}"
|
133
134
|
end
|
134
135
|
end
|
135
136
|
|
@@ -180,7 +181,14 @@ class Thor
|
|
180
181
|
|
181
182
|
say_status :apply, path, verbose
|
182
183
|
shell.padding += 1 if verbose
|
183
|
-
|
184
|
+
|
185
|
+
if URI(path).is_a?(URI::HTTP)
|
186
|
+
contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
|
187
|
+
else
|
188
|
+
contents = open(path) {|io| io.read }
|
189
|
+
end
|
190
|
+
|
191
|
+
instance_eval(contents, path)
|
184
192
|
shell.padding -= 1 if verbose
|
185
193
|
end
|
186
194
|
|
@@ -223,7 +231,7 @@ class Thor
|
|
223
231
|
run command, config.merge(:with => Thor::Util.ruby_command)
|
224
232
|
end
|
225
233
|
|
226
|
-
# Run a thor command. A hash of options can be given and it's converted to
|
234
|
+
# Run a thor command. A hash of options can be given and it's converted to
|
227
235
|
# switches.
|
228
236
|
#
|
229
237
|
# ==== Parameters
|
@@ -48,7 +48,7 @@ class Thor
|
|
48
48
|
#
|
49
49
|
def get(source, destination=nil, config={}, &block)
|
50
50
|
source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\//
|
51
|
-
render = open(source).binmode.read
|
51
|
+
render = open(source) {|input| input.binmode.read }
|
52
52
|
|
53
53
|
destination ||= if block_given?
|
54
54
|
block.arity == 1 ? block.call(render) : block.call
|
data/lib/thor/invocation.rb
CHANGED
data/lib/thor/runner.rb
CHANGED
@@ -16,7 +16,7 @@ class Thor::Runner < Thor #:nodoc:
|
|
16
16
|
def help(meth=nil)
|
17
17
|
if meth && !self.respond_to?(meth)
|
18
18
|
initialize_thorfiles(meth)
|
19
|
-
klass, task = Thor::Util.find_class_and_task_by_namespace
|
19
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
20
20
|
klass.start(["-h", task].compact, :shell => self.shell)
|
21
21
|
else
|
22
22
|
super
|
@@ -29,7 +29,7 @@ class Thor::Runner < Thor #:nodoc:
|
|
29
29
|
def method_missing(meth, *args)
|
30
30
|
meth = meth.to_s
|
31
31
|
initialize_thorfiles(meth)
|
32
|
-
klass, task = Thor::Util.find_class_and_task_by_namespace
|
32
|
+
klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
|
33
33
|
args.unshift(task) if task
|
34
34
|
klass.start(args, :shell => self.shell)
|
35
35
|
end
|
@@ -44,10 +44,10 @@ class Thor::Runner < Thor #:nodoc:
|
|
44
44
|
begin
|
45
45
|
if File.directory?(File.expand_path(name))
|
46
46
|
base, package = File.join(name, "main.thor"), :directory
|
47
|
-
contents = open(base).read
|
47
|
+
contents = open(base) {|input| input.read }
|
48
48
|
else
|
49
49
|
base, package = name, :file
|
50
|
-
contents = open(name).read
|
50
|
+
contents = open(name) {|input| input.read }
|
51
51
|
end
|
52
52
|
rescue OpenURI::HTTPError
|
53
53
|
raise Error, "Error opening URI '#{name}'"
|
data/lib/thor/util.rb
CHANGED
@@ -128,25 +128,19 @@ class Thor
|
|
128
128
|
# ==== Parameters
|
129
129
|
# namespace<String>
|
130
130
|
#
|
131
|
-
def self.find_class_and_task_by_namespace(namespace)
|
132
|
-
if namespace.include?(?:)
|
131
|
+
def self.find_class_and_task_by_namespace(namespace, fallback = true)
|
132
|
+
if namespace.include?(?:) # look for a namespaced task
|
133
133
|
pieces = namespace.split(":")
|
134
134
|
task = pieces.pop
|
135
135
|
klass = Thor::Util.find_by_namespace(pieces.join(":"))
|
136
136
|
end
|
137
|
-
|
138
|
-
unless klass
|
137
|
+
unless klass # look for a Thor::Group with the right name
|
139
138
|
klass, task = Thor::Util.find_by_namespace(namespace), nil
|
140
139
|
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
# The same as namespace_to_thor_class_and_task!, but raises an error if a klass
|
146
|
-
# could not be found.
|
147
|
-
def self.find_class_and_task_by_namespace!(namespace)
|
148
|
-
klass, task = find_class_and_task_by_namespace(namespace)
|
149
|
-
raise Error, "Could not find namespace or task #{namespace.inspect}." unless klass
|
140
|
+
if !klass && fallback # try a task in the default namespace
|
141
|
+
task = namespace
|
142
|
+
klass = Thor::Util.find_by_namespace('')
|
143
|
+
end
|
150
144
|
return klass, task
|
151
145
|
end
|
152
146
|
|
data/lib/thor/version.rb
CHANGED
data/spec/actions_spec.rb
CHANGED
@@ -195,7 +195,7 @@ describe Thor::Actions do
|
|
195
195
|
@template.instance_eval "def read; self; end" # Make the string respond to read
|
196
196
|
|
197
197
|
@file = "http://gist.github.com/103208.txt"
|
198
|
-
runner.should_receive(:open).and_return(@template)
|
198
|
+
runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
|
199
199
|
end
|
200
200
|
|
201
201
|
it "opens a file and executes its content in the instance binding" do
|
data/spec/fixtures/group.thor
CHANGED
@@ -20,7 +20,7 @@ class MyCounter < Thor::Group
|
|
20
20
|
|
21
21
|
desc <<-FOO
|
22
22
|
Description:
|
23
|
-
This generator
|
23
|
+
This generator runs three tasks: one, two and three.
|
24
24
|
FOO
|
25
25
|
|
26
26
|
def one
|
@@ -81,3 +81,10 @@ class WhinyGenerator < Thor::Group
|
|
81
81
|
def wrong_arity(required)
|
82
82
|
end
|
83
83
|
end
|
84
|
+
|
85
|
+
class TaskConflict < Thor::Group
|
86
|
+
desc "A group with the same name as a default task"
|
87
|
+
def group
|
88
|
+
puts "group"
|
89
|
+
end
|
90
|
+
end
|
data/spec/fixtures/script.thor
CHANGED
@@ -127,9 +127,14 @@ module Scripts
|
|
127
127
|
|
128
128
|
class MyDefaults < Thor
|
129
129
|
namespace :default
|
130
|
-
desc "
|
131
|
-
def
|
132
|
-
puts "
|
130
|
+
desc "cow", "prints 'moo'"
|
131
|
+
def cow
|
132
|
+
puts "moo"
|
133
|
+
end
|
134
|
+
|
135
|
+
desc "task_conflict", "only gets called when prepended with a colon"
|
136
|
+
def task_conflict
|
137
|
+
puts "task"
|
133
138
|
end
|
134
139
|
end
|
135
140
|
|
data/spec/group_spec.rb
CHANGED
@@ -36,11 +36,11 @@ describe Thor::Group do
|
|
36
36
|
|
37
37
|
describe "#desc" do
|
38
38
|
it "sets the description for a given class" do
|
39
|
-
MyCounter.desc.must == "Description:\n This generator
|
39
|
+
MyCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
|
40
40
|
end
|
41
41
|
|
42
42
|
it "can be inherited" do
|
43
|
-
BrokenCounter.desc.must == "Description:\n This generator
|
43
|
+
BrokenCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
|
44
44
|
end
|
45
45
|
|
46
46
|
it "can be nil" do
|
@@ -59,7 +59,7 @@ describe Thor::Group do
|
|
59
59
|
|
60
60
|
it "shows description" do
|
61
61
|
@content.must =~ /Description:/
|
62
|
-
@content.must =~ /This generator
|
62
|
+
@content.must =~ /This generator runs three tasks: one, two and three./
|
63
63
|
end
|
64
64
|
|
65
65
|
it "shows options information" do
|
data/spec/runner_spec.rb
CHANGED
@@ -30,9 +30,8 @@ describe Thor::Runner do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "raises error if a class/task cannot be found" do
|
33
|
-
Thor::Runner.should_receive(:exit).with(1)
|
34
33
|
content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
|
35
|
-
content.strip.must == 'Could not find
|
34
|
+
content.strip.must == 'Could not find task "unknown" in "default" namespace.'
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
@@ -68,10 +67,9 @@ describe Thor::Runner do
|
|
68
67
|
end
|
69
68
|
|
70
69
|
it "raises an error if class/task can't be found" do
|
71
|
-
Thor::Runner.should_receive(:exit).with(1)
|
72
70
|
ARGV.replace ["unknown"]
|
73
71
|
content = capture(:stderr){ Thor::Runner.start }
|
74
|
-
content.strip.must == 'Could not find
|
72
|
+
content.strip.must == 'Could not find task "unknown" in "default" namespace.'
|
75
73
|
end
|
76
74
|
|
77
75
|
it "does not swallow NoMethodErrors that occur inside the called method" do
|
@@ -145,12 +143,22 @@ describe Thor::Runner do
|
|
145
143
|
|
146
144
|
it "presents tasks in the default namespace with an empty namespace" do
|
147
145
|
ARGV.replace ["list"]
|
148
|
-
capture(:stdout) { Thor::Runner.start }.must =~ /^thor :
|
146
|
+
capture(:stdout) { Thor::Runner.start }.must =~ /^thor :cow\s+# prints 'moo'/m
|
149
147
|
end
|
150
148
|
|
151
149
|
it "runs tasks with an empty namespace from the default namespace" do
|
152
|
-
ARGV.replace [":
|
153
|
-
capture(:stdout) { Thor::Runner.start }.must == "
|
150
|
+
ARGV.replace [":task_conflict"]
|
151
|
+
capture(:stdout) { Thor::Runner.start }.must == "task\n"
|
152
|
+
end
|
153
|
+
|
154
|
+
it "runs groups even when there is a task with the same name" do
|
155
|
+
ARGV.replace ["task_conflict"]
|
156
|
+
capture(:stdout) { Thor::Runner.start }.must == "group\n"
|
157
|
+
end
|
158
|
+
|
159
|
+
it "runs tasks with no colon in the default namespace" do
|
160
|
+
ARGV.replace ["cow"]
|
161
|
+
capture(:stdout) { Thor::Runner.start }.must == "moo\n"
|
154
162
|
end
|
155
163
|
end
|
156
164
|
|
data/spec/util_spec.rb
CHANGED
@@ -100,18 +100,14 @@ describe Thor::Util do
|
|
100
100
|
Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
|
101
101
|
end
|
102
102
|
|
103
|
-
it "
|
103
|
+
it "falls back in the namespace:task look up even if a full namespace does not match" do
|
104
104
|
Thor.const_set(:Help, Module.new)
|
105
105
|
Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
|
106
106
|
Thor.send :remove_const, :Help
|
107
107
|
end
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
lambda {
|
112
|
-
Thor::Util.find_class_and_task_by_namespace!("foobar")
|
113
|
-
}.must raise_error(Thor::Error, 'Could not find namespace or task "foobar".')
|
114
|
-
end
|
109
|
+
it "falls back on the default namespace class if nothing else matches" do
|
110
|
+
Thor::Util.find_class_and_task_by_namespace("test").must == [Scripts::MyDefaults, "test"]
|
115
111
|
end
|
116
112
|
end
|
117
113
|
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 13
|
8
|
+
- 5
|
9
|
+
version: 0.13.5
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Yehuda Katz
|
@@ -10,7 +15,7 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2010-
|
18
|
+
date: 2010-04-29 00:00:00 +02:00
|
14
19
|
default_executable:
|
15
20
|
dependencies: []
|
16
21
|
|
@@ -73,18 +78,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
78
|
requirements:
|
74
79
|
- - ">="
|
75
80
|
- !ruby/object:Gem::Version
|
81
|
+
segments:
|
82
|
+
- 0
|
76
83
|
version: "0"
|
77
|
-
version:
|
78
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
85
|
requirements:
|
80
86
|
- - ">="
|
81
87
|
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
82
90
|
version: "0"
|
83
|
-
version:
|
84
91
|
requirements: []
|
85
92
|
|
86
93
|
rubyforge_project: textmate
|
87
|
-
rubygems_version: 1.3.
|
94
|
+
rubygems_version: 1.3.6
|
88
95
|
signing_key:
|
89
96
|
specification_version: 3
|
90
97
|
summary: A scripting framework that replaces rake, sake and rubigen
|