ratch 0.1

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 (47) hide show
  1. data/LICENSE.txt +344 -0
  2. data/README.txt +10 -0
  3. data/bin/lt +4 -0
  4. data/bin/ludo +4 -0
  5. data/bin/ratch +8 -0
  6. data/data/mint/ratch/announce +224 -0
  7. data/data/mint/ratch/install +49 -0
  8. data/data/mint/ratch/notes +183 -0
  9. data/data/mint/ratch/publish +44 -0
  10. data/data/mint/ratch/rdoc +40 -0
  11. data/data/mint/ratch/setup +1616 -0
  12. data/data/mint/ratch/stats +138 -0
  13. data/demo/README +8 -0
  14. data/demo/doc/rdoc/created.rid +1 -0
  15. data/demo/doc/rdoc/files/README.html +112 -0
  16. data/demo/doc/rdoc/files/lib/foo/foo_rb.html +145 -0
  17. data/demo/doc/rdoc/fr_class_index.html +26 -0
  18. data/demo/doc/rdoc/fr_file_index.html +28 -0
  19. data/demo/doc/rdoc/fr_method_index.html +27 -0
  20. data/demo/doc/rdoc/index.html +24 -0
  21. data/demo/doc/rdoc/rdoc-style.css +208 -0
  22. data/demo/lib/foo/foo.rb +7 -0
  23. data/demo/util/conf/rdoc +4 -0
  24. data/demo/util/one +6 -0
  25. data/demo/util/rdoc +39 -0
  26. data/demo/util/tryme +10 -0
  27. data/dev/taskable-simple.rb +42 -0
  28. data/dev/taskable.rb +573 -0
  29. data/lib/ratch/batch.rb +43 -0
  30. data/lib/ratch/cli/lt.rb +56 -0
  31. data/lib/ratch/cli/ludo.rb +14 -0
  32. data/lib/ratch/cli/ratch.rb +47 -0
  33. data/lib/ratch/configutils.rb +100 -0
  34. data/lib/ratch/consoleutils.rb +88 -0
  35. data/lib/ratch/emailutils.rb +88 -0
  36. data/lib/ratch/fileutils.rb +173 -0
  37. data/lib/ratch/options.rb +57 -0
  38. data/lib/ratch/runnable.rb +117 -0
  39. data/lib/ratch/taskable.rb +105 -0
  40. data/lib/ratch/taskutils.rb +44 -0
  41. data/lib/ratch/uploadutils.rb +413 -0
  42. data/meta/manifest.txt +70 -0
  43. data/meta/project.yaml +24 -0
  44. data/misc/original.rb +308 -0
  45. data/task/setup +1616 -0
  46. data/task/stats +138 -0
  47. metadata +114 -0
@@ -0,0 +1,27 @@
1
+
2
+ <?xml version="1.0" encoding="iso-8859-1"?>
3
+ <!DOCTYPE html
4
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
+
7
+ <!--
8
+
9
+ Methods
10
+
11
+ -->
12
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
13
+ <head>
14
+ <title>Methods</title>
15
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
16
+ <link rel="stylesheet" href="rdoc-style.css" type="text/css" />
17
+ <base target="docwin" />
18
+ </head>
19
+ <body>
20
+ <div id="index">
21
+ <h1 class="section-bar">Methods</h1>
22
+ <div id="index-entries">
23
+ <a href="files/lib/foo/foo_rb.html#M000001">hello (lib/foo/foo.rb)</a><br />
24
+ </div>
25
+ </div>
26
+ </body>
27
+ </html>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
5
+
6
+ <!--
7
+
8
+ Foo
9
+
10
+ -->
11
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
+ <head>
13
+ <title>Foo</title>
14
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
15
+ </head>
16
+ <frameset rows="20%, 80%">
17
+ <frameset cols="25%,35%,45%">
18
+ <frame src="fr_file_index.html" title="Files" name="Files" />
19
+ <frame src="fr_class_index.html" name="Classes" />
20
+ <frame src="fr_method_index.html" name="Methods" />
21
+ </frameset>
22
+ <frame src="files/README.html" name="docwin" />
23
+ </frameset>
24
+ </html>
@@ -0,0 +1,208 @@
1
+
2
+ body {
3
+ font-family: Verdana,Arial,Helvetica,sans-serif;
4
+ font-size: 90%;
5
+ margin: 0;
6
+ margin-left: 40px;
7
+ padding: 0;
8
+ background: white;
9
+ }
10
+
11
+ h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
+ h1 { font-size: 150%; }
13
+ h2,h3,h4 { margin-top: 1em; }
14
+
15
+ a { background: #eef; color: #039; text-decoration: none; }
16
+ a:hover { background: #039; color: #eef; }
17
+
18
+ /* Override the base stylesheet's Anchor inside a table cell */
19
+ td > a {
20
+ background: transparent;
21
+ color: #039;
22
+ text-decoration: none;
23
+ }
24
+
25
+ /* and inside a section title */
26
+ .section-title > a {
27
+ background: transparent;
28
+ color: #eee;
29
+ text-decoration: none;
30
+ }
31
+
32
+ /* === Structural elements =================================== */
33
+
34
+ div#index {
35
+ margin: 0;
36
+ margin-left: -40px;
37
+ padding: 0;
38
+ font-size: 90%;
39
+ }
40
+
41
+
42
+ div#index a {
43
+ margin-left: 0.7em;
44
+ }
45
+
46
+ div#index .section-bar {
47
+ margin-left: 0px;
48
+ padding-left: 0.7em;
49
+ background: #ccc;
50
+ font-size: small;
51
+ }
52
+
53
+
54
+ div#classHeader, div#fileHeader {
55
+ width: auto;
56
+ color: white;
57
+ padding: 0.5em 1.5em 0.5em 1.5em;
58
+ margin: 0;
59
+ margin-left: -40px;
60
+ border-bottom: 3px solid #006;
61
+ }
62
+
63
+ div#classHeader a, div#fileHeader a {
64
+ background: inherit;
65
+ color: white;
66
+ }
67
+
68
+ div#classHeader td, div#fileHeader td {
69
+ background: inherit;
70
+ color: white;
71
+ }
72
+
73
+
74
+ div#fileHeader {
75
+ background: #057;
76
+ }
77
+
78
+ div#classHeader {
79
+ background: #048;
80
+ }
81
+
82
+
83
+ .class-name-in-header {
84
+ font-size: 180%;
85
+ font-weight: bold;
86
+ }
87
+
88
+
89
+ div#bodyContent {
90
+ padding: 0 1.5em 0 1.5em;
91
+ }
92
+
93
+ div#description {
94
+ padding: 0.5em 1.5em;
95
+ background: #efefef;
96
+ border: 1px dotted #999;
97
+ }
98
+
99
+ div#description h1,h2,h3,h4,h5,h6 {
100
+ color: #125;;
101
+ background: transparent;
102
+ }
103
+
104
+ div#validator-badges {
105
+ text-align: center;
106
+ }
107
+ div#validator-badges img { border: 0; }
108
+
109
+ div#copyright {
110
+ color: #333;
111
+ background: #efefef;
112
+ font: 0.75em sans-serif;
113
+ margin-top: 5em;
114
+ margin-bottom: 0;
115
+ padding: 0.5em 2em;
116
+ }
117
+
118
+
119
+ /* === Classes =================================== */
120
+
121
+ table.header-table {
122
+ color: white;
123
+ font-size: small;
124
+ }
125
+
126
+ .type-note {
127
+ font-size: small;
128
+ color: #DEDEDE;
129
+ }
130
+
131
+ .xxsection-bar {
132
+ background: #eee;
133
+ color: #333;
134
+ padding: 3px;
135
+ }
136
+
137
+ .section-bar {
138
+ color: #333;
139
+ border-bottom: 1px solid #999;
140
+ margin-left: -20px;
141
+ }
142
+
143
+
144
+ .section-title {
145
+ background: #79a;
146
+ color: #eee;
147
+ padding: 3px;
148
+ margin-top: 2em;
149
+ margin-left: -30px;
150
+ border: 1px solid #999;
151
+ }
152
+
153
+ .top-aligned-row { vertical-align: top }
154
+ .bottom-aligned-row { vertical-align: bottom }
155
+
156
+ /* --- Context section classes ----------------------- */
157
+
158
+ .context-row { }
159
+ .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
+ .context-item-value { font-size: small; color: #448; }
161
+ .context-item-desc { color: #333; padding-left: 2em; }
162
+
163
+ /* --- Method classes -------------------------- */
164
+ .method-detail {
165
+ background: #efefef;
166
+ padding: 0;
167
+ margin-top: 0.5em;
168
+ margin-bottom: 1em;
169
+ border: 1px dotted #ccc;
170
+ }
171
+ .method-heading {
172
+ color: black;
173
+ background: #ccc;
174
+ border-bottom: 1px solid #666;
175
+ padding: 0.2em 0.5em 0 0.5em;
176
+ }
177
+ .method-signature { color: black; background: inherit; }
178
+ .method-name { font-weight: bold; }
179
+ .method-args { font-style: italic; }
180
+ .method-description { padding: 0 0.5em 0 0.5em; }
181
+
182
+ /* --- Source code sections -------------------- */
183
+
184
+ a.source-toggle { font-size: 90%; }
185
+ div.method-source-code {
186
+ background: #262626;
187
+ color: #ffdead;
188
+ margin: 1em;
189
+ padding: 0.5em;
190
+ border: 1px dashed #999;
191
+ overflow: hidden;
192
+ }
193
+
194
+ div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
+
196
+ /* --- Ruby keyword styles --------------------- */
197
+
198
+ .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
+
200
+ .ruby-constant { color: #7fffd4; background: transparent; }
201
+ .ruby-keyword { color: #00ffff; background: transparent; }
202
+ .ruby-ivar { color: #eedd82; background: transparent; }
203
+ .ruby-operator { color: #00ffee; background: transparent; }
204
+ .ruby-identifier { color: #ffdead; background: transparent; }
205
+ .ruby-node { color: #ffa07a; background: transparent; }
206
+ .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
+ .ruby-regexp { color: #ffa07a; background: transparent; }
208
+ .ruby-value { color: #7fffd4; background: transparent; }
@@ -0,0 +1,7 @@
1
+
2
+ # Say hello, Gracy.
3
+
4
+ def hello
5
+ "Hello, Gracy"
6
+ end
7
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ title: Foo
3
+ main: README
4
+
data/demo/util/one ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ratch
2
+
3
+ # run only once
4
+
5
+ puts "This should only happen once!"
6
+
data/demo/util/rdoc ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Generate RDocs
4
+
5
+ # Check for 'doc' directory.
6
+ # (Helps to ensure we're in the right place.)
7
+
8
+ require 'ratchets/batch'
9
+
10
+ dir! 'doc'
11
+
12
+ # Load rdoc configuration.
13
+
14
+ config = config_load('rdoc')
15
+
16
+ config = {
17
+ 'template' => 'html',
18
+ 'op' => 'doc/rdoc',
19
+ 'merge' => true,
20
+ 'inline-source' => true,
21
+ 'exclude' => %w{ InstalledFiles Manifest Project dev util },
22
+ 'include' => %w{ [A-Z]* lib }
23
+ }.update config
24
+
25
+ # Prepare command arguments.
26
+
27
+ vector = config_vector(config, 'include')
28
+
29
+ # Remove old rdocs, if any.
30
+
31
+ dir = config['op']
32
+
33
+ abort "bad ouput directory #{dir}" if dir =~ /^\//
34
+
35
+ rm_r dir if dir?(dir)
36
+
37
+ # Document.
38
+
39
+ rdoc(*vector)
data/demo/util/tryme ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ratch
2
+
3
+ # try out the task system
4
+
5
+ puts "Invoking 'one' three times..."
6
+
7
+ one
8
+ one
9
+ one
10
+
@@ -0,0 +1,42 @@
1
+ # Module extension for defining prequisite tasks.
2
+
3
+ module Taskable
4
+
5
+ # Define or call a task.
6
+
7
+ def task n, &block
8
+ case n
9
+ when Hash
10
+ name, preq = *n.to_a[0]
11
+ else
12
+ name, preq = n, []
13
+ end
14
+
15
+ task_name = "#{name}:task"
16
+
17
+ define_method(task_name) do |cache,*args|
18
+ cache ||= {}
19
+ return cache[name] if cache.key?(name)
20
+ preq.each do |q|
21
+ send("#{q}:task",cache,*args)
22
+ end
23
+ cache[name] = block.call(*args)
24
+ end
25
+
26
+ private task_name
27
+ end
28
+
29
+ def call_target(name,*a)
30
+ send("#{name}:task",nil,*a)
31
+ end
32
+
33
+ #def cache
34
+ # @taskable_cache ||= {}
35
+ #end
36
+
37
+ #def function s, &b
38
+ # define_method s, &b
39
+ # private s
40
+ #end
41
+
42
+ end
data/dev/taskable.rb ADDED
@@ -0,0 +1,573 @@
1
+ # TITLE:
2
+ #
3
+ # Taskable
4
+ #
5
+ # COPYRIGHT:
6
+ #
7
+ # Copyright (c) 2006 Thomas Sawyer
8
+ #
9
+ # LICENSE:
10
+ #
11
+ # Ruby License
12
+ #
13
+ # This module is free software. You may use, modify, and/or redistribute this
14
+ # software under the same terms as Ruby.
15
+ #
16
+ # This program is distributed in the hope that it will be useful, but WITHOUT
17
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
+ # FOR A PARTICULAR PURPOSE.
19
+ #
20
+ # AUTHORS:
21
+ #
22
+ # - Thomas Sawyer
23
+ #
24
+ # NOTES:
25
+ #
26
+ # - TODO The included call back does a comparison to Object.
27
+ # This is a bit of a hack b/c there is actually no way to
28
+ # check if it is the toplevel --a flaw w/ Ruby's toplevel proxy.
29
+ #
30
+ # - TODO Should Rake's namespace feature be added? This could interfer
31
+ # with other definitions of #namespace.
32
+ #
33
+ # - TODO The only reason the :exec method is defined is b/c instance_exec
34
+ # is not in Ruby yet, so until then this is the working hack.
35
+ #
36
+ # LOG:
37
+ #
38
+ # - CHANGE 2006-11-14 trans
39
+ #
40
+ # Taskable has been completely rewritten. While it is essentially
41
+ # compatible with the previous implementation, it is not 100% the
42
+ # same; mainly in that tasks are not defined as methods any longer.
43
+ # This new implementation is now nearly 100% compatible with Rake's
44
+ # design. Note, for a basic "taskable" system, more like the old
45
+ # version, see depend.rb.
46
+
47
+ require 'facets/class_extension'
48
+
49
+ $toplevel = self
50
+
51
+ # = Taskable
52
+ #
53
+ # The Taskable module provides a generic task system
54
+ # patterned after Rake, but useable in any
55
+ # code context --not just with the Rake tool. In other
56
+ # words one can create methods with dependencies.
57
+ #
58
+ # NOTE Unlike methods, tasks can't take independent parameters
59
+ # if they are to be used as prerequisites. The arguments passed
60
+ # to a task call will also be passed to it's prequisites.
61
+ #
62
+ # To use Taskable at the toplevel use:
63
+ #
64
+ # include Taskable
65
+ #
66
+ # Or if you want all modules to be "taskable":
67
+ #
68
+ # class Module
69
+ # include Taskable
70
+ # end
71
+
72
+ module Taskable
73
+
74
+ def self.included( base )
75
+ if base == Object #$toplevel
76
+ require 'facets/more/main_as_module.rb'
77
+ Module.module_eval{ include TaskableDSL }
78
+ else
79
+ base.extend TaskableDSL
80
+ end
81
+ end
82
+
83
+ ### CLASS LEVEL ###
84
+
85
+ module TaskableDSL
86
+
87
+ #--
88
+ # TODO Add task namespace functionality ???
89
+ #++
90
+ #def namespace
91
+ #end
92
+
93
+ # Define description for subsequent task.
94
+
95
+ def desc(line=nil)
96
+ return @_last_description unless line
97
+ @_last_description = line.gsub("\n",'')
98
+ end
99
+
100
+ # Use up the description for subsequent task.
101
+
102
+ def desc!
103
+ l, @_last_description = @_last_description, nil
104
+ l
105
+ end
106
+
107
+ # <b>Task</b>
108
+ #
109
+ #
110
+
111
+ def task( target_to_source, &build )
112
+ target, source = *Task.parse(target_to_source)
113
+ define_method("#{target}:exec",&build) if build
114
+ (@task||={})[target] = Task.new(target, source, desc!, &build)
115
+ end
116
+
117
+ # <b>File task</b>
118
+ #
119
+ # Task must be provide instructions for building the file.
120
+
121
+ def file( file_to_source, &build )
122
+ file, source = *Task.parse(file_to_source)
123
+ define_method("#{file}:exec",&build) if build
124
+ (@task||={})[file] = FileTask.new(file, source, desc!, &build)
125
+ end
126
+
127
+ # <b>Rule task</b>
128
+ #
129
+ # Task must be provide instructions for building the file(s).
130
+
131
+ def rule( pattern_to_source, &build )
132
+ pattern, source = *Task.parse(pattern_to_source)
133
+ define_method("#{pattern}:exec",&build) if build
134
+ (@task||={})[pattern] = RuleTask.new(pattern, source, desc!, &build)
135
+ end
136
+
137
+ #
138
+
139
+ def instance_tasks( ancestry=true )
140
+ @task ||= {}
141
+ if ancestry
142
+ ancestors.inject(@task.keys) do |m,a|
143
+ t = a.instance_variable_get("@task")
144
+ m |= t.keys if t
145
+ m
146
+ end
147
+ else
148
+ @task.keys
149
+ end
150
+ end
151
+
152
+ # List of task names with descriptions.
153
+
154
+ def described_tasks( ancestry=true )
155
+ memo = []
156
+ instance_tasks(ancestry).each do |name|
157
+ memo << name if @task[name].desc
158
+ end
159
+ return memo
160
+ end
161
+
162
+ # List of task names without descriptions.
163
+
164
+ def undescribed_tasks( ancestry=true )
165
+ memo = []
166
+ instance_tasks(ancestry).each do |name|
167
+ memo << name unless @task[name].desc
168
+ end
169
+ return memo
170
+ end
171
+
172
+ # Find matching task.
173
+ #--
174
+ # TODO Maybe this isn't really needed here and can be moved to Task class ???
175
+ #++
176
+
177
+ def instance_task( match )
178
+ hit = (@task||={}).values.find do |task|
179
+ task.match(match)
180
+ end
181
+ return hit if hit
182
+ ancestors.each do |a|
183
+ task_table = a.instance_variable_get("@task")
184
+ next unless task_table
185
+ hit = task_table.values.find do |task|
186
+ task.match(match)
187
+ end
188
+ break hit if hit
189
+ end
190
+ hit
191
+ end
192
+
193
+ end
194
+
195
+ ### INSTANCE LEVEL ###
196
+
197
+ #
198
+
199
+ def tasks
200
+ (class << self; self; end).instance_tasks
201
+ end
202
+
203
+ #
204
+
205
+ def task(name)
206
+ (class << self; self; end).instance_task(name)
207
+ end
208
+
209
+ # FIXME, THIS STILL WONT WORK AT TOPLEVEL!!!!
210
+
211
+ def method_missing(t, *a, &b)
212
+ p t
213
+ p tasks
214
+ p task(t)
215
+ #if self.class.respond_to?(:instance_task) && (task = self.class.instance_task(t))
216
+ if tsk = task(t)
217
+ tsk.run(self, t)
218
+ else
219
+ super(t.to_sym,*a,&b)
220
+ end
221
+ end
222
+
223
+ end
224
+
225
+ #
226
+
227
+ class Taskable::Task
228
+
229
+ # Parse target => [source,...] argument.
230
+
231
+ def self.parse(target_to_source)
232
+ if Hash === target_to_source
233
+ target = target_to_source.keys[0]
234
+ source = target_to_source.values[0]
235
+ else
236
+ target = target_to_source
237
+ source = []
238
+ end
239
+ return target.to_sym, source.collect{|s| s.to_sym}
240
+ end
241
+
242
+ #
243
+
244
+ attr_reader :target, :source, :desc, :build
245
+
246
+ alias :name :target
247
+ alias :description :desc
248
+
249
+ # New task.
250
+
251
+ def initialize( target, source, desc=nil, &build )
252
+ @target = target
253
+ @source = source
254
+ @desc = desc
255
+ @build = build
256
+ end
257
+
258
+ # Run task in given context.
259
+
260
+ def run( context, target )
261
+ task = self
262
+ source = @source
263
+ build = @build
264
+
265
+ presource(context).each do |d|
266
+ d.call(context)
267
+ end
268
+
269
+ call(context)
270
+ end
271
+
272
+ # Call build exec of task. Note that the use of :exec method
273
+ # is due to the lack of #instance_exec which will come wiht Ruby 1.9.
274
+
275
+ def call( context )
276
+ context.send("#{@target}:exec", self) if @build
277
+ end
278
+
279
+ #
280
+
281
+ def match( target )
282
+ @target.to_s == target.to_s
283
+ end
284
+
285
+ # Compile list of all unique prerequisite sources.
286
+
287
+ def presource( context, build=[] )
288
+ @source.each do |s|
289
+ t = context.class.instance_task(s)
290
+ raise NoMethodError, 'undefined source' unless t
291
+ build.unshift(t)
292
+ t.presource(context,build)
293
+ end
294
+ build.uniq!
295
+ build
296
+ end
297
+
298
+ end
299
+
300
+ #
301
+
302
+ class Taskable::FileTask < Taskable::Task
303
+
304
+ # Run file task in a given context.
305
+
306
+ def run( context, target )
307
+ task = self
308
+ source = @source
309
+ build = @build
310
+
311
+ context.instance_eval do
312
+ needed = false
313
+ if File.exist?(file)
314
+ #source.each { |s| send(s) if respond_to?(s) }
315
+ timestamp = File.mtime(file)
316
+ needed = source.any? { |f| File.mtime(f.to_s) > timestamp }
317
+ else
318
+ timestamp = Time.now - 1
319
+ needed = true
320
+ end
321
+ if needed
322
+ build.call(task)
323
+ unless File.exist?(file) and File.mtime(file) > timestamp
324
+ raise "failed to build -- #{file}"
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ #
331
+
332
+ def match(target)
333
+ @target.to_s == target.to_s
334
+ end
335
+
336
+ end
337
+
338
+ #
339
+
340
+ class Taskable::RuleTask < Taskable::FileTask
341
+
342
+ # Run rule task in given context.
343
+
344
+ def run( context, target )
345
+ @target = target
346
+ super(context)
347
+ end
348
+
349
+ #
350
+
351
+ def match(target)
352
+ case @target
353
+ when Regexp
354
+ @target =~ target.to_s
355
+ when String
356
+ #if @target.index('*') #TODO
357
+ # /#{@target.gsub('*', '.*?')}/ =~ target
358
+ if @target.index('.') == 0
359
+ /#{Regexp.escape(@target)}$/ =~ target
360
+ else
361
+ super
362
+ end
363
+ else
364
+ super
365
+ end
366
+ end
367
+
368
+ end
369
+
370
+
371
+
372
+ # _____ _
373
+ # |_ _|__ ___| |_
374
+ # | |/ _ \/ __| __|
375
+ # | | __/\__ \ |_
376
+ # |_|\___||___/\__|
377
+ #
378
+ =begin ##test
379
+
380
+ require 'test/unit'
381
+
382
+ class TestTaskable1 < Test::Unit::TestCase
383
+
384
+ module M
385
+ include Taskable
386
+ task :m1 => [ :c1 ] do @x << "m1" end
387
+ task :m2 => [ :c2 ] do @x << "m2" end
388
+ task :m3 => [ :c3 ] do @x << "m3" end
389
+ task :m4 => [ :c1, :c2, :c3 ] do @x << "m4" end
390
+ task :m5 do @x << 'm5' end
391
+ end
392
+
393
+ class B
394
+ include Taskable
395
+ attr :x
396
+ def initialize ; @x = [] ; end
397
+
398
+ desc "test-b1"
399
+ task :b1 do @x << "b1" end
400
+ task :b2 => [ :b1 ]
401
+ end
402
+
403
+ class C
404
+ include M
405
+ attr :x
406
+ def initialize ; @x = [] ; end
407
+
408
+ task :c1 do @x << "c1" end
409
+ task :c2 => [ :c1, :c1 ] do @x << "c2" end
410
+ task :c3 => [ :c1, :c2 ] do @x << "c3" end
411
+ task :c4 => [ :m1 ] do @x << "c4" end
412
+ task :c5 => [ :c5 ] do @x << "c5" end
413
+ task :c6 => [ :c7 ] do @x << "c6" end
414
+ task :c7 => [ :c6 ] do @x << "c7" end
415
+ end
416
+
417
+ class D < C
418
+ task :d1 => [ :c1 ] do @x << "d1" ; end
419
+ task :d2 => [ :m1 ] do @x << "d2" ; end
420
+ end
421
+
422
+ module N
423
+ include M
424
+ end
425
+
426
+ class E
427
+ include N
428
+ attr :x
429
+ def initialize ; @x = [] ; end
430
+
431
+ task :e1 => [ :c1 ] do @x << "e1" ; end
432
+ task :e2 => [ :m1 ] do @x << "e2" ; end
433
+ task :e3 => [ :m5 ] do @x << "e3" ; end
434
+ end
435
+
436
+ module O
437
+ include Taskable
438
+ attr :x
439
+ task :o1 do (@x||=[]) << "o1" end
440
+ task :o2 => [ :o1 ] do (@x||=[]) << "o2" end
441
+ end
442
+
443
+ # tests
444
+
445
+ def test_001
446
+ assert( B.described_tasks.include?(:b1) )
447
+ end
448
+
449
+ def test_B1
450
+ b = B.new ; b.b1
451
+ assert_equal( [ 'b1' ], b.x )
452
+ end
453
+
454
+ def test_B2
455
+ b = B.new ; b.b2
456
+ assert_equal( [ 'b1' ], b.x )
457
+ end
458
+
459
+ def test_C1
460
+ c = C.new ; c.c1
461
+ assert_equal( [ 'c1' ], c.x )
462
+ end
463
+
464
+ def test_C2
465
+ c = C.new ; c.c2
466
+ assert_equal( [ 'c1', 'c2' ], c.x )
467
+ end
468
+
469
+ def test_C3
470
+ c = C.new ; c.c3
471
+ assert_equal( [ 'c1', 'c2', 'c3' ], c.x )
472
+ end
473
+
474
+ def test_C4
475
+ c = C.new ; c.c4
476
+ assert_equal( [ 'c1', 'm1', 'c4' ], c.x )
477
+ end
478
+
479
+ def test_M1
480
+ c = C.new ; c.m1
481
+ assert_equal( [ 'c1', 'm1' ], c.x )
482
+ end
483
+
484
+ def test_M2
485
+ c = C.new ; c.m2
486
+ assert_equal( [ 'c1', 'c2', 'm2' ], c.x )
487
+ end
488
+
489
+ def test_M3
490
+ c = C.new ; c.m3
491
+ assert_equal( [ 'c1', 'c2', 'c3', 'm3' ], c.x )
492
+ end
493
+
494
+ def test_M4
495
+ c = C.new ; c.m4
496
+ assert_equal( [ 'c1', 'c2', 'c3', 'm4' ], c.x )
497
+ end
498
+
499
+ def test_D1
500
+ d = D.new ; d.d1
501
+ assert_equal( [ 'c1', 'd1' ], d.x )
502
+ end
503
+
504
+ def test_D2
505
+ d = D.new ; d.d2
506
+ assert_equal( [ 'c1', 'm1', 'd2' ], d.x )
507
+ end
508
+
509
+ def test_E1
510
+ e = E.new
511
+ assert_raises( NoMethodError ) { e.e1 }
512
+ #assert_equal( [ 'c1', 'e1' ], e.x )
513
+ end
514
+
515
+ def test_E2
516
+ e = E.new
517
+ assert_raises( NoMethodError ) { e.e2 }
518
+ #assert_equal( [ 'c1', 'm1', 'e2' ], e.x )
519
+ end
520
+
521
+ def test_E3
522
+ e = E.new ; e.e3
523
+ assert_equal( [ 'm5', 'e3' ], e.x )
524
+ end
525
+
526
+ # def test_F1
527
+ # F.o1
528
+ # assert_equal( [ 'o1' ], F.x )
529
+ # end
530
+ #
531
+ # def test_F2
532
+ # F.o2
533
+ # assert_equal( [ 'o1', 'o1', 'o2' ], F.x )
534
+ # end
535
+
536
+ end
537
+
538
+ =end
539
+
540
+ ##
541
+ # Test toplevel usage.
542
+ #
543
+
544
+ include Taskable
545
+
546
+ p Object.ancestors
547
+
548
+ task :foo do
549
+ "foo"
550
+ end
551
+
552
+ task :bar => [ :foo ] do
553
+ "bar"
554
+ end
555
+
556
+ #class TestTaskable2 #< Test::Unit::TestCase
557
+ def test_01
558
+ puts foo
559
+ end
560
+
561
+ def test_02
562
+ puts bar
563
+ end
564
+ #end
565
+
566
+ test_01
567
+ test_02
568
+
569
+ #=end
570
+
571
+ # Author:: Thomas Sawyer
572
+ # Copyright:: Copyright (c) 2006 Thomas Sawyer
573
+ # License:: Ruby License