millisami-thor 0.14.6

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.
Files changed (82) hide show
  1. data/.autotest +8 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +1 -0
  5. data/CHANGELOG.rdoc +103 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE.md +20 -0
  8. data/README.md +26 -0
  9. data/Thorfile +13 -0
  10. data/bin/rake2thor +86 -0
  11. data/bin/thor +6 -0
  12. data/lib/thor/actions/create_file.rb +105 -0
  13. data/lib/thor/actions/create_link.rb +57 -0
  14. data/lib/thor/actions/directory.rb +93 -0
  15. data/lib/thor/actions/empty_directory.rb +134 -0
  16. data/lib/thor/actions/file_manipulation.rb +270 -0
  17. data/lib/thor/actions/inject_into_file.rb +109 -0
  18. data/lib/thor/actions.rb +314 -0
  19. data/lib/thor/base.rb +598 -0
  20. data/lib/thor/core_ext/file_binary_read.rb +9 -0
  21. data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  22. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  23. data/lib/thor/error.rb +30 -0
  24. data/lib/thor/group.rb +276 -0
  25. data/lib/thor/invocation.rb +168 -0
  26. data/lib/thor/parser/argument.rb +67 -0
  27. data/lib/thor/parser/arguments.rb +165 -0
  28. data/lib/thor/parser/option.rb +120 -0
  29. data/lib/thor/parser/options.rb +181 -0
  30. data/lib/thor/parser.rb +4 -0
  31. data/lib/thor/rake_compat.rb +70 -0
  32. data/lib/thor/runner.rb +309 -0
  33. data/lib/thor/shell/basic.rb +302 -0
  34. data/lib/thor/shell/color.rb +108 -0
  35. data/lib/thor/shell/html.rb +121 -0
  36. data/lib/thor/shell.rb +88 -0
  37. data/lib/thor/task.rb +129 -0
  38. data/lib/thor/util.rb +229 -0
  39. data/lib/thor/version.rb +3 -0
  40. data/lib/thor.rb +336 -0
  41. data/spec/actions/create_file_spec.rb +170 -0
  42. data/spec/actions/directory_spec.rb +136 -0
  43. data/spec/actions/empty_directory_spec.rb +98 -0
  44. data/spec/actions/file_manipulation_spec.rb +317 -0
  45. data/spec/actions/inject_into_file_spec.rb +135 -0
  46. data/spec/actions_spec.rb +322 -0
  47. data/spec/base_spec.rb +274 -0
  48. data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  49. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  50. data/spec/fixtures/application.rb +2 -0
  51. data/spec/fixtures/bundle/execute.rb +6 -0
  52. data/spec/fixtures/bundle/main.thor +1 -0
  53. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  54. data/spec/fixtures/doc/README +3 -0
  55. data/spec/fixtures/doc/block_helper.rb +3 -0
  56. data/spec/fixtures/doc/components/.empty_directory +0 -0
  57. data/spec/fixtures/doc/config.rb +1 -0
  58. data/spec/fixtures/doc/config.yaml.tt +1 -0
  59. data/spec/fixtures/group.thor +114 -0
  60. data/spec/fixtures/invoke.thor +112 -0
  61. data/spec/fixtures/path with spaces +0 -0
  62. data/spec/fixtures/script.thor +184 -0
  63. data/spec/fixtures/task.thor +10 -0
  64. data/spec/group_spec.rb +216 -0
  65. data/spec/invocation_spec.rb +100 -0
  66. data/spec/parser/argument_spec.rb +47 -0
  67. data/spec/parser/arguments_spec.rb +65 -0
  68. data/spec/parser/option_spec.rb +202 -0
  69. data/spec/parser/options_spec.rb +329 -0
  70. data/spec/rake_compat_spec.rb +72 -0
  71. data/spec/register_spec.rb +92 -0
  72. data/spec/runner_spec.rb +210 -0
  73. data/spec/shell/basic_spec.rb +223 -0
  74. data/spec/shell/color_spec.rb +41 -0
  75. data/spec/shell/html_spec.rb +27 -0
  76. data/spec/shell_spec.rb +47 -0
  77. data/spec/spec_helper.rb +54 -0
  78. data/spec/task_spec.rb +74 -0
  79. data/spec/thor_spec.rb +362 -0
  80. data/spec/util_spec.rb +163 -0
  81. data/thor.gemspec +25 -0
  82. metadata +241 -0
@@ -0,0 +1,329 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'thor/parser'
3
+
4
+ describe Thor::Options do
5
+ def create(opts, defaults={})
6
+ opts.each do |key, value|
7
+ opts[key] = Thor::Option.parse(key, value) unless value.is_a?(Thor::Option)
8
+ end
9
+
10
+ @opt = Thor::Options.new(opts, defaults)
11
+ end
12
+
13
+ def parse(*args)
14
+ @opt.parse(args.flatten)
15
+ end
16
+
17
+ def check_unknown!
18
+ @opt.check_unknown!
19
+ end
20
+
21
+ describe "#to_switches" do
22
+ it "turns true values into a flag" do
23
+ Thor::Options.to_switches(:color => true).should == "--color"
24
+ end
25
+
26
+ it "ignores nil" do
27
+ Thor::Options.to_switches(:color => nil).should == ""
28
+ end
29
+
30
+ it "ignores false" do
31
+ Thor::Options.to_switches(:color => false).should == ""
32
+ end
33
+
34
+ it "writes --name value for anything else" do
35
+ Thor::Options.to_switches(:format => "specdoc").should == '--format "specdoc"'
36
+ end
37
+
38
+ it "joins several values" do
39
+ switches = Thor::Options.to_switches(:color => true, :foo => "bar").split(' ').sort
40
+ switches.should == ['"bar"', "--color", "--foo"]
41
+ end
42
+
43
+ it "accepts arrays" do
44
+ Thor::Options.to_switches(:count => [1,2,3]).should == "--count 1 2 3"
45
+ end
46
+
47
+ it "accepts hashes" do
48
+ Thor::Options.to_switches(:count => {:a => :b}).should == "--count a:b"
49
+ end
50
+
51
+ it "accepts underscored options" do
52
+ Thor::Options.to_switches(:under_score_option => "foo bar").should == '--under_score_option "foo bar"'
53
+ end
54
+
55
+ end
56
+
57
+ describe "#parse" do
58
+ it "allows multiple aliases for a given switch" do
59
+ create ["--foo", "--bar", "--baz"] => :string
60
+ parse("--foo", "12")["foo"].should == "12"
61
+ parse("--bar", "12")["foo"].should == "12"
62
+ parse("--baz", "12")["foo"].should == "12"
63
+ end
64
+
65
+ it "allows custom short names" do
66
+ create "-f" => :string
67
+ parse("-f", "12").should == {"f" => "12"}
68
+ end
69
+
70
+ it "allows custom short-name aliases" do
71
+ create ["--bar", "-f"] => :string
72
+ parse("-f", "12").should == {"bar" => "12"}
73
+ end
74
+
75
+ it "accepts conjoined short switches" do
76
+ create ["--foo", "-f"] => true, ["--bar", "-b"] => true, ["--app", "-a"] => true
77
+ opts = parse("-fba")
78
+ opts["foo"].should be_true
79
+ opts["bar"].should be_true
80
+ opts["app"].should be_true
81
+ end
82
+
83
+ it "accepts conjoined short switches with input" do
84
+ create ["--foo", "-f"] => true, ["--bar", "-b"] => true, ["--app", "-a"] => :required
85
+ opts = parse "-fba", "12"
86
+ opts["foo"].should be_true
87
+ opts["bar"].should be_true
88
+ opts["app"].should == "12"
89
+ end
90
+
91
+ it "returns the default value if none is provided" do
92
+ create :foo => "baz", :bar => :required
93
+ parse("--bar", "boom")["foo"].should == "baz"
94
+ end
95
+
96
+ it "returns the default value from defaults hash to required arguments" do
97
+ create Hash[:bar => :required], Hash[:bar => "baz"]
98
+ parse["bar"].should == "baz"
99
+ end
100
+
101
+ it "gives higher priority to defaults given in the hash" do
102
+ create Hash[:bar => true], Hash[:bar => false]
103
+ parse["bar"].should == false
104
+ end
105
+
106
+ it "raises an error for unknown switches" do
107
+ create :foo => "baz", :bar => :required
108
+ parse("--bar", "baz", "--baz", "unknown")
109
+ lambda { check_unknown! }.should raise_error(Thor::UnknownArgumentError, "Unknown switches '--baz'")
110
+ end
111
+
112
+ it "skips leading non-switches" do
113
+ create(:foo => "baz")
114
+
115
+ parse("asdf", "--foo", "bar").should == {"foo" => "bar"}
116
+ end
117
+
118
+ it "correctly recognizes things that look kind of like options, but aren't, as not options" do
119
+ create(:foo => "baz")
120
+ parse("--asdf---asdf", "baz", "--foo", "--asdf---dsf--asdf").should == {"foo" => "--asdf---dsf--asdf"}
121
+ check_unknown!
122
+ end
123
+
124
+ it "excepts underscores in commandline args hash for boolean" do
125
+ create :foo_bar => :boolean
126
+ parse("--foo_bar")["foo_bar"].should == true
127
+ parse("--no_foo_bar")["foo_bar"].should == false
128
+ end
129
+
130
+ it "excepts underscores in commandline args hash for strings" do
131
+ create :foo_bar => :string, :baz_foo => :string
132
+ parse("--foo_bar", "baz")["foo_bar"].should == "baz"
133
+ parse("--baz_foo", "foo bar")["baz_foo"].should == "foo bar"
134
+ end
135
+
136
+ describe "with no input" do
137
+ it "and no switches returns an empty hash" do
138
+ create({})
139
+ parse.should == {}
140
+ end
141
+
142
+ it "and several switches returns an empty hash" do
143
+ create "--foo" => :boolean, "--bar" => :string
144
+ parse.should == {}
145
+ end
146
+
147
+ it "and a required switch raises an error" do
148
+ create "--foo" => :required
149
+ lambda { parse }.should raise_error(Thor::RequiredArgumentMissingError, "No value provided for required options '--foo'")
150
+ end
151
+ end
152
+
153
+ describe "with one required and one optional switch" do
154
+ before :each do
155
+ create "--foo" => :required, "--bar" => :boolean
156
+ end
157
+
158
+ it "raises an error if the required switch has no argument" do
159
+ lambda { parse("--foo") }.should raise_error(Thor::MalformattedArgumentError)
160
+ end
161
+
162
+ it "raises an error if the required switch isn't given" do
163
+ lambda { parse("--bar") }.should raise_error(Thor::RequiredArgumentMissingError)
164
+ end
165
+
166
+ it "raises an error if the required switch is set to nil" do
167
+ lambda { parse("--no-foo") }.should raise_error(Thor::RequiredArgumentMissingError)
168
+ end
169
+
170
+ it "does not raises an error if the required option has a default value" do
171
+ create :foo => Thor::Option.new("foo", nil, true, :string, "baz"), :bar => :boolean
172
+ lambda { parse("--bar") }.should_not raise_error
173
+ end
174
+ end
175
+
176
+ describe "with :string type" do
177
+ before(:each) do
178
+ create ["--foo", "-f"] => :required
179
+ end
180
+
181
+ it "accepts a switch <value> assignment" do
182
+ parse("--foo", "12")["foo"].should == "12"
183
+ end
184
+
185
+ it "accepts a switch=<value> assignment" do
186
+ parse("-f=12")["foo"].should == "12"
187
+ parse("--foo=12")["foo"].should == "12"
188
+ parse("--foo=bar=baz")["foo"].should == "bar=baz"
189
+ end
190
+
191
+ it "must accept underscores switch=value assignment" do
192
+ create :foo_bar => :required
193
+ parse("--foo_bar=http://example.com/under_score/")["foo_bar"].should == "http://example.com/under_score/"
194
+ end
195
+
196
+ it "accepts a --no-switch format" do
197
+ create "--foo" => "bar"
198
+ parse("--no-foo")["foo"].should be_nil
199
+ end
200
+
201
+ it "does not consume an argument for --no-switch format" do
202
+ create "--cheese" => :string
203
+ parse('burger', '--no-cheese', 'fries')["cheese"].should be_nil
204
+ end
205
+
206
+ it "accepts a --switch format on non required types" do
207
+ create "--foo" => :string
208
+ parse("--foo")["foo"].should == "foo"
209
+ end
210
+
211
+ it "accepts a --switch format on non required types with default values" do
212
+ create "--baz" => :string, "--foo" => "bar"
213
+ parse("--baz", "bang", "--foo")["foo"].should == "bar"
214
+ end
215
+
216
+ it "overwrites earlier values with later values" do
217
+ parse("--foo=bar", "--foo", "12")["foo"].should == "12"
218
+ parse("--foo", "12", "--foo", "13")["foo"].should == "13"
219
+ end
220
+ end
221
+
222
+ describe "with :boolean type" do
223
+ before(:each) do
224
+ create "--foo" => false
225
+ end
226
+
227
+ it "accepts --opt assignment" do
228
+ parse("--foo")["foo"].should == true
229
+ parse("--foo", "--bar")["foo"].should == true
230
+ end
231
+
232
+ it "uses the default value if no switch is given" do
233
+ parse("")["foo"].should == false
234
+ end
235
+
236
+ it "accepts --opt=value assignment" do
237
+ parse("--foo=true")["foo"].should == true
238
+ parse("--foo=false")["foo"].should == false
239
+ end
240
+
241
+ it "accepts --[no-]opt variant, setting false for value" do
242
+ parse("--no-foo")["foo"].should == false
243
+ end
244
+
245
+ it "accepts --[skip-]opt variant, setting false for value" do
246
+ parse("--skip-foo")["foo"].should == false
247
+ end
248
+
249
+ it "will prefer 'no-opt' variant over inverting 'opt' if explicitly set" do
250
+ create "--no-foo" => true
251
+ parse("--no-foo")["no-foo"].should == true
252
+ end
253
+
254
+ it "will prefer 'skip-opt' variant over inverting 'opt' if explicitly set" do
255
+ create "--skip-foo" => true
256
+ parse("--skip-foo")["skip-foo"].should == true
257
+ end
258
+
259
+ it "accepts inputs in the human name format" do
260
+ create :foo_bar => :boolean
261
+ parse("--foo-bar")["foo_bar"].should == true
262
+ parse("--no-foo-bar")["foo_bar"].should == false
263
+ parse("--skip-foo-bar")["foo_bar"].should == false
264
+ end
265
+
266
+ it "doesn't eat the next part of the param" do
267
+ create :foo => :boolean
268
+ parse("--foo", "bar").should == {"foo" => true}
269
+ @opt.remaining.should == ["bar"]
270
+ end
271
+ end
272
+
273
+ describe "with :hash type" do
274
+ before(:each) do
275
+ create "--attributes" => :hash
276
+ end
277
+
278
+ it "accepts a switch=<value> assignment" do
279
+ parse("--attributes=name:string", "age:integer")["attributes"].should == {"name" => "string", "age" => "integer"}
280
+ end
281
+
282
+ it "accepts a switch <value> assignment" do
283
+ parse("--attributes", "name:string", "age:integer")["attributes"].should == {"name" => "string", "age" => "integer"}
284
+ end
285
+
286
+ it "must not mix values with other switches" do
287
+ parse("--attributes", "name:string", "age:integer", "--baz", "cool")["attributes"].should == {"name" => "string", "age" => "integer"}
288
+ end
289
+ end
290
+
291
+ describe "with :array type" do
292
+ before(:each) do
293
+ create "--attributes" => :array
294
+ end
295
+
296
+ it "accepts a switch=<value> assignment" do
297
+ parse("--attributes=a", "b", "c")["attributes"].should == ["a", "b", "c"]
298
+ end
299
+
300
+ it "accepts a switch <value> assignment" do
301
+ parse("--attributes", "a", "b", "c")["attributes"].should == ["a", "b", "c"]
302
+ end
303
+
304
+ it "must not mix values with other switches" do
305
+ parse("--attributes", "a", "b", "c", "--baz", "cool")["attributes"].should == ["a", "b", "c"]
306
+ end
307
+ end
308
+
309
+ describe "with :numeric type" do
310
+ before(:each) do
311
+ create "n" => :numeric, "m" => 5
312
+ end
313
+
314
+ it "accepts a -nXY assignment" do
315
+ parse("-n12")["n"].should == 12
316
+ end
317
+
318
+ it "converts values to numeric types" do
319
+ parse("-n", "3", "-m", ".5").should == {"n" => 3, "m" => 0.5}
320
+ end
321
+
322
+ it "raises error when value isn't numeric" do
323
+ lambda { parse("-n", "foo") }.should raise_error(Thor::MalformattedArgumentError,
324
+ "Expected numeric value for '-n'; got \"foo\"")
325
+ end
326
+ end
327
+
328
+ end
329
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_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
+ ["rake_compat_spec.rb", "Thorfile"].should include(Rake.application.rakefile)
36
+ end
37
+
38
+ it "adds rake tasks to thor classes too" do
39
+ task = ThorTask.tasks["cool"]
40
+ task.should be
41
+ end
42
+
43
+ it "uses rake tasks descriptions on thor" do
44
+ ThorTask.tasks["cool"].description.should == "Say it's cool"
45
+ end
46
+
47
+ it "gets usage from rake tasks name" do
48
+ ThorTask.tasks["cool"].usage.should == "cool"
49
+ end
50
+
51
+ it "uses non namespaced name as description if non is available" do
52
+ ThorTask::HiperMega.tasks["super"].description.should == "super"
53
+ end
54
+
55
+ it "converts namespaces to classes" do
56
+ ThorTask.const_get(:HiperMega).should == ThorTask::HiperMega
57
+ end
58
+
59
+ it "does not add tasks from higher namespaces in lowers namespaces" do
60
+ ThorTask.tasks["super"].should_not be
61
+ end
62
+
63
+ it "invoking the thor task invokes the rake task" do
64
+ capture(:stdout) do
65
+ ThorTask.start ["cool"]
66
+ end.should == "COOL\n"
67
+
68
+ capture(:stdout) do
69
+ ThorTask::HiperMega.start ["super"]
70
+ end.should == "HIPER MEGA SUPER\n"
71
+ end
72
+ end
@@ -0,0 +1,92 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_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_task :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
+
44
+ BoringVendorProvidedCLI.register(
45
+ ExcitingPluginCLI,
46
+ "exciting",
47
+ "do exciting things",
48
+ "Various non-boring actions")
49
+
50
+ BoringVendorProvidedCLI.register(
51
+ SuperSecretPlugin,
52
+ "secret",
53
+ "secret stuff",
54
+ "Nothing to see here. Move along.",
55
+ :hide => true)
56
+
57
+ BoringVendorProvidedCLI.register(
58
+ GroupPlugin,
59
+ 'groupwork',
60
+ "Do a bunch of things in a row",
61
+ "purple monkey dishwasher")
62
+
63
+ describe ".register-ing a Thor subclass" do
64
+ it "registers the plugin as a subcommand" do
65
+ fireworks_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[exciting fireworks]) }
66
+ fireworks_output.should == "kaboom!\n"
67
+ end
68
+
69
+ it "includes the plugin's usage in the help" do
70
+ help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
71
+ help_output.should include('do exciting things')
72
+ end
73
+
74
+ context "when hidden" do
75
+ it "omits the hidden plugin's usage from the help" do
76
+ help_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[help]) }
77
+ help_output.should_not include('secret stuff')
78
+ end
79
+
80
+ it "registers the plugin as a subcommand" do
81
+ secret_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[secret squirrel]) }
82
+ secret_output.should == "I love nuts\n"
83
+ end
84
+ end
85
+ end
86
+
87
+ describe ".register-ing a Thor::Group subclass" do
88
+ it "registers the group as a single command" do
89
+ group_output = capture(:stdout) { BoringVendorProvidedCLI.start(%w[groupwork]) }
90
+ group_output.should == "part one\npart two\n"
91
+ end
92
+ end