tap 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. data/MIT-LICENSE +21 -0
  2. data/README +71 -0
  3. data/Rakefile +117 -0
  4. data/bin/tap +63 -0
  5. data/lib/tap.rb +15 -0
  6. data/lib/tap/app.rb +739 -0
  7. data/lib/tap/file_task.rb +354 -0
  8. data/lib/tap/generator.rb +29 -0
  9. data/lib/tap/generator/generators/config/USAGE +0 -0
  10. data/lib/tap/generator/generators/config/config_generator.rb +23 -0
  11. data/lib/tap/generator/generators/config/templates/config.erb +2 -0
  12. data/lib/tap/generator/generators/file_task/USAGE +0 -0
  13. data/lib/tap/generator/generators/file_task/file_task_generator.rb +21 -0
  14. data/lib/tap/generator/generators/file_task/templates/task.erb +27 -0
  15. data/lib/tap/generator/generators/file_task/templates/test.erb +12 -0
  16. data/lib/tap/generator/generators/root/USAGE +0 -0
  17. data/lib/tap/generator/generators/root/root_generator.rb +36 -0
  18. data/lib/tap/generator/generators/root/templates/Rakefile +48 -0
  19. data/lib/tap/generator/generators/root/templates/app.yml +19 -0
  20. data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +4 -0
  21. data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +26 -0
  22. data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
  23. data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +57 -0
  24. data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +108 -0
  25. data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +40 -0
  26. data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +21 -0
  27. data/lib/tap/generator/generators/root/templates/server/config/environment.rb +60 -0
  28. data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +5 -0
  29. data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +53 -0
  30. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +3 -0
  31. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +4 -0
  32. data/lib/tap/generator/generators/task/USAGE +0 -0
  33. data/lib/tap/generator/generators/task/task_generator.rb +21 -0
  34. data/lib/tap/generator/generators/task/templates/task.erb +21 -0
  35. data/lib/tap/generator/generators/task/templates/test.erb +29 -0
  36. data/lib/tap/generator/generators/workflow/USAGE +0 -0
  37. data/lib/tap/generator/generators/workflow/templates/task.erb +16 -0
  38. data/lib/tap/generator/generators/workflow/templates/test.erb +7 -0
  39. data/lib/tap/generator/generators/workflow/workflow_generator.rb +21 -0
  40. data/lib/tap/generator/options.rb +26 -0
  41. data/lib/tap/generator/usage.rb +26 -0
  42. data/lib/tap/root.rb +275 -0
  43. data/lib/tap/script/console.rb +7 -0
  44. data/lib/tap/script/destroy.rb +8 -0
  45. data/lib/tap/script/generate.rb +8 -0
  46. data/lib/tap/script/run.rb +111 -0
  47. data/lib/tap/script/server.rb +12 -0
  48. data/lib/tap/support/audit.rb +415 -0
  49. data/lib/tap/support/batch_queue.rb +165 -0
  50. data/lib/tap/support/combinator.rb +114 -0
  51. data/lib/tap/support/logger.rb +91 -0
  52. data/lib/tap/support/rap.rb +38 -0
  53. data/lib/tap/support/run_error.rb +20 -0
  54. data/lib/tap/support/template.rb +81 -0
  55. data/lib/tap/support/templater.rb +155 -0
  56. data/lib/tap/support/versions.rb +63 -0
  57. data/lib/tap/task.rb +448 -0
  58. data/lib/tap/test.rb +320 -0
  59. data/lib/tap/test/env_vars.rb +16 -0
  60. data/lib/tap/test/inference_methods.rb +298 -0
  61. data/lib/tap/test/subset_methods.rb +260 -0
  62. data/lib/tap/version.rb +3 -0
  63. data/lib/tap/workflow.rb +73 -0
  64. data/test/app/config/addition_template.yml +6 -0
  65. data/test/app/config/batch.yml +2 -0
  66. data/test/app/config/empty.yml +0 -0
  67. data/test/app/config/erb.yml +1 -0
  68. data/test/app/config/template.yml +6 -0
  69. data/test/app/config/version-0.1.yml +1 -0
  70. data/test/app/config/version.yml +1 -0
  71. data/test/app/lib/app_test_task.rb +2 -0
  72. data/test/app_class_test.rb +33 -0
  73. data/test/app_test.rb +1372 -0
  74. data/test/file_task/config/batch.yml +2 -0
  75. data/test/file_task/config/configured.yml +1 -0
  76. data/test/file_task/old_file_one.txt +0 -0
  77. data/test/file_task/old_file_two.txt +0 -0
  78. data/test/file_task_test.rb +1041 -0
  79. data/test/root/alt_lib/alt_module.rb +4 -0
  80. data/test/root/lib/absolute_alt_filepath.rb +2 -0
  81. data/test/root/lib/alternative_filepath.rb +2 -0
  82. data/test/root/lib/another_module.rb +2 -0
  83. data/test/root/lib/nested/some_module.rb +4 -0
  84. data/test/root/lib/no_module_included.rb +0 -0
  85. data/test/root/lib/some/module.rb +4 -0
  86. data/test/root/lib/some_class.rb +2 -0
  87. data/test/root/lib/some_module.rb +3 -0
  88. data/test/root/load_path/load_path_module.rb +2 -0
  89. data/test/root/load_path/skip_module.rb +2 -0
  90. data/test/root/mtime/older.txt +0 -0
  91. data/test/root/unload/full_path.rb +2 -0
  92. data/test/root/unload/loaded_by_nested.rb +2 -0
  93. data/test/root/unload/nested/nested_load.rb +6 -0
  94. data/test/root/unload/nested/nested_with_ext.rb +4 -0
  95. data/test/root/unload/nested/relative_path.rb +4 -0
  96. data/test/root/unload/older.rb +2 -0
  97. data/test/root/unload/unload_base.rb +9 -0
  98. data/test/root/versions/another.yml +0 -0
  99. data/test/root/versions/file-0.1.2.yml +0 -0
  100. data/test/root/versions/file-0.1.yml +0 -0
  101. data/test/root/versions/file.yml +0 -0
  102. data/test/root_test.rb +483 -0
  103. data/test/support/audit_test.rb +449 -0
  104. data/test/support/batch_queue_test.rb +320 -0
  105. data/test/support/combinator_test.rb +249 -0
  106. data/test/support/logger_test.rb +31 -0
  107. data/test/support/template_test.rb +122 -0
  108. data/test/support/templater/erb.txt +2 -0
  109. data/test/support/templater/erb.yml +2 -0
  110. data/test/support/templater/somefile.txt +2 -0
  111. data/test/support/templater_test.rb +192 -0
  112. data/test/support/versions_test.rb +71 -0
  113. data/test/tap_test_helper.rb +4 -0
  114. data/test/tap_test_suite.rb +4 -0
  115. data/test/task/config/batch.yml +2 -0
  116. data/test/task/config/batched.yml +2 -0
  117. data/test/task/config/configured.yml +1 -0
  118. data/test/task/config/example.yml +1 -0
  119. data/test/task/config/overriding.yml +2 -0
  120. data/test/task/config/task_with_config.yml +1 -0
  121. data/test/task/config/template.yml +4 -0
  122. data/test/task_class_test.rb +118 -0
  123. data/test/task_execute_test.rb +233 -0
  124. data/test/task_test.rb +424 -0
  125. data/test/test/inference_methods/test_assert_expected/expected/file.txt +1 -0
  126. data/test/test/inference_methods/test_assert_expected/expected/folder/file.txt +1 -0
  127. data/test/test/inference_methods/test_assert_expected/input/file.txt +1 -0
  128. data/test/test/inference_methods/test_assert_expected/input/folder/file.txt +1 -0
  129. data/test/test/inference_methods/test_assert_files_exist/input/input_1.txt +0 -0
  130. data/test/test/inference_methods/test_assert_files_exist/input/input_2.txt +0 -0
  131. data/test/test/inference_methods/test_file_compare/expected/output_1.txt +3 -0
  132. data/test/test/inference_methods/test_file_compare/expected/output_2.txt +1 -0
  133. data/test/test/inference_methods/test_file_compare/input/input_1.txt +3 -0
  134. data/test/test/inference_methods/test_file_compare/input/input_2.txt +3 -0
  135. data/test/test/inference_methods/test_infer_glob/expected/file.yml +0 -0
  136. data/test/test/inference_methods/test_infer_glob/expected/file_1.txt +0 -0
  137. data/test/test/inference_methods/test_infer_glob/expected/file_2.txt +0 -0
  138. data/test/test/inference_methods/test_yml_compare/expected/output_1.yml +6 -0
  139. data/test/test/inference_methods/test_yml_compare/expected/output_2.yml +6 -0
  140. data/test/test/inference_methods/test_yml_compare/input/input_1.yml +4 -0
  141. data/test/test/inference_methods/test_yml_compare/input/input_2.yml +4 -0
  142. data/test/test/inference_methods_test.rb +311 -0
  143. data/test/test/subset_methods_test.rb +115 -0
  144. data/test/test_test.rb +233 -0
  145. data/test/workflow_test.rb +108 -0
  146. metadata +274 -0
@@ -0,0 +1,354 @@
1
+ module Tap
2
+
3
+ # FileTask provides methods for making files
4
+
5
+ # FileTask process adds error handling code to restore any files marked
6
+ # for backup or files that were made (using make or mkdir) if an unhandled
7
+ # error occurs during processing. Set +restore_on_error+ to false to
8
+ # turn off automatic restore. In addtion, backed-up files can be removed
9
+ # when process completes by setting +remove_backed_up_files+ to true.
10
+ class FileTask < Task
11
+ set_default_config({
12
+ :backup_dir => :backup,
13
+ :backup_timestamp => "%Y%m%d_%H%M%S",
14
+ :restore_on_error => true,
15
+ :remove_backed_up_files => false},
16
+ :make_accessors => true)
17
+
18
+ attr_reader :inference_block, :backed_up_files, :made_files
19
+ attr_accessor :dirname
20
+
21
+ def initialize(*args)
22
+ super
23
+
24
+ batch.each do |task|
25
+ task.dirname = task.default_dirname
26
+ task.backed_up_files = {}
27
+ task.made_files = []
28
+ end
29
+ end
30
+
31
+ # Sets a block to perform path inference. Raises an error if inference_block
32
+ # is already set, unless override = true.
33
+ def inference(override=false, &block) # :yields: app[dir], dirname, *paths
34
+ raise "Inference block for task already set: #{name}" unless inference_block.nil? || override
35
+ self.inference_block = block
36
+ end
37
+
38
+ # Infers a path using the inference block, or by using app.filepath if
39
+ # no inference block is given. Note the actual inputs to the inference
40
+ # block are the application directory identified by dir, the dirname
41
+ # for the task, and the provided paths.
42
+ #
43
+ # t = FileTask.new
44
+ # t.app[:data] # => "/data"
45
+ # t.dirname # => "tap/file_task"
46
+ # t.infer_filepath(:data, "result.txt") # => "/data/tap/file_task/result.txt"
47
+ #
48
+ # t.inference do |root, dir, path|
49
+ # File.join(root, dir, path.chomp(".txt") + ".yml")
50
+ # end
51
+ #
52
+ # t.infer_filepath(:data, "result.txt") # => "/data/tap/file_task/result.yml"
53
+ #
54
+ def infer_filepath(dir, *paths) # :yields: app[dir], dirname, *paths
55
+ inference_block ?
56
+ inference_block.call(app[dir], dirname, *paths) :
57
+ app.filepath(dir, dirname, *paths)
58
+ end
59
+
60
+ # Makes a backup filepath for input filepath by doing the following:
61
+ # - insert a timestamp between the basename and extname of the filepath
62
+ # - identify a backup path as the part of the filepath relative to
63
+ # dirname, or the basename if the filepath is not relative to dirname
64
+ # - infer_filepath using the backup_dir and this backup path
65
+ #
66
+ # t = FileTask.new("dir/name", :backup_dir => :backup, :backup_timestamp => "%Y%m%d")
67
+ # t.app[:backup] # => "/backup"
68
+ # Date.today.to_s # => "2007-08-08"
69
+ #
70
+ # t.backup_filepath("path/to/folder/file.txt") # => "/backup/file_20070808.txt"
71
+ # t.backup_filepath("dir/name/folder/file.txt") # => "/backup/folder/file_20070808.txt"
72
+ #
73
+ def backup_filepath(filepath)
74
+ extname = File.extname(filepath)
75
+ backup_path = File.expand_path("#{filepath.chomp(extname)}_#{Time.now.strftime(backup_timestamp)}#{extname}")
76
+
77
+ split_index = backup_path.index(dirname + "/")
78
+ backup_path = split_index ?
79
+ backup_path[(split_index + dirname.length + 1)..-1] :
80
+ File.basename(backup_path)
81
+
82
+ infer_filepath(backup_dir, backup_path)
83
+ end
84
+
85
+ # A batch File.open method. If a block is given, each file in the list will be
86
+ # opened the open files passed to the block. Files are automatically closed when
87
+ # the block returns. If no block is given, the open files are returned.
88
+ def open(list, mode="rb")
89
+ open_files = []
90
+ begin
91
+ fu_list(list).each do |filepath|
92
+ open_files << File.open(filepath, mode)
93
+ end
94
+
95
+ block_given? ? yield(open_files) : open_files
96
+ ensure
97
+ open_files.each {|file| file.close } if block_given?
98
+ end
99
+ end
100
+
101
+ # Returns true if all of the targets are up to date relative to all of the sources
102
+ # AND the task config_file (if it exists). Single values or arrays can be provided
103
+ # for both targets and sources.
104
+ #
105
+ # Returns false if +force?+ is true.
106
+ def uptodate?(targets, sources=[])
107
+ if app.options.force
108
+ log_filepaths(:force, *targets)
109
+ false
110
+ else
111
+ targets = [targets] unless targets.kind_of?(Array)
112
+ sources = [sources] unless sources.kind_of?(Array)
113
+ sources << config_file
114
+ targets.each do |target|
115
+ return false unless FileUtils.uptodate?(target, sources)
116
+ end
117
+ true
118
+ end
119
+ end
120
+
121
+ # Makes a backup of each file in list to backup_filepath(file) and registers
122
+ # the files so that they can be restored using restore. If copy is true, the
123
+ # files will be copied to backup_filepath, otherwise the file is moved to
124
+ # backup_filepath. Raises an error if the file is already backed up.
125
+ #
126
+ # Returns a list of the backup_filepaths.
127
+ def backup(list, copy=true)
128
+ fu_list(list).collect do |filepath|
129
+ next unless File.exists?(filepath)
130
+
131
+ filepath = File.expand_path(filepath)
132
+ if backed_up_files.include?(filepath)
133
+ raise "Backup for #{filepath} already exists."
134
+ end
135
+
136
+ target = File.expand_path(backup_filepath(filepath))
137
+ dir = File.dirname(target)
138
+ mkdir(dir)
139
+
140
+ if copy
141
+ log :cp, "#{filepath} to #{target}", Logger::DEBUG
142
+ FileUtils.cp(filepath, target)
143
+ else
144
+ log :mv, "#{filepath} to #{target}", Logger::DEBUG
145
+ FileUtils.mv(filepath, target)
146
+ end
147
+
148
+ # track the target for restores
149
+ backed_up_files[filepath] = target
150
+ target
151
+ end
152
+ end
153
+
154
+ # Restores a backed-up file to its original location and removes the
155
+ # directory of the backup if it is empty. Returns the restored files.
156
+ def restore(list)
157
+ fu_list(list).collect do |filepath|
158
+ filepath = File.expand_path(filepath)
159
+ raise "No backed up file for: #{filepath}" unless backed_up_files.has_key?(filepath)
160
+
161
+ target = backed_up_files.delete(filepath)
162
+
163
+ dir = File.dirname(filepath)
164
+ mkdir(dir)
165
+
166
+ log :restore, "#{target} to #{filepath}", Logger::DEBUG
167
+ FileUtils.mv(target, filepath, :force => true)
168
+
169
+ dir = File.dirname(target)
170
+ rmdir(dir)
171
+
172
+ filepath
173
+ end
174
+ end
175
+
176
+ # Creates the directories in list if they do not exist and adds
177
+ # them to made_files so they can be removed using rmdir.
178
+ #
179
+ # Returns the made directories.
180
+ def mkdir(list)
181
+ fu_list(list).each do |dir|
182
+ dir = File.expand_path(dir)
183
+
184
+ make_paths = []
185
+ while !File.exists?(dir)
186
+ make_paths << dir
187
+ dir = File.dirname(dir)
188
+ end
189
+
190
+ make_paths.reverse_each do |dir|
191
+ log :mkdir, dir, Logger::DEBUG
192
+ FileUtils.mkdir(dir)
193
+ made_files << dir
194
+ end
195
+ end
196
+ end
197
+
198
+ # Removes each directory in the input list, provided the directory is in
199
+ # made_files and the directory is empty. When checking if the directory
200
+ # is empty, rmdir checks for regular files and hidden files. Removed
201
+ # directories are removed from made_files.
202
+ #
203
+ # Returns a list of the removed directories.
204
+ def rmdir(list)
205
+ removed = []
206
+ fu_list(list).each do |dir|
207
+ dir = File.expand_path(dir)
208
+
209
+ # remove directories and parents until the
210
+ # directory was not made by the task
211
+ while made_files.include?(dir)
212
+ break unless Dir.entries(dir).delete_if {|d| d == "." || d == ".."}.empty?
213
+
214
+ if File.exists?(dir)
215
+ log :rmdir, dir, Logger::DEBUG
216
+ FileUtils.rmdir(dir)
217
+ end
218
+
219
+ removed << made_files.delete(dir)
220
+ dir = File.dirname(dir)
221
+ end
222
+ end
223
+ removed
224
+ end
225
+
226
+ # Make prepares the input list of files by backing them up (if they exist),
227
+ # ensuring that the parent directory for the file exists, and adds each file
228
+ # to made_files. As a result the files can be removed using rm, and
229
+ # the original files restored using restore.
230
+ #
231
+ # Returns the made files.
232
+ def make(list) # :yields: list
233
+ list = fu_list(list)
234
+ existing_files, non_existant_files = list.partition do |filepath|
235
+ File.exists?(filepath)
236
+ end
237
+
238
+ # backup existing files
239
+ existing_files.each do |filepath|
240
+ backup(filepath, false)
241
+ made_files << File.expand_path(filepath)
242
+ end
243
+
244
+ # ensure the parent directory exists
245
+ # for non-existant files
246
+ non_existant_files.each do |filepath|
247
+ dir = File.dirname(filepath)
248
+ mkdir(dir)
249
+ made_files << File.expand_path(filepath)
250
+ end
251
+
252
+ yield list if block_given?
253
+
254
+ list
255
+ end
256
+
257
+ # Removes each file in the input list, provided the file is in made_files.
258
+ # The parent directory of each file is removed using rmdir. Removed files
259
+ # are removed from made_files.
260
+ #
261
+ # Returns the removed files and directories.
262
+ def rm(list)
263
+ removed = []
264
+ fu_list(list).each do |filepath|
265
+ filepath = File.expand_path(filepath)
266
+ next unless made_files.include?(filepath)
267
+
268
+ # if the file exists, remove it
269
+ if File.exists?(filepath)
270
+ log :rm, filepath, Logger::DEBUG
271
+ FileUtils.rm(filepath, :force => true)
272
+ end
273
+
274
+ removed << made_files.delete(filepath)
275
+ removed.concat rmdir(File.dirname(filepath))
276
+ end
277
+ removed
278
+ end
279
+
280
+ # Logs the given action, with the basenames of the input filepaths.
281
+ def log_filepaths(action, *filepaths)
282
+ msg = filepaths.collect {|filepath| File.basename(filepath) }.join(',')
283
+ log(action , msg)
284
+ end
285
+
286
+ protected
287
+
288
+ attr_writer :inference_block, :backed_up_files, :made_files
289
+
290
+ # The default_dirname is based on the name of the task, and the
291
+ # index of the task in batch (if the task is batched):
292
+ #
293
+ # t = FileTask.new "name"
294
+ # t.default_dirname # => "name"
295
+ #
296
+ # t = FileTask.new "batched"
297
+ # t.batch[0].default_dirname # => "name_0"
298
+ # t.batch[1].default_dirname # => "name_1"
299
+ def default_dirname
300
+ batched? ? "#{name}_#{batch_index}" : name
301
+ end
302
+
303
+ def after_execute
304
+ backed_up_files.values.each do |filepath|
305
+ # the filepath needs to be added to made_files
306
+ # before it can be removed by rm
307
+ made_files << filepath
308
+ rm(filepath)
309
+ end if remove_backed_up_files
310
+ end
311
+
312
+ def on_execute_error(original_error)
313
+ restore_errors = []
314
+
315
+ if restore_on_error
316
+ made_files.dup.each do |filepath|
317
+ begin
318
+ case
319
+ when File.file?(filepath)
320
+ rm(filepath)
321
+ when File.directory?(filepath)
322
+ rmdir(filepath)
323
+ end
324
+ rescue
325
+ restore_errors << $!
326
+ end
327
+ end
328
+
329
+ backed_up_files.keys.each do |filepath|
330
+ begin
331
+ restore(filepath)
332
+ rescue
333
+ restore_errors << $!
334
+ end
335
+ end
336
+ end
337
+
338
+ # Re-raise an error unless the original error was due
339
+ # to task termination and no restore errors occured
340
+ if restore_errors.empty?
341
+ raise original_error
342
+ else
343
+ raise Support::RunError.new(original_error, restore_errors)
344
+ end
345
+ end
346
+
347
+ private
348
+
349
+ # Lifted from FileUtils
350
+ def fu_list(arg)
351
+ [arg].flatten.map {|path| path.to_str }
352
+ end
353
+ end
354
+ end
@@ -0,0 +1,29 @@
1
+ require 'active_record' # required by rails_generator, for some reason
2
+ require 'rails_generator'
3
+ require 'tap/generator/options'
4
+ require 'tap/generator/usage'
5
+
6
+ module Tap
7
+ module Generator
8
+ module Generators # :nodoc:
9
+ end
10
+ end
11
+ end
12
+
13
+ # These modifications are to make the rails generators work for Tap
14
+ module Rails # :nodoc:
15
+ module Generator # :nodoc:
16
+ class Base # :nodoc:
17
+ include Tap::Generator::Options
18
+
19
+ # Used to discover generators within tap. Adapted from code
20
+ # in 'rails/rails_generator/lookup.rb'
21
+ def self.use_tap_sources!
22
+ reset_sources
23
+ sources << PathSource.new(:builtin, "#{File.dirname(__FILE__)}/generator/generators")
24
+ sources << PathSource.new(:builtin, Tap::App.instance.filepath(:generators))
25
+ end
26
+ end
27
+ end
28
+ end
29
+
File without changes
@@ -0,0 +1,23 @@
1
+ module Tap::Generator::Generators
2
+ class ConfigGenerator < Rails::Generator::NamedBase # :nodoc:
3
+ attr_accessor :default_config
4
+
5
+ def initialize(*args)
6
+ super(*args)
7
+ @destination_root = Tap::App.instance[:root]
8
+ @app = Tap::App.instance
9
+ end
10
+
11
+ def manifest
12
+ record do |m|
13
+ task_name = class_path.empty? ? class_name : File.join(class_path, class_name)
14
+ task = @app.task(task_name)
15
+ self.default_config = task.class.default_config
16
+
17
+ config_path = @app.relative_filepath(:root, @app[:config])
18
+ m.directory File.join(config_path, class_path)
19
+ m.template "config.erb", File.join(config_path, class_name.underscore + ".yml")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,2 @@
1
+ # Configurations for <%= class_name %>
2
+ <%= default_config.stringify_keys.to_yaml %>
File without changes
@@ -0,0 +1,21 @@
1
+ module Tap::Generator::Generators
2
+ class FileTaskGenerator < Rails::Generator::NamedBase # :nodoc:
3
+ def initialize(*args)
4
+ super(*args)
5
+ @destination_root = Tap::App.instance[:root]
6
+ @app = Tap::App.instance
7
+ end
8
+
9
+ def manifest
10
+ record do |m|
11
+ lib_path = @app.relative_filepath(:root, @app[:lib])
12
+ m.directory File.join(lib_path, class_path)
13
+ m.template "task.erb", File.join(lib_path, class_name.underscore + ".rb")
14
+
15
+ test_path = @app.relative_filepath(:root, @app[:test])
16
+ m.directory File.join(test_path, class_path)
17
+ m.template "test.erb", File.join(test_path, class_name.underscore + "_test.rb")
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ # == Documentation
2
+ #
3
+ # === Command Line Usage
4
+ # Replace with your command line usage instructions
5
+ #
6
+ class <%= class_name %> < Tap::FileTask
7
+
8
+ def process(input)
9
+ # The process logic goes here. You don't have to use transform.
10
+ # Do whatever works!
11
+ output = infer_filepath(:data, input)
12
+
13
+ make(output)
14
+
15
+ File.open(input) do |source|
16
+ File.open(output, "w") do |target|
17
+ target.write "<root>\n"
18
+ while line = source.gets
19
+ next unless line =~ /(\w+): (\w+)/
20
+ target.write " <#{$1}>#{$2}</#{$1}>\n"
21
+ end
22
+ target.write "</root>"
23
+ end
24
+ end
25
+ end
26
+
27
+ end