tap-suite 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +4 -0
- data/README +20 -7
- data/doc/Tutorial +344 -0
- metadata +44 -7
data/History
CHANGED
data/README
CHANGED
@@ -1,19 +1,32 @@
|
|
1
1
|
= {Tap Suite}[http://tap.rubyforge.org/tap-suite]
|
2
2
|
|
3
|
-
|
3
|
+
suite n. a set of things belonging together
|
4
|
+
|
5
|
+
A collection of modules to rapidly develop {Tap}[http://tap.rubyforge.org]
|
6
|
+
workflows.
|
4
7
|
|
5
8
|
== Description
|
6
9
|
|
7
|
-
{Tap}[http://tap.rubyforge.org] is a
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
{Tap}[http://tap.rubyforge.org] is a configurable, distributable workflow
|
11
|
+
framework. Several related modules apply Tap in particularly useful ways. The
|
12
|
+
Tap-Suite is simply a collection of those gems, facilitating installation and
|
13
|
+
update.
|
11
14
|
|
12
15
|
Currently these modules are included:
|
13
16
|
|
14
|
-
* {Tap}[http://tap.rubyforge.org]
|
17
|
+
* {Tap}[http://tap.rubyforge.org/rdoc]
|
15
18
|
* {Rap}[http://tap.rubyforge.org/rap]
|
19
|
+
* {Tap-Generators}[http://tap.rubyforge.org/tap-gen]
|
16
20
|
* {Tap-Server}[http://tap.rubyforge.org/tap-server]
|
21
|
+
* {Tap-Tasks}[http://tap.rubyforge.org/tap-tasks]
|
22
|
+
* {Tap-Test}[http://tap.rubyforge.org/tap-test]
|
23
|
+
|
24
|
+
Check out these links for documentation, development, and bug tracking.
|
25
|
+
|
26
|
+
* Website[http://tap.rubyforge.org]
|
27
|
+
* Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/9908-tap-task-application/tickets]
|
28
|
+
* Github[http://github.com/bahuvrihi/tap/tree/master]
|
29
|
+
* {Google Group}[http://groups.google.com/group/ruby-on-tap]
|
17
30
|
|
18
31
|
== Installation
|
19
32
|
|
@@ -31,5 +44,5 @@ Tap requires an updated version of RubyGems[http://docs.rubygems.org/] (>= 1.2.0
|
|
31
44
|
Copyright (c) 2009, Regents of the University of Colorado.
|
32
45
|
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com], {Biomolecular Structure Program}[http://biomol.uchsc.edu/], {Hansen Lab}[http://hsc-proteomics.uchsc.edu/hansenlab/]
|
33
46
|
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
34
|
-
|
47
|
+
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
35
48
|
|
data/doc/Tutorial
ADDED
@@ -0,0 +1,344 @@
|
|
1
|
+
= Tap (Task Application)
|
2
|
+
|
3
|
+
Tap is a framework for creating configurable, distributable workflows.
|
4
|
+
Although scalable for complex workflows, at it simplest Tap works like a
|
5
|
+
supercharged rake. Using the rap executable, you can declare tasks using a
|
6
|
+
syntax almost identical to rake, but with added support for configurations and
|
7
|
+
documentation.
|
8
|
+
|
9
|
+
Note: this tutorial spans several modules in the {Tap-Suite}[http://tap.rubyforge.org/tap-suite].
|
10
|
+
Be sure to install the full suite beforehand.
|
11
|
+
|
12
|
+
% gem install tap-suite
|
13
|
+
|
14
|
+
== Quickstart
|
15
|
+
|
16
|
+
If you've used rake, Tap will be easy to pick up. To get started, make a
|
17
|
+
Rapfile with a simple task declaration:
|
18
|
+
|
19
|
+
[Rapfile]
|
20
|
+
|
21
|
+
# ::desc your basic goodnight moon task
|
22
|
+
# Says goodnight with a configurable message.
|
23
|
+
Rap.task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
24
|
+
puts "#{task.message} #{args.obj}\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
Now from the command line:
|
28
|
+
|
29
|
+
% rap goodnight moon
|
30
|
+
goodnight moon
|
31
|
+
|
32
|
+
% rap goodnight world --message hello
|
33
|
+
hello world
|
34
|
+
|
35
|
+
% rap goodnight --help
|
36
|
+
Goodnight -- your basic goodnight moon task
|
37
|
+
--------------------------------------------------------------------------------
|
38
|
+
Says goodnight with a configurable message.
|
39
|
+
--------------------------------------------------------------------------------
|
40
|
+
usage: rap goodnight OBJ
|
41
|
+
|
42
|
+
configurations:
|
43
|
+
--message MESSAGE
|
44
|
+
|
45
|
+
options:
|
46
|
+
-h, --help Print this help
|
47
|
+
--config FILE Specifies a config file
|
48
|
+
|
49
|
+
The declaration syntax is obviously similar to rake; configurations are new
|
50
|
+
but the task-block style is the same, as are inputs. Other rake constructs are
|
51
|
+
available. Here is a similar goodnight task using dependencies, rake-style.
|
52
|
+
|
53
|
+
[Rapfile]
|
54
|
+
|
55
|
+
# make the declarations available everywhere
|
56
|
+
include Rap::Declarations
|
57
|
+
|
58
|
+
namespace :example do
|
59
|
+
task(:say, :message) do |task, args|
|
60
|
+
print(args.message || 'goodnight')
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "your basic goodnight moon task"
|
64
|
+
task({:goodnight => 'example:say'}, :obj) do |task, args|
|
65
|
+
puts " #{args.obj}\n"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
And now from the command line:
|
70
|
+
|
71
|
+
% rap goodnight moon
|
72
|
+
goodnight moon
|
73
|
+
|
74
|
+
% rap goodnight world -- say hello
|
75
|
+
hello world
|
76
|
+
|
77
|
+
Unlike rake, rap inputs are written out individually and tasks are delimited
|
78
|
+
by a double-dash. Aside from that, you can see rap is basically a supercharged
|
79
|
+
rake. Furthermore, rap runs rake. Directly substitute rap for rake on the
|
80
|
+
command line and your tasks should run as normal (see the Rap {Syntax
|
81
|
+
Reference}[http://tap.rubyforge.org/rap/files/doc/Syntax%20Reference.html] for
|
82
|
+
more details).
|
83
|
+
|
84
|
+
However, supercharging rake isn't the point of Tap. Declarations bridge the
|
85
|
+
gap between rake and tap, but tap itself is a more general framework. To get
|
86
|
+
at other features like imperative workflows, testing, and distribution, we
|
87
|
+
have to go beyond rap and take a look at what declarations do.
|
88
|
+
|
89
|
+
Spoiler: declarations make subclasses of Tap::Task.
|
90
|
+
|
91
|
+
== Beyond Rap
|
92
|
+
|
93
|
+
Going back to the first example, lets take a look at how a task declaration
|
94
|
+
maps to a class definition:
|
95
|
+
|
96
|
+
[Rapfile]
|
97
|
+
|
98
|
+
# ::desc your basic goodnight moon task
|
99
|
+
# Says goodnight with a configurable message.
|
100
|
+
Rap.task(:goodnight, :obj, :message => 'goodnight') do
|
101
|
+
puts "#{task.message} #{args.obj}\n"
|
102
|
+
end
|
103
|
+
|
104
|
+
Here is a corresponding class:
|
105
|
+
|
106
|
+
# Goodnight::manifest your basic goodnight moon task
|
107
|
+
# Says goodnight with a configurable message.
|
108
|
+
class Goodnight < Tap::Task
|
109
|
+
config :message, 'goodnight'
|
110
|
+
|
111
|
+
def process(obj)
|
112
|
+
"#{message} #{obj}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
The name corresponds to the class, configurations (and dependencies, although
|
117
|
+
they aren't show) are written out individually, and the block corresponds to
|
118
|
+
process. There are a few differences, especially relating to process, but for
|
119
|
+
the moment lets gloss over them and see how Goodnight works.
|
120
|
+
|
121
|
+
goodnight = Goodnight.new
|
122
|
+
goodnight.message # => 'goodnight'
|
123
|
+
goodnight.process('moon') # => 'goodnight moon'
|
124
|
+
|
125
|
+
hello = Goodnight.new(:message => 'hello')
|
126
|
+
hello.message # => 'hello'
|
127
|
+
hello.process('world') # => 'hello world'
|
128
|
+
|
129
|
+
Totally straightforward. Goodnight stores the default configurations, each
|
130
|
+
instance has accessors to the configurations, and the defaults may be
|
131
|
+
overridden during initialization, or later.
|
132
|
+
|
133
|
+
Class definitions allow validation/transformation blocks to be specified for
|
134
|
+
configurations. These blocks process inputs (ex the string inputs from the
|
135
|
+
command line), literally defining the writer for a configuration accessor. A
|
136
|
+
set of standard blocks are available through +c+, an alias for the
|
137
|
+
{Configurable::Validation}[http://tap.rubyforge.org/configurable/classes/Configurable/Validation.html]
|
138
|
+
module.
|
139
|
+
|
140
|
+
[lib/goodnight.rb]
|
141
|
+
|
142
|
+
# Goodnight::manifest a fancy goodnight moon task
|
143
|
+
# Says goodnight with a configurable message.
|
144
|
+
class Goodnight < Tap::Task
|
145
|
+
config :message, 'goodnight' # a goodnight message
|
146
|
+
config :reverse, false, &c.switch # reverses the message
|
147
|
+
config :n, 1, &c.integer # repeats message n times
|
148
|
+
|
149
|
+
def process(*objects)
|
150
|
+
msg = "#{reverse == true ? message.reverse : message} " * n
|
151
|
+
msg + objects.join(', ')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
A few examples show a validation block in action:
|
156
|
+
|
157
|
+
goodnight = Goodnight.new
|
158
|
+
|
159
|
+
goodnight.n = 10
|
160
|
+
goodnight.n # => 10
|
161
|
+
|
162
|
+
goodnight.n = "100"
|
163
|
+
goodnight.n # => 100
|
164
|
+
|
165
|
+
goodnight.n = "not an integer" # !> ValidationError
|
166
|
+
|
167
|
+
Now from the command line:
|
168
|
+
|
169
|
+
% rap goodnight moon --: dump
|
170
|
+
goodnight moon
|
171
|
+
|
172
|
+
% rap goodnight moon mittens "little toy boat" --: dump
|
173
|
+
goodnight moon, mittens, little toy boat
|
174
|
+
|
175
|
+
% rap goodnight world --message hello --reverse --n 3 --: dump
|
176
|
+
olleh olleh olleh world
|
177
|
+
|
178
|
+
% rap goodnight --help
|
179
|
+
Goodnight -- a fancy goodnight moon task
|
180
|
+
--------------------------------------------------------------------------------
|
181
|
+
Says goodnight with a configurable message.
|
182
|
+
--------------------------------------------------------------------------------
|
183
|
+
usage: rap goodnight OBJECTS...
|
184
|
+
|
185
|
+
configurations:
|
186
|
+
--message MESSAGE a goodnight message
|
187
|
+
--[no-]reverse reverses the message
|
188
|
+
--n N repeats message n times
|
189
|
+
|
190
|
+
options:
|
191
|
+
-h, --help Print this help
|
192
|
+
--config FILE Specifies a config file
|
193
|
+
|
194
|
+
Take a quick look at the documentation. Class definitions map documentation
|
195
|
+
and, in some cases, metadata to the command line; the configurations now have
|
196
|
+
comments and reverse is a switch. Rich mapping like this allows tasks to act
|
197
|
+
as an script interface, not unlike
|
198
|
+
{OptionParser}[http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html]
|
199
|
+
(check out the {Configurable}[http://tap.rubyforge.org/configurable/] gem and
|
200
|
+
specifically
|
201
|
+
{ConfigParser}[http://tap.rubyforge.org/configurable/classes/ConfigParser.html]
|
202
|
+
for more details).
|
203
|
+
|
204
|
+
This is a stand-alone goodnight script:
|
205
|
+
|
206
|
+
[goodnight]
|
207
|
+
|
208
|
+
#!/usr/bin/env ruby
|
209
|
+
|
210
|
+
require 'rubygems'
|
211
|
+
require 'tap'
|
212
|
+
|
213
|
+
# Goodnight::task a goodnight moon script
|
214
|
+
# Says goodnight with a configurable message.
|
215
|
+
class Goodnight < Tap::Task
|
216
|
+
config :message, 'goodnight'
|
217
|
+
|
218
|
+
def process(obj)
|
219
|
+
puts "#{message} #{obj}\n"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
instance, args = Goodnight.parse!(ARGV)
|
224
|
+
instance.execute(*args)
|
225
|
+
|
226
|
+
Now, from the command line:
|
227
|
+
|
228
|
+
% ./goodnight moon
|
229
|
+
goodnight moon
|
230
|
+
|
231
|
+
% ./goodnight --help
|
232
|
+
...
|
233
|
+
|
234
|
+
Tasks may be subclassed, tested, and distributed as usual. No magic, just
|
235
|
+
convenience.
|
236
|
+
|
237
|
+
== Tap
|
238
|
+
|
239
|
+
Tap comes with two executables, rap and tap. The tap executable is more
|
240
|
+
verbose than rap for running tasks, but it is more configurable, scalable, and
|
241
|
+
logically pure. The full suite comes with a number of commands but we'll focus
|
242
|
+
on generate to make, test, and package a task library. Begin by creating a tap
|
243
|
+
directory structure and a task:
|
244
|
+
|
245
|
+
% tap generate root sample
|
246
|
+
% cd sample
|
247
|
+
% tap generate task goodnight
|
248
|
+
|
249
|
+
Take a look at the task files and you find something like this:
|
250
|
+
|
251
|
+
[lib/goodnight.rb]
|
252
|
+
|
253
|
+
# Goodnight::manifest <replace with manifest summary>
|
254
|
+
# <replace with command line description>
|
255
|
+
|
256
|
+
# Goodnight Documentation
|
257
|
+
class Goodnight < Tap::Task
|
258
|
+
|
259
|
+
# <config file documentation>
|
260
|
+
config :message, 'goodnight' # a sample config
|
261
|
+
|
262
|
+
def process(name)
|
263
|
+
log message, name
|
264
|
+
"#{message} #{name}"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
[test/goodnight_test.rb]
|
269
|
+
|
270
|
+
require File.join(File.dirname(__FILE__), 'tap_test_helper.rb')
|
271
|
+
require 'goodnight'
|
272
|
+
|
273
|
+
class GoodnightTest < Test::Unit::TestCase
|
274
|
+
acts_as_tap_test
|
275
|
+
|
276
|
+
def test_goodnight
|
277
|
+
task = Goodnight.new :message => "goodnight"
|
278
|
+
|
279
|
+
# a simple test
|
280
|
+
assert_equal({:message => 'goodnight'}, task.config)
|
281
|
+
assert_equal "goodnight moon", task.process("moon")
|
282
|
+
|
283
|
+
# a more complex test
|
284
|
+
task.enq("moon")
|
285
|
+
app.run
|
286
|
+
|
287
|
+
assert_equal ["goodnight moon"], app.results(task)
|
288
|
+
assert_audit_equal [[nil, "moon"], [task, "goodnight moon"]], app._results(task)[0]
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
Run the test:
|
293
|
+
|
294
|
+
% rap test
|
295
|
+
|
296
|
+
Run the task:
|
297
|
+
|
298
|
+
% rap goodnight moon
|
299
|
+
I[23:22:19] goodnight moon
|
300
|
+
|
301
|
+
Ok, lets share it. Print the current gemspec manifest:
|
302
|
+
|
303
|
+
% rap print_manifest
|
304
|
+
true README
|
305
|
+
Rakefile
|
306
|
+
lib/goodnight.rb
|
307
|
+
sample.gemspec
|
308
|
+
true tap.yml
|
309
|
+
test/goodnight_test.rb
|
310
|
+
true test/tap_test_helper.rb
|
311
|
+
true test/tap_test_suite.rb
|
312
|
+
|
313
|
+
As you can see, this needs an update to include the task file. Open up
|
314
|
+
sample.gemspec and fix the manifest.
|
315
|
+
|
316
|
+
[sample.gemspec]
|
317
|
+
|
318
|
+
Gem::Specification.new do |s|
|
319
|
+
s.name = "sample"
|
320
|
+
s.version = "0.0.1"
|
321
|
+
s.platform = Gem::Platform::RUBY
|
322
|
+
s.summary = "sample"
|
323
|
+
s.require_path = "lib"
|
324
|
+
s.add_dependency("tap")
|
325
|
+
s.files = %W{
|
326
|
+
lib/goodnight.rb
|
327
|
+
tap.yml
|
328
|
+
}
|
329
|
+
end
|
330
|
+
|
331
|
+
Now package the gem and install it (gem may require sudo):
|
332
|
+
|
333
|
+
% rap gem
|
334
|
+
% gem install pkg/sample-0.0.1.gem
|
335
|
+
|
336
|
+
Now you can say goodnight anywhere, using 'tap run' or rap:
|
337
|
+
|
338
|
+
% cd ~/Desktop
|
339
|
+
% tap run -- goodnight moon
|
340
|
+
goodnight moon
|
341
|
+
% rap goodnight opus
|
342
|
+
goodnight opus
|
343
|
+
|
344
|
+
And that is that.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tap-suite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Chiang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-25 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.17.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rap
|
@@ -30,7 +30,17 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.13.0
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: tap-gen
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.1.0
|
34
44
|
version:
|
35
45
|
- !ruby/object:Gem::Dependency
|
36
46
|
name: tap-server
|
@@ -42,6 +52,26 @@ dependencies:
|
|
42
52
|
- !ruby/object:Gem::Version
|
43
53
|
version: 0.1.0
|
44
54
|
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tap-tasks
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.2.0
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: tap-test
|
67
|
+
type: :runtime
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 0.1.0
|
74
|
+
version:
|
45
75
|
description:
|
46
76
|
email: simon.a.chiang@gmail.com
|
47
77
|
executables: []
|
@@ -52,15 +82,22 @@ extra_rdoc_files:
|
|
52
82
|
- README
|
53
83
|
- MIT-LICENSE
|
54
84
|
- History
|
85
|
+
- doc/Tutorial
|
55
86
|
files:
|
56
87
|
- README
|
57
88
|
- MIT-LICENSE
|
58
89
|
- History
|
90
|
+
- doc/Tutorial
|
59
91
|
has_rdoc: false
|
60
92
|
homepage: http://tap.rubyforge.org
|
61
93
|
post_install_message:
|
62
|
-
rdoc_options:
|
63
|
-
|
94
|
+
rdoc_options:
|
95
|
+
- --main
|
96
|
+
- README
|
97
|
+
- -S
|
98
|
+
- -N
|
99
|
+
- --title
|
100
|
+
- Tap-Suite
|
64
101
|
require_paths:
|
65
102
|
- lib
|
66
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -81,6 +118,6 @@ rubyforge_project: tap
|
|
81
118
|
rubygems_version: 1.3.1
|
82
119
|
signing_key:
|
83
120
|
specification_version: 2
|
84
|
-
summary: A
|
121
|
+
summary: A collection of modules to rapidly develop Tap workflows
|
85
122
|
test_files: []
|
86
123
|
|