tap 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/Basic Overview +151 -0
  2. data/Command Reference +99 -0
  3. data/History +24 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README +29 -57
  6. data/Rakefile +30 -37
  7. data/Tutorial +243 -191
  8. data/bin/tap +66 -35
  9. data/lib/tap.rb +47 -29
  10. data/lib/tap/app.rb +700 -342
  11. data/lib/tap/{script → cmd}/console.rb +0 -0
  12. data/lib/tap/{script → cmd}/destroy.rb +0 -0
  13. data/lib/tap/{script → cmd}/generate.rb +0 -0
  14. data/lib/tap/cmd/run.rb +156 -0
  15. data/lib/tap/constants.rb +4 -0
  16. data/lib/tap/dump.rb +57 -0
  17. data/lib/tap/env.rb +316 -0
  18. data/lib/tap/file_task.rb +106 -109
  19. data/lib/tap/generator.rb +4 -1
  20. data/lib/tap/generator/generators/command/USAGE +6 -0
  21. data/lib/tap/generator/generators/command/command_generator.rb +17 -0
  22. data/lib/tap/generator/generators/{script/templates/script.erb → command/templates/command.erb} +10 -10
  23. data/lib/tap/generator/generators/config/USAGE +21 -0
  24. data/lib/tap/generator/generators/config/config_generator.rb +17 -7
  25. data/lib/tap/generator/generators/file_task/USAGE +3 -0
  26. data/lib/tap/generator/generators/file_task/file_task_generator.rb +16 -0
  27. data/lib/tap/generator/generators/file_task/templates/file.txt +2 -0
  28. data/lib/tap/generator/generators/file_task/templates/file.yml +3 -0
  29. data/lib/tap/generator/generators/file_task/templates/task.erb +26 -20
  30. data/lib/tap/generator/generators/file_task/templates/test.erb +20 -10
  31. data/lib/tap/generator/generators/generator/generator_generator.rb +1 -1
  32. data/lib/tap/generator/generators/generator/templates/generator.erb +21 -12
  33. data/lib/tap/generator/generators/root/templates/Rakefile +33 -24
  34. data/lib/tap/generator/generators/root/templates/tap.yml +28 -31
  35. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +1 -0
  36. data/lib/tap/generator/generators/task/USAGE +3 -0
  37. data/lib/tap/generator/generators/task/task_generator.rb +18 -5
  38. data/lib/tap/generator/generators/task/templates/task.erb +7 -12
  39. data/lib/tap/generator/generators/task/templates/test.erb +10 -11
  40. data/lib/tap/generator/generators/workflow/templates/task.erb +1 -1
  41. data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
  42. data/lib/tap/patches/rake/rake_test_loader.rb +8 -0
  43. data/lib/tap/patches/rake/testtask.rb +55 -0
  44. data/lib/tap/patches/ruby19/backtrace_filter.rb +51 -0
  45. data/lib/tap/patches/ruby19/parsedate.rb +16 -0
  46. data/lib/tap/root.rb +172 -67
  47. data/lib/tap/script.rb +70 -336
  48. data/lib/tap/support/aggregator.rb +55 -0
  49. data/lib/tap/support/audit.rb +281 -280
  50. data/lib/tap/support/batchable.rb +59 -0
  51. data/lib/tap/support/class_configuration.rb +279 -0
  52. data/lib/tap/support/configurable.rb +92 -0
  53. data/lib/tap/support/configurable_methods.rb +296 -0
  54. data/lib/tap/support/executable.rb +98 -0
  55. data/lib/tap/support/executable_queue.rb +82 -0
  56. data/lib/tap/support/logger.rb +9 -15
  57. data/lib/tap/support/rake.rb +43 -54
  58. data/lib/tap/support/run_error.rb +32 -13
  59. data/lib/tap/support/shell_utils.rb +47 -0
  60. data/lib/tap/support/tdoc.rb +9 -8
  61. data/lib/tap/support/tdoc/config_attr.rb +40 -16
  62. data/lib/tap/support/validation.rb +77 -0
  63. data/lib/tap/support/versions.rb +36 -36
  64. data/lib/tap/task.rb +276 -482
  65. data/lib/tap/test.rb +20 -261
  66. data/lib/tap/test/env_vars.rb +7 -5
  67. data/lib/tap/test/file_methods.rb +126 -121
  68. data/lib/tap/test/subset_methods.rb +86 -45
  69. data/lib/tap/test/tap_methods.rb +271 -0
  70. data/lib/tap/workflow.rb +174 -46
  71. data/test/app/config/another/task.yml +1 -0
  72. data/test/app/config/erb.yml +2 -1
  73. data/test/app/config/some/task.yml +1 -0
  74. data/test/app/config/template.yml +2 -6
  75. data/test/app_test.rb +1241 -1008
  76. data/test/env/test_configure/recurse_a.yml +2 -0
  77. data/test/env/test_configure/recurse_b.yml +2 -0
  78. data/test/env/test_configure/tap.yml +23 -0
  79. data/test/env/test_load_env_config/dir/tap.yml +3 -0
  80. data/test/env/test_load_env_config/recurse_a.yml +2 -0
  81. data/test/env/test_load_env_config/recurse_b.yml +2 -0
  82. data/test/env/test_load_env_config/tap.yml +3 -0
  83. data/test/env_test.rb +198 -0
  84. data/test/file_task_test.rb +70 -53
  85. data/{lib/tap/generator/generators/package/USAGE → test/root/file.txt} +0 -0
  86. data/test/root_test.rb +621 -454
  87. data/test/script_test.rb +38 -174
  88. data/test/support/aggregator_test.rb +99 -0
  89. data/test/support/audit_test.rb +409 -416
  90. data/test/support/batchable_test.rb +74 -0
  91. data/test/support/{task_configuration_test.rb → class_configuration_test.rb} +106 -47
  92. data/test/{task/config/overriding.yml → support/configurable/config/configured.yml} +0 -0
  93. data/test/support/configurable_test.rb +295 -0
  94. data/test/support/executable_queue_test.rb +103 -0
  95. data/test/support/executable_test.rb +38 -0
  96. data/test/support/logger_test.rb +17 -17
  97. data/test/support/rake_test.rb +4 -2
  98. data/test/support/shell_utils_test.rb +24 -0
  99. data/test/support/tdoc_test.rb +265 -258
  100. data/test/support/validation_test.rb +54 -0
  101. data/test/support/versions_test.rb +38 -38
  102. data/test/tap_test_helper.rb +19 -5
  103. data/test/tap_test_suite.rb +5 -2
  104. data/test/task_base_test.rb +13 -104
  105. data/test/task_syntax_test.rb +300 -0
  106. data/test/task_test.rb +258 -381
  107. data/test/test/env_vars_test.rb +40 -40
  108. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/one.txt +0 -0
  109. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/expected/two.txt +0 -0
  110. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/one.txt +0 -0
  111. data/test/test/file_methods/{test_assert_output_files_equal → test_assert_files}/input/two.txt +0 -0
  112. data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/one.txt +0 -0
  113. data/test/test/{test_file_task_test → file_methods/test_assert_files_can_have_no_expected_files_if_specified}/input/two.txt +0 -0
  114. data/test/test/file_methods/test_assert_files_fails_for_different_content/expected/one.txt +1 -0
  115. data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_different_content}/expected/two.txt +0 -0
  116. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/one.txt +1 -0
  117. data/test/test/file_methods/test_assert_files_fails_for_different_content/input/two.txt +1 -0
  118. data/test/test/{test_file_task_test → file_methods/test_assert_files_fails_for_missing_expected_file}/expected/one.txt +0 -0
  119. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/one.txt +1 -0
  120. data/test/test/file_methods/test_assert_files_fails_for_missing_expected_file/input/two.txt +1 -0
  121. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/one.txt +1 -0
  122. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/expected/two.txt +1 -0
  123. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/one.txt +1 -0
  124. data/test/test/file_methods/test_assert_files_fails_for_missing_output_file/input/two.txt +1 -0
  125. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/one.txt +1 -0
  126. data/test/test/file_methods/test_assert_files_fails_for_no_expected_files/input/two.txt +1 -0
  127. data/test/test/file_methods_doc/test_sub/expected/one.txt +1 -0
  128. data/test/test/file_methods_doc/test_sub/expected/two.txt +1 -0
  129. data/test/test/file_methods_doc/test_sub/input/one.txt +1 -0
  130. data/test/test/file_methods_doc/test_sub/input/two.txt +1 -0
  131. data/test/test/file_methods_doc_test.rb +29 -0
  132. data/test/test/file_methods_test.rb +214 -143
  133. data/test/test/subset_methods_test.rb +111 -115
  134. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/a.txt +0 -0
  135. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/expected/task/name/b.txt +0 -0
  136. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/a.txt +0 -0
  137. data/test/test/{test_assert_expected_result_files → tap_methods/test_assert_files}/input/b.txt +0 -0
  138. data/test/test/tap_methods_test.rb +399 -0
  139. data/test/workflow_test.rb +101 -91
  140. metadata +86 -70
  141. data/lib/tap/generator/generators/package/package_generator.rb +0 -38
  142. data/lib/tap/generator/generators/package/templates/package.erb +0 -186
  143. data/lib/tap/generator/generators/script/USAGE +0 -0
  144. data/lib/tap/generator/generators/script/script_generator.rb +0 -17
  145. data/lib/tap/script/run.rb +0 -154
  146. data/lib/tap/support/batch_queue.rb +0 -162
  147. data/lib/tap/support/combinator.rb +0 -114
  148. data/lib/tap/support/task_configuration.rb +0 -169
  149. data/lib/tap/support/template.rb +0 -81
  150. data/lib/tap/support/templater.rb +0 -155
  151. data/lib/tap/version.rb +0 -4
  152. data/test/app/config/addition_template.yml +0 -6
  153. data/test/app_class_test.rb +0 -33
  154. data/test/check/binding_eval.rb +0 -23
  155. data/test/check/define_method_check.rb +0 -22
  156. data/test/check/dependencies_check.rb +0 -175
  157. data/test/check/inheritance_check.rb +0 -22
  158. data/test/support/batch_queue_test.rb +0 -320
  159. data/test/support/combinator_test.rb +0 -249
  160. data/test/support/template_test.rb +0 -122
  161. data/test/support/templater/erb.txt +0 -2
  162. data/test/support/templater/erb.yml +0 -2
  163. data/test/support/templater/somefile.txt +0 -2
  164. data/test/support/templater_test.rb +0 -192
  165. data/test/task/config/template.yml +0 -4
  166. data/test/task_class_test.rb +0 -170
  167. data/test/task_execute_test.rb +0 -262
  168. data/test/test/file_methods/test_assert_expected/expected/file.txt +0 -1
  169. data/test/test/file_methods/test_assert_expected/expected/folder/file.txt +0 -1
  170. data/test/test/file_methods/test_assert_expected/input/file.txt +0 -1
  171. data/test/test/file_methods/test_assert_expected/input/folder/file.txt +0 -1
  172. data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
  173. data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
  174. data/test/test/file_methods/test_file_compare/expected/output_1.txt +0 -3
  175. data/test/test/file_methods/test_file_compare/expected/output_2.txt +0 -1
  176. data/test/test/file_methods/test_file_compare/input/input_1.txt +0 -3
  177. data/test/test/file_methods/test_file_compare/input/input_2.txt +0 -3
  178. data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
  179. data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
  180. data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
  181. data/test/test/file_methods/test_yml_compare/expected/output_1.yml +0 -6
  182. data/test/test/file_methods/test_yml_compare/expected/output_2.yml +0 -6
  183. data/test/test/file_methods/test_yml_compare/input/input_1.yml +0 -4
  184. data/test/test/file_methods/test_yml_compare/input/input_2.yml +0 -4
  185. data/test/test_test.rb +0 -373
@@ -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
+
@@ -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
+
@@ -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 and tutorials.
5
+ See the {website}[http://tap.rubyforge.org] for more information.
6
6
 
7
7
  == Description
8
8
 
9
- Tap provides a framework facilitaing the definition, configuration, and joining of tasks into workflows.
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
- Running a task named 'sample/task' is simply:
15
-
16
- % tap run sample/task
11
+ Make a task:
17
12
 
18
- Packaging tasks into an executables can be accomplished using {rubyscript2exe}[http://rubyforge.org/projects/rubyscript2exe/].
19
- First you generate a packaging script, then use rubyscript2exe to make the executable.
13
+ % tap generate task sample/task
20
14
 
21
- % tap generate package sample "run sample/task"
22
- % rubyscript2exe pkg/sample.rb
15
+ Run the task setting the 'key' configuration:
23
16
 
24
- The result is a fully contained, documented executable that runs on other computers
25
- of the same platform, without Tap or even Ruby[http://www.ruby-lang.org/en/] being installed.
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
- - TDoc documentation is still under development. You may find small typographic bugs.
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
- == Usage
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
- Test the task (in fact invokes the rake test task):
68
-
69
- % tap run test
70
-
71
- Get help for the task:
59
+ == Credits
72
60
 
73
- % tap run -- sample/task --help
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
- % tap generate package sample "run sample/task"
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
- == Credits
65
+ Most of all I would like to <b>thank my family</b> for their never-ending support.
87
66
 
88
- A great deal of inspiration came from other excellent open-source projects including
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
- Thanks to my advisor {Dr. Kirk Hansen}[http://hsc-proteomics.uchsc.edu/hansenlab/]
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/version.rb'
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 = "http://rubyforge.org/projects/tap/"
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.file?(f) }
26
+ s.files = File.read("Manifest.txt").split("\n").select {|f| f !~ /^\s*#/ && !File.directory?(f) }
26
27
  s.require_path = "lib"
27
- s.autorequire = "tap"
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.pattern = File.join('test', ENV['subset'] || '', ENV['pattern'] || '**/*_test.rb')
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/root'
76
- require 'redcloth'
77
- require 'erb'
82
+ task :website => [:rdoc] do |t|
83
+ require 'tap'
78
84
 
79
- # setup some variables
80
- page_template = File.read('website/page.erb')
81
- output_dir = "pkg/website-#{Tap::VERSION}"
82
- pages = FileList.new('website/pages/**/*.txt') do |list|
83
- list.exclude /_sub\.txt$/
84
- end
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
- # remove existing dir, move in or create pages
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
- pages.each do |source|
95
- base = Tap::Root.relative_filepath("./website/pages", source).chomp(".txt")
96
- sub_source = source.chomp(".txt") + "_sub.txt"
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
  #