tap 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Basic Overview +151 -0
- data/Command Reference +99 -0
- data/History +24 -0
- data/MIT-LICENSE +1 -1
- data/README +29 -57
- data/Rakefile +30 -37
- data/Tutorial +243 -191
- data/bin/tap +66 -35
- data/lib/tap.rb +47 -29
- data/lib/tap/app.rb +700 -342
- data/lib/tap/{script → cmd}/console.rb +0 -0
- data/lib/tap/{script → cmd}/destroy.rb +0 -0
- data/lib/tap/{script → cmd}/generate.rb +0 -0
- data/lib/tap/cmd/run.rb +156 -0
- data/lib/tap/constants.rb +4 -0
- data/lib/tap/dump.rb +57 -0
- data/lib/tap/env.rb +316 -0
- data/lib/tap/file_task.rb +106 -109
- data/lib/tap/generator.rb +4 -1
- data/lib/tap/generator/generators/command/USAGE +6 -0
- data/lib/tap/generator/generators/command/command_generator.rb +17 -0
- data/lib/tap/generator/generators/{script/templates/script.erb → command/templates/command.erb} +10 -10
- data/lib/tap/generator/generators/config/USAGE +21 -0
- data/lib/tap/generator/generators/config/config_generator.rb +17 -7
- data/lib/tap/generator/generators/file_task/USAGE +3 -0
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -0
- data/lib/tap/generator/generators/file_task/templates/file.txt +2 -0
- data/lib/tap/generator/generators/file_task/templates/file.yml +3 -0
- data/lib/tap/generator/generators/file_task/templates/task.erb +26 -20
- data/lib/tap/generator/generators/file_task/templates/test.erb +20 -10
- data/lib/tap/generator/generators/generator/generator_generator.rb +1 -1
- data/lib/tap/generator/generators/generator/templates/generator.erb +21 -12
- data/lib/tap/generator/generators/root/templates/Rakefile +33 -24
- data/lib/tap/generator/generators/root/templates/tap.yml +28 -31
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +1 -0
- data/lib/tap/generator/generators/task/USAGE +3 -0
- data/lib/tap/generator/generators/task/task_generator.rb +18 -5
- data/lib/tap/generator/generators/task/templates/task.erb +7 -12
- data/lib/tap/generator/generators/task/templates/test.erb +10 -11
- data/lib/tap/generator/generators/workflow/templates/task.erb +1 -1
- data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
- data/lib/tap/patches/rake/rake_test_loader.rb +8 -0
- data/lib/tap/patches/rake/testtask.rb +55 -0
- data/lib/tap/patches/ruby19/backtrace_filter.rb +51 -0
- data/lib/tap/patches/ruby19/parsedate.rb +16 -0
- data/lib/tap/root.rb +172 -67
- data/lib/tap/script.rb +70 -336
- data/lib/tap/support/aggregator.rb +55 -0
- data/lib/tap/support/audit.rb +281 -280
- data/lib/tap/support/batchable.rb +59 -0
- data/lib/tap/support/class_configuration.rb +279 -0
- data/lib/tap/support/configurable.rb +92 -0
- data/lib/tap/support/configurable_methods.rb +296 -0
- data/lib/tap/support/executable.rb +98 -0
- data/lib/tap/support/executable_queue.rb +82 -0
- data/lib/tap/support/logger.rb +9 -15
- data/lib/tap/support/rake.rb +43 -54
- data/lib/tap/support/run_error.rb +32 -13
- data/lib/tap/support/shell_utils.rb +47 -0
- data/lib/tap/support/tdoc.rb +9 -8
- data/lib/tap/support/tdoc/config_attr.rb +40 -16
- data/lib/tap/support/validation.rb +77 -0
- data/lib/tap/support/versions.rb +36 -36
- data/lib/tap/task.rb +276 -482
- data/lib/tap/test.rb +20 -261
- data/lib/tap/test/env_vars.rb +7 -5
- data/lib/tap/test/file_methods.rb +126 -121
- data/lib/tap/test/subset_methods.rb +86 -45
- data/lib/tap/test/tap_methods.rb +271 -0
- data/lib/tap/workflow.rb +174 -46
- data/test/app/config/another/task.yml +1 -0
- data/test/app/config/erb.yml +2 -1
- data/test/app/config/some/task.yml +1 -0
- data/test/app/config/template.yml +2 -6
- data/test/app_test.rb +1241 -1008
- data/test/env/test_configure/recurse_a.yml +2 -0
- data/test/env/test_configure/recurse_b.yml +2 -0
- data/test/env/test_configure/tap.yml +23 -0
- data/test/env/test_load_env_config/dir/tap.yml +3 -0
- data/test/env/test_load_env_config/recurse_a.yml +2 -0
- data/test/env/test_load_env_config/recurse_b.yml +2 -0
- data/test/env/test_load_env_config/tap.yml +3 -0
- data/test/env_test.rb +198 -0
- data/test/file_task_test.rb +70 -53
- data/{lib/tap/generator/generators/package/USAGE → test/root/file.txt} +0 -0
- data/test/root_test.rb +621 -454
- data/test/script_test.rb +38 -174
- data/test/support/aggregator_test.rb +99 -0
- data/test/support/audit_test.rb +409 -416
- data/test/support/batchable_test.rb +74 -0
- data/test/support/{task_configuration_test.rb → class_configuration_test.rb} +106 -47
- data/test/{task/config/overriding.yml → support/configurable/config/configured.yml} +0 -0
- data/test/support/configurable_test.rb +295 -0
- data/test/support/executable_queue_test.rb +103 -0
- data/test/support/executable_test.rb +38 -0
- data/test/support/logger_test.rb +17 -17
- data/test/support/rake_test.rb +4 -2
- data/test/support/shell_utils_test.rb +24 -0
- data/test/support/tdoc_test.rb +265 -258
- data/test/support/validation_test.rb +54 -0
- data/test/support/versions_test.rb +38 -38
- data/test/tap_test_helper.rb +19 -5
- data/test/tap_test_suite.rb +5 -2
- data/test/task_base_test.rb +13 -104
- data/test/task_syntax_test.rb +300 -0
- data/test/task_test.rb +258 -381
- data/test/test/env_vars_test.rb +40 -40
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/one.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/two.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/one.txt +0 -0
- data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/two.txt +0 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/one.txt +0 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/two.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +1 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_different_content}/expected/two.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +1 -0
- data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_missing_expected_file}/expected/one.txt +0 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +1 -0
- data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +1 -0
- data/test/test/file_methods_doc/test_sub/expected/one.txt +1 -0
- data/test/test/file_methods_doc/test_sub/expected/two.txt +1 -0
- data/test/test/file_methods_doc/test_sub/input/one.txt +1 -0
- data/test/test/file_methods_doc/test_sub/input/two.txt +1 -0
- data/test/test/file_methods_doc_test.rb +29 -0
- data/test/test/file_methods_test.rb +214 -143
- data/test/test/subset_methods_test.rb +111 -115
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/a.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/b.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/a.txt +0 -0
- data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/b.txt +0 -0
- data/test/test/tap_methods_test.rb +399 -0
- data/test/workflow_test.rb +101 -91
- metadata +86 -70
- data/lib/tap/generator/generators/package/package_generator.rb +0 -38
- data/lib/tap/generator/generators/package/templates/package.erb +0 -186
- data/lib/tap/generator/generators/script/USAGE +0 -0
- data/lib/tap/generator/generators/script/script_generator.rb +0 -17
- data/lib/tap/script/run.rb +0 -154
- data/lib/tap/support/batch_queue.rb +0 -162
- data/lib/tap/support/combinator.rb +0 -114
- data/lib/tap/support/task_configuration.rb +0 -169
- data/lib/tap/support/template.rb +0 -81
- data/lib/tap/support/templater.rb +0 -155
- data/lib/tap/version.rb +0 -4
- data/test/app/config/addition_template.yml +0 -6
- data/test/app_class_test.rb +0 -33
- data/test/check/binding_eval.rb +0 -23
- data/test/check/define_method_check.rb +0 -22
- data/test/check/dependencies_check.rb +0 -175
- data/test/check/inheritance_check.rb +0 -22
- data/test/support/batch_queue_test.rb +0 -320
- data/test/support/combinator_test.rb +0 -249
- data/test/support/template_test.rb +0 -122
- data/test/support/templater/erb.txt +0 -2
- data/test/support/templater/erb.yml +0 -2
- data/test/support/templater/somefile.txt +0 -2
- data/test/support/templater_test.rb +0 -192
- data/test/task/config/template.yml +0 -4
- data/test/task_class_test.rb +0 -170
- data/test/task_execute_test.rb +0 -262
- data/test/test/file_methods/test_assert_expected/expected/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/expected/folder/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/input/file.txt +0 -1
- data/test/test/file_methods/test_assert_expected/input/folder/file.txt +0 -1
- data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
- data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
- data/test/test/file_methods/test_file_compare/expected/output_1.txt +0 -3
- data/test/test/file_methods/test_file_compare/expected/output_2.txt +0 -1
- data/test/test/file_methods/test_file_compare/input/input_1.txt +0 -3
- data/test/test/file_methods/test_file_compare/input/input_2.txt +0 -3
- data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
- data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
- data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
- data/test/test/file_methods/test_yml_compare/expected/output_1.yml +0 -6
- data/test/test/file_methods/test_yml_compare/expected/output_2.yml +0 -6
- data/test/test/file_methods/test_yml_compare/input/input_1.yml +0 -4
- data/test/test/file_methods/test_yml_compare/input/input_2.yml +0 -4
- data/test/test_test.rb +0 -373
data/Basic Overview
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
= The Tap Application (Tap::App)
|
2
|
+
|
3
|
+
Instances of Tap::App coordinate the execution of tasks. 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. Apps basically consist of reference to a root directory, and task queue.
|
4
|
+
|
5
|
+
=== Root Directory (Tap::Root)
|
6
|
+
|
7
|
+
The root directory establishes the base of a standard directory structure that facilitates configuration, dependency loading, and file handling. Apps 'live' in the directory structure, but are not confined to it. Code associated with the root directory allows you to alias directories, basically meaning that the conceptual standard directories can be put anywhere in the file system.
|
8
|
+
|
9
|
+
The basic structure looks like this:
|
10
|
+
|
11
|
+
/path/to/root_dir
|
12
|
+
|- config
|
13
|
+
| `- sample
|
14
|
+
| `- task.yml # a default config file for Sample::Task
|
15
|
+
|- lib
|
16
|
+
| `- sample
|
17
|
+
| `- task.rb # a class file like above
|
18
|
+
|- tap.yml # a configuration file for Tap::App
|
19
|
+
|
20
|
+
All these files/directories are optional (and there are others that could be added), but for illustration say you instantiated an App to the directory above:
|
21
|
+
|
22
|
+
require 'tap'
|
23
|
+
|
24
|
+
app = Tap::App.new :root => '/path/to/root_dir'
|
25
|
+
app.root # => '/path/to/root_dir'
|
26
|
+
app['config'] # => '/path/to/root_dir/config'
|
27
|
+
app.filepath('config', 'sample/task.yml') # => '/path/to/root_dir/config/sample/task.yml'
|
28
|
+
|
29
|
+
Then if you wanted to alias the config directory somewhere else:
|
30
|
+
|
31
|
+
# set a new directory relative to root
|
32
|
+
app['config'] = 'alt'
|
33
|
+
app['config'] # => '/path/to/root_dir/alt'
|
34
|
+
app.filepath('config', 'sample/task.yml') # => '/path/to/root_dir/alt/sample/task.yml'
|
35
|
+
|
36
|
+
# set an absolute path to anywhere
|
37
|
+
app['config', true] = '/path/somewhere/else'
|
38
|
+
app['config'] # => '/path/somewhere/else'
|
39
|
+
app.filepath('config', 'sample/task.yml') # => '/path/somewhere/else/sample/task.yml'
|
40
|
+
|
41
|
+
While very simple, this ability to reference files using directory aliases is useful, powerful, and forms the basis of the Tap execution environment. All directory aliases and environment configurations can be defined in the 'tap.yml' file.
|
42
|
+
|
43
|
+
=== Task Queue
|
44
|
+
|
45
|
+
Apps coordinate the execution of tasks through a queue. Although referred to here as a 'task queue', the queue is actually just a stack of methods to run and the inputs to the methods. Any methods from any object can be enqued; tasks do not need to be involved.
|
46
|
+
|
47
|
+
During a run the enqued methods are run sequentially. When multithreading, multiple methods can be run at once, but normally methods are run one at a time on the same thread.
|
48
|
+
|
49
|
+
= Tasks (Tap::Task)
|
50
|
+
|
51
|
+
Tasks can be defined within a script using a syntax similar to Rake:
|
52
|
+
|
53
|
+
t = Tap::Task.new do |task|
|
54
|
+
# .. do something ...
|
55
|
+
end
|
56
|
+
t.execute
|
57
|
+
|
58
|
+
Unlike a Rake task, Tap tasks can be made to take inputs:
|
59
|
+
|
60
|
+
t = Tap::Task.new do |task, one, two|
|
61
|
+
# .. do something with the inputs ...
|
62
|
+
end
|
63
|
+
t.execute(1,2)
|
64
|
+
|
65
|
+
Tasks are designed for subclassing. A task class is structured like this (with annotation):
|
66
|
+
|
67
|
+
module Sample
|
68
|
+
# == Description
|
69
|
+
# This documentation is available in RDoc, as well as from the command line.
|
70
|
+
# === Usage
|
71
|
+
# % tap run sample/task
|
72
|
+
#
|
73
|
+
# By default, usage info comes up as well...
|
74
|
+
#
|
75
|
+
class Task < Tap::Task
|
76
|
+
|
77
|
+
# Configurations are defined like this. Tap makes
|
78
|
+
# the config documentation available in Rdoc and
|
79
|
+
# in the command line.
|
80
|
+
#
|
81
|
+
# The default 'config' creates accessors, as can
|
82
|
+
# be seen in the process method.
|
83
|
+
|
84
|
+
# Full documentation for the configuration
|
85
|
+
# can be written here.
|
86
|
+
config :key, "input" # command line documentation
|
87
|
+
|
88
|
+
# Configurations can be transformed or
|
89
|
+
# validated by an optional block.
|
90
|
+
config :transformation, "string" do |value| # this config is modified to "STRING"
|
91
|
+
value.upcase
|
92
|
+
end
|
93
|
+
config :standard_validation, {}, &c.check(Hash) # non-hash values raise an error
|
94
|
+
|
95
|
+
# Process receives each input from the command line
|
96
|
+
# and is analogous to the block in the samples above.
|
97
|
+
# Any number of inputs are allowed, including an
|
98
|
+
# arbitrary number of inputs (using *) and no inputs.
|
99
|
+
def process(input)
|
100
|
+
|
101
|
+
# log is available to record information
|
102
|
+
result = "#{input} was processed with #{key}"
|
103
|
+
log self.name, result
|
104
|
+
|
105
|
+
result
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
Once instantiated, tasks can be enqued to an App or joined into a workflow.
|
111
|
+
|
112
|
+
All task instances may have a name, which serves as a relative filepath to a configuration file and other associated files. When the application instantiates a task by the name 'sample/task' it sets the instance configs from 'config/sample/task.yml'. Nil can be used to specify no config file.
|
113
|
+
|
114
|
+
Names need not be unique. Multiple task instances, even from different classes, may be named the same and thus get their configurations from the same file. A map of task names to task classes can be set up in an app, allowing easy lookup and task instantiation through the app.task method:
|
115
|
+
|
116
|
+
app = Tap:App.instance
|
117
|
+
|
118
|
+
# set up a mapping between a name and a task class
|
119
|
+
app.map["alt"] = Sample::Task
|
120
|
+
|
121
|
+
t1 = app.task("sample/task") # Sample::Task configured from 'config/sample/task.yml'
|
122
|
+
t2 = app.task("alt") # Sample::Task configured from 'config/alt.yml'
|
123
|
+
|
124
|
+
# the idea is the same if you manually make a task...
|
125
|
+
|
126
|
+
t3 = Tap::Task.new("alt") # Tap::Task configured from 'config/alt.yml'
|
127
|
+
|
128
|
+
t1.class # => Sample::Task
|
129
|
+
t2.class # => Sample::Task
|
130
|
+
t3.class # => Tap::Task
|
131
|
+
|
132
|
+
= Workflows (Tap::Workflow)
|
133
|
+
|
134
|
+
Once instantiated, tasks can be joined into workflows. The workflow model used by Tap is very simple; workflows are implemented using the App queue, whereby each tasks enques the next task (or tasks) in the workflow when the task completes.
|
135
|
+
|
136
|
+
Each task can be assigned an on_complete block to do so. Arbitrary workflow logic can be used to join tasks in this way, but by default Tap supports sequencing, forking, and merging. If a task has no on_complete block, App collects the unhandled results in app.aggregator so they can be handled somewhere else.
|
137
|
+
|
138
|
+
Workflows are not Tasks, but work exactly like Tasks. Workflows can be configured, enqued, used in or joined to other workflows, and subclassed.
|
139
|
+
|
140
|
+
= Auditing (Tap::Support::Audit)
|
141
|
+
|
142
|
+
Tap tracks inputs as they are modified by various tasks. At the end of a run, the individual results can be tracked back to it's original value, through the tasks that modified it. This auditing can be very useful when workflows diverge (as they often do), adding or subtracting steps depending on the input.
|
143
|
+
|
144
|
+
Auditing is largely invisible except in on_complete blocks. On complete blocks receive the audited results so that this information can be used, as needed, to make decisions.
|
145
|
+
|
146
|
+
t = Task.new
|
147
|
+
t.on_complete do |_result| # _result is an Audit instance
|
148
|
+
_result._current # the current value
|
149
|
+
_result._original # the original value
|
150
|
+
end
|
151
|
+
|
data/Command Reference
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
= Tap from the Command Line
|
2
|
+
|
3
|
+
The tap command is the gateway for the execution of sub-commands. To get help for tap, type:
|
4
|
+
|
5
|
+
% tap --help
|
6
|
+
|
7
|
+
The tap command sets up the execution environment from 'tap.yml', if it exists, and passes control to the specified sub-command. Sub-command help can be obtained using:
|
8
|
+
|
9
|
+
% tap [sub-command] --help
|
10
|
+
|
11
|
+
== run
|
12
|
+
|
13
|
+
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:
|
14
|
+
|
15
|
+
% tap run sample/task
|
16
|
+
% tap run -- sample/task --key=value input_one -- another/task input_two
|
17
|
+
|
18
|
+
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 run itself can be specified before the first option break.
|
19
|
+
|
20
|
+
% tap run --debug -- sample/task --key=value
|
21
|
+
|
22
|
+
Here run receives the '--debug' option and sample/task receives the '--key=value' option'. <em>NOTE</em> 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:
|
23
|
+
|
24
|
+
% tap run --help
|
25
|
+
% tap run sample/task --help
|
26
|
+
|
27
|
+
Inputs work the same way. For example:
|
28
|
+
|
29
|
+
% tap run -- sample/task --key=value one -- another/task two three
|
30
|
+
|
31
|
+
Specifies the following:
|
32
|
+
|
33
|
+
t1 = app.task('sample/task', :key => 'value')
|
34
|
+
t1.enq('one')
|
35
|
+
|
36
|
+
t2 = app.task('another/task')
|
37
|
+
t2.enq('two', 'three')
|
38
|
+
|
39
|
+
Any number of tasks, configurations, and inputs may be specified in this way. As a special note, rake tasks can be specified as well. If the app cannot find a tap task by the specified name, rake is loaded (using the same loading rules as the rake command) and run tries to find a corresponding rake task. ENV options can be specified in the rake statement.
|
40
|
+
|
41
|
+
% tap run -- test KEY=value
|
42
|
+
|
43
|
+
=== YAML inputs
|
44
|
+
|
45
|
+
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}.
|
46
|
+
|
47
|
+
On *nix, just hit enter to get the next line:
|
48
|
+
|
49
|
+
% tap run -- sample/task '---
|
50
|
+
> number: 1'
|
51
|
+
|
52
|
+
On Windows, you need to pull some tricks to get newlines into your argument. Cleverly use a caret to ignore the next line feed:
|
53
|
+
|
54
|
+
% tap run -- sample/task '---^
|
55
|
+
More?
|
56
|
+
More? number: 1'
|
57
|
+
|
58
|
+
Notice that pressing enter _every other line_ is what actually puts the "\n" into the parameter. Keep using carets to enter more lines. The syntax on Windows isn't exactly pretty, but it 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:
|
59
|
+
|
60
|
+
% ruby C:/ruby/bin/tap run -- sample/task '---^
|
61
|
+
More?
|
62
|
+
More? number: 1'
|
63
|
+
|
64
|
+
== generate/destroy
|
65
|
+
|
66
|
+
Generate and destory launch generator scripts, the same as in Rails. By default Tap provides generators for:
|
67
|
+
|
68
|
+
root:: the basic Tap directory structure
|
69
|
+
task:: a Tap:Task and test for the task
|
70
|
+
file_task:: a Tap::FileTask and test for the task
|
71
|
+
workflow:: a Tap::Workflow and test for the workflow
|
72
|
+
config:: a yaml config file for the specified task
|
73
|
+
command:: a new subcommand
|
74
|
+
generator:: a new generator
|
75
|
+
|
76
|
+
Some examples:
|
77
|
+
|
78
|
+
% tap generate root .
|
79
|
+
% tap generate task sample_task
|
80
|
+
% tap generate config sample_task
|
81
|
+
|
82
|
+
% tap destroy config sample_task
|
83
|
+
% tap destroy task sample_task
|
84
|
+
% tap destroy root .
|
85
|
+
|
86
|
+
== console
|
87
|
+
|
88
|
+
Console opens an irb session with Tap loaded and configured using 'tap.yml'. Console defines a variable 'app' referencing Tap::App.instance, for easy access.
|
89
|
+
|
90
|
+
% tap console
|
91
|
+
irb(main):001:0> app.log(:hello)
|
92
|
+
I[17:18:53] hello
|
93
|
+
=> true
|
94
|
+
irb(main):002:0>
|
95
|
+
|
96
|
+
For actively testing your code, remember that many of your files will be loaded using Dependencies (from {ActiveSupport}[http://rubyforge.org/projects/activesupport/]). You can modify your code, clear the dependencies, and observe the changes within a single session. The command is:
|
97
|
+
|
98
|
+
irb(main):003:0> app.reload
|
99
|
+
# => [... an array of unloaded constants ...]
|
data/History
CHANGED
@@ -24,5 +24,29 @@ Documentation is still patchy, but improving.
|
|
24
24
|
* documentation, documentation, documentation
|
25
25
|
* many other things as well...
|
26
26
|
|
27
|
+
== 0.9.0 / 2008-04-09 revision 246
|
27
28
|
|
29
|
+
Major update to Tap. Many changes in this release ARE NOT BACKWARD COMPATIBLE.
|
30
|
+
|
31
|
+
* Reworked Task and App such that methods, are
|
32
|
+
enqued and executed. Made the Executable module
|
33
|
+
to allow any Method to be enqued and executed.
|
34
|
+
* App now aggregates results for methods that have no
|
35
|
+
on_complete block; enabled access through App#results
|
36
|
+
and App#_results.
|
37
|
+
* Removed iteration from tasks
|
38
|
+
* Task no longer templates app.config_templates. Templating code
|
39
|
+
removed from this distribution.
|
40
|
+
* Work to improve audit usability and visualization
|
41
|
+
* Removed methods forwarding from Audit to Audit#_current,
|
42
|
+
as well as ambiguous Audit methods
|
43
|
+
* Root [] now returns expanded paths unchanged. Example:
|
44
|
+
app['relative/path'] # => File.join(app.root, 'relative/path')
|
45
|
+
app['/expanded/path'] # => '/expanded/path'
|
46
|
+
* Generalized rake support; now supports version 0.8.1
|
47
|
+
* Fixes in generators
|
48
|
+
* Improvements in running of multithread tasks
|
49
|
+
* Removed condition blocks from tasks
|
50
|
+
* many other things also...
|
28
51
|
|
52
|
+
|
data/MIT-LICENSE
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Copyright (c) 2006-2007, Regents of the University of Colorado.
|
2
|
-
Developer:: Simon Chiang, Biomolecular Structure Program
|
2
|
+
Developer:: Simon Chiang, Biomolecular Structure Program, Hansen Lab
|
3
3
|
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
data/README
CHANGED
@@ -2,41 +2,44 @@
|
|
2
2
|
|
3
3
|
A framework for creating configurable, distributable, and easy-to-use tasks and workflow applications.
|
4
4
|
|
5
|
-
See the {website}[http://tap.rubyforge.org] for more information
|
5
|
+
See the {website}[http://tap.rubyforge.org] for more information.
|
6
6
|
|
7
7
|
== Description
|
8
8
|
|
9
|
-
Tap provides a framework
|
10
|
-
Tap provides a lot of framework niceties like generators and libraries geared towards testing tasks,
|
11
|
-
generating documentation, as well as task execution and distribution. Tasks are immediately available
|
12
|
-
from the comand line through though the 'tap' command.
|
9
|
+
Tap provides a framework to define, configure, and join tasks into workflows. Tap provides a lot of niceties like generators and libraries geared towards testing tasks, generating documentation, as well as task execution and distribution. Tasks are immediately available from the command line through the 'tap' command.
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
% tap run sample/task
|
11
|
+
Make a task:
|
17
12
|
|
18
|
-
|
19
|
-
First you generate a packaging script, then use rubyscript2exe to make the executable.
|
13
|
+
% tap generate task sample/task
|
20
14
|
|
21
|
-
|
22
|
-
% rubyscript2exe pkg/sample.rb
|
15
|
+
Run the task setting the 'key' configuration:
|
23
16
|
|
24
|
-
|
25
|
-
|
17
|
+
% tap run -- sample/task --key=value input
|
18
|
+
ctl-i prints information
|
19
|
+
ctl-c interupts execution
|
20
|
+
beginning run...
|
21
|
+
I[10:53:11] sample/task input was processed with value
|
22
|
+
|
23
|
+
Interact with the task using irb:
|
24
|
+
|
25
|
+
% tap console
|
26
|
+
irb(main):001:0> t = app.task('sample/task', :key => 'value')
|
27
|
+
irb(main):002:0> t.enq('input')
|
28
|
+
irb(main):003:0> app.run
|
29
|
+
I[10:55:17] sample/task input was processed with value
|
26
30
|
|
27
31
|
Additional Notes:
|
28
32
|
|
29
33
|
- Tap can incorporate and run Rake[http://rake.rubyforge.org/] tasks as well as Tap tasks.
|
30
34
|
- Tap task libraries are designed for distribution as gems.
|
31
|
-
- Tap is tested on both MRI (the standard Ruby interpreter) and JRuby[http://jruby.codehaus.org/].
|
35
|
+
- Tap is tested on both MRI (the standard Ruby interpreter, versions 1.8.6 and 1.9.0) and JRuby[http://jruby.codehaus.org/].
|
32
36
|
|
33
37
|
=== Bugs/Known Issues
|
34
38
|
|
35
|
-
- The threading model for executing multithreaded tasks does not currently make shared resources
|
36
|
-
like Tap::App completely thread-safe and should be considered *experimental*. If you're concerned,
|
37
|
-
don't multithread your tasks.
|
38
39
|
- Some inconsequential tests on JRuby fail due to bugs in JRuby itself.
|
39
|
-
-
|
40
|
+
- Several patches are required so that Tap runs properly on MRI 1.9.0. These
|
41
|
+
will likely resolve themselves as 1.9.0 becomes stable.
|
42
|
+
- Some code is still in progress; in general the well-documented code is stable.
|
40
43
|
|
41
44
|
== Info
|
42
45
|
|
@@ -51,49 +54,18 @@ Tap is available as a gem on RubyForge[http://rubyforge.org/projects/tap]. Use:
|
|
51
54
|
|
52
55
|
% gem install tap
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
<b>See the tutorial for information on using Tap programatically.</b>
|
57
|
-
|
58
|
-
Begin by creating a tap root directory structure:
|
59
|
-
|
60
|
-
% tap generate root /path/to/root
|
61
|
-
% cd /path/to/root
|
62
|
-
|
63
|
-
Make a task:
|
64
|
-
|
65
|
-
% tap generate task sample/task
|
57
|
+
See the tutorial or check out the {website}[http://tap.rubyforge.org] to get started using Tap programatically.
|
66
58
|
|
67
|
-
|
68
|
-
|
69
|
-
% tap run test
|
70
|
-
|
71
|
-
Get help for the task:
|
59
|
+
== Credits
|
72
60
|
|
73
|
-
|
74
|
-
|
75
|
-
Run the task, setting the 'key' configuration and passing some inputs:
|
76
|
-
|
77
|
-
% tap run -- sample/task --label=processing one two
|
78
|
-
|
79
|
-
Package the task into an executable (rubyscript2exe must be installed
|
80
|
-
and may not work on platforms where rubyscript2exe is squirrelly, ie
|
81
|
-
OS X)
|
61
|
+
A great deal of inspiration came from other excellent open-source projects including Rake[http://rake.rubyforge.org] and {Ruby on Rails}[http://www.rubyonrails.org].
|
82
62
|
|
83
|
-
|
84
|
-
% rubyscript2exe pkg/sample.rb
|
63
|
+
Thanks to my advisor {Dr. Kirk Hansen}[http://hsc-proteomics.uchsc.edu/hansenlab/] for his patience in letting me work on this project, and for putting together an awesome lab.
|
85
64
|
|
86
|
-
|
65
|
+
Most of all I would like to <b>thank my family</b> for their never-ending support.
|
87
66
|
|
88
|
-
|
89
|
-
Rake[http://rake.rubyforge.org] and {Ruby on Rails}[http://www.rubyonrails.org].
|
90
|
-
I also want to give credit to RubyGems[http://www.rubygems.org] and
|
91
|
-
RubyForge[http://rubyforge.org] because they are crucial parts of what make Ruby a
|
92
|
-
great language to work with.
|
67
|
+
=== Code
|
93
68
|
|
94
|
-
|
95
|
-
for his patience in letting me work on this project, and for putting together an awesome
|
96
|
-
lab.
|
69
|
+
Tap uses ActiveSupport for dependencies loading and a variety of other extensions. Tap uses Rails generators and redistributes the code in the gem, to avoid an additional dependency.
|
97
70
|
|
98
|
-
Most of all I would like to thank my family for their never-ending support.
|
99
71
|
|
data/Rakefile
CHANGED
@@ -4,7 +4,8 @@ require 'rake/rdoctask'
|
|
4
4
|
require 'rake/gempackagetask'
|
5
5
|
|
6
6
|
$:.unshift "./lib"
|
7
|
-
require 'tap/
|
7
|
+
require 'tap/constants'
|
8
|
+
require 'tap/patches/rake/testtask.rb'
|
8
9
|
|
9
10
|
desc 'Default: Run tests.'
|
10
11
|
task :default => :test
|
@@ -19,12 +20,12 @@ spec = Gem::Specification.new do |s|
|
|
19
20
|
s.version = Tap::VERSION
|
20
21
|
s.author = "Simon Chiang"
|
21
22
|
s.email = "simon.chiang@uchsc.edu"
|
22
|
-
s.homepage =
|
23
|
+
s.homepage = Tap::WEBSITE
|
23
24
|
s.platform = Gem::Platform::RUBY
|
24
25
|
s.summary = "A framework for configurable, distributable, and easy-to-use tasks and workflow applications."
|
25
|
-
s.files = File.read("Manifest.txt").split("\n").select {|f| f !~ /^\s*#/ && File.
|
26
|
+
s.files = File.read("Manifest.txt").split("\n").select {|f| f !~ /^\s*#/ && !File.directory?(f) }
|
26
27
|
s.require_path = "lib"
|
27
|
-
s.
|
28
|
+
s.rubyforge_project = "tap"
|
28
29
|
s.test_file = "test/tap_test_suite.rb"
|
29
30
|
s.bindir = "bin"
|
30
31
|
s.executables = ["tap"]
|
@@ -32,7 +33,7 @@ spec = Gem::Specification.new do |s|
|
|
32
33
|
|
33
34
|
s.has_rdoc = true
|
34
35
|
s.rdoc_options << '--title' << 'Tap - Task Application' << '--main' << 'README'
|
35
|
-
s.extra_rdoc_files = ["README", "MIT-LICENSE", "History", "Tutorial"]
|
36
|
+
s.extra_rdoc_files = ["README", "MIT-LICENSE", "History", "Tutorial", "Basic Overview", "Command Reference"]
|
36
37
|
s.add_dependency("activesupport", ">=2.0.1")
|
37
38
|
end
|
38
39
|
|
@@ -49,7 +50,14 @@ end
|
|
49
50
|
|
50
51
|
desc 'Run tests.'
|
51
52
|
Rake::TestTask.new(:test) do |t|
|
52
|
-
t.
|
53
|
+
t.test_files = if ENV['check']
|
54
|
+
Dir.glob( File.join('test', "**/*#{ENV['check']}*_check.rb") )
|
55
|
+
else
|
56
|
+
Dir.glob( File.join('test', ENV['pattern'] || '**/*_test.rb') ).delete_if do |filename|
|
57
|
+
filename =~ /test\/check/
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
53
61
|
t.verbose = true
|
54
62
|
t.warning = true
|
55
63
|
end
|
@@ -66,45 +74,30 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
66
74
|
rdoc.title = 'tap'
|
67
75
|
rdoc.template = 'tap/support/tdoc/tdoc_html_template'
|
68
76
|
rdoc.options << '--line-numbers' << '--inline-source' << '--fmt' << 'tdoc'
|
69
|
-
rdoc.rdoc_files.include('README', 'MIT-LICENSE', "History", "Tutorial")
|
77
|
+
rdoc.rdoc_files.include('README', 'MIT-LICENSE', "History", "Tutorial", "Basic Overview", "Command Reference")
|
70
78
|
rdoc.rdoc_files.include('lib/tap/**/*.rb')
|
71
79
|
end
|
72
80
|
|
73
81
|
desc 'Generate website.'
|
74
|
-
task :website => [:rdoc] do |t|
|
75
|
-
require 'tap
|
76
|
-
require 'redcloth'
|
77
|
-
require 'erb'
|
82
|
+
task :website => [:rdoc] do |t|
|
83
|
+
require 'tap'
|
78
84
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
+
# temporary
|
86
|
+
$: << File.dirname(__FILE__) + "/tap/simple_site/lib"
|
87
|
+
$: << File.dirname(__FILE__) + "/tap/ddb/lib"
|
88
|
+
Dependencies.load_paths << File.dirname(__FILE__) + "/tap/simple_site/lib"
|
89
|
+
Dependencies.load_paths << File.dirname(__FILE__) + "/tap/ddb/lib"
|
90
|
+
|
91
|
+
require 'simple_site'
|
85
92
|
|
86
|
-
|
87
|
-
rm_r output_dir if File.exists?(output_dir)
|
88
|
-
mkdir_p output_dir
|
89
|
-
cp "website/index.html", File.join(output_dir, "index.html")
|
90
|
-
cp_r "website/images", File.join(output_dir, "images")
|
91
|
-
cp_r "website/stylesheets", File.join(output_dir, "stylesheets")
|
92
|
-
cp_r "rdoc", File.join(output_dir, "rdoc")
|
93
|
+
app = Tap::App.instance
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
@title = base.capitalize
|
99
|
-
@content_main = RedCloth.new(File.read(source)).to_html
|
100
|
-
@content_sub = File.exists?(sub_source) ? RedCloth.new(File.read(sub_source)).to_html : ""
|
101
|
-
|
102
|
-
target = File.join(output_dir, base + ".html")
|
103
|
-
File.open(target, "w") do |file|
|
104
|
-
file << ERB.new(page_template).result
|
105
|
-
end
|
106
|
-
end
|
95
|
+
app['pkg'] = "pkg/website-#{Tap::VERSION}"
|
96
|
+
app['content'] = 'website/content'
|
97
|
+
app['views'] = 'website/views'
|
98
|
+
app.run 'simple_site/compile', '.'
|
107
99
|
|
100
|
+
cp_r "rdoc", app.filepath('pkg', "rdoc")
|
108
101
|
end
|
109
102
|
|
110
103
|
#
|