tap 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/History +35 -1
  2. data/MIT-LICENSE +1 -1
  3. data/README +16 -15
  4. data/bin/tap +1 -1
  5. data/cmd/console.rb +4 -3
  6. data/cmd/manifest.rb +2 -2
  7. data/cmd/run.rb +12 -15
  8. data/doc/Class Reference +120 -117
  9. data/doc/Command Reference +27 -27
  10. data/doc/Syntax Reference +55 -111
  11. data/doc/Tutorial +69 -26
  12. data/lib/tap.rb +3 -8
  13. data/lib/tap/app.rb +122 -146
  14. data/lib/tap/constants.rb +2 -2
  15. data/lib/tap/env.rb +178 -252
  16. data/lib/tap/exe.rb +67 -30
  17. data/lib/tap/file_task.rb +224 -411
  18. data/lib/tap/generator/arguments.rb +13 -0
  19. data/lib/tap/generator/base.rb +112 -30
  20. data/lib/tap/generator/destroy.rb +36 -13
  21. data/lib/tap/generator/generate.rb +69 -48
  22. data/lib/tap/generator/generators/command/templates/command.erb +3 -3
  23. data/lib/tap/generator/generators/config/config_generator.rb +82 -10
  24. data/lib/tap/generator/generators/generator/generator_generator.rb +16 -6
  25. data/lib/tap/generator/generators/generator/templates/task.erb +2 -2
  26. data/lib/tap/generator/generators/generator/templates/test.erb +26 -0
  27. data/lib/tap/generator/generators/root/root_generator.rb +24 -13
  28. data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
  29. data/lib/tap/generator/generators/root/templates/{tapfile → Rapfile} +6 -6
  30. data/lib/tap/generator/generators/root/templates/gemspec +0 -1
  31. data/lib/tap/generator/generators/task/task_generator.rb +3 -3
  32. data/lib/tap/generator/generators/task/templates/test.erb +1 -1
  33. data/lib/tap/generator/manifest.rb +7 -1
  34. data/lib/tap/generator/preview.rb +76 -0
  35. data/lib/tap/root.rb +222 -156
  36. data/lib/tap/spec.rb +41 -0
  37. data/lib/tap/support/aggregator.rb +25 -28
  38. data/lib/tap/support/audit.rb +278 -357
  39. data/lib/tap/support/constant.rb +2 -1
  40. data/lib/tap/support/constant_manifest.rb +28 -25
  41. data/lib/tap/support/dependency.rb +1 -1
  42. data/lib/tap/support/executable.rb +52 -183
  43. data/lib/tap/support/executable_queue.rb +50 -20
  44. data/lib/tap/support/gems.rb +1 -1
  45. data/lib/tap/support/intern.rb +0 -6
  46. data/lib/tap/support/join.rb +49 -83
  47. data/lib/tap/support/joins.rb +0 -3
  48. data/lib/tap/support/joins/switch.rb +13 -11
  49. data/lib/tap/support/joins/sync_merge.rb +25 -50
  50. data/lib/tap/support/manifest.rb +1 -0
  51. data/lib/tap/support/node.rb +140 -20
  52. data/lib/tap/support/parser.rb +56 -42
  53. data/lib/tap/support/schema.rb +183 -157
  54. data/lib/tap/support/templater.rb +9 -1
  55. data/lib/tap/support/versions.rb +39 -0
  56. data/lib/tap/task.rb +150 -177
  57. data/lib/tap/tasks/dump.rb +4 -4
  58. data/lib/tap/tasks/load.rb +29 -29
  59. data/lib/tap/test.rb +66 -53
  60. data/lib/tap/test/env_vars.rb +3 -3
  61. data/lib/tap/test/extensions.rb +11 -17
  62. data/lib/tap/test/file_test.rb +74 -132
  63. data/lib/tap/test/file_test_class.rb +4 -1
  64. data/lib/tap/test/regexp_escape.rb +2 -2
  65. data/lib/tap/test/script_test.rb +2 -2
  66. data/lib/tap/test/subset_test.rb +6 -6
  67. data/lib/tap/test/tap_test.rb +28 -154
  68. metadata +30 -51
  69. data/bin/rap +0 -118
  70. data/cgi/run.rb +0 -97
  71. data/lib/tap/declarations.rb +0 -229
  72. data/lib/tap/generator/generators/config/templates/doc.erb +0 -12
  73. data/lib/tap/generator/generators/config/templates/nodoc.erb +0 -8
  74. data/lib/tap/generator/generators/file_task/file_task_generator.rb +0 -27
  75. data/lib/tap/generator/generators/file_task/templates/file.txt +0 -11
  76. data/lib/tap/generator/generators/file_task/templates/result.yml +0 -6
  77. data/lib/tap/generator/generators/file_task/templates/task.erb +0 -33
  78. data/lib/tap/generator/generators/file_task/templates/test.erb +0 -29
  79. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +0 -5
  80. data/lib/tap/patches/optparse/summarize.rb +0 -62
  81. data/lib/tap/support/assignments.rb +0 -173
  82. data/lib/tap/support/class_configuration.rb +0 -182
  83. data/lib/tap/support/combinator.rb +0 -125
  84. data/lib/tap/support/configurable.rb +0 -113
  85. data/lib/tap/support/configurable_class.rb +0 -271
  86. data/lib/tap/support/configuration.rb +0 -170
  87. data/lib/tap/support/gems/rake.rb +0 -111
  88. data/lib/tap/support/instance_configuration.rb +0 -173
  89. data/lib/tap/support/joins/fork.rb +0 -19
  90. data/lib/tap/support/joins/merge.rb +0 -22
  91. data/lib/tap/support/joins/sequence.rb +0 -21
  92. data/lib/tap/support/lazy_attributes.rb +0 -45
  93. data/lib/tap/support/lazydoc.rb +0 -386
  94. data/lib/tap/support/lazydoc/comment.rb +0 -503
  95. data/lib/tap/support/lazydoc/config.rb +0 -17
  96. data/lib/tap/support/lazydoc/definition.rb +0 -36
  97. data/lib/tap/support/lazydoc/document.rb +0 -152
  98. data/lib/tap/support/lazydoc/method.rb +0 -24
  99. data/lib/tap/support/tdoc.rb +0 -409
  100. data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
  101. data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
  102. data/lib/tap/support/validation.rb +0 -479
  103. 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
-
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2008, Regents of the University of Colorado.
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
- rake # run rake tasks
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
- -h, --help Print this help
69
- --name NAME Specify a name
70
- --use FILE Loads inputs from file
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
- % rap goodnight moon
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
- internally reworked. The workflow syntax should remain the same.
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/] (>= 1.2.0). To check the version and update RubyGems:
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-2008, Regents of the University of Colorado.
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
@@ -59,7 +59,7 @@ end
59
59
  begin
60
60
  env.activate
61
61
  env.execute(ARGV) do
62
- puts Tap::Support::Lazydoc.usage(__FILE__)
62
+ puts Lazydoc.usage(__FILE__)
63
63
  puts
64
64
  puts "available commands:"
65
65
  puts env.summarize(:commands)
@@ -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
- OptionParser.new do |opts|
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
- opts.banner = Tap::Support::Lazydoc.usage(__FILE__)
16
+ puts Lazydoc.usage(__FILE__)
16
17
  puts opts
17
18
  exit
18
19
  end
@@ -4,13 +4,13 @@
4
4
  #
5
5
 
6
6
  options = {}
7
- OptionParser.new do |opts|
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
- opts.banner = Tap::Support::Lazydoc.usage(__FILE__)
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
- OptionParser.new do |opts|
16
+ ConfigParser.new do |opts|
17
17
  opts.separator ""
18
18
  opts.separator "configurations:"
19
19
 
20
- Tap::App.configurations.each do |receiver, key, config|
21
- next if receiver == Tap::Root
22
-
23
- opts.on(*config.to_optparse_argv) do |value|
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 |v|
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
- queues = env.build(ARGV)
47
+ env.set_signals
48
+ env.build(ARGV)
50
49
  ARGV.clear
51
50
 
52
- if queues.empty?
51
+ if app.queue.empty?
53
52
  puts "no task specified"
54
53
  exit
55
54
  end
56
55
 
57
- env.set_signals
58
- env.run(queues)
59
-
56
+ app.run
@@ -1,6 +1,7 @@
1
1
  = Class Reference
2
2
 
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.
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 begin with methods, simply a block of code.
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 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
+ 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 (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.
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
- ==== Tap::Support::Configurable
28
+ ==== {Configurable}[http://tap.rubyforge.org/configurable/]
22
29
 
23
30
  http://tap.rubyforge.org/images/Configurable.png
24
31
 
25
- Configurable allows declaration of class configurations. Configurable classes have a <tt>configurations</tt> method accessing a {ClassConfiguration}[link:classes/Tap/Support/ClassConfiguration.html] which holds all declared configs, their default values, and metadata for transforming configurations into command line options (for example).
26
-
27
- Instances of a Configurable class have a <tt>config</tt> method accessing a {InstanceConfiguration}[link:classes/Tap/Support/InstanceConfiguration.html] object. The instance configuration acts like a forwarding hash; read and write operations for declared configs get forwarded to class methods while undeclared configs are stored directly. The writer for a config may be defined through a block provided during config declaration. For instance:
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 Tap::Support::Configurable
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
- As you can see here:
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
- ==== Tap::Support::Validation
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 method will inevitably receive a string, whereas configurations set within code can receive any type of object. The {Validation}[link:classes/Tap/Support/Validation.html] module provides standard blocks for validating and transforming inputs, accessible through the <tt>c</tt> method (ex: <tt>c.integer</tt> or <tt>c.regexp</tt>). These blocks (generally) load string inputs as YAML and validate that the result is the correct class; non-string inputs are simply validated.
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 Tap::Support::Configurable
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 a config into a flag on the command line.
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
- ==== Tap::Support::Lazydoc
110
+ ==== {Lazydoc}[http://tap.rubyforge.org/lazydoc]
93
111
 
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:
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
- 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:
119
+ For example:
99
120
 
100
121
  [lazydoc_file.rb]
101
- # Name::Space::key value
122
+ # Const::Name::key value
102
123
  #
103
- # This documentation
104
- # gets parsed.
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 = Tap::Support::Lazydoc[__FILE__]
130
+ lazydoc = Lazydoc[__FILE__]
116
131
  lazydoc.resolve
117
-
118
- lazydoc['Name::Space']['key'].to_s # => "This documentation gets parsed."
119
- lazydoc['Name::Space']['another'].value # => "another value"
120
-
121
- Furthermore, Lazydoc can register specific lines for documentation. These lines are parsed to echo what happens in RDoc.
122
-
123
- [another_lazydoc_file.rb]
124
- # documentation
125
- # for the method
126
- def method
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
- code_comment.subject # => "def method"
136
- code_comment.to_s # => "documentation for the method"
137
-
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.
139
-
140
- When no constant name is specified for a Lazydoc key, Env uses a constant based on the file name.
141
-
142
- [lib/sample/task.rb]
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
- 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.
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
- Task instances may be interned with a block that acts as a stand-in for <tt>process</tt>:
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
- Batched tasks enque together, and therefore execute sequentially with the same inputs. Results are aggregated into the underlying Tap::App.
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, t3, t2]
199
- app.results(t2) # => ["input:one:two", "input:three: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; 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:
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).collect do |_result|
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 directories and ease working with filepaths, basically allowing you to develop code for a conceptual directory structure that can be defined later.
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 basis of the Tap execution environment.
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 stack of Executable objects, basically methods, and the inputs to those methods; during a run the enqued methods are sequentially executed with the inputs.
239
-
240
- ==== Tap::Support::Dependencies
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 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.
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 workflows.
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
- 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:
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 the minimal path, which might be provided by the command line, to the actual path, and hence to the resource. Envs can be nested so that manifests span multiple directories. Indeed, this is how tap accesses tasks and generators within gems; the gem directories are initialized as Envs and nested within the Env for the working directory.
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 two Envs, Env allows selection of Envs, also by minimized paths. Say you installed the 'sample_tasks' gem.
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 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:
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
- 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.
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.