thor 0.19.1 → 0.19.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/CONTRIBUTING.md +15 -0
- data/README.md +7 -1
- data/lib/thor.rb +31 -23
- data/lib/thor/actions.rb +21 -22
- data/lib/thor/actions/create_file.rb +1 -1
- data/lib/thor/actions/create_link.rb +1 -1
- data/lib/thor/actions/directory.rb +2 -2
- data/lib/thor/actions/empty_directory.rb +8 -8
- data/lib/thor/actions/file_manipulation.rb +23 -12
- data/lib/thor/actions/inject_into_file.rb +10 -14
- data/lib/thor/base.rb +33 -33
- data/lib/thor/command.rb +9 -9
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
- data/lib/thor/core_ext/io_binary_read.rb +7 -5
- data/lib/thor/core_ext/ordered_hash.rb +94 -63
- data/lib/thor/error.rb +3 -3
- data/lib/thor/group.rb +12 -12
- data/lib/thor/invocation.rb +4 -5
- data/lib/thor/parser/argument.rb +4 -7
- data/lib/thor/parser/arguments.rb +16 -16
- data/lib/thor/parser/option.rb +39 -19
- data/lib/thor/parser/options.rb +7 -5
- data/lib/thor/runner.rb +25 -25
- data/lib/thor/shell.rb +1 -1
- data/lib/thor/shell/basic.rb +41 -26
- data/lib/thor/shell/color.rb +1 -1
- data/lib/thor/shell/html.rb +4 -4
- data/lib/thor/util.rb +8 -7
- data/lib/thor/version.rb +1 -1
- data/thor.gemspec +6 -9
- metadata +6 -148
- data/Thorfile +0 -29
- data/spec/actions/create_file_spec.rb +0 -168
- data/spec/actions/create_link_spec.rb +0 -96
- data/spec/actions/directory_spec.rb +0 -169
- data/spec/actions/empty_directory_spec.rb +0 -129
- data/spec/actions/file_manipulation_spec.rb +0 -392
- data/spec/actions/inject_into_file_spec.rb +0 -135
- data/spec/actions_spec.rb +0 -331
- data/spec/base_spec.rb +0 -298
- data/spec/command_spec.rb +0 -79
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -48
- data/spec/core_ext/ordered_hash_spec.rb +0 -115
- data/spec/exit_condition_spec.rb +0 -19
- data/spec/fixtures/application.rb +0 -2
- data/spec/fixtures/app{1}/README +0 -3
- data/spec/fixtures/bundle/execute.rb +0 -6
- data/spec/fixtures/bundle/main.thor +0 -1
- data/spec/fixtures/command.thor +0 -10
- data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
- data/spec/fixtures/doc/COMMENTER +0 -11
- data/spec/fixtures/doc/README +0 -3
- data/spec/fixtures/doc/block_helper.rb +0 -3
- data/spec/fixtures/doc/config.rb +0 -1
- data/spec/fixtures/doc/config.yaml.tt +0 -1
- data/spec/fixtures/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/fixtures/enum.thor +0 -10
- data/spec/fixtures/group.thor +0 -128
- data/spec/fixtures/invoke.thor +0 -131
- data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
- data/spec/fixtures/preserve/script.sh +0 -3
- data/spec/fixtures/script.thor +0 -220
- data/spec/fixtures/subcommand.thor +0 -17
- data/spec/group_spec.rb +0 -222
- data/spec/helper.rb +0 -80
- data/spec/invocation_spec.rb +0 -120
- data/spec/line_editor/basic_spec.rb +0 -28
- data/spec/line_editor/readline_spec.rb +0 -69
- data/spec/line_editor_spec.rb +0 -43
- data/spec/parser/argument_spec.rb +0 -53
- data/spec/parser/arguments_spec.rb +0 -66
- data/spec/parser/option_spec.rb +0 -210
- data/spec/parser/options_spec.rb +0 -414
- data/spec/quality_spec.rb +0 -75
- data/spec/rake_compat_spec.rb +0 -72
- data/spec/register_spec.rb +0 -227
- data/spec/runner_spec.rb +0 -246
- data/spec/sandbox/application.rb +0 -2
- data/spec/sandbox/app{1}/README +0 -3
- data/spec/sandbox/bundle/execute.rb +0 -6
- data/spec/sandbox/bundle/main.thor +0 -1
- data/spec/sandbox/command.thor +0 -10
- data/spec/sandbox/doc/%file_name%.rb.tt +0 -1
- data/spec/sandbox/doc/COMMENTER +0 -11
- data/spec/sandbox/doc/README +0 -3
- data/spec/sandbox/doc/block_helper.rb +0 -3
- data/spec/sandbox/doc/config.rb +0 -1
- data/spec/sandbox/doc/config.yaml.tt +0 -1
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +0 -1
- data/spec/sandbox/enum.thor +0 -10
- data/spec/sandbox/group.thor +0 -128
- data/spec/sandbox/invoke.thor +0 -131
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +0 -3
- data/spec/sandbox/script.thor +0 -220
- data/spec/sandbox/subcommand.thor +0 -17
- data/spec/shell/basic_spec.rb +0 -337
- data/spec/shell/color_spec.rb +0 -119
- data/spec/shell/html_spec.rb +0 -31
- data/spec/shell_spec.rb +0 -47
- data/spec/subcommand_spec.rb +0 -48
- data/spec/thor_spec.rb +0 -505
- data/spec/util_spec.rb +0 -196
data/spec/quality_spec.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
if defined?(Encoding) && Encoding.default_external != "UTF-8"
|
2
|
-
Encoding.default_external = "UTF-8"
|
3
|
-
end
|
4
|
-
|
5
|
-
describe "The library itself" do
|
6
|
-
def check_for_spec_defs_with_single_quotes(filename)
|
7
|
-
failing_lines = []
|
8
|
-
|
9
|
-
File.readlines(filename).each_with_index do |line,number|
|
10
|
-
failing_lines << number + 1 if line =~ /^ *(describe|it|context) {1}'{1}/
|
11
|
-
end
|
12
|
-
|
13
|
-
unless failing_lines.empty?
|
14
|
-
"#{filename} uses inconsistent single quotes on lines #{failing_lines.join(', ')}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def check_for_tab_characters(filename)
|
19
|
-
failing_lines = []
|
20
|
-
File.readlines(filename).each_with_index do |line,number|
|
21
|
-
failing_lines << number + 1 if line =~ /\t/
|
22
|
-
end
|
23
|
-
|
24
|
-
unless failing_lines.empty?
|
25
|
-
"#{filename} has tab characters on lines #{failing_lines.join(', ')}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def check_for_extra_spaces(filename)
|
30
|
-
failing_lines = []
|
31
|
-
File.readlines(filename).each_with_index do |line,number|
|
32
|
-
next if line =~ /^\s+#.*\s+\n$/
|
33
|
-
failing_lines << number + 1 if line =~ /\s+\n$/
|
34
|
-
end
|
35
|
-
|
36
|
-
unless failing_lines.empty?
|
37
|
-
"#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
RSpec::Matchers.define :be_well_formed do
|
42
|
-
failure_message_for_should do |actual|
|
43
|
-
actual.join("\n")
|
44
|
-
end
|
45
|
-
|
46
|
-
match do |actual|
|
47
|
-
actual.empty?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it "has no malformed whitespace" do
|
52
|
-
exempt = /\.gitmodules|\.marshal|fixtures|vendor|spec|ssl_certs|LICENSE/
|
53
|
-
error_messages = []
|
54
|
-
Dir.chdir(File.expand_path("../..", __FILE__)) do
|
55
|
-
`git ls-files`.split("\n").each do |filename|
|
56
|
-
next if filename =~ exempt
|
57
|
-
error_messages << check_for_tab_characters(filename)
|
58
|
-
error_messages << check_for_extra_spaces(filename)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
expect(error_messages.compact).to be_well_formed
|
62
|
-
end
|
63
|
-
|
64
|
-
it "uses double-quotes consistently in specs" do
|
65
|
-
included = /spec/
|
66
|
-
error_messages = []
|
67
|
-
Dir.chdir(File.expand_path("../", __FILE__)) do
|
68
|
-
`git ls-files`.split("\n").each do |filename|
|
69
|
-
next unless filename =~ included
|
70
|
-
error_messages << check_for_spec_defs_with_single_quotes(filename)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
expect(error_messages.compact).to be_well_formed
|
74
|
-
end
|
75
|
-
end
|
data/spec/rake_compat_spec.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
require "thor/rake_compat"
|
3
|
-
require "rake/tasklib"
|
4
|
-
|
5
|
-
$main = self
|
6
|
-
|
7
|
-
class RakeTask < Rake::TaskLib
|
8
|
-
def initialize
|
9
|
-
define
|
10
|
-
end
|
11
|
-
|
12
|
-
def define
|
13
|
-
$main.instance_eval do
|
14
|
-
desc "Say it's cool"
|
15
|
-
task :cool do
|
16
|
-
puts "COOL"
|
17
|
-
end
|
18
|
-
|
19
|
-
namespace :hiper_mega do
|
20
|
-
task :super do
|
21
|
-
puts "HIPER MEGA SUPER"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class ThorTask < Thor
|
29
|
-
include Thor::RakeCompat
|
30
|
-
RakeTask.new
|
31
|
-
end
|
32
|
-
|
33
|
-
describe Thor::RakeCompat do
|
34
|
-
it "sets the rakefile application" do
|
35
|
-
expect(%w[rake_compat_spec.rb Thorfile]).to include(Rake.application.rakefile)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "adds rake tasks to thor classes too" do
|
39
|
-
task = ThorTask.tasks["cool"]
|
40
|
-
expect(task).to be
|
41
|
-
end
|
42
|
-
|
43
|
-
it "uses rake tasks descriptions on thor" do
|
44
|
-
expect(ThorTask.tasks["cool"].description).to eq("Say it's cool")
|
45
|
-
end
|
46
|
-
|
47
|
-
it "gets usage from rake tasks name" do
|
48
|
-
expect(ThorTask.tasks["cool"].usage).to eq("cool")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "uses non namespaced name as description if non is available" do
|
52
|
-
expect(ThorTask::HiperMega.tasks["super"].description).to eq("super")
|
53
|
-
end
|
54
|
-
|
55
|
-
it "converts namespaces to classes" do
|
56
|
-
expect(ThorTask.const_get(:HiperMega)).to eq(ThorTask::HiperMega)
|
57
|
-
end
|
58
|
-
|
59
|
-
it "does not add tasks from higher namespaces in lowers namespaces" do
|
60
|
-
expect(ThorTask.tasks["super"]).not_to be
|
61
|
-
end
|
62
|
-
|
63
|
-
it "invoking the thor task invokes the rake task" do
|
64
|
-
expect(capture(:stdout) do
|
65
|
-
ThorTask.start %w[cool]
|
66
|
-
end).to eq("COOL\n")
|
67
|
-
|
68
|
-
expect(capture(:stdout) do
|
69
|
-
ThorTask::HiperMega.start %w[super]
|
70
|
-
end).to eq("HIPER MEGA SUPER\n")
|
71
|
-
end
|
72
|
-
end
|
data/spec/register_spec.rb
DELETED
@@ -1,227 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
|
3
|
-
class BoringVendorProvidedCLI < Thor
|
4
|
-
desc "boring", "do boring stuff"
|
5
|
-
def boring
|
6
|
-
puts "bored. <yawn>"
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class ExcitingPluginCLI < Thor
|
11
|
-
desc "hooray", "say hooray!"
|
12
|
-
def hooray
|
13
|
-
puts "hooray!"
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "fireworks", "exciting fireworks!"
|
17
|
-
def fireworks
|
18
|
-
puts "kaboom!"
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class SuperSecretPlugin < Thor
|
23
|
-
default_command :squirrel
|
24
|
-
|
25
|
-
desc "squirrel", "All of secret squirrel's secrets"
|
26
|
-
def squirrel
|
27
|
-
puts "I love nuts"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class GroupPlugin < Thor::Group
|
32
|
-
desc "part one"
|
33
|
-
def part_one
|
34
|
-
puts "part one"
|
35
|
-
end
|
36
|
-
|
37
|
-
desc "part two"
|
38
|
-
def part_two
|
39
|
-
puts "part two"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class ClassOptionGroupPlugin < Thor::Group
|
44
|
-
class_option :who,
|
45
|
-
:type => :string,
|
46
|
-
:aliases => "-w",
|
47
|
-
:default => "zebra"
|
48
|
-
end
|
49
|
-
|
50
|
-
class CompatibleWith19Plugin < ClassOptionGroupPlugin
|
51
|
-
desc "animal"
|
52
|
-
def animal
|
53
|
-
p options[:who]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class PluginWithDefault < Thor
|
58
|
-
desc "say MSG", "print MSG"
|
59
|
-
def say(msg)
|
60
|
-
puts msg
|
61
|
-
end
|
62
|
-
|
63
|
-
default_command :say
|
64
|
-
end
|
65
|
-
|
66
|
-
class PluginWithDefaultMultipleArguments < Thor
|
67
|
-
desc "say MSG [MSG]", "print multiple messages"
|
68
|
-
def say(*args)
|
69
|
-
puts args
|
70
|
-
end
|
71
|
-
|
72
|
-
default_command :say
|
73
|
-
end
|
74
|
-
|
75
|
-
class PluginWithDefaultcommandAndDeclaredArgument < Thor
|
76
|
-
desc "say MSG [MSG]", "print multiple messages"
|
77
|
-
argument :msg
|
78
|
-
def say
|
79
|
-
puts msg
|
80
|
-
end
|
81
|
-
|
82
|
-
default_command :say
|
83
|
-
end
|
84
|
-
|
85
|
-
class SubcommandWithDefault < Thor
|
86
|
-
default_command :default
|
87
|
-
|
88
|
-
desc "default", "default subcommand"
|
89
|
-
def default
|
90
|
-
puts "default"
|
91
|
-
end
|
92
|
-
|
93
|
-
desc "with_args", "subcommand with arguments"
|
94
|
-
def with_args(*args)
|
95
|
-
puts "received arguments: " + args.join(",")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
BoringVendorProvidedCLI.register(
|
100
|
-
ExcitingPluginCLI,
|
101
|
-
"exciting",
|
102
|
-
"do exciting things",
|
103
|
-
"Various non-boring actions")
|
104
|
-
|
105
|
-
BoringVendorProvidedCLI.register(
|
106
|
-
SuperSecretPlugin,
|
107
|
-
"secret",
|
108
|
-
"secret stuff",
|
109
|
-
"Nothing to see here. Move along.",
|
110
|
-
:hide => true)
|
111
|
-
|
112
|
-
BoringVendorProvidedCLI.register(
|
113
|
-
GroupPlugin,
|
114
|
-
"groupwork",
|
115
|
-
"Do a bunch of things in a row",
|
116
|
-
"purple monkey dishwasher")
|
117
|
-
|
118
|
-
BoringVendorProvidedCLI.register(
|
119
|
-
CompatibleWith19Plugin,
|
120
|
-
"zoo",
|
121
|
-
"zoo [-w animal]",
|
122
|
-
"Shows a provided animal or just zebra")
|
123
|
-
|
124
|
-
BoringVendorProvidedCLI.register(
|
125
|
-
PluginWithDefault,
|
126
|
-
"say",
|
127
|
-
"say message",
|
128
|
-
"subcommands ftw")
|
129
|
-
|
130
|
-
BoringVendorProvidedCLI.register(
|
131
|
-
PluginWithDefaultMultipleArguments,
|
132
|
-
"say_multiple",
|
133
|
-
"say message",
|
134
|
-
"subcommands ftw")
|
135
|
-
|
136
|
-
BoringVendorProvidedCLI.register(
|
137
|
-
PluginWithDefaultcommandAndDeclaredArgument,
|
138
|
-
"say_argument",
|
139
|
-
"say message",
|
140
|
-
"subcommands ftw")
|
141
|
-
|
142
|
-
BoringVendorProvidedCLI.register(SubcommandWithDefault,
|
143
|
-
"subcommand", "subcommand", "Run subcommands")
|
144
|
-
|
145
|
-
describe ".register-ing a Thor subclass" do
|
146
|
-
it "registers the plugin as a subcommand" do
|
147
|
-
fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting fireworks]) }
|
148
|
-
expect(fireworks_output).to eq("kaboom!\n")
|
149
|
-
end
|
150
|
-
|
151
|
-
it "includes the plugin's usage in the help" do
|
152
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
|
153
|
-
expect(help_output).to include("do exciting things")
|
154
|
-
end
|
155
|
-
|
156
|
-
context "with a default command," do
|
157
|
-
it "invokes the default command correctly" do
|
158
|
-
output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say hello]) }
|
159
|
-
expect(output).to include("hello")
|
160
|
-
end
|
161
|
-
|
162
|
-
it "invokes the default command correctly with multiple args" do
|
163
|
-
output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_multiple hello adam]) }
|
164
|
-
expect(output).to include("hello")
|
165
|
-
expect(output).to include("adam")
|
166
|
-
end
|
167
|
-
|
168
|
-
it "invokes the default command correctly with a declared argument" do
|
169
|
-
output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[say_argument hello]) }
|
170
|
-
expect(output).to include("hello")
|
171
|
-
end
|
172
|
-
|
173
|
-
it "displays the subcommand's help message" do
|
174
|
-
output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand help]) }
|
175
|
-
expect(output).to include("default subcommand")
|
176
|
-
expect(output).to include("subcommand with argument")
|
177
|
-
end
|
178
|
-
|
179
|
-
it "invokes commands with their actual args" do
|
180
|
-
output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[subcommand with_args actual_argument]) }
|
181
|
-
expect(output.strip).to eql("received arguments: actual_argument")
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
context "when $thor_runner is false" do
|
186
|
-
it "includes the plugin's subcommand name in subcommand's help" do
|
187
|
-
begin
|
188
|
-
$thor_runner = false
|
189
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting]) }
|
190
|
-
expect(help_output).to include("thor exciting_plugin_c_l_i fireworks")
|
191
|
-
ensure
|
192
|
-
$thor_runner = true
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context "when hidden" do
|
198
|
-
it "omits the hidden plugin's usage from the help" do
|
199
|
-
help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
|
200
|
-
expect(help_output).not_to include("secret stuff")
|
201
|
-
end
|
202
|
-
|
203
|
-
it "registers the plugin as a subcommand" do
|
204
|
-
secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[secret squirrel]) }
|
205
|
-
expect(secret_output).to eq("I love nuts\n")
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe ".register-ing a Thor::Group subclass" do
|
211
|
-
it "registers the group as a single command" do
|
212
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[groupwork]) }
|
213
|
-
expect(group_output).to eq("part one\npart two\n")
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
describe "1.8 and 1.9 syntax compatibility" do
|
218
|
-
it "is compatible with both 1.8 and 1.9 syntax w/o command options" do
|
219
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo]) }
|
220
|
-
expect(group_output).to match(/zebra/)
|
221
|
-
end
|
222
|
-
|
223
|
-
it "is compatible with both 1.8 and 1.9 syntax w/command options" do
|
224
|
-
group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[zoo -w lion]) }
|
225
|
-
expect(group_output).to match(/lion/)
|
226
|
-
end
|
227
|
-
end
|
data/spec/runner_spec.rb
DELETED
@@ -1,246 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
require "thor/runner"
|
3
|
-
|
4
|
-
describe Thor::Runner do
|
5
|
-
def when_no_thorfiles_exist
|
6
|
-
old_dir = Dir.pwd
|
7
|
-
Dir.chdir ".."
|
8
|
-
delete = Thor::Base.subclasses.select { |e| e.namespace == "default" }
|
9
|
-
delete.each { |e| Thor::Base.subclasses.delete e }
|
10
|
-
yield
|
11
|
-
Thor::Base.subclasses.concat delete
|
12
|
-
Dir.chdir old_dir
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#help" do
|
16
|
-
it "shows information about Thor::Runner itself" do
|
17
|
-
expect(capture(:stdout) { Thor::Runner.start(%w[help]) }).to match(/List the available thor commands/)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "shows information about a specific Thor::Runner command" do
|
21
|
-
content = capture(:stdout) { Thor::Runner.start(%w[help list]) }
|
22
|
-
expect(content).to match(/List the available thor commands/)
|
23
|
-
expect(content).not_to match(/help \[COMMAND\]/)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "shows information about a specific Thor class" do
|
27
|
-
content = capture(:stdout) { Thor::Runner.start(%w[help my_script]) }
|
28
|
-
expect(content).to match(/zoo\s+# zoo around/m)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "shows information about a specific command from a specific Thor class" do
|
32
|
-
content = capture(:stdout) { Thor::Runner.start(%w[help my_script:zoo]) }
|
33
|
-
expect(content).to match(/zoo around/)
|
34
|
-
expect(content).not_to match(/help \[COMMAND\]/)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "shows information about a specific Thor group class" do
|
38
|
-
content = capture(:stdout) { Thor::Runner.start(%w[help my_counter]) }
|
39
|
-
expect(content).to match(/my_counter N/)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "raises error if a class/command cannot be found" do
|
43
|
-
content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) }
|
44
|
-
expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
|
45
|
-
end
|
46
|
-
|
47
|
-
it "raises error if a class/command cannot be found for a setup without thorfiles" do
|
48
|
-
when_no_thorfiles_exist do
|
49
|
-
expect(Thor::Runner).to receive :exit
|
50
|
-
content = capture(:stderr) { Thor::Runner.start(%w[help unknown]) }
|
51
|
-
expect(content.strip).to eq('Could not find command "unknown".')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#start" do
|
57
|
-
it "invokes a command from Thor::Runner" do
|
58
|
-
ARGV.replace %w[list]
|
59
|
-
expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "invokes a command from a specific Thor class" do
|
63
|
-
ARGV.replace %w[my_script:zoo]
|
64
|
-
expect(Thor::Runner.start).to be true
|
65
|
-
end
|
66
|
-
|
67
|
-
it "invokes the default command from a specific Thor class if none is specified" do
|
68
|
-
ARGV.replace %w[my_script]
|
69
|
-
expect(Thor::Runner.start).to eq("default command")
|
70
|
-
end
|
71
|
-
|
72
|
-
it "forwards arguments to the invoked command" do
|
73
|
-
ARGV.replace %w[my_script:animal horse]
|
74
|
-
expect(Thor::Runner.start).to eq(%w[horse])
|
75
|
-
end
|
76
|
-
|
77
|
-
it "invokes commands through shortcuts" do
|
78
|
-
ARGV.replace %w[my_script -T horse]
|
79
|
-
expect(Thor::Runner.start).to eq(%w[horse])
|
80
|
-
end
|
81
|
-
|
82
|
-
it "invokes a Thor::Group" do
|
83
|
-
ARGV.replace %w[my_counter 1 2 --third 3]
|
84
|
-
expect(Thor::Runner.start).to eq([1, 2, 3, nil, nil, nil])
|
85
|
-
end
|
86
|
-
|
87
|
-
it "raises an error if class/command can't be found" do
|
88
|
-
ARGV.replace %w[unknown]
|
89
|
-
content = capture(:stderr) { Thor::Runner.start }
|
90
|
-
expect(content.strip).to eq('Could not find command "unknown" in "default" namespace.')
|
91
|
-
end
|
92
|
-
|
93
|
-
it "raises an error if class/command can't be found in a setup without thorfiles" do
|
94
|
-
when_no_thorfiles_exist do
|
95
|
-
ARGV.replace %w[unknown]
|
96
|
-
expect(Thor::Runner).to receive :exit
|
97
|
-
content = capture(:stderr) { Thor::Runner.start }
|
98
|
-
expect(content.strip).to eq('Could not find command "unknown".')
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
it "does not swallow NoMethodErrors that occur inside the called method" do
|
103
|
-
ARGV.replace %w[my_script:call_unexistent_method]
|
104
|
-
expect { Thor::Runner.start }.to raise_error(NoMethodError)
|
105
|
-
end
|
106
|
-
|
107
|
-
it "does not swallow Thor::Group InvocationError" do
|
108
|
-
ARGV.replace %w[whiny_generator]
|
109
|
-
expect { Thor::Runner.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "does not swallow Thor InvocationError" do
|
113
|
-
ARGV.replace %w[my_script:animal]
|
114
|
-
content = capture(:stderr) { Thor::Runner.start }
|
115
|
-
expect(content.strip).to eq(%Q(ERROR: "thor animal" was called with no arguments
|
116
|
-
Usage: "thor my_script:animal TYPE"))
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
describe "commands" do
|
121
|
-
before do
|
122
|
-
@location = "#{File.dirname(__FILE__)}/fixtures/command.thor"
|
123
|
-
@original_yaml = {
|
124
|
-
"random" => {
|
125
|
-
:location => @location,
|
126
|
-
:filename => "4a33b894ffce85d7b412fc1b36f88fe0",
|
127
|
-
:namespaces => %w[amazing]
|
128
|
-
}
|
129
|
-
}
|
130
|
-
|
131
|
-
root_file = File.join(Thor::Util.thor_root, "thor.yml")
|
132
|
-
|
133
|
-
# Stub load and save to avoid thor.yaml from being overwritten
|
134
|
-
allow(YAML).to receive(:load_file).and_return(@original_yaml)
|
135
|
-
allow(File).to receive(:exist?).with(root_file).and_return(true)
|
136
|
-
allow(File).to receive(:open).with(root_file, "w")
|
137
|
-
end
|
138
|
-
|
139
|
-
describe "list" do
|
140
|
-
it "gives a list of the available commands" do
|
141
|
-
ARGV.replace %w[list]
|
142
|
-
content = capture(:stdout) { Thor::Runner.start }
|
143
|
-
expect(content).to match(/amazing:describe NAME\s+# say that someone is amazing/m)
|
144
|
-
end
|
145
|
-
|
146
|
-
it "gives a list of the available Thor::Group classes" do
|
147
|
-
ARGV.replace %w[list]
|
148
|
-
expect(capture(:stdout) { Thor::Runner.start }).to match(/my_counter N/)
|
149
|
-
end
|
150
|
-
|
151
|
-
it "can filter a list of the available commands by --group" do
|
152
|
-
ARGV.replace %w[list --group standard]
|
153
|
-
expect(capture(:stdout) { Thor::Runner.start }).to match(/amazing:describe NAME/)
|
154
|
-
ARGV.replace []
|
155
|
-
expect(capture(:stdout) { Thor::Runner.start }).not_to match(/my_script:animal TYPE/)
|
156
|
-
ARGV.replace %w[list --group script]
|
157
|
-
expect(capture(:stdout) { Thor::Runner.start }).to match(/my_script:animal TYPE/)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "can skip all filters to show all commands using --all" do
|
161
|
-
ARGV.replace %w[list --all]
|
162
|
-
content = capture(:stdout) { Thor::Runner.start }
|
163
|
-
expect(content).to match(/amazing:describe NAME/)
|
164
|
-
expect(content).to match(/my_script:animal TYPE/)
|
165
|
-
end
|
166
|
-
|
167
|
-
it "doesn't list superclass commands in the subclass" do
|
168
|
-
ARGV.replace %w[list]
|
169
|
-
expect(capture(:stdout) { Thor::Runner.start }).not_to match(/amazing:help/)
|
170
|
-
end
|
171
|
-
|
172
|
-
it "presents commands in the default namespace with an empty namespace" do
|
173
|
-
ARGV.replace %w[list]
|
174
|
-
expect(capture(:stdout) { Thor::Runner.start }).to match(/^thor :cow\s+# prints 'moo'/m)
|
175
|
-
end
|
176
|
-
|
177
|
-
it "runs commands with an empty namespace from the default namespace" do
|
178
|
-
ARGV.replace %w[:command_conflict]
|
179
|
-
expect(capture(:stdout) { Thor::Runner.start }).to eq("command\n")
|
180
|
-
end
|
181
|
-
|
182
|
-
it "runs groups even when there is a command with the same name" do
|
183
|
-
ARGV.replace %w[command_conflict]
|
184
|
-
expect(capture(:stdout) { Thor::Runner.start }).to eq("group\n")
|
185
|
-
end
|
186
|
-
|
187
|
-
it "runs commands with no colon in the default namespace" do
|
188
|
-
ARGV.replace %w[cow]
|
189
|
-
expect(capture(:stdout) { Thor::Runner.start }).to eq("moo\n")
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
describe "uninstall" do
|
194
|
-
before do
|
195
|
-
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
196
|
-
expect(FileUtils).to receive(:rm_rf).with(path)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "uninstalls existing thor modules" do
|
200
|
-
silence(:stdout) { Thor::Runner.start(%w[uninstall random]) }
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
describe "installed" do
|
205
|
-
before do
|
206
|
-
expect(Dir).to receive(:[]).and_return([])
|
207
|
-
end
|
208
|
-
|
209
|
-
it "displays the modules installed in a pretty way" do
|
210
|
-
stdout = capture(:stdout) { Thor::Runner.start(%w[installed]) }
|
211
|
-
expect(stdout).to match(/random\s*amazing/)
|
212
|
-
expect(stdout).to match(/amazing:describe NAME\s+# say that someone is amazing/m)
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe "install/update" do
|
217
|
-
before do
|
218
|
-
allow(FileUtils).to receive(:mkdir_p)
|
219
|
-
allow(FileUtils).to receive(:touch)
|
220
|
-
allow(Thor::LineEditor).to receive(:readline).and_return("Y")
|
221
|
-
|
222
|
-
path = File.join(Thor::Util.thor_root, Digest::MD5.hexdigest(@location + "random"))
|
223
|
-
expect(File).to receive(:open).with(path, "w")
|
224
|
-
end
|
225
|
-
|
226
|
-
it "updates existing thor files" do
|
227
|
-
path = File.join(Thor::Util.thor_root, @original_yaml["random"][:filename])
|
228
|
-
if File.directory? path
|
229
|
-
expect(FileUtils).to receive(:rm_rf).with(path)
|
230
|
-
else
|
231
|
-
expect(File).to receive(:delete).with(path)
|
232
|
-
end
|
233
|
-
silence_warnings do
|
234
|
-
silence(:stdout) { Thor::Runner.start(%w[update random]) }
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
it "installs thor files" do
|
239
|
-
ARGV.replace %W[install #{@location}]
|
240
|
-
silence_warnings do
|
241
|
-
silence(:stdout) { Thor::Runner.start }
|
242
|
-
end
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|