tap 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +12 -0
- data/MIT-LICENSE +0 -2
- data/README +23 -32
- data/bin/rap +116 -0
- data/bin/tap +6 -9
- data/cgi/run.rb +67 -0
- data/cmd/console.rb +1 -1
- data/cmd/destroy.rb +4 -4
- data/cmd/generate.rb +4 -4
- data/cmd/manifest.rb +61 -53
- data/cmd/run.rb +8 -75
- data/doc/Class Reference +130 -121
- data/doc/Command Reference +76 -124
- data/doc/Syntax Reference +290 -0
- data/doc/Tutorial +305 -237
- data/lib/tap/app.rb +140 -467
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/declarations.rb +211 -0
- data/lib/tap/env.rb +171 -193
- data/lib/tap/exe.rb +100 -21
- data/lib/tap/file_task.rb +3 -3
- data/lib/tap/generator/base.rb +1 -1
- data/lib/tap/generator/destroy.rb +10 -10
- data/lib/tap/generator/generate.rb +29 -18
- data/lib/tap/generator/generators/command/command_generator.rb +2 -2
- data/lib/tap/generator/generators/command/templates/command.erb +2 -2
- data/lib/tap/generator/generators/config/config_generator.rb +3 -3
- data/lib/tap/generator/generators/config/templates/doc.erb +1 -1
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +1 -1
- data/lib/tap/generator/generators/file_task/templates/task.erb +1 -1
- data/lib/tap/generator/generators/file_task/templates/test.erb +1 -1
- data/lib/tap/generator/generators/generator/generator_generator.rb +27 -0
- data/lib/tap/generator/generators/generator/templates/task.erb +27 -0
- data/lib/tap/generator/generators/root/root_generator.rb +13 -13
- data/lib/tap/generator/generators/root/templates/README +0 -0
- data/lib/tap/generator/generators/root/templates/Rakefile +2 -2
- data/lib/tap/generator/generators/root/templates/gemspec +4 -5
- data/lib/tap/generator/generators/root/templates/tapfile +11 -8
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
- data/lib/tap/generator/generators/task/task_generator.rb +1 -3
- data/lib/tap/generator/generators/task/templates/test.erb +1 -3
- data/lib/tap/patches/optparse/summarize.rb +62 -0
- data/lib/tap/root.rb +41 -29
- data/lib/tap/support/aggregator.rb +16 -3
- data/lib/tap/support/assignments.rb +10 -9
- data/lib/tap/support/audit.rb +58 -64
- data/lib/tap/support/class_configuration.rb +33 -44
- data/lib/tap/support/combinator.rb +125 -0
- data/lib/tap/support/configurable.rb +13 -14
- data/lib/tap/support/configurable_class.rb +21 -43
- data/lib/tap/support/configuration.rb +55 -9
- data/lib/tap/support/constant.rb +87 -13
- data/lib/tap/support/constant_manifest.rb +116 -0
- data/lib/tap/support/dependencies.rb +54 -0
- data/lib/tap/support/dependency.rb +44 -0
- data/lib/tap/support/executable.rb +247 -32
- data/lib/tap/support/executable_queue.rb +1 -1
- data/lib/tap/support/gems/rake.rb +29 -8
- data/lib/tap/support/gems.rb +10 -30
- data/lib/tap/support/instance_configuration.rb +29 -3
- data/lib/tap/support/intern.rb +46 -0
- data/lib/tap/support/join.rb +143 -0
- data/lib/tap/support/joins/fork.rb +19 -0
- data/lib/tap/support/joins/merge.rb +22 -0
- data/lib/tap/support/joins/sequence.rb +21 -0
- data/lib/tap/support/joins/switch.rb +25 -0
- data/lib/tap/support/joins/sync_merge.rb +63 -0
- data/lib/tap/support/joins.rb +15 -0
- data/lib/tap/support/lazy_attributes.rb +17 -2
- data/lib/tap/support/lazydoc/comment.rb +503 -0
- data/lib/tap/support/lazydoc/config.rb +17 -0
- data/lib/tap/support/lazydoc/definition.rb +36 -0
- data/lib/tap/support/lazydoc/document.rb +152 -0
- data/lib/tap/support/lazydoc/method.rb +24 -0
- data/lib/tap/support/lazydoc.rb +269 -343
- data/lib/tap/support/manifest.rb +121 -103
- data/lib/tap/support/minimap.rb +90 -0
- data/lib/tap/support/node.rb +56 -0
- data/lib/tap/support/parser.rb +436 -0
- data/lib/tap/support/schema.rb +359 -0
- data/lib/tap/support/shell_utils.rb +3 -5
- data/lib/tap/support/string_ext.rb +60 -0
- data/lib/tap/support/tdoc.rb +7 -2
- data/lib/tap/support/templater.rb +30 -16
- data/lib/tap/support/validation.rb +77 -8
- data/lib/tap/task.rb +431 -143
- data/lib/tap/tasks/dump.rb +15 -10
- data/lib/tap/tasks/load.rb +112 -0
- data/lib/tap/tasks/rake.rb +4 -41
- data/lib/tap/test/assertions.rb +38 -0
- data/lib/tap/test/env_vars.rb +1 -1
- data/lib/tap/test/extensions.rb +79 -0
- data/lib/tap/test/file_test.rb +420 -0
- data/lib/tap/test/file_test_class.rb +12 -0
- data/lib/tap/test/regexp_escape.rb +87 -0
- data/lib/tap/test/script_test.rb +46 -0
- data/lib/tap/test/script_tester.rb +115 -0
- data/lib/tap/test/subset_test.rb +260 -0
- data/lib/tap/test/subset_test_class.rb +99 -0
- data/lib/tap/test/{tap_methods.rb → tap_test.rb} +45 -43
- data/lib/tap/test/utils.rb +231 -0
- data/lib/tap/test.rb +53 -26
- data/lib/tap.rb +3 -20
- metadata +50 -27
- data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +0 -15
- data/lib/tap/patches/rake/rake_test_loader.rb +0 -8
- data/lib/tap/patches/rake/testtask.rb +0 -57
- data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -51
- data/lib/tap/patches/ruby19/parsedate.rb +0 -16
- data/lib/tap/support/batchable.rb +0 -47
- data/lib/tap/support/batchable_class.rb +0 -107
- data/lib/tap/support/command_line.rb +0 -98
- data/lib/tap/support/comment.rb +0 -270
- data/lib/tap/support/constant_utils.rb +0 -127
- data/lib/tap/support/declarations.rb +0 -111
- data/lib/tap/support/framework.rb +0 -83
- data/lib/tap/support/framework_class.rb +0 -180
- data/lib/tap/support/run_error.rb +0 -39
- data/lib/tap/support/summary.rb +0 -30
- data/lib/tap/test/file_methods.rb +0 -377
- data/lib/tap/test/script_methods/script_test.rb +0 -98
- data/lib/tap/test/script_methods.rb +0 -107
- data/lib/tap/test/subset_methods.rb +0 -420
- data/lib/tap/workflow.rb +0 -200
data/doc/Class Reference
CHANGED
@@ -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
|
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
|
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>
|
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
|
-
|
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'].
|
119
|
+
lazydoc['Name::Space']['another'].value # => "another value"
|
128
120
|
|
129
|
-
Furthermore, Lazydoc
|
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
|
-
|
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
|
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
|
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.
|
159
|
+
t = Tap::Task.intern {|task| 1 + 2 }
|
168
160
|
t.process # => 3
|
169
161
|
|
170
|
-
t = Tap::Task.
|
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
|
-
|
176
|
-
t1.process('str') # => "str:one"
|
177
|
-
|
178
|
-
And batched:
|
165
|
+
Tasks can be configured,
|
179
166
|
|
180
|
-
|
181
|
-
|
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
|
-
|
173
|
+
joined into dependency-based workflows,
|
184
174
|
|
185
|
-
|
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
|
-
|
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 = '
|
199
|
-
t2.name = '
|
200
|
-
t3.name = '
|
203
|
+
t1.name = 'un'
|
204
|
+
t2.name = 'deux'
|
205
|
+
t3.name = 'trois'
|
201
206
|
|
202
|
-
app._results(
|
203
|
-
_result.
|
207
|
+
app._results(t2).collect do |_result|
|
208
|
+
_result._to_s
|
204
209
|
end.join("---\n")
|
205
210
|
# =>
|
206
|
-
# o-[]
|
207
|
-
# o-[
|
211
|
+
# o-[] "input"
|
212
|
+
# o-[un] "input:one"
|
213
|
+
# o-[deux] "input:one:two"
|
208
214
|
# ---
|
209
|
-
# o-[]
|
210
|
-
# o-[
|
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/
|
230
|
+
root.filepath('config', 'sample.yml') # => '/path/to/root/config/sample.yml'
|
237
231
|
|
238
|
-
While simple, this ability to
|
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
|
-
|
240
|
+
==== Tap::Support::Dependencies
|
247
241
|
|
248
|
-
|
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
|
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
|
-
|
262
|
-
|
263
|
-
_result.
|
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.
|
274
|
+
t = Tap::Task.intern {|task, *inputs| inputs }
|
284
275
|
t.log 'action', 'to app'
|
285
|
-
log.string # => " I
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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.
|
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.
|
data/doc/Command Reference
CHANGED
@@ -1,125 +1,18 @@
|
|
1
1
|
= Command Reference
|
2
2
|
|
3
|
-
The
|
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
|
-
|
7
|
+
=== configuration
|
81
8
|
|
82
|
-
|
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
|
-
|
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
|
-
|
13
|
+
== tap console
|
87
14
|
|
88
|
-
|
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
|
-
|
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/
|
142
|
-
{
|
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.
|