wijet-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 (75) hide show
  1. data/CHANGELOG.rdoc +103 -0
  2. data/LICENSE +20 -0
  3. data/README.md +307 -0
  4. data/Thorfile +24 -0
  5. data/bin/rake2thor +86 -0
  6. data/bin/thor +6 -0
  7. data/lib/thor.rb +334 -0
  8. data/lib/thor/actions.rb +314 -0
  9. data/lib/thor/actions/create_file.rb +105 -0
  10. data/lib/thor/actions/create_link.rb +57 -0
  11. data/lib/thor/actions/directory.rb +93 -0
  12. data/lib/thor/actions/empty_directory.rb +134 -0
  13. data/lib/thor/actions/file_manipulation.rb +270 -0
  14. data/lib/thor/actions/inject_into_file.rb +109 -0
  15. data/lib/thor/base.rb +579 -0
  16. data/lib/thor/core_ext/file_binary_read.rb +9 -0
  17. data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  18. data/lib/thor/core_ext/ordered_hash.rb +100 -0
  19. data/lib/thor/error.rb +30 -0
  20. data/lib/thor/group.rb +273 -0
  21. data/lib/thor/invocation.rb +168 -0
  22. data/lib/thor/parser.rb +4 -0
  23. data/lib/thor/parser/argument.rb +67 -0
  24. data/lib/thor/parser/arguments.rb +161 -0
  25. data/lib/thor/parser/option.rb +120 -0
  26. data/lib/thor/parser/options.rb +173 -0
  27. data/lib/thor/rake_compat.rb +66 -0
  28. data/lib/thor/runner.rb +309 -0
  29. data/lib/thor/shell.rb +88 -0
  30. data/lib/thor/shell/basic.rb +290 -0
  31. data/lib/thor/shell/color.rb +108 -0
  32. data/lib/thor/shell/html.rb +121 -0
  33. data/lib/thor/task.rb +114 -0
  34. data/lib/thor/util.rb +229 -0
  35. data/lib/thor/version.rb +3 -0
  36. data/spec/actions/create_file_spec.rb +170 -0
  37. data/spec/actions/directory_spec.rb +136 -0
  38. data/spec/actions/empty_directory_spec.rb +98 -0
  39. data/spec/actions/file_manipulation_spec.rb +310 -0
  40. data/spec/actions/inject_into_file_spec.rb +135 -0
  41. data/spec/actions_spec.rb +322 -0
  42. data/spec/base_spec.rb +269 -0
  43. data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
  44. data/spec/core_ext/ordered_hash_spec.rb +115 -0
  45. data/spec/fixtures/application.rb +2 -0
  46. data/spec/fixtures/bundle/execute.rb +6 -0
  47. data/spec/fixtures/bundle/main.thor +1 -0
  48. data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
  49. data/spec/fixtures/doc/README +3 -0
  50. data/spec/fixtures/doc/block_helper.rb +3 -0
  51. data/spec/fixtures/doc/components/.empty_directory +0 -0
  52. data/spec/fixtures/doc/config.rb +1 -0
  53. data/spec/fixtures/group.thor +114 -0
  54. data/spec/fixtures/invoke.thor +112 -0
  55. data/spec/fixtures/path with spaces b/data/spec/fixtures/path with → spaces +0 -0
  56. data/spec/fixtures/script.thor +184 -0
  57. data/spec/fixtures/task.thor +10 -0
  58. data/spec/group_spec.rb +178 -0
  59. data/spec/invocation_spec.rb +100 -0
  60. data/spec/parser/argument_spec.rb +47 -0
  61. data/spec/parser/arguments_spec.rb +64 -0
  62. data/spec/parser/option_spec.rb +202 -0
  63. data/spec/parser/options_spec.rb +319 -0
  64. data/spec/rake_compat_spec.rb +68 -0
  65. data/spec/register_spec.rb +104 -0
  66. data/spec/runner_spec.rb +210 -0
  67. data/spec/shell/basic_spec.rb +223 -0
  68. data/spec/shell/color_spec.rb +41 -0
  69. data/spec/shell/html_spec.rb +27 -0
  70. data/spec/shell_spec.rb +47 -0
  71. data/spec/spec_helper.rb +54 -0
  72. data/spec/task_spec.rb +74 -0
  73. data/spec/thor_spec.rb +334 -0
  74. data/spec/util_spec.rb +163 -0
  75. metadata +193 -0
@@ -0,0 +1,3 @@
1
+ <% world do -%>
2
+ Hello
3
+ <% end -%>
@@ -0,0 +1 @@
1
+ class <%= @klass %>; end
@@ -0,0 +1,114 @@
1
+ class MyCounter < Thor::Group
2
+ include Thor::Actions
3
+ add_runtime_options!
4
+
5
+ def self.get_from_super
6
+ from_superclass(:get_from_super, 13)
7
+ end
8
+
9
+ source_root File.expand_path(File.dirname(__FILE__))
10
+ source_paths << File.expand_path("broken", File.dirname(__FILE__))
11
+
12
+ argument :first, :type => :numeric
13
+ argument :second, :type => :numeric, :default => 2
14
+
15
+ class_option :third, :type => :numeric, :desc => "The third argument", :default => 3,
16
+ :banner => "THREE", :aliases => "-t"
17
+ class_option :fourth, :type => :numeric, :desc => "The fourth argument"
18
+
19
+ desc <<-FOO
20
+ Description:
21
+ This generator runs three tasks: one, two and three.
22
+ FOO
23
+
24
+ def one
25
+ first
26
+ end
27
+
28
+ def two
29
+ second
30
+ end
31
+
32
+ def three
33
+ options[:third]
34
+ end
35
+
36
+ def self.inherited(base)
37
+ super
38
+ base.source_paths.unshift(File.expand_path(File.join(File.dirname(__FILE__), "doc")))
39
+ end
40
+
41
+ no_tasks do
42
+ def world(&block)
43
+ result = capture(&block)
44
+ concat(result.strip + " world!")
45
+ end
46
+ end
47
+ end
48
+
49
+ class ClearCounter < MyCounter
50
+ remove_argument :first, :second, :undefine => true
51
+ remove_class_option :third
52
+
53
+ def self.source_root
54
+ File.expand_path(File.join(File.dirname(__FILE__), "bundle"))
55
+ end
56
+ end
57
+
58
+ class BrokenCounter < MyCounter
59
+ namespace "app:broken:counter"
60
+ class_option :fail, :type => :boolean, :default => false
61
+
62
+ class << self
63
+ undef_method :source_root
64
+ end
65
+
66
+ def one
67
+ options[:first]
68
+ end
69
+
70
+ def four
71
+ respond_to?(:fail)
72
+ end
73
+
74
+ def five
75
+ options[:fail] ? this_method_does_not_exist : 5
76
+ end
77
+ end
78
+
79
+ class WhinyGenerator < Thor::Group
80
+ include Thor::Actions
81
+
82
+ def self.source_root
83
+ File.expand_path(File.dirname(__FILE__))
84
+ end
85
+
86
+ def wrong_arity(required)
87
+ end
88
+ end
89
+
90
+ class TaskConflict < Thor::Group
91
+ desc "A group with the same name as a default task"
92
+ def group
93
+ puts "group"
94
+ end
95
+ end
96
+
97
+ class ParentGroup < Thor::Group
98
+ private
99
+ def foo
100
+ "foo"
101
+ end
102
+
103
+ def baz(name = 'baz')
104
+ name
105
+ end
106
+ end
107
+
108
+ class ChildGroup < ParentGroup
109
+ def bar
110
+ "bar"
111
+ end
112
+
113
+ public_task :foo, :baz
114
+ end
@@ -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 task"
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, task|
100
+ instance.invoke klass, task, [ "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,184 @@
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
+ group :script
9
+ default_task :example_default_task
10
+
11
+ map "-T" => :animal, ["-f", "--foo"] => :foo
12
+
13
+ desc "zoo", "zoo around"
14
+ def zoo
15
+ true
16
+ end
17
+
18
+ desc "animal TYPE", "horse around"
19
+
20
+ no_tasks do
21
+ def this_is_not_a_task
22
+ end
23
+ end
24
+
25
+ def animal(type)
26
+ [type]
27
+ end
28
+
29
+ desc "hidden TYPE", "this is hidden", :hide => true
30
+ def hidden(type)
31
+ [type]
32
+ end
33
+
34
+ desc "foo BAR", <<END
35
+ do some fooing
36
+ This is more info!
37
+ Everyone likes more info!
38
+ END
39
+ method_option :force, :type => :boolean, :desc => "Force to do some fooing"
40
+ def foo(bar)
41
+ [bar, options]
42
+ end
43
+
44
+ desc "example_default_task", "example!"
45
+ method_options :with => :string
46
+ def example_default_task
47
+ options.empty? ? "default task" : options
48
+ end
49
+
50
+ desc "call_myself_with_wrong_arity", "get the right error"
51
+ def call_myself_with_wrong_arity
52
+ call_myself_with_wrong_arity(4)
53
+ end
54
+
55
+ desc "call_unexistent_method", "Call unexistent method inside a task"
56
+ def call_unexistent_method
57
+ boom!
58
+ end
59
+
60
+ desc "long_description", "a" * 80
61
+ long_desc <<-D
62
+ This is a really really really long description.
63
+ Here you go. So very long.
64
+
65
+ It even has two paragraphs.
66
+ D
67
+ def long_description
68
+ end
69
+
70
+ desc "name-with-dashes", "Ensure normalization of task names"
71
+ def name_with_dashes
72
+ end
73
+
74
+ method_options :all => :boolean
75
+ method_option :lazy, :lazy_default => "yes"
76
+ method_option :lazy_numeric, :type => :numeric, :lazy_default => 42
77
+ method_option :lazy_array, :type => :array, :lazy_default => %w[eat at joes]
78
+ method_option :lazy_hash, :type => :hash, :lazy_default => {'swedish' => 'meatballs'}
79
+ desc "with_optional NAME", "invoke with optional name"
80
+ def with_optional(name=nil)
81
+ [ name, options ]
82
+ end
83
+
84
+ class AnotherScript < Thor
85
+ desc "baz", "do some bazing"
86
+ def baz
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def method_missing(meth, *args)
93
+ if meth == :boom!
94
+ super
95
+ else
96
+ [meth, args]
97
+ end
98
+ end
99
+
100
+ desc "what", "what"
101
+ def what
102
+ end
103
+ end
104
+
105
+ class MyChildScript < MyScript
106
+ remove_task :bar
107
+
108
+ method_options :force => :boolean, :param => :numeric
109
+ def initialize(*args)
110
+ super
111
+ end
112
+
113
+ desc "zoo", "zoo around"
114
+ method_options :param => :required
115
+ def zoo
116
+ options
117
+ end
118
+
119
+ desc "animal TYPE", "horse around"
120
+ def animal(type)
121
+ [type, options]
122
+ end
123
+ method_option :other, :type => :string, :default => "method default", :for => :animal
124
+ desc "animal KIND", "fish around", :for => :animal
125
+
126
+ desc "boom", "explodes everything"
127
+ def boom
128
+ end
129
+
130
+ remove_task :boom, :undefine => true
131
+ end
132
+
133
+ class Barn < Thor
134
+ desc "open [ITEM]", "open the barn door"
135
+ def open(item = nil)
136
+ if item == "shotgun"
137
+ puts "That's going to leave a mark."
138
+ else
139
+ puts "Open sesame!"
140
+ end
141
+ end
142
+
143
+ desc "paint [COLOR]", "paint the barn"
144
+ method_option :coats, :type => :numeric, :default => 2, :desc => 'how many coats of paint'
145
+ def paint(color='red')
146
+ puts "#{options[:coats]} coats of #{color} paint"
147
+ end
148
+
149
+ end
150
+
151
+ module Scripts
152
+ class MyScript < MyChildScript
153
+ argument :accessor, :type => :string
154
+ class_options :force => :boolean
155
+ method_option :new_option, :type => :string, :for => :example_default_task
156
+
157
+ def zoo
158
+ self.accessor
159
+ end
160
+ end
161
+
162
+ class MyDefaults < Thor
163
+ check_unknown_options!
164
+
165
+ namespace :default
166
+ desc "cow", "prints 'moo'"
167
+ def cow
168
+ puts "moo"
169
+ end
170
+
171
+ desc "task_conflict", "only gets called when prepended with a colon"
172
+ def task_conflict
173
+ puts "task"
174
+ end
175
+
176
+ desc "barn", "commands to manage the barn"
177
+ subcommand "barn", Barn
178
+ end
179
+
180
+ class ChildDefault < Thor
181
+ namespace "default:child"
182
+ end
183
+ end
184
+
@@ -0,0 +1,10 @@
1
+ # module: random
2
+
3
+ class Amazing < Thor
4
+ desc "describe NAME", "say that someone is amazing"
5
+ method_options :forcefully => :boolean
6
+ def describe(name, opts)
7
+ ret = "#{name} is amazing"
8
+ puts opts["forcefully"] ? ret.upcase : ret
9
+ end
10
+ end
@@ -0,0 +1,178 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Thor::Group do
4
+ describe "task" do
5
+ it "allows to use private methods from parent class as tasks" do
6
+ ChildGroup.start.should == ["bar", "foo", "baz"]
7
+ ChildGroup.new.baz("bar").should == "bar"
8
+ end
9
+ end
10
+
11
+ describe "#start" do
12
+ it "invokes all the tasks under the Thor group" do
13
+ MyCounter.start(["1", "2", "--third", "3"]).should == [ 1, 2, 3 ]
14
+ end
15
+
16
+ it "uses argument default value" do
17
+ MyCounter.start(["1", "--third", "3"]).should == [ 1, 2, 3 ]
18
+ end
19
+
20
+ it "invokes all the tasks in the Thor group and his parents" do
21
+ BrokenCounter.start(["1", "2", "--third", "3"]).should == [ nil, 2, 3, false, 5 ]
22
+ end
23
+
24
+ it "raises an error if a required argument is added after a non-required" do
25
+ lambda {
26
+ MyCounter.argument(:foo, :type => :string)
27
+ }.should 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 task call" do
31
+ lambda { BrokenCounter.start(["1", "2", "--fail"]) }.should raise_error
32
+ end
33
+
34
+ it "raises an error when a Thor group task expects arguments" do
35
+ lambda { WhinyGenerator.start }.should raise_error(ArgumentError, /Are you sure it has arity equals to 0\?/)
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
+ MyCounter.desc.should == "Description:\n This generator runs three tasks: one, two and three.\n"
47
+ end
48
+
49
+ it "can be inherited" do
50
+ BrokenCounter.desc.should == "Description:\n This generator runs three tasks: one, two and three.\n"
51
+ end
52
+
53
+ it "can be nil" do
54
+ WhinyGenerator.desc.should be_nil
55
+ end
56
+ end
57
+
58
+ describe "#help" do
59
+ before(:each) do
60
+ @content = capture(:stdout){ MyCounter.help(Thor::Base.shell.new) }
61
+ end
62
+
63
+ it "provides usage information" do
64
+ @content.should =~ /my_counter N \[N\]/
65
+ end
66
+
67
+ it "shows description" do
68
+ @content.should =~ /Description:/
69
+ @content.should =~ /This generator runs three tasks: one, two and three./
70
+ end
71
+
72
+ it "shows options information" do
73
+ @content.should =~ /Options/
74
+ @content.should =~ /\[\-\-third=THREE\]/
75
+ end
76
+ end
77
+
78
+ describe "#invoke" do
79
+ before(:each) do
80
+ @content = capture(:stdout){ E.start }
81
+ end
82
+
83
+ it "allows to invoke a class from the class binding" do
84
+ @content.should =~ /1\n2\n3\n4\n5\n/
85
+ end
86
+
87
+ it "shows invocation information to the user" do
88
+ @content.should =~ /invoke Defined/
89
+ end
90
+
91
+ it "uses padding on status generated by the invoked class" do
92
+ @content.should =~ /finished counting/
93
+ end
94
+
95
+ it "allows invocation to be configured with blocks" do
96
+ capture(:stdout) do
97
+ F.start.should == ["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
+ content.should =~ /Defined options:/
104
+ content.should =~ /\[--unused\]/
105
+ content.should =~ /# This option has no use/
106
+ end
107
+ end
108
+
109
+ describe "#invoke_from_option" do
110
+ describe "with default type" do
111
+ before(:each) 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
+ @content.should =~ /1\n2\n3\n4\n5\n/
117
+ end
118
+
119
+ it "does not invoke if the option is nil" do
120
+ capture(:stdout){ G.start(["--skip-invoked"]) }.should_not =~ /invoke/
121
+ end
122
+
123
+ it "prints a message if invocation cannot be found" do
124
+ content = capture(:stdout){ G.start(["--invoked", "unknown"]) }
125
+ content.should =~ /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
+ content.should =~ /invoke e/
131
+ end
132
+
133
+ it "shows invocation information to the user" do
134
+ @content.should =~ /invoke defined/
135
+ end
136
+
137
+ it "uses padding on status generated by the invoked class" do
138
+ @content.should =~ /finished counting/
139
+ end
140
+
141
+ it "shows invoked options on help" do
142
+ content = capture(:stdout){ G.help(Thor::Base.shell.new) }
143
+ content.should =~ /defined options:/
144
+ content.should =~ /\[--unused\]/
145
+ content.should =~ /# This option has no use/
146
+ end
147
+ end
148
+
149
+ describe "with boolean type" do
150
+ before(:each) 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
+ @content.should =~ /1\n2\n3\n4\n5\n/
156
+ end
157
+
158
+ it "does not invoke if the option is false" do
159
+ capture(:stdout){ H.start(["--no-defined"]) }.should_not =~ /invoke/
160
+ end
161
+
162
+ it "shows invocation information to the user" do
163
+ @content.should =~ /invoke defined/
164
+ end
165
+
166
+ it "uses padding on status generated by the invoked class" do
167
+ @content.should =~ /finished counting/
168
+ end
169
+
170
+ it "shows invoked options on help" do
171
+ content = capture(:stdout){ H.help(Thor::Base.shell.new) }
172
+ content.should =~ /defined options:/
173
+ content.should =~ /\[--unused\]/
174
+ content.should =~ /# This option has no use/
175
+ end
176
+ end
177
+ end
178
+ end