josevalim-thor 0.10.9 → 0.10.10
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/thor.rb +1 -1
- data/lib/thor/base.rb +36 -0
- data/lib/thor/group.rb +1 -67
- data/lib/thor/task.rb +5 -41
- metadata +1 -1
data/lib/thor.rb
CHANGED
@@ -198,7 +198,7 @@ class Thor
|
|
198
198
|
end
|
199
199
|
|
200
200
|
def create_task(meth) #:nodoc:
|
201
|
-
tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options
|
201
|
+
tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options)
|
202
202
|
@usage, @desc, @method_options = nil
|
203
203
|
end
|
204
204
|
|
data/lib/thor/base.rb
CHANGED
@@ -160,6 +160,42 @@ class Thor
|
|
160
160
|
build_option(name, options, class_options)
|
161
161
|
end
|
162
162
|
|
163
|
+
# Removes a previous defined argument. If :undefine is given, undefine
|
164
|
+
# accessors as well.
|
165
|
+
#
|
166
|
+
# ==== Paremeters
|
167
|
+
# names<Array>:: Arguments to be removed
|
168
|
+
#
|
169
|
+
# ==== Examples
|
170
|
+
#
|
171
|
+
# remove_argument :foo
|
172
|
+
# remove_argument :foo, :bar, :baz, :undefine => true
|
173
|
+
#
|
174
|
+
def remove_argument(*names)
|
175
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
176
|
+
|
177
|
+
names.each do |name|
|
178
|
+
class_options.delete(name)
|
179
|
+
undef_method name, "#{name}=" if options[:undefine]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Removes a previous defined class option.
|
184
|
+
#
|
185
|
+
# ==== Paremeters
|
186
|
+
# names<Array>:: Class options to be removed
|
187
|
+
#
|
188
|
+
# ==== Examples
|
189
|
+
#
|
190
|
+
# remove_class_option :foo
|
191
|
+
# remove_class_option :foo, :bar, :baz
|
192
|
+
#
|
193
|
+
def remove_class_option(*names)
|
194
|
+
names.each do |name|
|
195
|
+
class_options.delete(name)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
163
199
|
# Defines the group. This is used when thor list is invoked so you can specify
|
164
200
|
# that only tasks from a pre-defined group will be shown. Defaults to standard.
|
165
201
|
#
|
data/lib/thor/group.rb
CHANGED
@@ -22,71 +22,6 @@ class Thor::Group
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# Sets the condition for some task to be executed in the class level. Why
|
26
|
-
# is this important? Setting the conditions in the class level allows to
|
27
|
-
# an inherited class change the conditions and customize the Thor::Group as
|
28
|
-
# it wishes.
|
29
|
-
#
|
30
|
-
# The conditions given are retrieved from the options hash. Let's suppose
|
31
|
-
# that a task is only executed if --test-framework is rspec. You could do
|
32
|
-
# this:
|
33
|
-
#
|
34
|
-
# class_option :test_framework, :type => :string
|
35
|
-
#
|
36
|
-
# conditions :test_framework => :rspec
|
37
|
-
# def create_rspec_files
|
38
|
-
# # magic
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# Later someone creates a framework on top of rspec and need rspec files to
|
42
|
-
# generated as well. He could then change the conditions:
|
43
|
-
#
|
44
|
-
# conditions :test_framework => [ :rspec, :remarkable ], :for => :create_rspec_files
|
45
|
-
#
|
46
|
-
# He could also use remove_conditions and remove previous set conditions:
|
47
|
-
#
|
48
|
-
# remove_conditions :test_framework, :for => :create_rspec_files
|
49
|
-
#
|
50
|
-
# Conditions only work with the class option to be comparead to is a boolean,
|
51
|
-
# string or numeric (no array or hash comparisions).
|
52
|
-
#
|
53
|
-
# ==== Parameters
|
54
|
-
# conditions<Hash>:: the conditions for the task. The key is the option name
|
55
|
-
# and the value is the condition to be checked. If the
|
56
|
-
# condition is an array, it checkes if the current value
|
57
|
-
# is included in the array. If a regexp, checks if the
|
58
|
-
# value matches, all other values are simply compared (==).
|
59
|
-
#
|
60
|
-
def conditions(conditions=nil)
|
61
|
-
subject = if conditions && conditions[:for]
|
62
|
-
find_and_refresh_task(conditions.delete(:for)).conditions
|
63
|
-
else
|
64
|
-
@conditions ||= {}
|
65
|
-
end
|
66
|
-
|
67
|
-
subject.merge!(conditions) if conditions
|
68
|
-
subject
|
69
|
-
end
|
70
|
-
|
71
|
-
# Remove a previous specified condition. Check <tt>conditions</tt> above for
|
72
|
-
# a complete example.
|
73
|
-
#
|
74
|
-
# ==== Parameters
|
75
|
-
# conditions<Array>:: An array of conditions to be removed.
|
76
|
-
# for<Hash>:: A hash with :for as key indicating the task to remove the conditions from.
|
77
|
-
#
|
78
|
-
# ==== Examples
|
79
|
-
#
|
80
|
-
# remove_conditions :test_framework, :orm, :for => :create_app_skeleton
|
81
|
-
#
|
82
|
-
def remove_conditions(*conditions)
|
83
|
-
subject = find_and_refresh_task(conditions.pop[:for]).conditions
|
84
|
-
conditions.each do |condition|
|
85
|
-
subject.delete(condition)
|
86
|
-
end
|
87
|
-
subject
|
88
|
-
end
|
89
|
-
|
90
25
|
# Start in Thor::Group works differently. It invokes all tasks inside the
|
91
26
|
# class and does not have to parse task options.
|
92
27
|
#
|
@@ -140,8 +75,7 @@ class Thor::Group
|
|
140
75
|
end
|
141
76
|
|
142
77
|
def create_task(meth) #:nodoc:
|
143
|
-
tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil
|
144
|
-
@conditions = nil
|
78
|
+
tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil)
|
145
79
|
end
|
146
80
|
end
|
147
81
|
|
data/lib/thor/task.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Thor
|
2
|
-
class Task < Struct.new(:name, :description, :usage, :options
|
2
|
+
class Task < Struct.new(:name, :description, :usage, :options)
|
3
3
|
|
4
4
|
# Creates a dynamic task. Dynamic tasks are created on demand to allow method
|
5
5
|
# missing calls (since a method missing does not have a task object for it).
|
@@ -8,16 +8,15 @@ class Thor
|
|
8
8
|
new(name, "A dynamically-generated task", name.to_s)
|
9
9
|
end
|
10
10
|
|
11
|
-
def initialize(name, description, usage, options=nil
|
12
|
-
super(name.to_s, description, usage, options || {}
|
11
|
+
def initialize(name, description, usage, options=nil)
|
12
|
+
super(name.to_s, description, usage, options || {})
|
13
13
|
end
|
14
14
|
|
15
15
|
# Dup the options hash on clone.
|
16
16
|
#
|
17
17
|
def initialize_copy(other)
|
18
18
|
super(other)
|
19
|
-
self.options
|
20
|
-
self.conditions = other.conditions.dup if other.conditions
|
19
|
+
self.options = other.options.dup if other.options
|
21
20
|
end
|
22
21
|
|
23
22
|
# By default, a task invokes a method in the thor class. You can change this
|
@@ -25,7 +24,7 @@ class Thor
|
|
25
24
|
#
|
26
25
|
def run(instance, args=[])
|
27
26
|
raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance)
|
28
|
-
instance.send(name, *args)
|
27
|
+
instance.send(name, *args)
|
29
28
|
rescue ArgumentError => e
|
30
29
|
backtrace = sans_backtrace(e.backtrace, caller)
|
31
30
|
|
@@ -91,28 +90,6 @@ class Thor
|
|
91
90
|
!(collection).include?(name.to_s) && !(collection).include?(name.to_sym) # For Ruby 1.9
|
92
91
|
end
|
93
92
|
|
94
|
-
# Check if the task conditions are met before invoking.
|
95
|
-
#
|
96
|
-
def valid_conditions?(instance)
|
97
|
-
return true if conditions.empty?
|
98
|
-
|
99
|
-
conditions.each do |key, expected|
|
100
|
-
actual = stringify!(instance.options[key])
|
101
|
-
expected = stringify!(expected)
|
102
|
-
|
103
|
-
return false if case expected
|
104
|
-
when Regexp
|
105
|
-
actual !~ expected
|
106
|
-
when Array
|
107
|
-
!expected.include?(actual)
|
108
|
-
else
|
109
|
-
actual != expected
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
true
|
114
|
-
end
|
115
|
-
|
116
93
|
# Clean everything that comes from the Thor gempath and remove the caller.
|
117
94
|
#
|
118
95
|
def sans_backtrace(backtrace, caller)
|
@@ -121,18 +98,5 @@ class Thor
|
|
121
98
|
saned -= caller
|
122
99
|
end
|
123
100
|
|
124
|
-
# Receives an object and convert any symbol to string.
|
125
|
-
#
|
126
|
-
def stringify!(duck)
|
127
|
-
case duck
|
128
|
-
when Array
|
129
|
-
duck.map!{ |i| i.is_a?(Symbol) ? i.to_s : i }
|
130
|
-
when Symbol
|
131
|
-
duck.to_s
|
132
|
-
else
|
133
|
-
duck
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
101
|
end
|
138
102
|
end
|