tap 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/History +12 -0
  2. data/MIT-LICENSE +0 -2
  3. data/README +23 -32
  4. data/bin/rap +116 -0
  5. data/bin/tap +6 -9
  6. data/cgi/run.rb +67 -0
  7. data/cmd/console.rb +1 -1
  8. data/cmd/destroy.rb +4 -4
  9. data/cmd/generate.rb +4 -4
  10. data/cmd/manifest.rb +61 -53
  11. data/cmd/run.rb +8 -75
  12. data/doc/Class Reference +130 -121
  13. data/doc/Command Reference +76 -124
  14. data/doc/Syntax Reference +290 -0
  15. data/doc/Tutorial +305 -237
  16. data/lib/tap/app.rb +140 -467
  17. data/lib/tap/constants.rb +2 -2
  18. data/lib/tap/declarations.rb +211 -0
  19. data/lib/tap/env.rb +171 -193
  20. data/lib/tap/exe.rb +100 -21
  21. data/lib/tap/file_task.rb +3 -3
  22. data/lib/tap/generator/base.rb +1 -1
  23. data/lib/tap/generator/destroy.rb +10 -10
  24. data/lib/tap/generator/generate.rb +29 -18
  25. data/lib/tap/generator/generators/command/command_generator.rb +2 -2
  26. data/lib/tap/generator/generators/command/templates/command.erb +2 -2
  27. data/lib/tap/generator/generators/config/config_generator.rb +3 -3
  28. data/lib/tap/generator/generators/config/templates/doc.erb +1 -1
  29. data/lib/tap/generator/generators/file_task/file_task_generator.rb +1 -1
  30. data/lib/tap/generator/generators/file_task/templates/task.erb +1 -1
  31. data/lib/tap/generator/generators/file_task/templates/test.erb +1 -1
  32. data/lib/tap/generator/generators/generator/generator_generator.rb +27 -0
  33. data/lib/tap/generator/generators/generator/templates/task.erb +27 -0
  34. data/lib/tap/generator/generators/root/root_generator.rb +13 -13
  35. data/lib/tap/generator/generators/root/templates/README +0 -0
  36. data/lib/tap/generator/generators/root/templates/Rakefile +2 -2
  37. data/lib/tap/generator/generators/root/templates/gemspec +4 -5
  38. data/lib/tap/generator/generators/root/templates/tapfile +11 -8
  39. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
  40. data/lib/tap/generator/generators/task/task_generator.rb +1 -3
  41. data/lib/tap/generator/generators/task/templates/test.erb +1 -3
  42. data/lib/tap/patches/optparse/summarize.rb +62 -0
  43. data/lib/tap/root.rb +41 -29
  44. data/lib/tap/support/aggregator.rb +16 -3
  45. data/lib/tap/support/assignments.rb +10 -9
  46. data/lib/tap/support/audit.rb +58 -64
  47. data/lib/tap/support/class_configuration.rb +33 -44
  48. data/lib/tap/support/combinator.rb +125 -0
  49. data/lib/tap/support/configurable.rb +13 -14
  50. data/lib/tap/support/configurable_class.rb +21 -43
  51. data/lib/tap/support/configuration.rb +55 -9
  52. data/lib/tap/support/constant.rb +87 -13
  53. data/lib/tap/support/constant_manifest.rb +116 -0
  54. data/lib/tap/support/dependencies.rb +54 -0
  55. data/lib/tap/support/dependency.rb +44 -0
  56. data/lib/tap/support/executable.rb +247 -32
  57. data/lib/tap/support/executable_queue.rb +1 -1
  58. data/lib/tap/support/gems/rake.rb +29 -8
  59. data/lib/tap/support/gems.rb +10 -30
  60. data/lib/tap/support/instance_configuration.rb +29 -3
  61. data/lib/tap/support/intern.rb +46 -0
  62. data/lib/tap/support/join.rb +143 -0
  63. data/lib/tap/support/joins/fork.rb +19 -0
  64. data/lib/tap/support/joins/merge.rb +22 -0
  65. data/lib/tap/support/joins/sequence.rb +21 -0
  66. data/lib/tap/support/joins/switch.rb +25 -0
  67. data/lib/tap/support/joins/sync_merge.rb +63 -0
  68. data/lib/tap/support/joins.rb +15 -0
  69. data/lib/tap/support/lazy_attributes.rb +17 -2
  70. data/lib/tap/support/lazydoc/comment.rb +503 -0
  71. data/lib/tap/support/lazydoc/config.rb +17 -0
  72. data/lib/tap/support/lazydoc/definition.rb +36 -0
  73. data/lib/tap/support/lazydoc/document.rb +152 -0
  74. data/lib/tap/support/lazydoc/method.rb +24 -0
  75. data/lib/tap/support/lazydoc.rb +269 -343
  76. data/lib/tap/support/manifest.rb +121 -103
  77. data/lib/tap/support/minimap.rb +90 -0
  78. data/lib/tap/support/node.rb +56 -0
  79. data/lib/tap/support/parser.rb +436 -0
  80. data/lib/tap/support/schema.rb +359 -0
  81. data/lib/tap/support/shell_utils.rb +3 -5
  82. data/lib/tap/support/string_ext.rb +60 -0
  83. data/lib/tap/support/tdoc.rb +7 -2
  84. data/lib/tap/support/templater.rb +30 -16
  85. data/lib/tap/support/validation.rb +77 -8
  86. data/lib/tap/task.rb +431 -143
  87. data/lib/tap/tasks/dump.rb +15 -10
  88. data/lib/tap/tasks/load.rb +112 -0
  89. data/lib/tap/tasks/rake.rb +4 -41
  90. data/lib/tap/test/assertions.rb +38 -0
  91. data/lib/tap/test/env_vars.rb +1 -1
  92. data/lib/tap/test/extensions.rb +79 -0
  93. data/lib/tap/test/file_test.rb +420 -0
  94. data/lib/tap/test/file_test_class.rb +12 -0
  95. data/lib/tap/test/regexp_escape.rb +87 -0
  96. data/lib/tap/test/script_test.rb +46 -0
  97. data/lib/tap/test/script_tester.rb +115 -0
  98. data/lib/tap/test/subset_test.rb +260 -0
  99. data/lib/tap/test/subset_test_class.rb +99 -0
  100. data/lib/tap/test/{tap_methods.rb → tap_test.rb} +45 -43
  101. data/lib/tap/test/utils.rb +231 -0
  102. data/lib/tap/test.rb +53 -26
  103. data/lib/tap.rb +3 -20
  104. metadata +50 -27
  105. data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +0 -15
  106. data/lib/tap/patches/rake/rake_test_loader.rb +0 -8
  107. data/lib/tap/patches/rake/testtask.rb +0 -57
  108. data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -51
  109. data/lib/tap/patches/ruby19/parsedate.rb +0 -16
  110. data/lib/tap/support/batchable.rb +0 -47
  111. data/lib/tap/support/batchable_class.rb +0 -107
  112. data/lib/tap/support/command_line.rb +0 -98
  113. data/lib/tap/support/comment.rb +0 -270
  114. data/lib/tap/support/constant_utils.rb +0 -127
  115. data/lib/tap/support/declarations.rb +0 -111
  116. data/lib/tap/support/framework.rb +0 -83
  117. data/lib/tap/support/framework_class.rb +0 -180
  118. data/lib/tap/support/run_error.rb +0 -39
  119. data/lib/tap/support/summary.rb +0 -30
  120. data/lib/tap/test/file_methods.rb +0 -377
  121. data/lib/tap/test/script_methods/script_test.rb +0 -98
  122. data/lib/tap/test/script_methods.rb +0 -107
  123. data/lib/tap/test/subset_methods.rb +0 -420
  124. data/lib/tap/workflow.rb +0 -200
@@ -2,7 +2,7 @@
2
2
 
3
3
  Working up from the ground is useful to get a sense for how Tap does what it does. This reference goes through the modules and classes that build up a task application: Tasks, Apps, and Envs.
4
4
 
5
- == Tasks (Tap::Task, Tap::Workflow)
5
+ == Tasks
6
6
 
7
7
  ==== Methods
8
8
 
@@ -14,15 +14,9 @@ Tasks begin with methods, simply a block of code.
14
14
 
15
15
  http://tap.rubyforge.org/images/Executable.png
16
16
 
17
- Executable extends objects allowing them to be enqued and run by an App. Executable objects specify a method that gets called upon execution; in essence Executable wraps this method and adds workflow behaviors like auditing and an <tt>on_complete</tt> block.
17
+ Executable extends objects allowing them to be used in workflows, enqued, and run by an App. Executable objects specify a method that gets called upon execution; in essence Executable wraps this method and adds workflow support for dependencies, joins, batches, and auditing. Any method may be made executable, and so any method can participate in a workflow (see Object#_method).
18
18
 
19
- Tasks are constructed such that <tt>execute</tt> is their executable method. Task#execute simply provides hooks before and after forwarding control to the <tt>process</tt> method. Hence <tt>process</tt> is the standard method overridden in subclasses of Task.
20
-
21
- ==== Tap::Support::Batchable
22
-
23
- http://tap.rubyforge.org/images/Batchable.png
24
-
25
- Tasks can be assembled into batches that all enque at the same time and share the same <tt>on_complete</tt> block. This behavior is very powerful, allowing workflow logic to be defined once but executed under multiple conditions. Task includes the Batchable module to facilitate batching.
19
+ Tasks are constructed such that <tt>process</tt> is the executable method (actually execute_with_callbacks is used to wrap process with before/after execute callbacks, but effectively this is the case). Hence <tt>process</tt> is the standard method overridden in Task subclasses.
26
20
 
27
21
  ==== Tap::Support::Configurable
28
22
 
@@ -38,6 +32,10 @@ Instances of a Configurable class have a <tt>config</tt> method accessing a {Ins
38
32
  config :key, 'value' do |input|
39
33
  input.upcase
40
34
  end
35
+
36
+ def initialize
37
+ initialize_config
38
+ end
41
39
  end
42
40
 
43
41
  Is basically the same as:
@@ -93,16 +91,10 @@ Validation blocks sometimes imply metadata. For instance <tt>c.flag</tt> makes
93
91
 
94
92
  ==== Tap::Support::Lazydoc
95
93
 
96
- http://tap.rubyforge.org/images/Lazydoc.png
97
-
98
- Ah lazydoc. Lazydoc fits into the space between live code and code documentation. Lazydoc can scan a file (code or not) and pull out documentation into the object space where it can be utilized. Lazydoc uses a key-value syntax that is both invalid Ruby and easily hidden in RDoc. Looks like this:
94
+ Ah lazydoc. Lazydoc fits into the space between live code and code documentation. Lazydoc can scan a file (code or not) and pull documentation into the object space where it can be utilized. Lazydoc uses a key-value syntax like this:
99
95
 
100
96
  # ::key value
101
97
 
102
- Try the former line without the comment and a syntax error results. In RDoc, the syntax doesn't interfere with any of the standard documentation conventions and can be hidden with the use of a <tt>:startdoc:</tt> attribute (an extra space is added to <tt>:startdoc:</tt> so the line isn't actually hidden in this document):
103
-
104
- # :start doc::key value
105
-
106
98
  Lazydoc parses a constant name, the key, the value, and any comment following the value until a non-comment line or an end key. For example:
107
99
 
108
100
  [lazydoc_file.rb]
@@ -124,9 +116,9 @@ Lazydoc parses a constant name, the key, the value, and any comment following th
124
116
  lazydoc.resolve
125
117
 
126
118
  lazydoc['Name::Space']['key'].to_s # => "This documentation gets parsed."
127
- lazydoc['Name::Space']['another'].subject # => "another value"
119
+ lazydoc['Name::Space']['another'].value # => "another value"
128
120
 
129
- Furthermore, Lazydoc allows living code to register lines that should get documented. These lines are parsed to echo what happens in RDoc.
121
+ Furthermore, Lazydoc can register specific lines for documentation. These lines are parsed to echo what happens in RDoc.
130
122
 
131
123
  [another_lazydoc_file.rb]
132
124
  # documentation
@@ -145,7 +137,7 @@ Furthermore, Lazydoc allows living code to register lines that should get docume
145
137
 
146
138
  Tap uses Lazydoc to indicate when a file contains a Task (<tt>::manifest</tt>) or a generator (<tt>::generator</tt>), and for config documentation. Tap::Env uses this information to facilitate lookup and instantiation of task classes.
147
139
 
148
- One note: when no constant name is specified for a Lazydoc key, it gets treated as a default for the whole file.
140
+ When no constant name is specified for a Lazydoc key, Env uses a constant based on the file name.
149
141
 
150
142
  [lib/sample/task.rb]
151
143
  # ::manifest sample task description
@@ -160,67 +152,69 @@ However, the best practice is to include the namespace explicitly.
160
152
 
161
153
  http://tap.rubyforge.org/images/Task.png
162
154
 
163
- Running a task through the tap executable instantiates a task class, configures it, enques it, and runs a Tap::App to get the inputs to the <tt>process</tt> method. Tasks do not have to be used this way; they are perfectly capable as objects in free-standing scripts.
155
+ Running a task from the command line using tap (or rap) instantiates a task, configures it, enques it, and runs an App to pass inputs to the <tt>process</tt> method. Tasks do not have to be used this way; they are perfectly capable as objects in free-standing scripts.
164
156
 
165
- Task instances can take a block that acts as a stand-in for <tt>process</tt>:
157
+ Task instances may be interned with a block that acts as a stand-in for <tt>process</tt>:
166
158
 
167
- t = Tap::Task.new {|task| 1 + 2 }
159
+ t = Tap::Task.intern {|task| 1 + 2 }
168
160
  t.process # => 3
169
161
 
170
- t = Tap::Task.new {|task, x, y| x + y }
162
+ t = Tap::Task.intern {|task, x, y| x + y }
171
163
  t.process(1, 2) # => 3
172
-
173
- Tasks can be configured:
174
164
 
175
- t1 = Tap::Task.new(:key => 'one') {|task, input| "#{input}:#{task.config[:key]}"}
176
- t1.process('str') # => "str:one"
177
-
178
- And batched:
165
+ Tasks can be configured,
179
166
 
180
- t2 = t1.initialize_batch_obj(:key => 'two')
181
- t3 = t1.initialize_batch_obj(:key => 'three')
167
+ runlist = []
168
+ t1 = Tap::Task.intern(:key => 'one') do |task, input|
169
+ runlist << task
170
+ "#{input}:#{task.config[:key]}"
171
+ end
182
172
 
183
- t1.batch # => [t1, t2, t3]
173
+ joined into dependency-based workflows,
184
174
 
185
- Batched tasks enque together, and therefore run sequentially with the same inputs:
175
+ t0 = Tap::Task.intern {|task| runlist << task }
176
+ t1.depends_on(t0)
186
177
 
178
+ imperative workflows,
179
+
180
+ t2 = Tap::Task.intern do |task, input|
181
+ runlist << task
182
+ "#{input}:two"
183
+ end
184
+ t1.sequence(t2)
185
+
186
+ and batched.
187
+
188
+ t3 = t1.initialize_batch_obj(:key => 'three')
189
+ t1.batch # => [t1, t3]
190
+
191
+ Batched tasks enque together, and therefore execute sequentially with the same inputs. Results are aggregated into the underlying Tap::App.
192
+
193
+ t1.enq('input')
194
+
187
195
  app = Tap::App.instance
188
- app.enq(t1, 'str')
189
- app.queue.to_a # => [[t1, ['str']], [t2, ['str']], [t3, ['str']]]
190
196
  app.run
197
+
198
+ runlist # => [t0, t1, t2, t3, t2]
199
+ app.results(t2) # => ["input:one:two", "input:three:two"]
191
200
 
192
- app.results(t1) # => ["str:one"]
193
- app.results(t2) # => ["str:two"]
194
- app.results(t3) # => ["str:three"]
195
-
196
- Also, as a consequence of Task being Executable, the results have audit trails. In the audit trail, the tasks are identified by name (by default the name the underscored class name):
201
+ Tracking the evolution of a result through a workflow can get complex; Tap audits workflows to help. In the audit trail, the tasks are identified by name. Lets set the names of the tasks and take a look at the audit trails of the t2 results:
197
202
 
198
- t1.name = 'task one'
199
- t2.name = 'task two'
200
- t3.name = 'task three'
203
+ t1.name = 'un'
204
+ t2.name = 'deux'
205
+ t3.name = 'trois'
201
206
 
202
- app._results(t1,t2,t3).collect do |_result|
203
- _result.to_s
207
+ app._results(t2).collect do |_result|
208
+ _result._to_s
204
209
  end.join("---\n")
205
210
  # =>
206
- # o-[] 1
207
- # o-[task one] "str:one"
211
+ # o-[] "input"
212
+ # o-[un] "input:one"
213
+ # o-[deux] "input:one:two"
208
214
  # ---
209
- # o-[] 1
210
- # o-[task two] "str:two"
211
- # ---
212
- # o-[] 1
213
- # o-[task three] "str:three"
214
-
215
- Task instances can be joined into workflows. The workflow model used by Tap is very simple; when a task completes it calls its <tt>on_complete</tt> block to enque the next task (or tasks) in the workflow. Arbitrary workflow logic is allowed since there are no restrictions on what the <tt>on_complete</tt> block does. If a task has no <tt>on_complete</tt> block, App collects the unhandled results (as shown above) so they can be handled somewhere else. See below for more details.
216
-
217
- === Tap::Workflow
218
-
219
- http://tap.rubyforge.org/images/Workflow.png
220
-
221
- Workflows are not Tasks but are constructed with the same modules as Task and work very similarly Tasks. Workflows have a <tt>workflow</tt> method which defines the entry and exit points for the workflow; there can be 1+ entry points and 0+ exit points. The enque method for a workflow enques all it's entry points, and when the <tt>on_complete</tt> block is set for a workflow, it is set for all exit points.
222
-
223
- Like Tasks, Workflows can be configured, enqued, used in workflows, and subclassed.
215
+ # o-[] "input"
216
+ # o-[trois] "input:three"
217
+ # o-[deux] "input:three:two"
224
218
 
225
219
  == Apps
226
220
 
@@ -233,35 +227,29 @@ A Root represents the base of a directory structure. Roots allow you to alias di
233
227
  root = Tap::Root.new '/path/to/root'
234
228
  root.root # => '/path/to/root'
235
229
  root['config'] # => '/path/to/root/config'
236
- root.filepath('config', 'sample.yml') # => '/path/to/root/config/sampl.yml'
230
+ root.filepath('config', 'sample.yml') # => '/path/to/root/config/sample.yml'
237
231
 
238
- While simple, this ability to reference files using aliases is useful, powerful, and forms the basis of the Tap execution environment.
232
+ While simple, this ability to alias paths is useful, powerful, and forms the basis of the Tap execution environment.
239
233
 
240
234
  ==== Tap::Support::ExecutableQueue
241
235
 
242
236
  http://tap.rubyforge.org/images/ExecutableQueue.png
243
237
 
244
- Apps coordinate the execution of tasks through a queue. The queue is just a stack of Executable objects, basically methods, and the inputs to those methods; during a run the enqued methods are sequentially executed with the inputs.
238
+ Apps coordinate the execution of tasks through a queue. The queue is just a stack of Executable objects, basically methods, and the inputs to those methods; during a run the enqued methods are sequentially executed with the inputs.
245
239
 
246
- Normally the methods execute one after the other on the main thread, however the methods can be set to multithread. In this case all sequential, multithreadable methods are executed on their own thread (up to a configurable maximum number of threads). A non-multithreadable method blocks until all these threads finish, and then the sequential, single thread execution resumes.
240
+ ==== Tap::Support::Dependencies
247
241
 
248
- For instance, assuming non-multithreadable executables [a,b,c] and multithread executables [m1, m2, m3], a queue of [a, m1, m2, m3, b, c] executes like:
249
-
250
- a... done
251
- (m1, m2, m3)... done
252
- b... done
253
- c... done
242
+ Dependencies coordinate the registration and resolution of dependencies, which may be shared across multiple tasks.
254
243
 
255
244
  ==== Tap::Support::Audit
256
245
 
257
- Tap tracks inputs as they are modified by various tasks, again through Executable. At the end of a run, any individual result can be tracked back to it's original value with references to the source of each change in the value (ie the task or Executable). This auditing can be very useful when workflows diverge, as they often do.
246
+ Tap tracks inputs as they are modified by various tasks, again through Executable. At the end of a run, any individual result can be tracked back to it's original value with references to the source of each change (ie the task). This auditing can be very useful when workflows diverge, as they often do.
258
247
 
259
248
  Auditing is largely invisible except in <tt>on_complete</tt> blocks. <tt>on_complete</tt> blocks receive the audited results so that this information can be used, as needed, to make decisions.
260
249
 
261
- t = Task.new
262
- t.on_complete do |_result| # _result is an Audit instance
263
- _result._current # the current value
264
- _result._original # the original value
250
+ Task.new.on_complete do |_result| # _result is an Audit instance
251
+ _result._current # the current value
252
+ _result._original # the original value
265
253
  end
266
254
 
267
255
  To help indicate when a result is actually a result and when it is an audit, Tap uses a convention whereby a leading underscore signals auditing is involved.
@@ -274,65 +262,35 @@ When a task completes, it executes it's <tt>on_complete</tt> block to handle the
274
262
 
275
263
  http://tap.rubyforge.org/images/App.png
276
264
 
277
- Instances of Tap::App coordinate the execution of tasks. Apps are basically a subclass of Root with an ExecutableQueue and Aggregator. Task initialization requires an App, which is by default Tap::App.instance. Tasks use their app for logging, checks, and to enque themselves. Normally a script will only need and use a single instance (often Tap::App.instance), but there is no reason why multiple instances could not be used.
265
+ Instances of Tap::App coordinate the execution of tasks. Apps are basically a subclass of Root with an ExecutableQueue, Dependencies, and an Aggregator. Task initialization requires an App, which is by default Tap::App.instance. Tasks use their app for logging, dependency-resolution, checks, and to enque themselves. Normally a script will only need and use a single instance (often Tap::App.instance), but there is no reason why multiple instances could not be used.
278
266
 
279
267
  log = StringIO.new
280
268
  app = Tap::App.instance
281
269
  app.logger = Logger.new(log)
270
+ app.logger.formatter = lambda do |severity, time, progname, msg|
271
+ " %s %s: %s\n" % [severity[0,1], progname, msg]
272
+ end
282
273
 
283
- t = Tap::Task.new
274
+ t = Tap::Task.intern {|task, *inputs| inputs }
284
275
  t.log 'action', 'to app'
285
- log.string # => " I[15:21:23] action to app\n"
276
+ log.string # => " I action: to app\n"
286
277
 
287
278
  t.enq(1)
288
279
  t.enq(2,3)
289
- app.queue.to_a # => [[t, [1]], [t, [2,3]]
290
-
291
- Apps also coordinate the creation of standard workflow patterns like sequence, fork, and merge. These methods set <tt>on_complete</tt> blocks for the input tasks.
292
-
293
- t1 = Tap.task('t1') {|t| 'hellO'}
294
- t2 = Tap.task('t2') {|t, input| input + ' woRld' }
295
- t3 = Tap.task('t3') {|t, input| input.downcase }
296
- t4 = Tap.task('t4') {|t, input| input.upcase }
297
- t5 = Tap.task('t5') {|t, input| input + "!" }
298
-
299
- # sequence t1, t2
300
- app.sequence(t1, t2)
301
280
 
302
- # fork t2 results to t3 and t4
303
- app.fork(t2, t3, t4)
304
-
305
- # unsynchronized merge of t3 and t4 into t5
306
- app.merge(t5, t3, t4)
307
-
308
- app.enq(t1)
281
+ app.queue.to_a # => [[t, [1]], [t, [2,3]]]
309
282
  app.run
283
+ app.results(t) # => [[1], [2,3]]
310
284
 
311
- app.results(t5) # => ["hello world!", "HELLO WORLD!"]
312
-
313
- As shown above, aggregated results may be accessed by task through the <tt>results</tt> method. To access the audited results, use <tt>_results</tt>:
285
+ As shown, apps also aggregate results for tasks, which is important for workflows.
314
286
 
315
- app._results(t5).collect do |_result|
316
- _result.to_s
317
- end.join("---\n")
318
- # =>
319
- # o-[t1] "hellO"
320
- # o-[t2] "hellO woRld"
321
- # o-[t3] "hello world"
322
- # o-[t5] "hello world!"
323
- # ----
324
- # o-[t1] "hellO"
325
- # o-[t2] "hellO woRld"
326
- # o-[t4] "HELLO WORLD"
327
- # o-[t5] "HELLO WORLD!"
328
-
329
287
  == Envs
330
288
 
331
289
  ==== Tap::Env
332
290
 
333
291
  http://tap.rubyforge.org/images/Env.png
334
292
 
335
- Environments are still under construction. Basically a wrapper for a Root, Envs define methods to generate manifests for a type of file-based resource (tasks, generators, etc). Furthermore they provide methods to uniquely identify the resource by path or, more specifically, minimized base paths. In this directory structure:
293
+ Basically a wrapper for a Root, Envs define methods to generate manifests for a type of file-based resource (tasks, generators, etc). Furthermore they provide methods to uniquely identify the resource by path or, more specifically, minimized base paths. In this directory structure:
336
294
 
337
295
  path
338
296
  `- to
@@ -353,10 +311,61 @@ Envs facilitate mapping the minimal path, which might be provided by the command
353
311
 
354
312
  http://tap.rubyforge.org/images/Nested-Env.png
355
313
 
356
- To prevent conflicts between similarly-named resources under two Envs, Env allows selection of Envs, also by minimized paths. At present this is difficult to illustrate in a code snippit.
314
+ To prevent conflicts between similarly-named resources under two Envs, Env allows selection of Envs, also by minimized paths. Say you installed the 'sample_tasks' gem.
315
+
316
+ % tap manifest
317
+ --------------------------------------------------------------------------------
318
+ Desktop: (/Users/username/Desktop)
319
+ --------------------------------------------------------------------------------
320
+ sample_tasks: (/Library/Ruby/Gems/1.8/gems/sample_tasks-0.10.0)
321
+ tasks
322
+ concat (lib/tap/tasks/concat.rb)
323
+ copy (lib/tap/tasks/copy.rb)
324
+ grep (lib/tap/tasks/grep.rb)
325
+ print_tree (lib/tap/tasks/print_tree.rb)
326
+ --------------------------------------------------------------------------------
327
+ tap: (/Library/Ruby/Gems/1.8/gems/tap-0.10.8)
328
+ generators
329
+ command (lib/tap/generator/generators/command/command_generator.rb)
330
+ config (lib/tap/generator/generators/config/config_generator.rb)
331
+ file_task (lib/tap/generator/generators/file_task/file_task_generator.rb)
332
+ generator (lib/tap/generator/generators/generator/generator_generator.rb)
333
+ root (lib/tap/generator/generators/root/root_generator.rb)
334
+ task (lib/tap/generator/generators/task/task_generator.rb)
335
+ commands
336
+ console (cmd/console.rb)
337
+ destroy (cmd/destroy.rb)
338
+ generate (cmd/generate.rb)
339
+ manifest (cmd/manifest.rb)
340
+ run (cmd/run.rb)
341
+ server (cmd/server.rb)
342
+ tasks
343
+ dump (lib/tap/tasks/dump.rb)
344
+ load (lib/tap/tasks/load.rb)
345
+ rake (lib/tap/tasks/rake.rb)
346
+ --------------------------------------------------------------------------------
347
+
348
+ Desktop
349
+ |- sample_tasks
350
+ `- tap
351
+
352
+ In this printout of the manifest, you can see the resources available to tap on the Desktop (none), in the sample_tasks gem, and in tap itself. Since there aren't any conflicts among tasks, the minipath of any of the tasks is sufficient for identification:
353
+
354
+ % tap run -- print_tree
355
+ % tap run -- dump
356
+
357
+ If there were a conflict, you'd have to specify the environment minipath like:
358
+
359
+ % tap run -- sample_tasks:print_tree
360
+ % tap run -- tap:dump
361
+
362
+ Note the same rules apply for rap:
363
+
364
+ % rap print_tree
365
+ % rap tap:dump
366
+
367
+ ==== Tap::Exe
357
368
 
358
- --
359
- ==== Run Env
360
369
  http://tap.rubyforge.org/images/Run-Env.png
361
- ++
362
370
 
371
+ The tap (and rap) executable environment. Tap::Exe adds several configurations (ex before/after) which only get loaded for the present directory, and methods for building and executing workflows from command line inputs. Tap::Exe is a singleton, and is special because it wraps Tap::App.
@@ -1,125 +1,18 @@
1
1
  = Command Reference
2
2
 
3
- The <tt>tap</tt> executable is the gateway for the execution of tasks. To get help for tap, type:
3
+ Tap comes with two executables: tap (a gateway application) and rap (a shortcut for running tasks). The syntax for running tasks via 'tap run' and rap is covered in the {Syntax Reference}[link:files/doc/Syntax%20Reference.html]; this reference covers all of the other tap commands. For help on the command line, type:
4
4
 
5
5
  % tap --help
6
-
7
- <tt>tap</tt> sets up the execution environment from <tt>tap.yml</tt>, if it exists, and passes control to the specified command. Command help can be obtained using:
8
-
9
- % tap [command] --help
10
-
11
- This reference covers the commands: run, console, generate, destroy
12
-
13
- === tap run
14
-
15
- Run configures, enqueues, and executes tasks. Run has a rich syntax allowing the specification of any number of tasks with configurations and inputs, but simplifies under most circumstances. Several examples illustrate the key points:
16
-
17
- % tap run sample/task
18
- % tap run -- sample/task --key=value input_one -- another/task input_two
19
-
20
- The second statement specifies two tasks with inputs, and specifies a configuration for sample/task. As can be seen, run separates tasks using a double-dash, the standard option break. Options for the run command can be specified before the first option break.
21
-
22
- % tap run --debug -- sample/task --key=value
23
-
24
- Here run receives the <tt>--debug</tt> option and sample/task receives the <tt>--key=value</tt> option. NOTE: it's always a good idea to include the first option break to formally signify when configuration of run stops. Otherwise you may be confused when the following commands both produce the help for run:
25
-
26
- % tap run --help
27
- % tap run sample/task --help
28
-
29
- Inputs work the same way. For example:
30
-
31
- % tap run -- sample/task --key=value one -- another/task two three
32
-
33
- Specifies the following:
34
-
35
- t1 = Sample::Task.new(:key => 'value')
36
- t1.enq('one')
37
-
38
- t2 = Another::Task.new
39
- t2.enq('two', 'three')
40
-
41
- Any number of tasks, configurations, and inputs may be specified in this way.
42
-
43
- ==== Task Lookup
44
-
45
- Tap can find and run tasks from multiple environments, for instance from multiple gems. Tap provides a compact way to specify which task to run in the event of a name conflict. The actual process involves minimizing the path to the environment and the relative path to the task file, but from the command line all of the details are hidden:
46
-
47
- % tap run -T
48
- one:
49
- sample/task # some sample task
50
- another/task # another task
51
- two:
52
- sample/task # a conflicting sample task
53
-
54
- In this situation, these commands run the 'one' sample/task:
55
-
56
- % tap run -- sample/task
57
- % tap run -- one:sample/task
58
-
59
- While this runs the 'two' sample/task:
60
-
61
- % tap run -- two::sample/task
62
-
63
- Additionally, base-fragments of the minimized paths can be specified (if laziness strikes); they will be resolved in order from top to bottom within the specified environment.
64
-
65
- Runs the 'one' sample/task:
66
-
67
- % tap run -- task
68
-
69
- Runs the 'two' sample/task:
70
-
71
- % tap run -- two::task
72
-
73
- The full minimized path must be specified for another/task:
74
-
75
- % tap run -- another/task
76
- % tap run -- one:another/task
77
-
78
- ==== Rounds
79
6
 
80
- Run allows specification of a number of rounds of tasks. All tasks in a round are run to completion before the next round begins. Rounds are specified by adding '+' characters after the double-dash task break.
7
+ === configuration
81
8
 
82
- % tap run -- round_one_task --+ round_two_task
9
+ Tap sets up the local execution environment from 'tap.yml', if it exists. The config file is, as the extension implies, a YAML file and will be automatically created by the root generator. Naturally, you can create it yourself. See Tap::Env and Tap::Exe for a list of the available configurations.
83
10
 
84
- Tasks may be added to rounds in any order. This is equivalent to the last:
11
+ In addition, default configurations may be specified in the global configuration file '~/.tap.yml', where '~' is evaluated as Gem.user_home.
85
12
 
86
- % tap run --+ round_two_task -- round_one_task
13
+ == tap console
87
14
 
88
- Rounds are particularly useful for dump tasks; add a dump task as a final round to capture all results from previous rounds:
89
-
90
- % tap run -- task -- task --+ dump
91
-
92
- ==== YAML inputs
93
-
94
- Non-string inputs can be provided through run. If an input begins with "---\n" then it is loaded as YAML into an object before being passed to a task. The syntax can be a lot to type, but is very handy to have around. The following enques sample/task with a hash input, {'number' => 1}.
95
-
96
- On *nix, just hit enter to get the next line:
97
-
98
- % tap run -- sample/task '---
99
- > number: 1'
100
-
101
- On Windows, you need to pull some tricks to get newlines into your argument. Cleverly use a caret to ignore the next line feed:
102
-
103
- % tap run -- sample/task '---^
104
- More?
105
- More? number: 1'
106
-
107
- Notice that pressing enter <em>every other line</em> is what actually puts the "\n" into the parameter. Keep using carets to enter more lines. The syntax on Windows isn't exactly pretty, and it only works with a caveat: the latest execution script generated by rubygems (tap.bat) re-processes inputs to tap before executing the command for real. I haven't found a workaround short of invoking tap from ruby itself:
108
-
109
- % ruby C:/ruby/bin/tap run -- sample/task '---^
110
- More?
111
- More? number: 1'
112
-
113
- In these cases, consider putting the inputs into a file and load them to the command line with the <tt>--use</tt> option:
114
-
115
- [inputs.yml]
116
- number: 1
117
-
118
- % tap run -- sample/task --use inputs.yml
119
-
120
- === tap console
121
-
122
- Console opens an irb session with Tap loaded and configured using <tt>tap.yml</tt>. Console defines variables 'app' and 'env' referencing Tap::App.instance and Tap::Env.instance, for easy access.
15
+ Console opens an irb session after loading the tap environment. Console defines variables 'app' and 'env' referencing Tap::App.instance and Tap::Env.instance, for easy access.
123
16
 
124
17
  % tap console
125
18
  irb(main):001:0> app.log(:hello)
@@ -127,20 +20,16 @@ Console opens an irb session with Tap loaded and configured using <tt>tap.yml</t
127
20
  => true
128
21
  irb(main):002:0>
129
22
 
130
- === tap generate/destroy
23
+ == tap generate/destroy
131
24
 
132
- Generate and destory launch generator scripts, similar to those in Rails. By default Tap provides generators for:
25
+ Generate and destory launch generator scripts, similar to those in {Rails}[http://www.rubyonrails.org/]. By default Tap provides generators for:
133
26
 
134
- {root}[link:classes/Tap/Generator/Generators/RootGenerator.html]:: the basic Tap directory structure
135
- {task}[link:classes/Tap/Generator/Generators/TaskGenerator.html]:: a Tap::Task and test
136
- {file_task}[link:classes/Tap/Generator/Generators/FileTaskGenerator.html]:: a Tap::FileTask and test
137
- {config}[link:classes/Tap/Generator/Generators/ConfigGenerator.html]:: a yaml config file for the specified task
138
27
  {command}[link:classes/Tap/Generator/Generators/CommandGenerator.html]:: a new command
139
-
140
- --
141
- {generator}[link:classes/Tap/Generator/GeneratorseneratorGenerator.html]:: a new generator
142
- {workflow}[link:classes/Tap/Generator/Generators/Workflow/WorkflowGenerator.html]:: a Tap::Workflow and test
143
- ++
28
+ {config}[link:classes/Tap/Generator/Generators/ConfigGenerator.html]:: a static config file for the specified task
29
+ {file_task}[link:classes/Tap/Generator/Generators/FileTaskGenerator.html]:: a file task and test
30
+ {generator}[link:classes/Tap/Generator/Generators/GeneratorGenerator.html]:: a new generator
31
+ {root}[link:classes/Tap/Generator/Generators/RootGenerator.html]:: the basic directory structure
32
+ {task}[link:classes/Tap/Generator/Generators/TaskGenerator.html]:: a task class and test
144
33
 
145
34
  For example:
146
35
 
@@ -151,3 +40,66 @@ For example:
151
40
  % tap destroy config sample_task
152
41
  % tap destroy task sample_task
153
42
  % tap destroy root .
43
+
44
+ Each generator works a little differently. For help:
45
+
46
+ % tap generate --help
47
+ % tap generate <generator> --help
48
+
49
+ == tap manifest
50
+
51
+ Manifest prints a list of all resources (commands, tasks, generators, etc) available to tap. Environments are listed in the same order as they are searched, and at the end a tree diagram is printed showing how the environments are nested.
52
+
53
+ % tap manifest
54
+ --------------------------------------------------------------------------------
55
+ Desktop: (/Users/username/Desktop)
56
+ --------------------------------------------------------------------------------
57
+ tap: (/Library/Ruby/Gems/1.8/gems/tap-0.10.8)
58
+ generators
59
+ command (lib/tap/generator/generators/command/command_generator.rb)
60
+ config (lib/tap/generator/generators/config/config_generator.rb)
61
+ file_task (lib/tap/generator/generators/file_task/file_task_generator.rb)
62
+ generator (lib/tap/generator/generators/generator/generator_generator.rb)
63
+ root (lib/tap/generator/generators/root/root_generator.rb)
64
+ task (lib/tap/generator/generators/task/task_generator.rb)
65
+ commands
66
+ console (cmd/console.rb)
67
+ destroy (cmd/destroy.rb)
68
+ generate (cmd/generate.rb)
69
+ manifest (cmd/manifest.rb)
70
+ run (cmd/run.rb)
71
+ tasks
72
+ dump (lib/tap/tasks/dump.rb)
73
+ load (lib/tap/tasks/load.rb)
74
+ rake (lib/tap/tasks/rake.rb)
75
+ --------------------------------------------------------------------------------
76
+
77
+ Desktop
78
+ `- tap
79
+
80
+ == tap run
81
+
82
+ Run configures, enqueues, and executes tasks. Run has a rich syntax allowing the specification of any number of tasks with configurations and inputs, but simplifies under most circumstances. The run syntax is detailed in the {Syntax Reference}[link:files/doc/Syntax%20Reference.html], but a couple examples illustrate the key points:
83
+
84
+ % tap run sample/task
85
+ % tap run -- sample/task --key=value input_one -- another/task input_two
86
+
87
+ The second statement specifies two tasks with inputs, and specifies a configuration for sample/task. As can be seen, run separates tasks using a double-dash, the standard option break. Options for the run command can be specified before the first break.
88
+
89
+ % tap run --debug -- sample/task --key=value
90
+
91
+ Here run receives the <tt>--debug</tt> option and sample/task receives the <tt>--key=value</tt> option. Inputs work the same way. For example:
92
+
93
+ % tap run -- sample/task --key=value one -- another/task two three
94
+
95
+ Specifies the following:
96
+
97
+ Sample::Task.new(:key => 'value').enq('one')
98
+ Another::Task.new.enq('two', 'three')
99
+
100
+ Any number of tasks, configurations, and inputs may be specified in this way.
101
+
102
+ --
103
+ == tap server
104
+
105
+ An experimental local server for tap tasks.