thor-exclude_pattern 0.18.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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/CHANGELOG.md +130 -0
  4. data/LICENSE.md +20 -0
  5. data/README.md +34 -0
  6. data/Thorfile +30 -0
  7. data/bin/rake2thor +86 -0
  8. data/bin/thor +6 -0
  9. data/lib/thor.rb +458 -0
  10. data/lib/thor/actions.rb +318 -0
  11. data/lib/thor/actions/create_file.rb +105 -0
  12. data/lib/thor/actions/create_link.rb +60 -0
  13. data/lib/thor/actions/directory.rb +119 -0
  14. data/lib/thor/actions/empty_directory.rb +153 -0
  15. data/lib/thor/actions/file_manipulation.rb +314 -0
  16. data/lib/thor/actions/inject_into_file.rb +109 -0
  17. data/lib/thor/base.rb +649 -0
  18. data/lib/thor/command.rb +136 -0
  19. data/lib/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  20. data/lib/thor/core_ext/io_binary_read.rb +12 -0
  21. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  22. data/lib/thor/error.rb +32 -0
  23. data/lib/thor/exclude_pattern/version.rb +5 -0
  24. data/lib/thor/group.rb +287 -0
  25. data/lib/thor/invocation.rb +172 -0
  26. data/lib/thor/parser.rb +4 -0
  27. data/lib/thor/parser/argument.rb +74 -0
  28. data/lib/thor/parser/arguments.rb +171 -0
  29. data/lib/thor/parser/option.rb +121 -0
  30. data/lib/thor/parser/options.rb +218 -0
  31. data/lib/thor/rake_compat.rb +72 -0
  32. data/lib/thor/runner.rb +322 -0
  33. data/lib/thor/shell.rb +88 -0
  34. data/lib/thor/shell/basic.rb +393 -0
  35. data/lib/thor/shell/color.rb +148 -0
  36. data/lib/thor/shell/html.rb +127 -0
  37. data/lib/thor/util.rb +270 -0
  38. data/lib/thor/version.rb +3 -0
  39. data/spec/actions/create_file_spec.rb +170 -0
  40. data/spec/actions/create_link_spec.rb +95 -0
  41. data/spec/actions/directory_spec.rb +169 -0
  42. data/spec/actions/empty_directory_spec.rb +130 -0
  43. data/spec/actions/file_manipulation_spec.rb +382 -0
  44. data/spec/actions/inject_into_file_spec.rb +135 -0
  45. data/spec/actions_spec.rb +331 -0
  46. data/spec/base_spec.rb +294 -0
  47. data/spec/command_spec.rb +80 -0
  48. data/spec/core_ext/hash_with_indifferent_access_spec.rb +48 -0
  49. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  50. data/spec/exit_condition_spec.rb +19 -0
  51. data/spec/fixtures/application.rb +2 -0
  52. data/spec/fixtures/app{1}/README +3 -0
  53. data/spec/fixtures/bundle/execute.rb +6 -0
  54. data/spec/fixtures/bundle/main.thor +1 -0
  55. data/spec/fixtures/command.thor +10 -0
  56. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  57. data/spec/fixtures/doc/COMMENTER +11 -0
  58. data/spec/fixtures/doc/README +3 -0
  59. data/spec/fixtures/doc/block_helper.rb +3 -0
  60. data/spec/fixtures/doc/config.rb +1 -0
  61. data/spec/fixtures/doc/config.yaml.tt +1 -0
  62. data/spec/fixtures/doc/excluding/%file_name%.rb.tt +1 -0
  63. data/spec/fixtures/enum.thor +10 -0
  64. data/spec/fixtures/group.thor +128 -0
  65. data/spec/fixtures/invoke.thor +112 -0
  66. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  67. data/spec/fixtures/preserve/script.sh +3 -0
  68. data/spec/fixtures/script.thor +199 -0
  69. data/spec/fixtures/subcommand.thor +17 -0
  70. data/spec/group_spec.rb +216 -0
  71. data/spec/helper.rb +67 -0
  72. data/spec/invocation_spec.rb +100 -0
  73. data/spec/parser/argument_spec.rb +53 -0
  74. data/spec/parser/arguments_spec.rb +66 -0
  75. data/spec/parser/option_spec.rb +202 -0
  76. data/spec/parser/options_spec.rb +400 -0
  77. data/spec/rake_compat_spec.rb +72 -0
  78. data/spec/register_spec.rb +197 -0
  79. data/spec/runner_spec.rb +241 -0
  80. data/spec/sandbox/application.rb +2 -0
  81. data/spec/sandbox/app{1}/README +3 -0
  82. data/spec/sandbox/bundle/execute.rb +6 -0
  83. data/spec/sandbox/bundle/main.thor +1 -0
  84. data/spec/sandbox/command.thor +10 -0
  85. data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
  86. data/spec/sandbox/doc/COMMENTER +11 -0
  87. data/spec/sandbox/doc/README +4 -0
  88. data/spec/sandbox/doc/block_helper.rb +3 -0
  89. data/spec/sandbox/doc/config.rb +1 -0
  90. data/spec/sandbox/doc/config.yaml.tt +1 -0
  91. data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
  92. data/spec/sandbox/enum.thor +10 -0
  93. data/spec/sandbox/group.thor +128 -0
  94. data/spec/sandbox/invoke.thor +112 -0
  95. data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
  96. data/spec/sandbox/preserve/script.sh +3 -0
  97. data/spec/sandbox/script.thor +199 -0
  98. data/spec/sandbox/subcommand.thor +17 -0
  99. data/spec/shell/basic_spec.rb +311 -0
  100. data/spec/shell/color_spec.rb +95 -0
  101. data/spec/shell/html_spec.rb +32 -0
  102. data/spec/shell_spec.rb +47 -0
  103. data/spec/subcommand_spec.rb +30 -0
  104. data/spec/thor_spec.rb +469 -0
  105. data/spec/util_spec.rb +196 -0
  106. data/thor.gemspec +24 -0
  107. metadata +232 -0
@@ -0,0 +1,112 @@
1
+ class A < Thor
2
+ include Thor::Actions
3
+
4
+ desc "one", "invoke one"
5
+ def one
6
+ p 1
7
+ invoke :two
8
+ invoke :three
9
+ end
10
+
11
+ desc "two", "invoke two"
12
+ def two
13
+ p 2
14
+ invoke :three
15
+ end
16
+
17
+ desc "three", "invoke three"
18
+ def three
19
+ p 3
20
+ end
21
+
22
+ desc "four", "invoke four"
23
+ def four
24
+ p 4
25
+ invoke "defined:five"
26
+ end
27
+
28
+ desc "five N", "check if number is equal 5"
29
+ def five(number)
30
+ number == 5
31
+ end
32
+
33
+ desc "invoker", "invoke a b command"
34
+ def invoker(*args)
35
+ invoke :b, :one, ["Jose"]
36
+ end
37
+ end
38
+
39
+ class B < Thor
40
+ class_option :last_name, :type => :string
41
+
42
+ desc "one FIRST_NAME", "invoke one"
43
+ def one(first_name)
44
+ "#{options.last_name}, #{first_name}"
45
+ end
46
+
47
+ desc "two", "invoke two"
48
+ def two
49
+ options
50
+ end
51
+
52
+ desc "three", "invoke three"
53
+ def three
54
+ self
55
+ end
56
+ end
57
+
58
+ class C < Thor::Group
59
+ include Thor::Actions
60
+
61
+ def one
62
+ p 1
63
+ end
64
+
65
+ def two
66
+ p 2
67
+ end
68
+
69
+ def three
70
+ p 3
71
+ end
72
+ end
73
+
74
+ class Defined < Thor::Group
75
+ class_option :unused, :type => :boolean, :desc => "This option has no use"
76
+
77
+ def one
78
+ p 1
79
+ invoke "a:two"
80
+ invoke "a:three"
81
+ invoke "a:four"
82
+ invoke "defined:five"
83
+ end
84
+
85
+ def five
86
+ p 5
87
+ end
88
+
89
+ def print_status
90
+ say_status :finished, :counting
91
+ end
92
+ end
93
+
94
+ class E < Thor::Group
95
+ invoke Defined
96
+ end
97
+
98
+ class F < Thor::Group
99
+ invoke "b:one" do |instance, klass, command|
100
+ instance.invoke klass, command, [ "Jose" ], :last_name => "Valim"
101
+ end
102
+ end
103
+
104
+ class G < Thor::Group
105
+ class_option :invoked, :type => :string, :default => "defined"
106
+ invoke_from_option :invoked
107
+ end
108
+
109
+ class H < Thor::Group
110
+ class_option :defined, :type => :boolean, :default => true
111
+ invoke_from_option :defined
112
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ exit 0
@@ -0,0 +1,199 @@
1
+ class MyScript < Thor
2
+ check_unknown_options! :except => :with_optional
3
+
4
+ attr_accessor :some_attribute
5
+ attr_writer :another_attribute
6
+ attr_reader :another_attribute
7
+
8
+ private
9
+ attr_reader :private_attribute
10
+
11
+ public
12
+ group :script
13
+ default_command :example_default_command
14
+
15
+ map "-T" => :animal, ["-f", "--foo"] => :foo
16
+
17
+ map "animal_prison" => "zoo"
18
+
19
+ desc "zoo", "zoo around"
20
+ def zoo
21
+ true
22
+ end
23
+
24
+ desc "animal TYPE", "horse around"
25
+
26
+ no_commands do
27
+ def this_is_not_a_command
28
+ end
29
+ end
30
+
31
+ def animal(type)
32
+ [type]
33
+ end
34
+
35
+ map "hid" => "hidden"
36
+
37
+ desc "hidden TYPE", "this is hidden", :hide => true
38
+ def hidden(type)
39
+ [type]
40
+ end
41
+
42
+ map "fu" => "zoo"
43
+
44
+ desc "foo BAR", <<END
45
+ do some fooing
46
+ This is more info!
47
+ Everyone likes more info!
48
+ END
49
+ method_option :force, :type => :boolean, :desc => "Force to do some fooing"
50
+ def foo(bar)
51
+ [bar, options]
52
+ end
53
+
54
+ desc "example_default_command", "example!"
55
+ method_options :with => :string
56
+ def example_default_command
57
+ options.empty? ? "default command" : options
58
+ end
59
+
60
+ desc "call_myself_with_wrong_arity", "get the right error"
61
+ def call_myself_with_wrong_arity
62
+ call_myself_with_wrong_arity(4)
63
+ end
64
+
65
+ desc "call_unexistent_method", "Call unexistent method inside a command"
66
+ def call_unexistent_method
67
+ boom!
68
+ end
69
+
70
+ desc "long_description", "a" * 80
71
+ long_desc <<-D
72
+ This is a really really really long description.
73
+ Here you go. So very long.
74
+
75
+ It even has two paragraphs.
76
+ D
77
+ def long_description
78
+ end
79
+
80
+ desc "name-with-dashes", "Ensure normalization of command names"
81
+ def name_with_dashes
82
+ end
83
+
84
+ method_options :all => :boolean
85
+ method_option :lazy, :lazy_default => "yes"
86
+ method_option :lazy_numeric, :type => :numeric, :lazy_default => 42
87
+ method_option :lazy_array, :type => :array, :lazy_default => %w[eat at joes]
88
+ method_option :lazy_hash, :type => :hash, :lazy_default => {'swedish' => 'meatballs'}
89
+ desc "with_optional NAME", "invoke with optional name"
90
+ def with_optional(name=nil, *args)
91
+ [ name, options, args ]
92
+ end
93
+
94
+ class AnotherScript < Thor
95
+ desc "baz", "do some bazing"
96
+ def baz
97
+ end
98
+ end
99
+
100
+ desc "send", "send as a command name"
101
+ def send
102
+ true
103
+ end
104
+
105
+ private
106
+
107
+ def method_missing(meth, *args)
108
+ if meth == :boom!
109
+ super
110
+ else
111
+ [meth, args]
112
+ end
113
+ end
114
+
115
+ desc "what", "what"
116
+ def what
117
+ end
118
+ end
119
+
120
+ class MyChildScript < MyScript
121
+ remove_command :bar
122
+
123
+ method_options :force => :boolean, :param => :numeric
124
+ def initialize(*args)
125
+ super
126
+ end
127
+
128
+ desc "zoo", "zoo around"
129
+ method_options :param => :required
130
+ def zoo
131
+ options
132
+ end
133
+
134
+ desc "animal TYPE", "horse around"
135
+ def animal(type)
136
+ [type, options]
137
+ end
138
+ method_option :other, :type => :string, :default => "method default", :for => :animal
139
+ desc "animal KIND", "fish around", :for => :animal
140
+
141
+ desc "boom", "explodes everything"
142
+ def boom
143
+ end
144
+
145
+ remove_command :boom, :undefine => true
146
+ end
147
+
148
+ class Barn < Thor
149
+ desc "open [ITEM]", "open the barn door"
150
+ def open(item = nil)
151
+ if item == "shotgun"
152
+ puts "That's going to leave a mark."
153
+ else
154
+ puts "Open sesame!"
155
+ end
156
+ end
157
+
158
+ desc "paint [COLOR]", "paint the barn"
159
+ method_option :coats, :type => :numeric, :default => 2, :desc => 'how many coats of paint'
160
+ def paint(color='red')
161
+ puts "#{options[:coats]} coats of #{color} paint"
162
+ end
163
+
164
+ end
165
+
166
+ module Scripts
167
+ class MyScript < MyChildScript
168
+ argument :accessor, :type => :string
169
+ class_options :force => :boolean
170
+ method_option :new_option, :type => :string, :for => :example_default_command
171
+
172
+ def zoo
173
+ self.accessor
174
+ end
175
+ end
176
+
177
+ class MyDefaults < Thor
178
+ check_unknown_options!
179
+
180
+ namespace :default
181
+ desc "cow", "prints 'moo'"
182
+ def cow
183
+ puts "moo"
184
+ end
185
+
186
+ desc "command_conflict", "only gets called when prepended with a colon"
187
+ def command_conflict
188
+ puts "command"
189
+ end
190
+
191
+ desc "barn", "commands to manage the barn"
192
+ subcommand "barn", Barn
193
+ end
194
+
195
+ class ChildDefault < Thor
196
+ namespace "default:child"
197
+ end
198
+ end
199
+
@@ -0,0 +1,17 @@
1
+ module TestSubcommands
2
+
3
+ class Subcommand < Thor
4
+ desc "print_opt", "My method"
5
+ def print_opt
6
+ print options["opt"]
7
+ end
8
+ end
9
+
10
+ class Parent < Thor
11
+ class_option "opt"
12
+
13
+ desc "sub", "My subcommand"
14
+ subcommand "sub", Subcommand
15
+ end
16
+
17
+ end
@@ -0,0 +1,216 @@
1
+ require 'helper'
2
+
3
+ describe Thor::Group do
4
+ describe "command" do
5
+ it "allows to use private methods from parent class as commands" do
6
+ expect(ChildGroup.start).to eq(["bar", "foo", "baz"])
7
+ expect(ChildGroup.new.baz("bar")).to eq("bar")
8
+ end
9
+ end
10
+
11
+ describe "#start" do
12
+ it "invokes all the commands under the Thor group" do
13
+ expect(MyCounter.start(["1", "2", "--third", "3"])).to eq([ 1, 2, 3, nil, nil, nil ])
14
+ end
15
+
16
+ it "uses argument default value" do
17
+ expect(MyCounter.start(["1", "--third", "3"])).to eq([ 1, 2, 3, nil, nil, nil ])
18
+ end
19
+
20
+ it "invokes all the commands in the Thor group and his parents" do
21
+ expect(BrokenCounter.start(["1", "2", "--third", "3"])).to eq([ nil, 2, 3, false, 5, nil ])
22
+ end
23
+
24
+ it "raises an error if a required argument is added after a non-required" do
25
+ expect {
26
+ MyCounter.argument(:foo, :type => :string)
27
+ }.to raise_error(ArgumentError, 'You cannot have "foo" as required argument after the non-required argument "second".')
28
+ end
29
+
30
+ it "raises when an exception happens within the command call" do
31
+ expect{ BrokenCounter.start(["1", "2", "--fail"]) }.to raise_error
32
+ end
33
+
34
+ it "raises an error when a Thor group command expects arguments" do
35
+ expect{ WhinyGenerator.start }.to raise_error(ArgumentError, /thor wrong_arity takes 1 argument, but it should not/)
36
+ end
37
+
38
+ it "invokes help message if any of the shortcuts is given" do
39
+ MyCounter.should_receive(:help)
40
+ MyCounter.start(["-h"])
41
+ end
42
+ end
43
+
44
+ describe "#desc" do
45
+ it "sets the description for a given class" do
46
+ expect(MyCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
47
+ end
48
+
49
+ it "can be inherited" do
50
+ expect(BrokenCounter.desc).to eq("Description:\n This generator runs three commands: one, two and three.\n")
51
+ end
52
+
53
+ it "can be nil" do
54
+ expect(WhinyGenerator.desc).to be_nil
55
+ end
56
+ end
57
+
58
+ describe "#help" do
59
+ before do
60
+ @content = capture(:stdout) { MyCounter.help(Thor::Base.shell.new) }
61
+ end
62
+
63
+ it "provides usage information" do
64
+ expect(@content).to match(/my_counter N \[N\]/)
65
+ end
66
+
67
+ it "shows description" do
68
+ expect(@content).to match(/Description:/)
69
+ expect(@content).to match(/This generator runs three commands: one, two and three./)
70
+ end
71
+
72
+ it "shows options information" do
73
+ expect(@content).to match(/Options/)
74
+ expect(@content).to match(/\[\-\-third=THREE\]/)
75
+ end
76
+ end
77
+
78
+ describe "#invoke" do
79
+ before do
80
+ @content = capture(:stdout) { E.start }
81
+ end
82
+
83
+ it "allows to invoke a class from the class binding" do
84
+ expect(@content).to match(/1\n2\n3\n4\n5\n/)
85
+ end
86
+
87
+ it "shows invocation information to the user" do
88
+ expect(@content).to match(/invoke Defined/)
89
+ end
90
+
91
+ it "uses padding on status generated by the invoked class" do
92
+ expect(@content).to match(/finished counting/)
93
+ end
94
+
95
+ it "allows invocation to be configured with blocks" do
96
+ capture(:stdout) do
97
+ expect(F.start).to eq(["Valim, Jose"])
98
+ end
99
+ end
100
+
101
+ it "shows invoked options on help" do
102
+ content = capture(:stdout) { E.help(Thor::Base.shell.new) }
103
+ expect(content).to match(/Defined options:/)
104
+ expect(content).to match(/\[--unused\]/)
105
+ expect(content).to match(/# This option has no use/)
106
+ end
107
+ end
108
+
109
+ describe "#invoke_from_option" do
110
+ describe "with default type" do
111
+ before do
112
+ @content = capture(:stdout) { G.start }
113
+ end
114
+
115
+ it "allows to invoke a class from the class binding by a default option" do
116
+ expect(@content).to match(/1\n2\n3\n4\n5\n/)
117
+ end
118
+
119
+ it "does not invoke if the option is nil" do
120
+ expect(capture(:stdout) { G.start(["--skip-invoked"]) }).not_to match(/invoke/)
121
+ end
122
+
123
+ it "prints a message if invocation cannot be found" do
124
+ content = capture(:stdout) { G.start(["--invoked", "unknown"]) }
125
+ expect(content).to match(/error unknown \[not found\]/)
126
+ end
127
+
128
+ it "allows to invoke a class from the class binding by the given option" do
129
+ content = capture(:stdout) { G.start(["--invoked", "e"]) }
130
+ expect(content).to match(/invoke e/)
131
+ end
132
+
133
+ it "shows invocation information to the user" do
134
+ expect(@content).to match(/invoke defined/)
135
+ end
136
+
137
+ it "uses padding on status generated by the invoked class" do
138
+ expect(@content).to match(/finished counting/)
139
+ end
140
+
141
+ it "shows invoked options on help" do
142
+ content = capture(:stdout) { G.help(Thor::Base.shell.new) }
143
+ expect(content).to match(/defined options:/)
144
+ expect(content).to match(/\[--unused\]/)
145
+ expect(content).to match(/# This option has no use/)
146
+ end
147
+ end
148
+
149
+ describe "with boolean type" do
150
+ before do
151
+ @content = capture(:stdout) { H.start }
152
+ end
153
+
154
+ it "allows to invoke a class from the class binding by a default option" do
155
+ expect(@content).to match(/1\n2\n3\n4\n5\n/)
156
+ end
157
+
158
+ it "does not invoke if the option is false" do
159
+ expect(capture(:stdout) { H.start(["--no-defined"]) }).not_to match(/invoke/)
160
+ end
161
+
162
+ it "shows invocation information to the user" do
163
+ expect(@content).to match(/invoke defined/)
164
+ end
165
+
166
+ it "uses padding on status generated by the invoked class" do
167
+ expect(@content).to match(/finished counting/)
168
+ end
169
+
170
+ it "shows invoked options on help" do
171
+ content = capture(:stdout) { H.help(Thor::Base.shell.new) }
172
+ expect(content).to match(/defined options:/)
173
+ expect(content).to match(/\[--unused\]/)
174
+ expect(content).to match(/# This option has no use/)
175
+ end
176
+ end
177
+ end
178
+
179
+ describe "edge-cases" do
180
+ it "can handle boolean options followed by arguments" do
181
+ klass = Class.new(Thor::Group) do
182
+ desc "say hi to name"
183
+ argument :name, :type => :string
184
+ class_option :loud, :type => :boolean
185
+
186
+ def hi
187
+ name.upcase! if options[:loud]
188
+ "Hi #{name}"
189
+ end
190
+ end
191
+
192
+ expect(klass.start(["jose"])).to eq(["Hi jose"])
193
+ expect(klass.start(["jose", "--loud"])).to eq(["Hi JOSE"])
194
+ expect(klass.start(["--loud", "jose"])).to eq(["Hi JOSE"])
195
+ end
196
+
197
+ it "provides extra args as `args`" do
198
+ klass = Class.new(Thor::Group) do
199
+ desc "say hi to name"
200
+ argument :name, :type => :string
201
+ class_option :loud, :type => :boolean
202
+
203
+ def hi
204
+ name.upcase! if options[:loud]
205
+ out = "Hi #{name}"
206
+ out << ": " << args.join(", ") unless args.empty?
207
+ out
208
+ end
209
+ end
210
+
211
+ expect(klass.start(["jose"])).to eq(["Hi jose"])
212
+ expect(klass.start(["jose", "--loud"])).to eq(["Hi JOSE"])
213
+ expect(klass.start(["--loud", "jose"])).to eq(["Hi JOSE"])
214
+ end
215
+ end
216
+ end