thor 0.14.4 → 0.14.5
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 +11 -0
- data/Thorfile +9 -55
- data/lib/thor.rb +17 -0
- data/lib/thor/actions.rb +11 -6
- data/lib/thor/actions/create_file.rb +2 -2
- data/lib/thor/actions/create_link.rb +57 -0
- data/lib/thor/actions/file_manipulation.rb +36 -12
- data/lib/thor/actions/inject_into_file.rb +15 -10
- data/lib/thor/parser/option.rb +1 -1
- data/lib/thor/task.rb +1 -1
- data/lib/thor/version.rb +1 -1
- data/spec/actions/create_file_spec.rb +27 -27
- data/spec/actions/directory_spec.rb +23 -23
- data/spec/actions/empty_directory_spec.rb +12 -12
- data/spec/actions/file_manipulation_spec.rb +65 -42
- data/spec/actions/inject_into_file_spec.rb +24 -24
- data/spec/actions_spec.rb +63 -58
- data/spec/base_spec.rb +60 -60
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +14 -14
- data/spec/core_ext/ordered_hash_spec.rb +28 -28
- data/spec/group_spec.rb +39 -39
- data/spec/invocation_spec.rb +21 -21
- data/spec/parser/argument_spec.rb +7 -7
- data/spec/parser/arguments_spec.rb +11 -11
- data/spec/parser/option_spec.rb +45 -45
- data/spec/parser/options_spec.rb +75 -75
- data/spec/rake_compat_spec.rb +10 -10
- data/spec/register_spec.rb +92 -0
- data/spec/runner_spec.rb +32 -32
- data/spec/shell/basic_spec.rb +18 -18
- data/spec/shell/color_spec.rb +3 -3
- data/spec/shell_spec.rb +10 -10
- data/spec/spec_helper.rb +9 -10
- data/spec/task_spec.rb +8 -8
- data/spec/thor_spec.rb +62 -62
- data/spec/util_spec.rb +35 -35
- metadata +100 -68
- data/spec/spec.opts +0 -1
@@ -16,11 +16,11 @@ describe Thor::Actions::InjectIntoFile do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def invoke!(*args, &block)
|
19
|
-
capture(:stdout){ invoker.
|
19
|
+
capture(:stdout){ invoker.insert_into_file(*args, &block) }
|
20
20
|
end
|
21
21
|
|
22
22
|
def revoke!(*args, &block)
|
23
|
-
capture(:stdout){ revoker.
|
23
|
+
capture(:stdout){ revoker.insert_into_file(*args, &block) }
|
24
24
|
end
|
25
25
|
|
26
26
|
def file
|
@@ -30,12 +30,12 @@ describe Thor::Actions::InjectIntoFile do
|
|
30
30
|
describe "#invoke!" do
|
31
31
|
it "changes the file adding content after the flag" do
|
32
32
|
invoke! "doc/README", "\nmore content", :after => "__start__"
|
33
|
-
File.read(file).
|
33
|
+
File.read(file).should == "__start__\nmore content\nREADME\n__end__\n"
|
34
34
|
end
|
35
35
|
|
36
36
|
it "changes the file adding content before the flag" do
|
37
37
|
invoke! "doc/README", "more content\n", :before => "__end__"
|
38
|
-
File.read(file).
|
38
|
+
File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
|
39
39
|
end
|
40
40
|
|
41
41
|
it "accepts data as a block" do
|
@@ -43,17 +43,17 @@ describe Thor::Actions::InjectIntoFile do
|
|
43
43
|
"more content\n"
|
44
44
|
end
|
45
45
|
|
46
|
-
File.read(file).
|
46
|
+
File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
|
47
47
|
end
|
48
48
|
|
49
49
|
it "logs status" do
|
50
|
-
invoke!("doc/README", "\nmore content", :after => "__start__").
|
50
|
+
invoke!("doc/README", "\nmore content", :after => "__start__").should == " insert doc/README\n"
|
51
51
|
end
|
52
52
|
|
53
53
|
it "does not change the file if pretending" do
|
54
54
|
invoker :pretend => true
|
55
55
|
invoke! "doc/README", "\nmore content", :after => "__start__"
|
56
|
-
File.read(file).
|
56
|
+
File.read(file).should == "__start__\nREADME\n__end__\n"
|
57
57
|
end
|
58
58
|
|
59
59
|
it "does not change the file if already include content" do
|
@@ -61,13 +61,13 @@ describe Thor::Actions::InjectIntoFile do
|
|
61
61
|
"more content\n"
|
62
62
|
end
|
63
63
|
|
64
|
-
File.read(file).
|
64
|
+
File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
|
65
65
|
|
66
66
|
invoke! "doc/README", :before => "__end__" do
|
67
67
|
"more content\n"
|
68
68
|
end
|
69
69
|
|
70
|
-
File.read(file).
|
70
|
+
File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
|
71
71
|
end
|
72
72
|
|
73
73
|
it "does change the file if already include content and :force == true" do
|
@@ -75,61 +75,61 @@ describe Thor::Actions::InjectIntoFile do
|
|
75
75
|
"more content\n"
|
76
76
|
end
|
77
77
|
|
78
|
-
File.read(file).
|
78
|
+
File.read(file).should == "__start__\nREADME\nmore content\n__end__\n"
|
79
79
|
|
80
80
|
invoke! "doc/README", :before => "__end__", :force => true do
|
81
81
|
"more content\n"
|
82
82
|
end
|
83
83
|
|
84
|
-
File.read(file).
|
84
|
+
File.read(file).should == "__start__\nREADME\nmore content\nmore content\n__end__\n"
|
85
85
|
end
|
86
86
|
|
87
87
|
end
|
88
88
|
|
89
89
|
describe "#revoke!" do
|
90
|
-
it "
|
90
|
+
it "substracts the destination file after injection" do
|
91
91
|
invoke! "doc/README", "\nmore content", :after => "__start__"
|
92
92
|
revoke! "doc/README", "\nmore content", :after => "__start__"
|
93
|
-
File.read(file).
|
93
|
+
File.read(file).should == "__start__\nREADME\n__end__\n"
|
94
94
|
end
|
95
95
|
|
96
|
-
it "
|
96
|
+
it "substracts the destination file before injection" do
|
97
97
|
invoke! "doc/README", "more content\n", :before => "__start__"
|
98
98
|
revoke! "doc/README", "more content\n", :before => "__start__"
|
99
|
-
File.read(file).
|
99
|
+
File.read(file).should == "__start__\nREADME\n__end__\n"
|
100
100
|
end
|
101
101
|
|
102
|
-
it "
|
102
|
+
it "substracts even with double after injection" do
|
103
103
|
invoke! "doc/README", "\nmore content", :after => "__start__"
|
104
104
|
invoke! "doc/README", "\nanother stuff", :after => "__start__"
|
105
105
|
revoke! "doc/README", "\nmore content", :after => "__start__"
|
106
|
-
File.read(file).
|
106
|
+
File.read(file).should == "__start__\nanother stuff\nREADME\n__end__\n"
|
107
107
|
end
|
108
108
|
|
109
|
-
it "
|
109
|
+
it "substracts even with double before injection" do
|
110
110
|
invoke! "doc/README", "more content\n", :before => "__start__"
|
111
111
|
invoke! "doc/README", "another stuff\n", :before => "__start__"
|
112
112
|
revoke! "doc/README", "more content\n", :before => "__start__"
|
113
|
-
File.read(file).
|
113
|
+
File.read(file).should == "another stuff\n__start__\nREADME\n__end__\n"
|
114
114
|
end
|
115
115
|
|
116
|
-
it "
|
116
|
+
it "substracts when prepending" do
|
117
117
|
invoke! "doc/README", "more content\n", :after => /\A/
|
118
118
|
invoke! "doc/README", "another stuff\n", :after => /\A/
|
119
119
|
revoke! "doc/README", "more content\n", :after => /\A/
|
120
|
-
File.read(file).
|
120
|
+
File.read(file).should == "another stuff\n__start__\nREADME\n__end__\n"
|
121
121
|
end
|
122
122
|
|
123
|
-
it "
|
123
|
+
it "substracts when appending" do
|
124
124
|
invoke! "doc/README", "more content\n", :before => /\z/
|
125
125
|
invoke! "doc/README", "another stuff\n", :before => /\z/
|
126
126
|
revoke! "doc/README", "more content\n", :before => /\z/
|
127
|
-
File.read(file).
|
127
|
+
File.read(file).should == "__start__\nREADME\n__end__\nanother stuff\n"
|
128
128
|
end
|
129
129
|
|
130
130
|
it "shows progress information to the user" do
|
131
131
|
invoke!("doc/README", "\nmore content", :after => "__start__")
|
132
|
-
revoke!("doc/README", "\nmore content", :after => "__start__").
|
132
|
+
revoke!("doc/README", "\nmore content", :after => "__start__").should == " subtract doc/README\n"
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
data/spec/actions_spec.rb
CHANGED
@@ -15,34 +15,34 @@ describe Thor::Actions do
|
|
15
15
|
|
16
16
|
describe "on include" do
|
17
17
|
it "adds runtime options to the base class" do
|
18
|
-
MyCounter.class_options.keys.
|
19
|
-
MyCounter.class_options.keys.
|
20
|
-
MyCounter.class_options.keys.
|
21
|
-
MyCounter.class_options.keys.
|
18
|
+
MyCounter.class_options.keys.should include(:pretend)
|
19
|
+
MyCounter.class_options.keys.should include(:force)
|
20
|
+
MyCounter.class_options.keys.should include(:quiet)
|
21
|
+
MyCounter.class_options.keys.should include(:skip)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe "#initialize" do
|
26
26
|
it "has default behavior invoke" do
|
27
|
-
runner.behavior.
|
27
|
+
runner.behavior.should == :invoke
|
28
28
|
end
|
29
29
|
|
30
30
|
it "can have behavior revoke" do
|
31
|
-
MyCounter.new([1], {}, :behavior => :revoke).behavior.
|
31
|
+
MyCounter.new([1], {}, :behavior => :revoke).behavior.should == :revoke
|
32
32
|
end
|
33
33
|
|
34
34
|
it "when behavior is set to force, overwrite options" do
|
35
35
|
runner = MyCounter.new([1], { :force => false, :skip => true }, :behavior => :force)
|
36
|
-
runner.behavior.
|
37
|
-
runner.options.force.
|
38
|
-
runner.options.skip.
|
36
|
+
runner.behavior.should == :invoke
|
37
|
+
runner.options.force.should be_true
|
38
|
+
runner.options.skip.should_not be_true
|
39
39
|
end
|
40
40
|
|
41
41
|
it "when behavior is set to skip, overwrite options" do
|
42
42
|
runner = MyCounter.new([1], ["--force"], :behavior => :skip)
|
43
|
-
runner.behavior.
|
44
|
-
runner.options.force.
|
45
|
-
runner.options.skip.
|
43
|
+
runner.behavior.should == :invoke
|
44
|
+
runner.options.force.should_not be_true
|
45
|
+
runner.options.skip.should be_true
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -51,54 +51,54 @@ describe Thor::Actions do
|
|
51
51
|
it "gets the current directory and expands the path to set the root" do
|
52
52
|
base = MyCounter.new([1])
|
53
53
|
base.destination_root = "here"
|
54
|
-
base.destination_root.
|
54
|
+
base.destination_root.should == File.expand_path(File.join(File.dirname(__FILE__), "..", "here"))
|
55
55
|
end
|
56
56
|
|
57
57
|
it "does not use the current directory if one is given" do
|
58
58
|
root = File.expand_path("/")
|
59
59
|
base = MyCounter.new([1])
|
60
60
|
base.destination_root = root
|
61
|
-
base.destination_root.
|
61
|
+
base.destination_root.should == root
|
62
62
|
end
|
63
63
|
|
64
64
|
it "uses the current directory if none is given" do
|
65
65
|
base = MyCounter.new([1])
|
66
|
-
base.destination_root.
|
66
|
+
base.destination_root.should == File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
describe "#relative_to_original_destination_root" do
|
71
71
|
it "returns the path relative to the absolute root" do
|
72
|
-
runner.relative_to_original_destination_root(file).
|
72
|
+
runner.relative_to_original_destination_root(file).should == "foo"
|
73
73
|
end
|
74
74
|
|
75
75
|
it "does not remove dot if required" do
|
76
|
-
runner.relative_to_original_destination_root(file, false).
|
76
|
+
runner.relative_to_original_destination_root(file, false).should == "./foo"
|
77
77
|
end
|
78
78
|
|
79
79
|
it "always use the absolute root" do
|
80
80
|
runner.inside("foo") do
|
81
|
-
runner.relative_to_original_destination_root(file).
|
81
|
+
runner.relative_to_original_destination_root(file).should == "foo"
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
describe "#source_paths_for_search" do
|
86
86
|
it "add source_root to source_paths_for_search" do
|
87
|
-
MyCounter.source_paths_for_search.
|
87
|
+
MyCounter.source_paths_for_search.should include(File.expand_path("fixtures", File.dirname(__FILE__)))
|
88
88
|
end
|
89
89
|
|
90
90
|
it "keeps only current source root in source paths" do
|
91
|
-
ClearCounter.source_paths_for_search.
|
92
|
-
ClearCounter.source_paths_for_search.
|
91
|
+
ClearCounter.source_paths_for_search.should include(File.expand_path("fixtures/bundle", File.dirname(__FILE__)))
|
92
|
+
ClearCounter.source_paths_for_search.should_not include(File.expand_path("fixtures", File.dirname(__FILE__)))
|
93
93
|
end
|
94
94
|
|
95
95
|
it "customized source paths should be before source roots" do
|
96
|
-
ClearCounter.source_paths_for_search[0].
|
97
|
-
ClearCounter.source_paths_for_search[1].
|
96
|
+
ClearCounter.source_paths_for_search[0].should == File.expand_path("fixtures/doc", File.dirname(__FILE__))
|
97
|
+
ClearCounter.source_paths_for_search[1].should == File.expand_path("fixtures/bundle", File.dirname(__FILE__))
|
98
98
|
end
|
99
99
|
|
100
100
|
it "keeps inherited source paths at the end" do
|
101
|
-
ClearCounter.source_paths_for_search.last.
|
101
|
+
ClearCounter.source_paths_for_search.last.should == File.expand_path("fixtures/broken", File.dirname(__FILE__))
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
@@ -107,17 +107,17 @@ describe Thor::Actions do
|
|
107
107
|
it "raises an error if source path is empty" do
|
108
108
|
lambda {
|
109
109
|
A.new.find_in_source_paths("foo")
|
110
|
-
}.
|
110
|
+
}.should raise_error(Thor::Error, /Currently you have no source paths/)
|
111
111
|
end
|
112
112
|
|
113
113
|
it "finds a template inside the source path" do
|
114
|
-
runner.find_in_source_paths("doc").
|
115
|
-
lambda { runner.find_in_source_paths("README") }.
|
114
|
+
runner.find_in_source_paths("doc").should == File.expand_path("doc", source_root)
|
115
|
+
lambda { runner.find_in_source_paths("README") }.should raise_error
|
116
116
|
|
117
117
|
new_path = File.join(source_root, "doc")
|
118
118
|
runner.instance_variable_set(:@source_paths, nil)
|
119
119
|
runner.source_paths.unshift(new_path)
|
120
|
-
runner.find_in_source_paths("README").
|
120
|
+
runner.find_in_source_paths("README").should == File.expand_path("README", new_path)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -125,26 +125,26 @@ describe Thor::Actions do
|
|
125
125
|
describe "#inside" do
|
126
126
|
it "executes the block inside the given folder" do
|
127
127
|
runner.inside("foo") do
|
128
|
-
Dir.pwd.
|
128
|
+
Dir.pwd.should == file
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
132
|
it "changes the base root" do
|
133
133
|
runner.inside("foo") do
|
134
|
-
runner.destination_root.
|
134
|
+
runner.destination_root.should == file
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
138
|
it "creates the directory if it does not exist" do
|
139
139
|
runner.inside("foo") do
|
140
|
-
File.exists?(file).
|
140
|
+
File.exists?(file).should be_true
|
141
141
|
end
|
142
142
|
end
|
143
|
-
|
143
|
+
|
144
144
|
describe "when pretending" do
|
145
145
|
it "no directories should be created" do
|
146
146
|
runner.inside("bar", :pretend => true) {}
|
147
|
-
File.exists?("bar").
|
147
|
+
File.exists?("bar").should be_false
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -152,7 +152,7 @@ describe Thor::Actions do
|
|
152
152
|
it "logs status" do
|
153
153
|
capture(:stdout) do
|
154
154
|
runner.inside("foo", :verbose => true) {}
|
155
|
-
end.
|
155
|
+
end.should =~ /inside foo/
|
156
156
|
end
|
157
157
|
|
158
158
|
it "uses padding in next status" do
|
@@ -160,14 +160,14 @@ describe Thor::Actions do
|
|
160
160
|
runner.inside("foo", :verbose => true) do
|
161
161
|
runner.say_status :cool, :padding
|
162
162
|
end
|
163
|
-
end.
|
163
|
+
end.should =~ /cool padding/
|
164
164
|
end
|
165
165
|
|
166
166
|
it "removes padding after block" do
|
167
167
|
capture(:stdout) do
|
168
168
|
runner.inside("foo", :verbose => true) {}
|
169
169
|
runner.say_status :no, :padding
|
170
|
-
end.
|
170
|
+
end.should =~ /no padding/
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
@@ -175,20 +175,20 @@ describe Thor::Actions do
|
|
175
175
|
describe "#in_root" do
|
176
176
|
it "executes the block in the root folder" do
|
177
177
|
runner.inside("foo") do
|
178
|
-
runner.in_root { Dir.pwd.
|
178
|
+
runner.in_root { Dir.pwd.should == destination_root }
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
182
|
it "changes the base root" do
|
183
183
|
runner.inside("foo") do
|
184
|
-
runner.in_root { runner.destination_root.
|
184
|
+
runner.in_root { runner.destination_root.should == destination_root }
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
188
188
|
it "returns to the previous state" do
|
189
189
|
runner.inside("foo") do
|
190
190
|
runner.in_root { }
|
191
|
-
runner.destination_root.
|
191
|
+
runner.destination_root.should == file
|
192
192
|
end
|
193
193
|
end
|
194
194
|
end
|
@@ -225,27 +225,27 @@ describe Thor::Actions do
|
|
225
225
|
|
226
226
|
it "opens a file and executes its content in the instance binding" do
|
227
227
|
action :apply, @file
|
228
|
-
runner.instance_variable_get("@foo").
|
228
|
+
runner.instance_variable_get("@foo").should == "FOO"
|
229
229
|
end
|
230
230
|
|
231
231
|
it "applies padding to the content inside the file" do
|
232
|
-
action(:apply, @file).
|
232
|
+
action(:apply, @file).should =~ /cool padding/
|
233
233
|
end
|
234
234
|
|
235
235
|
it "logs its status" do
|
236
|
-
action(:apply, @file).
|
236
|
+
action(:apply, @file).should =~ / apply #{@file}\n/
|
237
237
|
end
|
238
238
|
|
239
239
|
it "does not log status" do
|
240
240
|
content = action(:apply, @file, :verbose => false)
|
241
|
-
content.
|
242
|
-
content.
|
241
|
+
content.should =~ /cool padding/
|
242
|
+
content.should_not =~ /apply http/
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
246
246
|
describe "#run" do
|
247
247
|
before(:each) do
|
248
|
-
runner.should_receive(
|
248
|
+
runner.should_receive(:system).with("ls")
|
249
249
|
end
|
250
250
|
|
251
251
|
it "executes the command given" do
|
@@ -253,11 +253,11 @@ describe Thor::Actions do
|
|
253
253
|
end
|
254
254
|
|
255
255
|
it "logs status" do
|
256
|
-
action(:run, "ls").
|
256
|
+
action(:run, "ls").should == " run ls from \".\"\n"
|
257
257
|
end
|
258
258
|
|
259
259
|
it "does not log status if required" do
|
260
|
-
action(:run, "ls", :verbose => false).
|
260
|
+
action(:run, "ls", :verbose => false).should be_empty
|
261
261
|
end
|
262
262
|
|
263
263
|
it "accepts a color as status" do
|
@@ -269,7 +269,7 @@ describe Thor::Actions do
|
|
269
269
|
describe "#run_ruby_script" do
|
270
270
|
before(:each) do
|
271
271
|
Thor::Util.stub!(:ruby_command).and_return("/opt/jruby")
|
272
|
-
runner.should_receive(
|
272
|
+
runner.should_receive(:system).with("/opt/jruby script.rb")
|
273
273
|
end
|
274
274
|
|
275
275
|
it "executes the ruby script" do
|
@@ -277,41 +277,46 @@ describe Thor::Actions do
|
|
277
277
|
end
|
278
278
|
|
279
279
|
it "logs status" do
|
280
|
-
action(:run_ruby_script, "script.rb").
|
280
|
+
action(:run_ruby_script, "script.rb").should == " run jruby script.rb from \".\"\n"
|
281
281
|
end
|
282
282
|
|
283
283
|
it "does not log status if required" do
|
284
|
-
action(:run_ruby_script, "script.rb", :verbose => false).
|
284
|
+
action(:run_ruby_script, "script.rb", :verbose => false).should be_empty
|
285
285
|
end
|
286
286
|
end
|
287
287
|
|
288
288
|
describe "#thor" do
|
289
289
|
it "executes the thor command" do
|
290
|
-
runner.should_receive(
|
290
|
+
runner.should_receive(:system).with("thor list")
|
291
291
|
action :thor, :list, :verbose => true
|
292
292
|
end
|
293
293
|
|
294
294
|
it "converts extra arguments to command arguments" do
|
295
|
-
runner.should_receive(
|
295
|
+
runner.should_receive(:system).with("thor list foo bar")
|
296
296
|
action :thor, :list, "foo", "bar"
|
297
297
|
end
|
298
298
|
|
299
299
|
it "converts options hash to switches" do
|
300
|
-
runner.should_receive(
|
300
|
+
runner.should_receive(:system).with("thor list foo bar --foo")
|
301
301
|
action :thor, :list, "foo", "bar", :foo => true
|
302
302
|
|
303
|
-
runner.should_receive(
|
303
|
+
runner.should_receive(:system).with("thor list --foo 1 2 3")
|
304
304
|
action :thor, :list, :foo => [1,2,3]
|
305
305
|
end
|
306
306
|
|
307
307
|
it "logs status" do
|
308
|
-
runner.should_receive(
|
309
|
-
action(:thor, :list).
|
308
|
+
runner.should_receive(:system).with("thor list")
|
309
|
+
action(:thor, :list).should == " run thor list from \".\"\n"
|
310
310
|
end
|
311
311
|
|
312
312
|
it "does not log status if required" do
|
313
|
-
runner.should_receive(
|
314
|
-
action(:thor, :list, :foo => [1,2,3], :verbose => false).
|
313
|
+
runner.should_receive(:system).with("thor list --foo 1 2 3")
|
314
|
+
action(:thor, :list, :foo => [1,2,3], :verbose => false).should be_empty
|
315
|
+
end
|
316
|
+
|
317
|
+
it "captures the output when :capture is given" do
|
318
|
+
runner.should_receive(:`).with("thor foo bar")
|
319
|
+
action(:thor, "foo", "bar", :capture => true)
|
315
320
|
end
|
316
321
|
end
|
317
322
|
end
|