thor 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +5 -5
- data/README.rdoc +65 -2
- data/Thorfile +13 -8
- data/bin/thor +1 -0
- data/lib/thor/actions/create_file.rb +2 -2
- data/lib/thor/actions/file_manipulation.rb +4 -4
- data/lib/thor/actions/inject_into_file.rb +10 -7
- data/lib/thor/actions.rb +1 -0
- data/lib/thor/base.rb +15 -0
- data/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/thor/group.rb +41 -28
- data/lib/thor/runner.rb +45 -42
- data/lib/thor/shell/color.rb +1 -1
- data/lib/thor/task.rb +13 -14
- data/lib/thor/util.rb +4 -22
- data/lib/thor/version.rb +1 -1
- data/lib/thor.rb +35 -39
- data/spec/actions/create_file_spec.rb +7 -7
- data/spec/actions/directory_spec.rb +1 -1
- data/spec/actions/file_manipulation_spec.rb +15 -15
- data/spec/actions/inject_into_file_spec.rb +29 -0
- data/spec/actions_spec.rb +14 -13
- data/spec/base_spec.rb +15 -0
- data/spec/fixtures/script.thor +4 -0
- data/spec/group_spec.rb +1 -7
- data/spec/runner_spec.rb +30 -34
- data/spec/shell/basic_spec.rb +43 -43
- data/spec/shell/color_spec.rb +6 -6
- data/spec/spec_helper.rb +5 -4
- data/spec/task_spec.rb +11 -9
- data/spec/thor_spec.rb +10 -13
- data/spec/util_spec.rb +7 -31
- metadata +3 -29
data/lib/thor/version.rb
CHANGED
data/lib/thor.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'thor/base'
|
|
2
|
-
require 'thor/group'
|
|
3
|
-
require 'thor/actions'
|
|
4
2
|
|
|
3
|
+
# TODO: Update thor to allow for git-style CLI (git bisect run)
|
|
5
4
|
class Thor
|
|
6
5
|
class << self
|
|
7
6
|
# Sets the default task when thor is executed without an explicit task to be called.
|
|
@@ -139,51 +138,47 @@ class Thor
|
|
|
139
138
|
end
|
|
140
139
|
end
|
|
141
140
|
|
|
142
|
-
# Prints help information
|
|
143
|
-
# only about the specific task.
|
|
141
|
+
# Prints help information for the given task.
|
|
144
142
|
#
|
|
145
143
|
# ==== Parameters
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
shell.say
|
|
160
|
-
class_options_help(shell, nil => task.options.map { |_, o| o })
|
|
161
|
-
shell.say task.description
|
|
162
|
-
else
|
|
163
|
-
list = printable_tasks(!options[:short])
|
|
164
|
-
|
|
165
|
-
Thor::Util.thor_classes_in(self).each do |klass|
|
|
166
|
-
list += klass.printable_tasks(false)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
list.sort!{ |a,b| a[0] <=> b[0] }
|
|
144
|
+
# shell<Thor::Shell>
|
|
145
|
+
# task_name<String>
|
|
146
|
+
#
|
|
147
|
+
def task_help(shell, task_name)
|
|
148
|
+
task = all_tasks[task_name]
|
|
149
|
+
raise UndefinedTaskError, "task '#{task_name}' could not be found in namespace '#{self.namespace}'" unless task
|
|
150
|
+
|
|
151
|
+
shell.say "Usage:"
|
|
152
|
+
shell.say " #{banner(task)}"
|
|
153
|
+
shell.say
|
|
154
|
+
class_options_help(shell, nil => task.options.map { |_, o| o })
|
|
155
|
+
shell.say task.description
|
|
156
|
+
end
|
|
170
157
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
158
|
+
# Prints help information for this class.
|
|
159
|
+
#
|
|
160
|
+
# ==== Parameters
|
|
161
|
+
# shell<Thor::Shell>
|
|
162
|
+
#
|
|
163
|
+
def help(shell)
|
|
164
|
+
list = printable_tasks
|
|
165
|
+
Thor::Util.thor_classes_in(self).each do |klass|
|
|
166
|
+
list += klass.printable_tasks(false)
|
|
179
167
|
end
|
|
168
|
+
list.sort!{ |a,b| a[0] <=> b[0] }
|
|
169
|
+
|
|
170
|
+
shell.say "Tasks:"
|
|
171
|
+
shell.print_table(list, :ident => 2, :truncate => true)
|
|
172
|
+
shell.say
|
|
173
|
+
class_options_help(shell)
|
|
180
174
|
end
|
|
181
175
|
|
|
176
|
+
# Returns tasks ready to be printed.
|
|
182
177
|
def printable_tasks(all=true)
|
|
183
178
|
(all ? all_tasks : tasks).map do |_, task|
|
|
184
179
|
item = []
|
|
185
180
|
item << banner(task)
|
|
186
|
-
item << "# #{task.description}"
|
|
181
|
+
item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
|
|
187
182
|
item
|
|
188
183
|
end
|
|
189
184
|
end
|
|
@@ -196,7 +191,8 @@ class Thor
|
|
|
196
191
|
# the namespace should be displayed as arguments.
|
|
197
192
|
#
|
|
198
193
|
def banner(task)
|
|
199
|
-
"thor
|
|
194
|
+
base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
|
|
195
|
+
"#{base} #{task.formatted_usage(self, base == "thor")}"
|
|
200
196
|
end
|
|
201
197
|
|
|
202
198
|
def baseclass #:nodoc:
|
|
@@ -239,6 +235,6 @@ class Thor
|
|
|
239
235
|
|
|
240
236
|
desc "help [TASK]", "Describe available tasks or one specific task"
|
|
241
237
|
def help(task=nil)
|
|
242
|
-
self.class.
|
|
238
|
+
task ? self.class.task_help(shell, task) : self.class.help(shell)
|
|
243
239
|
end
|
|
244
240
|
end
|
|
@@ -8,7 +8,7 @@ describe Thor::Actions::CreateFile do
|
|
|
8
8
|
|
|
9
9
|
def create_file(destination=nil, config={}, options={})
|
|
10
10
|
@base = MyCounter.new([1,2], options, { :destination_root => destination_root })
|
|
11
|
-
stub(
|
|
11
|
+
@base.stub!(:file_name).and_return('rdoc')
|
|
12
12
|
|
|
13
13
|
@action = Thor::Actions::CreateFile.new(@base, destination, "CONFIGURATION",
|
|
14
14
|
{ :verbose => !@silence }.merge(config))
|
|
@@ -103,7 +103,7 @@ describe Thor::Actions::CreateFile do
|
|
|
103
103
|
|
|
104
104
|
it "shows conflict status to ther user" do
|
|
105
105
|
create_file("doc/config.rb").must_not be_identical
|
|
106
|
-
|
|
106
|
+
$stdin.should_receive(:gets).and_return('s')
|
|
107
107
|
file = File.join(destination_root, 'doc/config.rb')
|
|
108
108
|
|
|
109
109
|
content = invoke!
|
|
@@ -114,21 +114,21 @@ describe Thor::Actions::CreateFile do
|
|
|
114
114
|
|
|
115
115
|
it "creates the file if the file collision menu returns true" do
|
|
116
116
|
create_file("doc/config.rb")
|
|
117
|
-
|
|
117
|
+
$stdin.should_receive(:gets).and_return('y')
|
|
118
118
|
invoke!.must =~ /force doc\/config\.rb/
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
it "skips the file if the file collision menu returns false" do
|
|
122
122
|
create_file("doc/config.rb")
|
|
123
|
-
|
|
123
|
+
$stdin.should_receive(:gets).and_return('n')
|
|
124
124
|
invoke!.must =~ /skip doc\/config\.rb/
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
it "executes the block given to show file content" do
|
|
128
128
|
create_file("doc/config.rb")
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
$stdin.should_receive(:gets).and_return('d')
|
|
130
|
+
$stdin.should_receive(:gets).and_return('n')
|
|
131
|
+
@base.shell.should_receive(:system).with(/diff -u/)
|
|
132
132
|
invoke!
|
|
133
133
|
end
|
|
134
134
|
end
|
|
@@ -29,23 +29,23 @@ describe Thor::Actions do
|
|
|
29
29
|
|
|
30
30
|
describe "#chmod" do
|
|
31
31
|
it "executes the command given" do
|
|
32
|
-
|
|
32
|
+
FileUtils.should_receive(:chmod_R).with(0755, file)
|
|
33
33
|
action :chmod, "foo", 0755
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it "does not execute the command if pretending given" do
|
|
37
|
-
|
|
37
|
+
FileUtils.should_not_receive(:chmod_R)
|
|
38
38
|
runner(:pretend => true)
|
|
39
39
|
action :chmod, "foo", 0755
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "logs status" do
|
|
43
|
-
|
|
43
|
+
FileUtils.should_receive(:chmod_R).with(0755, file)
|
|
44
44
|
action(:chmod, "foo", 0755).must == " chmod foo\n"
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "does not log status if required" do
|
|
48
|
-
|
|
48
|
+
FileUtils.should_receive(:chmod_R).with(0755, file)
|
|
49
49
|
action(:chmod, "foo", 0755, :verbose => false).must be_empty
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -123,7 +123,7 @@ describe Thor::Actions do
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "converts enconded instructions" do
|
|
126
|
-
|
|
126
|
+
runner.should_receive(:file_name).and_return("rdoc")
|
|
127
127
|
action :template, "doc/%file_name%.rb.tt"
|
|
128
128
|
file = File.join(destination_root, "doc/rdoc.rb.tt")
|
|
129
129
|
File.exists?(file).must be_true
|
|
@@ -179,18 +179,18 @@ describe Thor::Actions do
|
|
|
179
179
|
describe "#gsub_file" do
|
|
180
180
|
it "replaces the content in the file" do
|
|
181
181
|
action :gsub_file, "doc/README", "__start__", "START"
|
|
182
|
-
File.
|
|
182
|
+
File.binread(file).must == "START\nREADME\n__end__\n"
|
|
183
183
|
end
|
|
184
184
|
|
|
185
185
|
it "does not replace if pretending" do
|
|
186
186
|
runner(:pretend => true)
|
|
187
187
|
action :gsub_file, "doc/README", "__start__", "START"
|
|
188
|
-
File.
|
|
188
|
+
File.binread(file).must == "__start__\nREADME\n__end__\n"
|
|
189
189
|
end
|
|
190
190
|
|
|
191
191
|
it "accepts a block" do
|
|
192
192
|
action(:gsub_file, "doc/README", "__start__"){ |match| match.gsub('__', '').upcase }
|
|
193
|
-
File.
|
|
193
|
+
File.binread(file).must == "START\nREADME\n__end__\n"
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
it "logs status" do
|
|
@@ -205,12 +205,12 @@ describe Thor::Actions do
|
|
|
205
205
|
describe "#append_file" do
|
|
206
206
|
it "appends content to the file" do
|
|
207
207
|
action :append_file, "doc/README", "END\n"
|
|
208
|
-
File.
|
|
208
|
+
File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
|
|
209
209
|
end
|
|
210
210
|
|
|
211
211
|
it "accepts a block" do
|
|
212
212
|
action(:append_file, "doc/README"){ "END\n" }
|
|
213
|
-
File.
|
|
213
|
+
File.binread(file).must == "__start__\nREADME\n__end__\nEND\n"
|
|
214
214
|
end
|
|
215
215
|
|
|
216
216
|
it "logs status" do
|
|
@@ -221,12 +221,12 @@ describe Thor::Actions do
|
|
|
221
221
|
describe "#prepend_file" do
|
|
222
222
|
it "prepends content to the file" do
|
|
223
223
|
action :prepend_file, "doc/README", "START\n"
|
|
224
|
-
File.
|
|
224
|
+
File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
it "accepts a block" do
|
|
228
228
|
action(:prepend_file, "doc/README"){ "START\n" }
|
|
229
|
-
File.
|
|
229
|
+
File.binread(file).must == "START\n__start__\nREADME\n__end__\n"
|
|
230
230
|
end
|
|
231
231
|
|
|
232
232
|
it "logs status" do
|
|
@@ -241,12 +241,12 @@ describe Thor::Actions do
|
|
|
241
241
|
|
|
242
242
|
it "appends content to a class" do
|
|
243
243
|
action :inject_into_class, "application.rb", Application, " filter_parameters :password\n"
|
|
244
|
-
File.
|
|
244
|
+
File.binread(file).must == "class Application < Base\n filter_parameters :password\nend\n"
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
it "accepts a block" do
|
|
248
248
|
action(:inject_into_class, "application.rb", Application){ " filter_parameters :password\n" }
|
|
249
|
-
File.
|
|
249
|
+
File.binread(file).must == "class Application < Base\n filter_parameters :password\nend\n"
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
it "logs status" do
|
|
@@ -255,7 +255,7 @@ describe Thor::Actions do
|
|
|
255
255
|
|
|
256
256
|
it "does not append if class name does not match" do
|
|
257
257
|
action :inject_into_class, "application.rb", "App", " filter_parameters :password\n"
|
|
258
|
-
File.
|
|
258
|
+
File.binread(file).must == "class Application < Base\nend\n"
|
|
259
259
|
end
|
|
260
260
|
end
|
|
261
261
|
end
|
|
@@ -55,6 +55,35 @@ describe Thor::Actions::InjectIntoFile do
|
|
|
55
55
|
invoke! "doc/README", "\nmore content", :after => "__start__"
|
|
56
56
|
File.read(file).must == "__start__\nREADME\n__end__\n"
|
|
57
57
|
end
|
|
58
|
+
|
|
59
|
+
it "does not change the file if already include content" do
|
|
60
|
+
invoke! "doc/README", :before => "__end__" do
|
|
61
|
+
"more content\n"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
File.read(file).must == "__start__\nREADME\nmore content\n__end__\n"
|
|
65
|
+
|
|
66
|
+
invoke! "doc/README", :before => "__end__" do
|
|
67
|
+
"more content\n"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
File.read(file).must == "__start__\nREADME\nmore content\n__end__\n"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "does change the file if already include content and :force == true" do
|
|
74
|
+
invoke! "doc/README", :before => "__end__" do
|
|
75
|
+
"more content\n"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
File.read(file).must == "__start__\nREADME\nmore content\n__end__\n"
|
|
79
|
+
|
|
80
|
+
invoke! "doc/README", :before => "__end__", :force => true do
|
|
81
|
+
"more content\n"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
File.read(file).must == "__start__\nREADME\nmore content\nmore content\n__end__\n"
|
|
85
|
+
end
|
|
86
|
+
|
|
58
87
|
end
|
|
59
88
|
|
|
60
89
|
describe "#revoke!" do
|
data/spec/actions_spec.rb
CHANGED
|
@@ -55,9 +55,10 @@ describe Thor::Actions do
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it "does not use the current directory if one is given" do
|
|
58
|
+
root = File.expand_path("/")
|
|
58
59
|
base = MyCounter.new([1])
|
|
59
|
-
base.destination_root =
|
|
60
|
-
base.destination_root.must ==
|
|
60
|
+
base.destination_root = root
|
|
61
|
+
base.destination_root.must == root
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
it "uses the current directory if none is given" do
|
|
@@ -194,7 +195,7 @@ describe Thor::Actions do
|
|
|
194
195
|
@template.instance_eval "def read; self; end" # Make the string respond to read
|
|
195
196
|
|
|
196
197
|
@file = "http://gist.github.com/103208.txt"
|
|
197
|
-
|
|
198
|
+
runner.should_receive(:open).and_return(@template)
|
|
198
199
|
end
|
|
199
200
|
|
|
200
201
|
it "opens a file and executes its content in the instance binding" do
|
|
@@ -219,7 +220,7 @@ describe Thor::Actions do
|
|
|
219
220
|
|
|
220
221
|
describe "#run" do
|
|
221
222
|
before(:each) do
|
|
222
|
-
|
|
223
|
+
runner.should_receive(:system).with("ls")
|
|
223
224
|
end
|
|
224
225
|
|
|
225
226
|
it "executes the command given" do
|
|
@@ -235,15 +236,15 @@ describe Thor::Actions do
|
|
|
235
236
|
end
|
|
236
237
|
|
|
237
238
|
it "accepts a color as status" do
|
|
238
|
-
|
|
239
|
+
runner.shell.should_receive(:say_status).with(:run, 'ls from "."', :yellow)
|
|
239
240
|
action :run, "ls", :verbose => :yellow
|
|
240
241
|
end
|
|
241
242
|
end
|
|
242
243
|
|
|
243
244
|
describe "#run_ruby_script" do
|
|
244
245
|
before(:each) do
|
|
245
|
-
|
|
246
|
-
|
|
246
|
+
Thor::Util.stub!(:ruby_command).and_return("/opt/jruby")
|
|
247
|
+
runner.should_receive(:system).with("/opt/jruby script.rb")
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
it "executes the ruby script" do
|
|
@@ -261,30 +262,30 @@ describe Thor::Actions do
|
|
|
261
262
|
|
|
262
263
|
describe "#thor" do
|
|
263
264
|
it "executes the thor command" do
|
|
264
|
-
|
|
265
|
+
runner.should_receive(:system).with("thor list")
|
|
265
266
|
action :thor, :list, :verbose => true
|
|
266
267
|
end
|
|
267
268
|
|
|
268
269
|
it "converts extra arguments to command arguments" do
|
|
269
|
-
|
|
270
|
+
runner.should_receive(:system).with("thor list foo bar")
|
|
270
271
|
action :thor, :list, "foo", "bar"
|
|
271
272
|
end
|
|
272
273
|
|
|
273
274
|
it "converts options hash to switches" do
|
|
274
|
-
|
|
275
|
+
runner.should_receive(:system).with("thor list foo bar --foo")
|
|
275
276
|
action :thor, :list, "foo", "bar", :foo => true
|
|
276
277
|
|
|
277
|
-
|
|
278
|
+
runner.should_receive(:system).with("thor list --foo 1 2 3")
|
|
278
279
|
action :thor, :list, :foo => [1,2,3]
|
|
279
280
|
end
|
|
280
281
|
|
|
281
282
|
it "logs status" do
|
|
282
|
-
|
|
283
|
+
runner.should_receive(:system).with("thor list")
|
|
283
284
|
action(:thor, :list).must == " run thor list from \".\"\n"
|
|
284
285
|
end
|
|
285
286
|
|
|
286
287
|
it "does not log status if required" do
|
|
287
|
-
|
|
288
|
+
runner.should_receive(:system).with("thor list --foo 1 2 3")
|
|
288
289
|
action(:thor, :list, :foo => [1,2,3], :verbose => false).must be_empty
|
|
289
290
|
end
|
|
290
291
|
end
|
data/spec/base_spec.rb
CHANGED
|
@@ -233,4 +233,19 @@ describe Thor::Base do
|
|
|
233
233
|
}.must raise_error(Thor::UndefinedTaskError, /the 'what' task of MyScript is private/)
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
|
+
|
|
237
|
+
describe "attr_*" do
|
|
238
|
+
it "should not add attr_reader as a task" do
|
|
239
|
+
capture(:stderr){ MyScript.start(["another_attribute"]) }.must =~ /could not find/
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should not add attr_writer as a task" do
|
|
243
|
+
capture(:stderr){ MyScript.start(["another_attribute=", "foo"]) }.must =~ /could not find/
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "should not add attr_accessor as a task" do
|
|
247
|
+
capture(:stderr){ MyScript.start(["some_attribute"]) }.must =~ /could not find/
|
|
248
|
+
capture(:stderr){ MyScript.start(["some_attribute=", "foo"]) }.must =~ /could not find/
|
|
249
|
+
end
|
|
250
|
+
end
|
|
236
251
|
end
|
data/spec/fixtures/script.thor
CHANGED
data/spec/group_spec.rb
CHANGED
|
@@ -29,7 +29,7 @@ describe Thor::Group do
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it "invokes help message if any of the shortcuts is given" do
|
|
32
|
-
|
|
32
|
+
MyCounter.should_receive(:help)
|
|
33
33
|
MyCounter.start(["-h"])
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -66,12 +66,6 @@ describe Thor::Group do
|
|
|
66
66
|
@content.must =~ /Options/
|
|
67
67
|
@content.must =~ /\[\-\-third=THREE\]/
|
|
68
68
|
end
|
|
69
|
-
|
|
70
|
-
it "shows only usage if a short help is required" do
|
|
71
|
-
content = capture(:stdout){ MyCounter.help(Thor::Base.shell.new, :short => true) }
|
|
72
|
-
content.must =~ /my_counter N \[N\]/
|
|
73
|
-
content.must_not =~ /Options/
|
|
74
|
-
end
|
|
75
69
|
end
|
|
76
70
|
|
|
77
71
|
describe "#invoke" do
|
data/spec/runner_spec.rb
CHANGED
|
@@ -26,11 +26,11 @@ describe Thor::Runner do
|
|
|
26
26
|
|
|
27
27
|
it "shows information about a specific Thor group class" do
|
|
28
28
|
content = capture(:stdout){ Thor::Runner.start(["help", "my_counter"]) }
|
|
29
|
-
content.must =~ /my_counter N
|
|
29
|
+
content.must =~ /my_counter N/
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it "raises error if a class/task cannot be found" do
|
|
33
|
-
|
|
33
|
+
Thor::Runner.should_receive(:exit).with(1)
|
|
34
34
|
content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
|
|
35
35
|
content.must =~ /could not find Thor class or task 'unknown'/
|
|
36
36
|
end
|
|
@@ -39,7 +39,7 @@ describe Thor::Runner do
|
|
|
39
39
|
describe "#start" do
|
|
40
40
|
it "invokes a task from Thor::Runner" do
|
|
41
41
|
ARGV.replace ["list"]
|
|
42
|
-
capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N
|
|
42
|
+
capture(:stdout){ Thor::Runner.start }.must =~ /my_counter N/
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it "invokes a task from a specific Thor class" do
|
|
@@ -68,7 +68,7 @@ describe Thor::Runner do
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it "raises an error if class/task can't be found" do
|
|
71
|
-
|
|
71
|
+
Thor::Runner.should_receive(:exit).with(1)
|
|
72
72
|
ARGV.replace ["unknown"]
|
|
73
73
|
capture(:stderr){ Thor::Runner.start }.must =~ /could not find Thor class or task 'unknown'/
|
|
74
74
|
end
|
|
@@ -96,14 +96,16 @@ describe Thor::Runner do
|
|
|
96
96
|
"random" => {
|
|
97
97
|
:location => @location,
|
|
98
98
|
:filename => "4a33b894ffce85d7b412fc1b36f88fe0",
|
|
99
|
-
:
|
|
99
|
+
:namespaces => ["amazing"]
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
root_file = File.join(Thor::Util.thor_root, "thor.yml")
|
|
104
|
+
|
|
103
105
|
# Stub load and save to avoid thor.yaml from being overwritten
|
|
104
|
-
stub(
|
|
105
|
-
stub(
|
|
106
|
-
stub(
|
|
106
|
+
YAML.stub!(:load_file).and_return(@original_yaml)
|
|
107
|
+
File.stub!(:exists?).with(root_file).and_return(true)
|
|
108
|
+
File.stub!(:open).with(root_file, "w")
|
|
107
109
|
end
|
|
108
110
|
|
|
109
111
|
describe "list" do
|
|
@@ -115,7 +117,7 @@ describe Thor::Runner do
|
|
|
115
117
|
|
|
116
118
|
it "gives a list of the available Thor::Group classes" do
|
|
117
119
|
ARGV.replace ["list"]
|
|
118
|
-
capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N
|
|
120
|
+
capture(:stdout) { Thor::Runner.start }.must =~ /my_counter N/
|
|
119
121
|
end
|
|
120
122
|
|
|
121
123
|
it "can filter a list of the available tasks by --group" do
|
|
@@ -148,26 +150,12 @@ describe Thor::Runner do
|
|
|
148
150
|
ARGV.replace [":test"]
|
|
149
151
|
capture(:stdout) { Thor::Runner.start }.must == "test\n"
|
|
150
152
|
end
|
|
151
|
-
|
|
152
|
-
it "updates the yaml file when invoked" do
|
|
153
|
-
capture(:stdout) { Thor::Runner.start(["list"]) }
|
|
154
|
-
@original_yaml["random"][:namespaces].must == ["amazing"]
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
describe "update" do
|
|
159
|
-
it "updates existing thor files" do
|
|
160
|
-
mock.instance_of(Thor::Runner).install(@original_yaml["random"][:location]) { true }
|
|
161
|
-
stub(File).delete(File.join(Thor::Util.thor_root, @original_yaml["random"][:filename]))
|
|
162
|
-
silence(:stdout) { Thor::Runner.start(["update", "random"]) }
|
|
163
|
-
end
|
|
164
153
|
end
|
|
165
154
|
|
|
166
155
|
describe "uninstall" do
|
|
167
156
|
before(:each) do
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
stub(@original_yaml).delete(anything)
|
|
157
|
+
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
|
158
|
+
FileUtils.should_receive(:rm_rf).with(path)
|
|
171
159
|
end
|
|
172
160
|
|
|
173
161
|
it "uninstalls existing thor modules" do
|
|
@@ -177,7 +165,7 @@ describe Thor::Runner do
|
|
|
177
165
|
|
|
178
166
|
describe "installed" do
|
|
179
167
|
before(:each) do
|
|
180
|
-
|
|
168
|
+
Dir.should_receive(:[]).and_return([])
|
|
181
169
|
end
|
|
182
170
|
|
|
183
171
|
it "displays the modules installed in a pretty way" do
|
|
@@ -187,16 +175,24 @@ describe Thor::Runner do
|
|
|
187
175
|
end
|
|
188
176
|
end
|
|
189
177
|
|
|
190
|
-
describe "install" do
|
|
191
|
-
|
|
192
|
-
|
|
178
|
+
describe "install/update" do
|
|
179
|
+
before(:each) do
|
|
180
|
+
FileUtils.stub!(:mkdir_p)
|
|
181
|
+
FileUtils.stub!(:touch)
|
|
182
|
+
$stdin.stub!(:gets).and_return("Y")
|
|
193
183
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
stub(FileUtils).touch
|
|
184
|
+
path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
|
|
185
|
+
File.should_receive(:open).with(path, "w")
|
|
186
|
+
end
|
|
198
187
|
|
|
199
|
-
|
|
188
|
+
it "updates existing thor files" do
|
|
189
|
+
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
|
190
|
+
File.should_receive(:delete).with(path)
|
|
191
|
+
silence(:stdout) { Thor::Runner.start(["update", "random"]) }
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "installs thor files" do
|
|
195
|
+
ARGV.replace ["install", @location]
|
|
200
196
|
silence(:stdout) { Thor::Runner.start }
|
|
201
197
|
end
|
|
202
198
|
end
|