tap 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +35 -1
- data/MIT-LICENSE +1 -1
- data/README +16 -15
- data/bin/tap +1 -1
- data/cmd/console.rb +4 -3
- data/cmd/manifest.rb +2 -2
- data/cmd/run.rb +12 -15
- data/doc/Class Reference +120 -117
- data/doc/Command Reference +27 -27
- data/doc/Syntax Reference +55 -111
- data/doc/Tutorial +69 -26
- data/lib/tap.rb +3 -8
- data/lib/tap/app.rb +122 -146
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/env.rb +178 -252
- data/lib/tap/exe.rb +67 -30
- data/lib/tap/file_task.rb +224 -411
- data/lib/tap/generator/arguments.rb +13 -0
- data/lib/tap/generator/base.rb +112 -30
- data/lib/tap/generator/destroy.rb +36 -13
- data/lib/tap/generator/generate.rb +69 -48
- data/lib/tap/generator/generators/command/templates/command.erb +3 -3
- data/lib/tap/generator/generators/config/config_generator.rb +82 -10
- data/lib/tap/generator/generators/generator/generator_generator.rb +16 -6
- data/lib/tap/generator/generators/generator/templates/task.erb +2 -2
- data/lib/tap/generator/generators/generator/templates/test.erb +26 -0
- data/lib/tap/generator/generators/root/root_generator.rb +24 -13
- data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
- data/lib/tap/generator/generators/root/templates/{tapfile → Rapfile} +6 -6
- data/lib/tap/generator/generators/root/templates/gemspec +0 -1
- data/lib/tap/generator/generators/task/task_generator.rb +3 -3
- data/lib/tap/generator/generators/task/templates/test.erb +1 -1
- data/lib/tap/generator/manifest.rb +7 -1
- data/lib/tap/generator/preview.rb +76 -0
- data/lib/tap/root.rb +222 -156
- data/lib/tap/spec.rb +41 -0
- data/lib/tap/support/aggregator.rb +25 -28
- data/lib/tap/support/audit.rb +278 -357
- data/lib/tap/support/constant.rb +2 -1
- data/lib/tap/support/constant_manifest.rb +28 -25
- data/lib/tap/support/dependency.rb +1 -1
- data/lib/tap/support/executable.rb +52 -183
- data/lib/tap/support/executable_queue.rb +50 -20
- data/lib/tap/support/gems.rb +1 -1
- data/lib/tap/support/intern.rb +0 -6
- data/lib/tap/support/join.rb +49 -83
- data/lib/tap/support/joins.rb +0 -3
- data/lib/tap/support/joins/switch.rb +13 -11
- data/lib/tap/support/joins/sync_merge.rb +25 -50
- data/lib/tap/support/manifest.rb +1 -0
- data/lib/tap/support/node.rb +140 -20
- data/lib/tap/support/parser.rb +56 -42
- data/lib/tap/support/schema.rb +183 -157
- data/lib/tap/support/templater.rb +9 -1
- data/lib/tap/support/versions.rb +39 -0
- data/lib/tap/task.rb +150 -177
- data/lib/tap/tasks/dump.rb +4 -4
- data/lib/tap/tasks/load.rb +29 -29
- data/lib/tap/test.rb +66 -53
- data/lib/tap/test/env_vars.rb +3 -3
- data/lib/tap/test/extensions.rb +11 -17
- data/lib/tap/test/file_test.rb +74 -132
- data/lib/tap/test/file_test_class.rb +4 -1
- data/lib/tap/test/regexp_escape.rb +2 -2
- data/lib/tap/test/script_test.rb +2 -2
- data/lib/tap/test/subset_test.rb +6 -6
- data/lib/tap/test/tap_test.rb +28 -154
- metadata +30 -51
- data/bin/rap +0 -118
- data/cgi/run.rb +0 -97
- data/lib/tap/declarations.rb +0 -229
- data/lib/tap/generator/generators/config/templates/doc.erb +0 -12
- data/lib/tap/generator/generators/config/templates/nodoc.erb +0 -8
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +0 -27
- data/lib/tap/generator/generators/file_task/templates/file.txt +0 -11
- data/lib/tap/generator/generators/file_task/templates/result.yml +0 -6
- data/lib/tap/generator/generators/file_task/templates/task.erb +0 -33
- data/lib/tap/generator/generators/file_task/templates/test.erb +0 -29
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +0 -5
- data/lib/tap/patches/optparse/summarize.rb +0 -62
- data/lib/tap/support/assignments.rb +0 -173
- data/lib/tap/support/class_configuration.rb +0 -182
- data/lib/tap/support/combinator.rb +0 -125
- data/lib/tap/support/configurable.rb +0 -113
- data/lib/tap/support/configurable_class.rb +0 -271
- data/lib/tap/support/configuration.rb +0 -170
- data/lib/tap/support/gems/rake.rb +0 -111
- data/lib/tap/support/instance_configuration.rb +0 -173
- data/lib/tap/support/joins/fork.rb +0 -19
- data/lib/tap/support/joins/merge.rb +0 -22
- data/lib/tap/support/joins/sequence.rb +0 -21
- data/lib/tap/support/lazy_attributes.rb +0 -45
- data/lib/tap/support/lazydoc.rb +0 -386
- data/lib/tap/support/lazydoc/comment.rb +0 -503
- data/lib/tap/support/lazydoc/config.rb +0 -17
- data/lib/tap/support/lazydoc/definition.rb +0 -36
- data/lib/tap/support/lazydoc/document.rb +0 -152
- data/lib/tap/support/lazydoc/method.rb +0 -24
- data/lib/tap/support/tdoc.rb +0 -409
- data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
- data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
- data/lib/tap/support/validation.rb +0 -479
- data/lib/tap/tasks/rake.rb +0 -57
data/History
CHANGED
@@ -1,3 +1,38 @@
|
|
1
|
+
== 0.12.0 / 2009-02-17
|
2
|
+
|
3
|
+
As of the 0.12.0 release, Tap is distributed as several independent modules
|
4
|
+
which can be collectively installed through tap-suite. Tap has been cleaned
|
5
|
+
up significantly since the 0.11 series, and some changes are not backwards
|
6
|
+
compatible. The main task API has been preserved.
|
7
|
+
|
8
|
+
Notable changes include:
|
9
|
+
|
10
|
+
* Lazydoc, Configurable, Rap, and Tap generators are now
|
11
|
+
independent gems. Install the whole suite via tap-suite
|
12
|
+
* Removed use of OptionParser
|
13
|
+
* Root#directories was refactored to Root#relative_paths
|
14
|
+
* Added several methods to Root
|
15
|
+
* Added splat option for joins
|
16
|
+
* Refactored stack short option to 'k'
|
17
|
+
* Reworked Sequence, Fork, and Merge as special cases of Join
|
18
|
+
* Reworked Audit as a directed acyclic graph
|
19
|
+
* Cleanup and extension of FileTask API
|
20
|
+
* Removed RSpec support
|
21
|
+
* Added Mini::Test support
|
22
|
+
* Added/clarified Task nesting
|
23
|
+
* Removed batching from Executable (neat feature but complex in joins)
|
24
|
+
* The tap executable longer automatically reconfigures tasks from config files
|
25
|
+
|
26
|
+
Upgrade note:
|
27
|
+
|
28
|
+
* Root#directories was refactored to Root#relative_path, so the file_test
|
29
|
+
:directories option needs to be updated to :relative_paths
|
30
|
+
* Several test methods were removed in favor of better alternatives through
|
31
|
+
method_root itself. In particular method_tempfile('path') should be
|
32
|
+
replaced with method_root.prepare(:tmp, 'path').
|
33
|
+
* EnvVars#env was refactored to EnvVars#env_var to prevent a common collision
|
34
|
+
with env as a test variable.
|
35
|
+
|
1
36
|
== 0.11.0 / 2008-10-20
|
2
37
|
|
3
38
|
Significant update to Tap with many internal reworks.
|
@@ -87,4 +122,3 @@ Documentation is still patchy, but improving.
|
|
87
122
|
== 0.7.9 / 2007-09-14
|
88
123
|
|
89
124
|
* Initial testing release with partial documentation
|
90
|
-
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2006-
|
1
|
+
Copyright (c) 2006-2009, Regents of the University of Colorado.
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
4
4
|
software and associated documentation files (the "Software"), to deal in the Software
|
data/README
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= {Tap (Task Application)}[http://tap.rubyforge.org]
|
2
2
|
|
3
|
+
tap n. to draw a supply from a resource
|
4
|
+
|
3
5
|
A framework for creating configurable, distributable tasks and workflows.
|
4
6
|
|
5
7
|
== Description
|
@@ -23,7 +25,9 @@ Check out these links for tutorials, development, and bug tracking.
|
|
23
25
|
but play well together. See the {Tutorial}[link:files/doc/Tutorial.html].
|
24
26
|
- Tap is tested on MRI (the standard Ruby interpreter, versions 1.8.6 and
|
25
27
|
1.9.0) and JRuby[http://jruby.codehaus.org/].
|
26
|
-
|
28
|
+
- Tap is the core of the {Tap-Suite}[http://tap.rubyforge.org/tap-suite], a
|
29
|
+
collection of several modules that simplify development.
|
30
|
+
|
27
31
|
=== Usage
|
28
32
|
|
29
33
|
A simple task illustrates the usage of tap:
|
@@ -50,8 +54,7 @@ Tap pulls documentation out of task classes to generate manifests:
|
|
50
54
|
tap:
|
51
55
|
dump # the default dump task
|
52
56
|
load # the default load task
|
53
|
-
|
54
|
-
|
57
|
+
|
55
58
|
And help:
|
56
59
|
|
57
60
|
% tap run -- goodnight --help
|
@@ -65,31 +68,28 @@ And help:
|
|
65
68
|
--message MESSAGE a goodnight message
|
66
69
|
|
67
70
|
options:
|
68
|
-
|
69
|
-
--name NAME
|
70
|
-
--
|
71
|
+
--help Print this help
|
72
|
+
--name NAME Specifies the task name
|
73
|
+
--config FILE Specifies a config file
|
74
|
+
--use FILE Loads inputs to ARGV
|
71
75
|
|
72
|
-
|
73
|
-
Tasks are immediately available to run through tap or rap:
|
76
|
+
Tasks are immediately available to run through the tap executable:
|
74
77
|
|
75
78
|
% tap run -- goodnight moon
|
76
79
|
I[00:09:55] goodnight moon
|
77
|
-
|
78
|
-
% rap goodnight moon --message hello
|
79
|
-
I[00:10:01] hello moon
|
80
80
|
|
81
81
|
Tap comes with generators. To get started:
|
82
82
|
|
83
83
|
% tap generate root sample
|
84
84
|
% cd sample
|
85
85
|
% tap generate task goodnight
|
86
|
-
%
|
86
|
+
% tap run -- goodnight moon
|
87
87
|
|
88
88
|
=== Bugs/Known Issues
|
89
89
|
|
90
90
|
- Some inconsequential tests on JRuby fail due to bugs in JRuby itself.
|
91
91
|
- Joins, Parser, and Schema require additional documentation and may be
|
92
|
-
|
92
|
+
reworked in a future release. The workflow syntax should remain the same.
|
93
93
|
|
94
94
|
== Installation
|
95
95
|
|
@@ -97,14 +97,15 @@ Tap is available as a gem on RubyForge[http://rubyforge.org/projects/tap]. Use:
|
|
97
97
|
|
98
98
|
% gem install tap
|
99
99
|
|
100
|
-
Tap requires an updated version of RubyGems[http://docs.rubygems.org/]
|
100
|
+
Tap requires an updated version of RubyGems[http://docs.rubygems.org/]
|
101
|
+
(>= 1.2.0). To check the version and update RubyGems:
|
101
102
|
|
102
103
|
% gem --version
|
103
104
|
% gem --update system
|
104
105
|
|
105
106
|
== Info
|
106
107
|
|
107
|
-
Copyright (c) 2006-
|
108
|
+
Copyright (c) 2006-2009, Regents of the University of Colorado.
|
108
109
|
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com], {Biomolecular Structure Program}[http://biomol.uchsc.edu/], {Hansen Lab}[http://hsc-proteomics.uchsc.edu/hansenlab/]
|
109
110
|
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
110
111
|
Licence:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
data/bin/tap
CHANGED
data/cmd/console.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# tap console {options}
|
2
2
|
#
|
3
3
|
# Opens up an IRB session with Tap initialized to the configurations
|
4
|
-
# in tap.yml. Access the Tap::App.instance through 'app'
|
4
|
+
# in tap.yml. Access the Tap::App.instance through 'app', and
|
5
|
+
# Tap::Env.instance through 'env'.
|
5
6
|
|
6
7
|
#
|
7
8
|
# handle options
|
8
9
|
#
|
9
10
|
|
10
|
-
|
11
|
+
ConfigParser.new do |opts|
|
11
12
|
opts.separator ""
|
12
13
|
opts.separator "options:"
|
13
14
|
|
14
15
|
opts.on("-h", "--help", "Show this message") do
|
15
|
-
|
16
|
+
puts Lazydoc.usage(__FILE__)
|
16
17
|
puts opts
|
17
18
|
exit
|
18
19
|
end
|
data/cmd/manifest.rb
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
options = {}
|
7
|
-
|
7
|
+
ConfigParser.new do |opts|
|
8
8
|
|
9
9
|
opts.separator ""
|
10
10
|
opts.separator "options:"
|
11
11
|
|
12
12
|
opts.on("-h", "--help", "Show this message") do
|
13
|
-
|
13
|
+
puts Lazydoc.usage(__FILE__)
|
14
14
|
puts opts
|
15
15
|
exit
|
16
16
|
end
|
data/cmd/run.rb
CHANGED
@@ -13,29 +13,27 @@ app = Tap::App.instance
|
|
13
13
|
#
|
14
14
|
|
15
15
|
dump = false
|
16
|
-
|
16
|
+
ConfigParser.new do |opts|
|
17
17
|
opts.separator ""
|
18
18
|
opts.separator "configurations:"
|
19
19
|
|
20
|
-
Tap::
|
21
|
-
|
22
|
-
|
23
|
-
opts.
|
24
|
-
app.send(config.writer, value)
|
25
|
-
end
|
20
|
+
root_keys = Tap::Root.configurations.keys
|
21
|
+
Tap::App.configurations.each_pair do |key, config|
|
22
|
+
next if root_keys.include?(key)
|
23
|
+
opts.define(key, config.default, config.attributes)
|
26
24
|
end
|
27
25
|
|
28
26
|
opts.separator ""
|
29
27
|
opts.separator "options:"
|
30
|
-
|
28
|
+
|
31
29
|
opts.on("-h", "--help", "Show this message") do
|
32
|
-
opts.banner = Tap::Support::Lazydoc.usage(__FILE__)
|
33
30
|
Tap::App.lazydoc.resolve
|
31
|
+
puts Lazydoc.usage(__FILE__)
|
34
32
|
puts opts
|
35
33
|
exit
|
36
34
|
end
|
37
35
|
|
38
|
-
opts.on('-T', '--manifest', 'Print a list of available tasks') do
|
36
|
+
opts.on('-T', '--manifest', 'Print a list of available tasks') do
|
39
37
|
puts env.summarize(:tasks)
|
40
38
|
exit
|
41
39
|
end
|
@@ -46,14 +44,13 @@ end.parse!(ARGV)
|
|
46
44
|
# build and run the argv
|
47
45
|
#
|
48
46
|
|
49
|
-
|
47
|
+
env.set_signals
|
48
|
+
env.build(ARGV)
|
50
49
|
ARGV.clear
|
51
50
|
|
52
|
-
if
|
51
|
+
if app.queue.empty?
|
53
52
|
puts "no task specified"
|
54
53
|
exit
|
55
54
|
end
|
56
55
|
|
57
|
-
|
58
|
-
env.run(queues)
|
59
|
-
|
56
|
+
app.run
|
data/doc/Class Reference
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
= Class Reference
|
2
2
|
|
3
|
-
|
3
|
+
This is a ground-up overview of the main classes and modules used by Tap,
|
4
|
+
specifically Tasks, Apps, and Envs.
|
4
5
|
|
5
6
|
== Tasks
|
6
7
|
|
@@ -8,26 +9,33 @@ Working up from the ground is useful to get a sense for how Tap does what it doe
|
|
8
9
|
|
9
10
|
http://tap.rubyforge.org/images/Method.png
|
10
11
|
|
11
|
-
Tasks
|
12
|
+
Tasks are fundamentally just a method, simply a block of code.
|
12
13
|
|
13
14
|
==== Tap::Support::Executable
|
14
15
|
|
15
16
|
http://tap.rubyforge.org/images/Executable.png
|
16
17
|
|
17
|
-
Executable
|
18
|
+
Executable essentially wraps a method and adds support for dependencies, joins,
|
19
|
+
and auditing. Executables are the nodes in a workflow. Any Executable may be
|
20
|
+
joined to another Executable, enqued, and run by an App. To wrap a method,
|
21
|
+
Executable extends an object and defines which method on the object is 'executable'.
|
22
|
+
Any method may be made executable, and so any method can participate in a workflow
|
23
|
+
(see Object#_method).
|
18
24
|
|
19
|
-
Tasks are constructed such that <tt>process</tt> is the executable method
|
25
|
+
Tasks are constructed such that <tt>process</tt> is the executable method, hence
|
26
|
+
<tt>process</tt> is the standard method overridden in Task subclasses.
|
20
27
|
|
21
|
-
====
|
28
|
+
==== {Configurable}[http://tap.rubyforge.org/configurable/]
|
22
29
|
|
23
30
|
http://tap.rubyforge.org/images/Configurable.png
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
Tap uses the {Configurable}[http://tap.rubyforge.org/configurable/] module to
|
33
|
+
declare class configurations and make them available on the command line.
|
34
|
+
Configurations are essentially a shorthand to define attributes with a default
|
35
|
+
value. For instance:
|
36
|
+
|
29
37
|
class ConfigClass
|
30
|
-
include
|
38
|
+
include Configurable
|
31
39
|
|
32
40
|
config :key, 'value' do |input|
|
33
41
|
input.upcase
|
@@ -52,7 +60,8 @@ Is basically the same as:
|
|
52
60
|
end
|
53
61
|
end
|
54
62
|
|
55
|
-
|
63
|
+
Configurations may be accessed through a hash-like config object, as you can
|
64
|
+
see here:
|
56
65
|
|
57
66
|
c = ConfigClass.new
|
58
67
|
c.key # => 'VALUE'
|
@@ -63,14 +72,22 @@ As you can see here:
|
|
63
72
|
c.key = 'another value'
|
64
73
|
c.config[:key] # => 'ANOTHER VALUE'
|
65
74
|
|
66
|
-
This setup is both fast and convenient.
|
75
|
+
This setup is both fast and convenient. See the {Configurable}[http://tap.rubyforge.org/configurable]
|
76
|
+
documentation for more information.
|
67
77
|
|
68
|
-
====
|
78
|
+
==== {Configurable::Validation}[http://tap.rubyforge.org/configurable/classes/Configurable/Validation.html]
|
69
79
|
|
70
|
-
When configurations are set from the command line, the writer
|
80
|
+
When configurations are set from the command line, the config writer inevitably
|
81
|
+
receives a string, even though you may want a non-string input. The
|
82
|
+
{Validation}[http://tap.rubyforge.org/configurable/classes/Configurable/Validation.html]
|
83
|
+
module provides standard blocks for validating and transforming inputs, and
|
84
|
+
may be accessed through the shortcut method <tt>c</tt> (ex: <tt>c.integer</tt>
|
85
|
+
or <tt>c.regexp</tt>). Validation blocks (generally) load string inputs as
|
86
|
+
YAML and validate that the result is the correct class; non-string inputs are
|
87
|
+
simply validated.
|
71
88
|
|
72
89
|
class ValidatingClass
|
73
|
-
include
|
90
|
+
include Configurable
|
74
91
|
|
75
92
|
config :int, 1, &c.integer # assures the input is an integer
|
76
93
|
config :int_or_nil, 1, &c.integer_or_nil # integer or nil only
|
@@ -87,74 +104,68 @@ When configurations are set from the command line, the writer method will inevit
|
|
87
104
|
|
88
105
|
vc.array = "string" # !> ValidationError
|
89
106
|
|
90
|
-
Validation blocks sometimes imply metadata. For instance <tt>c.flag</tt> makes
|
107
|
+
Validation blocks sometimes imply metadata. For instance <tt>c.flag</tt> makes
|
108
|
+
a config into a flag on the command line.
|
91
109
|
|
92
|
-
====
|
110
|
+
==== {Lazydoc}[http://tap.rubyforge.org/lazydoc]
|
93
111
|
|
94
|
-
|
112
|
+
{Lazydoc}[http://tap.rubyforge.org/lazydoc] fits into the space between live
|
113
|
+
code and code documentation. Lazydoc can scan a file and pull documentation
|
114
|
+
into the object space, typically via a syntax like this:
|
95
115
|
|
96
|
-
# ::key value
|
116
|
+
# Constant::key value
|
117
|
+
# comment
|
97
118
|
|
98
|
-
|
119
|
+
For example:
|
99
120
|
|
100
121
|
[lazydoc_file.rb]
|
101
|
-
# Name::
|
122
|
+
# Const::Name::key value
|
102
123
|
#
|
103
|
-
# This
|
104
|
-
#
|
105
|
-
#
|
106
|
-
|
107
|
-
# Name::Space::another another value
|
108
|
-
# This gets parsed.
|
109
|
-
# Name::Space::another-
|
124
|
+
# This is an extended,
|
125
|
+
# multiline comment.
|
110
126
|
#
|
111
|
-
# This does not.
|
112
127
|
|
113
128
|
require 'tap'
|
114
129
|
|
115
|
-
lazydoc =
|
130
|
+
lazydoc = Lazydoc[__FILE__]
|
116
131
|
lazydoc.resolve
|
117
|
-
|
118
|
-
lazydoc['Name
|
119
|
-
lazydoc['Name
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
132
|
+
|
133
|
+
lazydoc['Const::Name']['key'].value # => "value"
|
134
|
+
lazydoc['Const::Name']['key'].comment # => "This is an extended, multiline comment."
|
135
|
+
|
136
|
+
Lazydoc can also register specific lines for documentation, like method
|
137
|
+
definitions or configurations. Tap uses Lazydoc to identify files that contain
|
138
|
+
tasks and generators, to extract config documentation, and to infer the args
|
139
|
+
arguments a task receives. Here is an example of information gleaned from a
|
140
|
+
task definition:
|
141
|
+
|
142
|
+
# Sample::manifest a summary of the task
|
143
|
+
class Sample < Tap::Task
|
144
|
+
config :key, 'value' # a simple configuration
|
145
|
+
|
146
|
+
def process(a, b='B', *c)
|
147
|
+
end
|
127
148
|
end
|
128
|
-
|
129
|
-
require 'tap'
|
130
|
-
|
131
|
-
lazydoc = Tap::Support::Lazydoc[__FILE__]
|
132
|
-
code_comment = lazydoc.register(2)
|
133
|
-
lazydoc.resolve
|
134
149
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
# ::manifest sample task description
|
144
|
-
#
|
145
|
-
# This manifest is expected to apply to the Sample::Task class.
|
146
|
-
# If more than one task is defined in this file, or if Sample::Task
|
147
|
-
# is not defined by loading this file, Tap will run into trouble.
|
148
|
-
|
149
|
-
However, the best practice is to include the namespace explicitly.
|
150
|
+
Sample::manifest.to_s # => "a summary of the task"
|
151
|
+
Sample::args.to_s # => "A B='B' C..."
|
152
|
+
|
153
|
+
key = Sample.configurations[:key]
|
154
|
+
key.attributes[:desc].to_s # => "a simple configuration"
|
155
|
+
|
156
|
+
See the {Lazydoc}[http://tap.rubyforge.org/lazydoc] documentation for more
|
157
|
+
information.
|
150
158
|
|
151
159
|
=== Tap::Task
|
152
160
|
|
153
161
|
http://tap.rubyforge.org/images/Task.png
|
154
162
|
|
155
|
-
|
163
|
+
Tasks are the bread and butter of Tap. Tasks act as the nodes in workflows and,
|
164
|
+
using the Configurable and Lazydoc metadata, map to the command line as miniature
|
165
|
+
applications. That said, tasks are perfectly useful as ordinary objects.
|
156
166
|
|
157
|
-
|
167
|
+
When subclassing is too much, tasks may be interned with a block that effectively
|
168
|
+
replaces <tt>process</tt>:
|
158
169
|
|
159
170
|
t = Tap::Task.intern {|task| 1 + 2 }
|
160
171
|
t.process # => 3
|
@@ -175,46 +186,36 @@ joined into dependency-based workflows,
|
|
175
186
|
t0 = Tap::Task.intern {|task| runlist << task }
|
176
187
|
t1.depends_on(t0)
|
177
188
|
|
178
|
-
imperative workflows
|
189
|
+
and imperative workflows.
|
179
190
|
|
180
191
|
t2 = Tap::Task.intern do |task, input|
|
181
192
|
runlist << task
|
182
193
|
"#{input}:two"
|
183
194
|
end
|
184
195
|
t1.sequence(t2)
|
185
|
-
|
186
|
-
and batched.
|
187
|
-
|
188
|
-
t3 = t1.initialize_batch_obj(:key => 'three')
|
189
|
-
t1.batch # => [t1, t3]
|
190
196
|
|
191
|
-
|
197
|
+
Results are aggregated into the underlying Tap::App.
|
192
198
|
|
193
199
|
t1.enq('input')
|
194
200
|
|
195
201
|
app = Tap::App.instance
|
196
202
|
app.run
|
197
203
|
|
198
|
-
runlist # => [t0, t1, t2
|
199
|
-
app.results(t2) # => ["input:one:two"
|
204
|
+
runlist # => [t0, t1, t2]
|
205
|
+
app.results(t2) # => ["input:one:two"]
|
200
206
|
|
201
|
-
Tracking the evolution of a result through a workflow can get complex
|
207
|
+
Tracking the evolution of a result through a workflow can get complex. Tap
|
208
|
+
audits workflows to help. Setting the names of the tasks will identify them
|
209
|
+
in an audit dump:
|
202
210
|
|
203
211
|
t1.name = 'un'
|
204
212
|
t2.name = 'deux'
|
205
|
-
t3.name = 'trois'
|
206
213
|
|
207
|
-
app._results(t2).
|
208
|
-
_result._to_s
|
209
|
-
end.join("---\n")
|
214
|
+
app._results(t2)[0].dump
|
210
215
|
# =>
|
211
216
|
# o-[] "input"
|
212
217
|
# o-[un] "input:one"
|
213
218
|
# o-[deux] "input:one:two"
|
214
|
-
# ---
|
215
|
-
# o-[] "input"
|
216
|
-
# o-[trois] "input:three"
|
217
|
-
# o-[deux] "input:three:two"
|
218
219
|
|
219
220
|
== Apps
|
220
221
|
|
@@ -222,47 +223,39 @@ Tracking the evolution of a result through a workflow can get complex; Tap audit
|
|
222
223
|
|
223
224
|
http://tap.rubyforge.org/images/Root.png
|
224
225
|
|
225
|
-
A Root represents the base of a directory structure. Roots allow you to alias
|
226
|
+
A Root represents the base of a directory structure. Roots allow you to alias
|
227
|
+
relative paths, basically allowing you to develop code for a conceptual
|
228
|
+
directory structure that can be defined later.
|
226
229
|
|
227
230
|
root = Tap::Root.new '/path/to/root'
|
228
231
|
root.root # => '/path/to/root'
|
229
232
|
root['config'] # => '/path/to/root/config'
|
230
233
|
root.filepath('config', 'sample.yml') # => '/path/to/root/config/sample.yml'
|
231
234
|
|
232
|
-
While simple, this ability to alias paths is useful, powerful, and forms the
|
235
|
+
While simple, this ability to alias paths is useful, powerful, and forms the
|
236
|
+
basis of the Tap execution environment.
|
233
237
|
|
234
238
|
==== Tap::Support::ExecutableQueue
|
235
239
|
|
236
240
|
http://tap.rubyforge.org/images/ExecutableQueue.png
|
237
241
|
|
238
|
-
Apps coordinate the execution of tasks through a queue. The queue is just a
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
Dependencies coordinate the registration and resolution of dependencies, which may be shared across multiple tasks.
|
243
|
-
|
244
|
-
==== Tap::Support::Audit
|
245
|
-
|
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.
|
247
|
-
|
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.
|
249
|
-
|
250
|
-
Task.new.on_complete do |_result| # _result is an Audit instance
|
251
|
-
_result._current # the current value
|
252
|
-
_result._original # the original value
|
253
|
-
end
|
254
|
-
|
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.
|
256
|
-
|
257
|
-
==== Tap::Support::Aggregator
|
258
|
-
|
259
|
-
When a task completes, it executes it's <tt>on_complete</tt> block to handle the results, perhaps passing them on to other tasks. Aggregators collect results when no <tt>on_complete</tt> block is specified. Results are collected per-task into an array; a single task executed many times will have it's results aggregated into this single array.
|
242
|
+
Apps coordinate the execution of tasks through a queue. The queue is just a
|
243
|
+
stack of Executable objects, basically methods, and the inputs to those
|
244
|
+
methods; during a run the enqued methods are sequentially executed with the
|
245
|
+
inputs.
|
260
246
|
|
261
247
|
=== Tap::App
|
262
248
|
|
263
249
|
http://tap.rubyforge.org/images/App.png
|
264
250
|
|
265
|
-
Instances of Tap::App coordinate the execution of tasks. Apps are basically a
|
251
|
+
Instances of Tap::App coordinate the execution of tasks. Apps are basically a
|
252
|
+
subclass of Root with an ExecutableQueue.
|
253
|
+
|
254
|
+
Task initialization requires an App, which is by default Tap::App.instance.
|
255
|
+
Tasks use their app for logging, dependency-resolution, checks, and to enque
|
256
|
+
themselves. Normally a script will only need and use a single instance (often
|
257
|
+
Tap::App.instance), but there is no reason why multiple instances could not be
|
258
|
+
used.
|
266
259
|
|
267
260
|
log = StringIO.new
|
268
261
|
app = Tap::App.instance
|
@@ -282,7 +275,8 @@ Instances of Tap::App coordinate the execution of tasks. Apps are basically a s
|
|
282
275
|
app.run
|
283
276
|
app.results(t) # => [[1], [2,3]]
|
284
277
|
|
285
|
-
As shown, apps also aggregate results for tasks, which is important for
|
278
|
+
As shown, apps also aggregate results for tasks, which is important for
|
279
|
+
divergent workflows.
|
286
280
|
|
287
281
|
== Envs
|
288
282
|
|
@@ -290,7 +284,9 @@ As shown, apps also aggregate results for tasks, which is important for workflow
|
|
290
284
|
|
291
285
|
http://tap.rubyforge.org/images/Env.png
|
292
286
|
|
293
|
-
|
287
|
+
Envs generate manifests of various resources (tasks, generators, etc) and
|
288
|
+
provide methods to uniquely identify resources using minimized base paths.
|
289
|
+
In this directory structure:
|
294
290
|
|
295
291
|
path
|
296
292
|
`- to
|
@@ -307,11 +303,17 @@ The minimal paths that uniquely identify these files are (respectively):
|
|
307
303
|
'file-0.2.0'
|
308
304
|
'file.rb'
|
309
305
|
|
310
|
-
Envs facilitate mapping
|
306
|
+
Envs facilitate mapping a minimal path to an actual path, and hence to a
|
307
|
+
resource. Envs can be nested so that manifests span multiple directories.
|
308
|
+
Indeed, this is how tap accesses tasks and generators within gems; the gem
|
309
|
+
directories are initialized as Envs and nested within the Env for the working
|
310
|
+
directory.
|
311
311
|
|
312
312
|
http://tap.rubyforge.org/images/Nested-Env.png
|
313
313
|
|
314
|
-
To prevent conflicts between similarly-named resources under
|
314
|
+
To prevent conflicts between similarly-named resources under different Envs,
|
315
|
+
Env allows selection of Envs, also by minimized paths. Say you installed the
|
316
|
+
'sample_tasks' gem.
|
315
317
|
|
316
318
|
% tap manifest
|
317
319
|
--------------------------------------------------------------------------------
|
@@ -349,7 +351,10 @@ To prevent conflicts between similarly-named resources under two Envs, Env allow
|
|
349
351
|
|- sample_tasks
|
350
352
|
`- tap
|
351
353
|
|
352
|
-
In this printout of the manifest, you can see the resources available to tap on
|
354
|
+
In this printout of the manifest, you can see the resources available to tap on
|
355
|
+
the Desktop (none), in the sample_tasks gem, and in tap itself. Since there
|
356
|
+
aren't any conflicts among tasks, the minipath of any of the tasks is sufficient
|
357
|
+
for identification:
|
353
358
|
|
354
359
|
% tap run -- print_tree
|
355
360
|
% tap run -- dump
|
@@ -358,14 +363,12 @@ If there were a conflict, you'd have to specify the environment minipath like:
|
|
358
363
|
|
359
364
|
% tap run -- sample_tasks:print_tree
|
360
365
|
% tap run -- tap:dump
|
361
|
-
|
362
|
-
Note the same rules apply for rap:
|
363
|
-
|
364
|
-
% rap print_tree
|
365
|
-
% rap tap:dump
|
366
366
|
|
367
367
|
==== Tap::Exe
|
368
368
|
|
369
369
|
http://tap.rubyforge.org/images/Run-Env.png
|
370
370
|
|
371
|
-
|
371
|
+
Tap::Exe adds several configurations (ex before/after) which only get loaded
|
372
|
+
for the present directory, and methods for building and executing workflows
|
373
|
+
from command line inputs. Tap::Exe is a singleton, and is special because it
|
374
|
+
wraps Tap::App.instance.
|