bahuvrihi-tap 0.10.7 → 0.10.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/MIT-LICENSE +0 -2
  2. data/README +20 -31
  3. data/bin/rap +18 -8
  4. data/cgi/run.rb +47 -37
  5. data/cmd/console.rb +1 -1
  6. data/cmd/destroy.rb +3 -3
  7. data/cmd/generate.rb +3 -3
  8. data/cmd/manifest.rb +61 -53
  9. data/cmd/run.rb +1 -1
  10. data/doc/Class Reference +119 -110
  11. data/doc/Command Reference +76 -123
  12. data/doc/Syntax Reference +290 -0
  13. data/doc/Tutorial +307 -237
  14. data/lib/tap.rb +1 -12
  15. data/lib/tap/app.rb +46 -71
  16. data/lib/tap/constants.rb +1 -1
  17. data/lib/tap/declarations.rb +110 -100
  18. data/lib/tap/env.rb +141 -173
  19. data/lib/tap/exe.rb +5 -5
  20. data/lib/tap/file_task.rb +2 -2
  21. data/lib/tap/generator/base.rb +0 -4
  22. data/lib/tap/generator/destroy.rb +8 -12
  23. data/lib/tap/generator/generate.rb +19 -14
  24. data/lib/tap/generator/generators/command/command_generator.rb +1 -1
  25. data/lib/tap/generator/generators/config/config_generator.rb +3 -3
  26. data/lib/tap/generator/generators/file_task/file_task_generator.rb +1 -1
  27. data/lib/tap/generator/generators/generator/generator_generator.rb +27 -0
  28. data/lib/tap/generator/generators/generator/templates/task.erb +27 -0
  29. data/lib/tap/generator/generators/root/root_generator.rb +12 -12
  30. data/lib/tap/generator/generators/root/templates/Rakefile +1 -2
  31. data/lib/tap/generator/generators/root/templates/tapfile +11 -8
  32. data/lib/tap/generator/generators/task/task_generator.rb +1 -3
  33. data/lib/tap/generator/generators/task/templates/test.erb +1 -3
  34. data/lib/tap/root.rb +4 -2
  35. data/lib/tap/support/aggregator.rb +16 -3
  36. data/lib/tap/support/assignments.rb +10 -9
  37. data/lib/tap/support/audit.rb +58 -62
  38. data/lib/tap/support/class_configuration.rb +32 -43
  39. data/lib/tap/support/combinator.rb +7 -7
  40. data/lib/tap/support/configurable.rb +13 -14
  41. data/lib/tap/support/configurable_class.rb +6 -30
  42. data/lib/tap/support/configuration.rb +36 -9
  43. data/lib/tap/support/constant.rb +75 -13
  44. data/lib/tap/support/constant_manifest.rb +115 -0
  45. data/lib/tap/support/dependencies.rb +27 -67
  46. data/lib/tap/support/dependency.rb +44 -0
  47. data/lib/tap/support/executable.rb +78 -109
  48. data/lib/tap/support/executable_queue.rb +1 -1
  49. data/lib/tap/support/gems.rb +6 -0
  50. data/lib/tap/support/gems/rack.rb +197 -84
  51. data/lib/tap/support/instance_configuration.rb +29 -3
  52. data/lib/tap/support/intern.rb +46 -0
  53. data/lib/tap/support/join.rb +67 -11
  54. data/lib/tap/support/joins.rb +2 -0
  55. data/lib/tap/support/joins/fork.rb +1 -0
  56. data/lib/tap/support/joins/merge.rb +3 -1
  57. data/lib/tap/support/joins/sequence.rb +2 -2
  58. data/lib/tap/support/joins/switch.rb +3 -1
  59. data/lib/tap/support/joins/sync_merge.rb +6 -0
  60. data/lib/tap/support/lazy_attributes.rb +16 -1
  61. data/lib/tap/support/lazydoc.rb +21 -21
  62. data/lib/tap/support/lazydoc/comment.rb +59 -55
  63. data/lib/tap/support/lazydoc/definition.rb +36 -0
  64. data/lib/tap/support/lazydoc/document.rb +37 -13
  65. data/lib/tap/support/manifest.rb +120 -131
  66. data/lib/tap/support/minimap.rb +90 -0
  67. data/lib/tap/support/node.rb +4 -6
  68. data/lib/tap/support/parser.rb +63 -6
  69. data/lib/tap/support/schema.rb +11 -2
  70. data/lib/tap/support/shell_utils.rb +3 -5
  71. data/lib/tap/support/string_ext.rb +60 -0
  72. data/lib/tap/support/tdoc.rb +2 -2
  73. data/lib/tap/support/templater.rb +29 -15
  74. data/lib/tap/support/validation.rb +22 -11
  75. data/lib/tap/task.rb +155 -156
  76. data/lib/tap/tasks/load.rb +95 -8
  77. data/lib/tap/test/extensions.rb +2 -1
  78. data/lib/tap/test/script_tester.rb +7 -1
  79. data/template/index.erb +39 -32
  80. metadata +13 -13
  81. data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +0 -15
  82. data/lib/tap/patches/rake/rake_test_loader.rb +0 -8
  83. data/lib/tap/patches/rake/testtask.rb +0 -57
  84. data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -51
  85. data/lib/tap/patches/ruby19/parsedate.rb +0 -16
  86. data/lib/tap/spec.rb +0 -42
  87. data/lib/tap/spec/adapter.rb +0 -25
  88. data/lib/tap/spec/inheritable_class_test_root.rb +0 -9
  89. data/lib/tap/support/constant_utils.rb +0 -127
  90. data/lib/tap/support/summary.rb +0 -30
@@ -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
 
@@ -93,16 +87,10 @@ Validation blocks sometimes imply metadata. For instance <tt>c.flag</tt> makes
93
87
 
94
88
  ==== Tap::Support::Lazydoc
95
89
 
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:
90
+ 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
91
 
100
92
  # ::key value
101
93
 
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
94
  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
95
 
108
96
  [lazydoc_file.rb]
@@ -126,7 +114,7 @@ Lazydoc parses a constant name, the key, the value, and any comment following th
126
114
  lazydoc['Name::Space']['key'].to_s # => "This documentation gets parsed."
127
115
  lazydoc['Name::Space']['another'].subject # => "another value"
128
116
 
129
- Furthermore, Lazydoc allows living code to register lines that should get documented. These lines are parsed to echo what happens in RDoc.
117
+ Furthermore, Lazydoc can register specific lines for documentation. These lines are parsed to echo what happens in RDoc.
130
118
 
131
119
  [another_lazydoc_file.rb]
132
120
  # documentation
@@ -145,7 +133,7 @@ Furthermore, Lazydoc allows living code to register lines that should get docume
145
133
 
146
134
  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
135
 
148
- One note: when no constant name is specified for a Lazydoc key, it gets treated as a default for the whole file.
136
+ When no constant name is specified for a Lazydoc key, Env uses a constant based on the file name.
149
137
 
150
138
  [lib/sample/task.rb]
151
139
  # ::manifest sample task description
@@ -160,67 +148,67 @@ However, the best practice is to include the namespace explicitly.
160
148
 
161
149
  http://tap.rubyforge.org/images/Task.png
162
150
 
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.
151
+ 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
152
 
165
- Task instances can take a block that acts as a stand-in for <tt>process</tt>:
153
+ Task instances may be interned with a block that acts as a stand-in for <tt>process</tt>:
166
154
 
167
- t = Tap::Task.new {|task| 1 + 2 }
155
+ t = Tap::Task.intern {|task| 1 + 2 }
168
156
  t.process # => 3
169
157
 
170
- t = Tap::Task.new {|task, x, y| x + y }
158
+ t = Tap::Task.intern {|task, x, y| x + y }
171
159
  t.process(1, 2) # => 3
172
-
173
- Tasks can be configured:
174
160
 
175
- t1 = Tap::Task.new(:key => 'one') {|task, input| "#{input}:#{task.config[:key]}"}
176
- t1.process('str') # => "str:one"
177
-
178
- And batched:
161
+ Tasks can be configured,
179
162
 
180
- t2 = t1.initialize_batch_obj(:key => 'two')
181
- t3 = t1.initialize_batch_obj(:key => 'three')
163
+ runlist = []
164
+ t1 = Tap::Task.intern(:key => 'one') do |task, input|
165
+ runlist << task
166
+ "#{input}:#{task.config[:key]}"
167
+ end
182
168
 
183
- t1.batch # => [t1, t2, t3]
169
+ joined into dependency-based workflows,
184
170
 
185
- Batched tasks enque together, and therefore run sequentially with the same inputs:
171
+ t0 = Tap::Task.intern {|task| runlist << task }
172
+ t1.depends_on(t0)
186
173
 
187
- app = Tap::App.instance
188
- app.enq(t1, 'str')
189
- app.queue.to_a # => [[t1, ['str']], [t2, ['str']], [t3, ['str']]]
190
- app.run
174
+ imperative workflows,
191
175
 
192
- app.results(t1) # => ["str:one"]
193
- app.results(t2) # => ["str:two"]
194
- app.results(t3) # => ["str:three"]
176
+ t2 = Tap::Task.intern do |task, input|
177
+ runlist << task
178
+ "#{input}:two"
179
+ end
180
+ t1.sequence(t2)
181
+
182
+ and batched.
195
183
 
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):
184
+ t3 = t1.initialize_batch_obj(:key => 'three')
185
+ t1.batch # => [t1, t3]
186
+
187
+ Batched tasks enque together, and therefore execute sequentially with the same inputs. Results are aggregated into the underlying Tap::App.
197
188
 
198
- t1.name = 'task one'
199
- t2.name = 'task two'
200
- t3.name = 'task three'
189
+ t1.execute('input')
190
+ runlist # => [t0, t1, t2, t3, t2]
201
191
 
202
- app._results(t1,t2,t3).collect do |_result|
192
+ app = Tap::App.instance
193
+ app.results(t2) # => ["input:one:two", "input:three:two"]
194
+
195
+ 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:
196
+
197
+ t1.name = 'un'
198
+ t2.name = 'deux'
199
+ t3.name = 'trois'
200
+
201
+ app._results(t2).collect do |_result|
203
202
  _result.to_s
204
203
  end.join("---\n")
205
204
  # =>
206
- # o-[] 1
207
- # o-[task one] "str:one"
208
- # ---
209
- # o-[] 1
210
- # o-[task two] "str:two"
205
+ # o-[] "input"
206
+ # o-[un] "input:one"
207
+ # o-[deux] "input:one:two"
211
208
  # ---
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.
209
+ # o-[] "input"
210
+ # o-[trois] "input:three"
211
+ # o-[deux] "input:three:two"
224
212
 
225
213
  == Apps
226
214
 
@@ -235,7 +223,7 @@ A Root represents the base of a directory structure. Roots allow you to alias di
235
223
  root['config'] # => '/path/to/root/config'
236
224
  root.filepath('config', 'sample.yml') # => '/path/to/root/config/sampl.yml'
237
225
 
238
- While simple, this ability to reference files using aliases is useful, powerful, and forms the basis of the Tap execution environment.
226
+ While simple, this ability to alias paths is useful, powerful, and forms the basis of the Tap execution environment.
239
227
 
240
228
  ==== Tap::Support::ExecutableQueue
241
229
 
@@ -243,16 +231,19 @@ http://tap.rubyforge.org/images/ExecutableQueue.png
243
231
 
244
232
  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
233
 
234
+ ==== Tap::Support::Dependencies
235
+
236
+ Dependencies coordinate the registration and resolution of dependencies, which may be shared across multiple tasks.
237
+
246
238
  ==== Tap::Support::Audit
247
239
 
248
- 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.
240
+ 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.
249
241
 
250
242
  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.
251
243
 
252
- t = Task.new
253
- t.on_complete do |_result| # _result is an Audit instance
254
- _result._current # the current value
255
- _result._original # the original value
244
+ Task.new.on_complete do |_result| # _result is an Audit instance
245
+ _result._current # the current value
246
+ _result._original # the original value
256
247
  end
257
248
 
258
249
  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.
@@ -265,65 +256,32 @@ When a task completes, it executes it's <tt>on_complete</tt> block to handle the
265
256
 
266
257
  http://tap.rubyforge.org/images/App.png
267
258
 
268
- 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.
259
+ 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.
269
260
 
270
261
  log = StringIO.new
271
262
  app = Tap::App.instance
272
263
  app.logger = Logger.new(log)
273
264
 
274
- t = Tap::Task.new
265
+ t = Tap::Task.intern {|task, *inputs| inputs }
275
266
  t.log 'action', 'to app'
276
267
  log.string # => " I[15:21:23] action to app\n"
277
268
 
278
269
  t.enq(1)
279
270
  t.enq(2,3)
280
- app.queue.to_a # => [[t, [1]], [t, [2,3]]
281
-
282
- 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.
283
-
284
- t1 = Tap.task('t1') {|t| 'hellO'}
285
- t2 = Tap.task('t2') {|t, input| input + ' woRld' }
286
- t3 = Tap.task('t3') {|t, input| input.downcase }
287
- t4 = Tap.task('t4') {|t, input| input.upcase }
288
- t5 = Tap.task('t5') {|t, input| input + "!" }
289
-
290
- # sequence t1, t2
291
- app.sequence(t1, t2)
292
-
293
- # fork t2 results to t3 and t4
294
- app.fork(t2, t3, t4)
295
-
296
- # unsynchronized merge of t3 and t4 into t5
297
- app.merge(t5, t3, t4)
298
271
 
299
- app.enq(t1)
272
+ app.queue.to_a # => [[t, [1]], [t, [2,3]]
300
273
  app.run
274
+ app.results(t) # => [[1], [2,3]]
301
275
 
302
- app.results(t5) # => ["hello world!", "HELLO WORLD!"]
303
-
304
- 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>:
276
+ As shown, apps also aggregate results for tasks, which is important for workflows.
305
277
 
306
- app._results(t5).collect do |_result|
307
- _result.to_s
308
- end.join("---\n")
309
- # =>
310
- # o-[t1] "hellO"
311
- # o-[t2] "hellO woRld"
312
- # o-[t3] "hello world"
313
- # o-[t5] "hello world!"
314
- # ----
315
- # o-[t1] "hellO"
316
- # o-[t2] "hellO woRld"
317
- # o-[t4] "HELLO WORLD"
318
- # o-[t5] "HELLO WORLD!"
319
-
320
278
  == Envs
321
279
 
322
280
  ==== Tap::Env
323
281
 
324
282
  http://tap.rubyforge.org/images/Env.png
325
283
 
326
- 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:
284
+ 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:
327
285
 
328
286
  path
329
287
  `- to
@@ -344,10 +302,61 @@ Envs facilitate mapping the minimal path, which might be provided by the command
344
302
 
345
303
  http://tap.rubyforge.org/images/Nested-Env.png
346
304
 
347
- 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.
305
+ 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.
306
+
307
+ % tap manifest
308
+ --------------------------------------------------------------------------------
309
+ Desktop: (/Users/username/Desktop)
310
+ --------------------------------------------------------------------------------
311
+ sample_tasks: (/Library/Ruby/Gems/1.8/gems/sample_tasks-0.10.0)
312
+ tasks
313
+ concat (lib/tap/tasks/concat.rb)
314
+ copy (lib/tap/tasks/copy.rb)
315
+ grep (lib/tap/tasks/grep.rb)
316
+ print_tree (lib/tap/tasks/print_tree.rb)
317
+ --------------------------------------------------------------------------------
318
+ tap: (/Library/Ruby/Gems/1.8/gems/tap-0.10.8)
319
+ generators
320
+ command (lib/tap/generator/generators/command/command_generator.rb)
321
+ config (lib/tap/generator/generators/config/config_generator.rb)
322
+ file_task (lib/tap/generator/generators/file_task/file_task_generator.rb)
323
+ generator (lib/tap/generator/generators/generator/generator_generator.rb)
324
+ root (lib/tap/generator/generators/root/root_generator.rb)
325
+ task (lib/tap/generator/generators/task/task_generator.rb)
326
+ commands
327
+ console (cmd/console.rb)
328
+ destroy (cmd/destroy.rb)
329
+ generate (cmd/generate.rb)
330
+ manifest (cmd/manifest.rb)
331
+ run (cmd/run.rb)
332
+ server (cmd/server.rb)
333
+ tasks
334
+ dump (lib/tap/tasks/dump.rb)
335
+ load (lib/tap/tasks/load.rb)
336
+ rake (lib/tap/tasks/rake.rb)
337
+ --------------------------------------------------------------------------------
338
+
339
+ Desktop
340
+ |- sample_tasks
341
+ `- tap
342
+
343
+ 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:
344
+
345
+ % tap run -- print_tree
346
+ % tap run -- dump
347
+
348
+ If there were a conflict, you'd have to specify the environment minipath like:
349
+
350
+ % tap run -- sample_tasks:print_tree
351
+ % tap run -- tap:dump
352
+
353
+ Note the same rules apply for rap:
354
+
355
+ % rap print_tree
356
+ % rap tap:dump
357
+
358
+ ==== Tap::Exe
348
359
 
349
- --
350
- ==== Run Env
351
360
  http://tap.rubyforge.org/images/Run-Env.png
352
- ++
353
361
 
362
+ 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
- --
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
141
30
  {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
- ++
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,67 @@ 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
+ server (cmd/server.rb)
72
+ tasks
73
+ dump (lib/tap/tasks/dump.rb)
74
+ load (lib/tap/tasks/load.rb)
75
+ rake (lib/tap/tasks/rake.rb)
76
+ --------------------------------------------------------------------------------
77
+
78
+ Desktop
79
+ `- tap
80
+
81
+ == tap run
82
+
83
+ 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:
84
+
85
+ % tap run sample/task
86
+ % tap run -- sample/task --key=value input_one -- another/task input_two
87
+
88
+ 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.
89
+
90
+ % tap run --debug -- sample/task --key=value
91
+
92
+ 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:
93
+
94
+ % tap run -- sample/task --key=value one -- another/task two three
95
+
96
+ Specifies the following:
97
+
98
+ Sample::Task.new(:key => 'value').enq('one')
99
+ Another::Task.new.enq('two', 'three')
100
+
101
+ Any number of tasks, configurations, and inputs may be specified in this way.
102
+
103
+ --
104
+ == tap server
105
+
106
+ An experimental local server for tap tasks.