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.
- data/MIT-LICENSE +21 -0
- data/README +71 -0
- data/Rakefile +117 -0
- data/bin/tap +63 -0
- data/lib/tap.rb +15 -0
- data/lib/tap/app.rb +739 -0
- data/lib/tap/file_task.rb +354 -0
- data/lib/tap/generator.rb +29 -0
- data/lib/tap/generator/generators/config/USAGE +0 -0
- data/lib/tap/generator/generators/config/config_generator.rb +23 -0
- data/lib/tap/generator/generators/config/templates/config.erb +2 -0
- data/lib/tap/generator/generators/file_task/USAGE +0 -0
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +21 -0
- data/lib/tap/generator/generators/file_task/templates/task.erb +27 -0
- data/lib/tap/generator/generators/file_task/templates/test.erb +12 -0
- data/lib/tap/generator/generators/root/USAGE +0 -0
- data/lib/tap/generator/generators/root/root_generator.rb +36 -0
- data/lib/tap/generator/generators/root/templates/Rakefile +48 -0
- data/lib/tap/generator/generators/root/templates/app.yml +19 -0
- data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +4 -0
- data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +26 -0
- data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
- data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +57 -0
- data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +108 -0
- data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +40 -0
- data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +21 -0
- data/lib/tap/generator/generators/root/templates/server/config/environment.rb +60 -0
- data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +5 -0
- data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +53 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +3 -0
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +4 -0
- data/lib/tap/generator/generators/task/USAGE +0 -0
- data/lib/tap/generator/generators/task/task_generator.rb +21 -0
- data/lib/tap/generator/generators/task/templates/task.erb +21 -0
- data/lib/tap/generator/generators/task/templates/test.erb +29 -0
- data/lib/tap/generator/generators/workflow/USAGE +0 -0
- data/lib/tap/generator/generators/workflow/templates/task.erb +16 -0
- data/lib/tap/generator/generators/workflow/templates/test.erb +7 -0
- data/lib/tap/generator/generators/workflow/workflow_generator.rb +21 -0
- data/lib/tap/generator/options.rb +26 -0
- data/lib/tap/generator/usage.rb +26 -0
- data/lib/tap/root.rb +275 -0
- data/lib/tap/script/console.rb +7 -0
- data/lib/tap/script/destroy.rb +8 -0
- data/lib/tap/script/generate.rb +8 -0
- data/lib/tap/script/run.rb +111 -0
- data/lib/tap/script/server.rb +12 -0
- data/lib/tap/support/audit.rb +415 -0
- data/lib/tap/support/batch_queue.rb +165 -0
- data/lib/tap/support/combinator.rb +114 -0
- data/lib/tap/support/logger.rb +91 -0
- data/lib/tap/support/rap.rb +38 -0
- data/lib/tap/support/run_error.rb +20 -0
- data/lib/tap/support/template.rb +81 -0
- data/lib/tap/support/templater.rb +155 -0
- data/lib/tap/support/versions.rb +63 -0
- data/lib/tap/task.rb +448 -0
- data/lib/tap/test.rb +320 -0
- data/lib/tap/test/env_vars.rb +16 -0
- data/lib/tap/test/inference_methods.rb +298 -0
- data/lib/tap/test/subset_methods.rb +260 -0
- data/lib/tap/version.rb +3 -0
- data/lib/tap/workflow.rb +73 -0
- data/test/app/config/addition_template.yml +6 -0
- data/test/app/config/batch.yml +2 -0
- data/test/app/config/empty.yml +0 -0
- data/test/app/config/erb.yml +1 -0
- data/test/app/config/template.yml +6 -0
- data/test/app/config/version-0.1.yml +1 -0
- data/test/app/config/version.yml +1 -0
- data/test/app/lib/app_test_task.rb +2 -0
- data/test/app_class_test.rb +33 -0
- data/test/app_test.rb +1372 -0
- data/test/file_task/config/batch.yml +2 -0
- data/test/file_task/config/configured.yml +1 -0
- data/test/file_task/old_file_one.txt +0 -0
- data/test/file_task/old_file_two.txt +0 -0
- data/test/file_task_test.rb +1041 -0
- data/test/root/alt_lib/alt_module.rb +4 -0
- data/test/root/lib/absolute_alt_filepath.rb +2 -0
- data/test/root/lib/alternative_filepath.rb +2 -0
- data/test/root/lib/another_module.rb +2 -0
- data/test/root/lib/nested/some_module.rb +4 -0
- data/test/root/lib/no_module_included.rb +0 -0
- data/test/root/lib/some/module.rb +4 -0
- data/test/root/lib/some_class.rb +2 -0
- data/test/root/lib/some_module.rb +3 -0
- data/test/root/load_path/load_path_module.rb +2 -0
- data/test/root/load_path/skip_module.rb +2 -0
- data/test/root/mtime/older.txt +0 -0
- data/test/root/unload/full_path.rb +2 -0
- data/test/root/unload/loaded_by_nested.rb +2 -0
- data/test/root/unload/nested/nested_load.rb +6 -0
- data/test/root/unload/nested/nested_with_ext.rb +4 -0
- data/test/root/unload/nested/relative_path.rb +4 -0
- data/test/root/unload/older.rb +2 -0
- data/test/root/unload/unload_base.rb +9 -0
- data/test/root/versions/another.yml +0 -0
- data/test/root/versions/file-0.1.2.yml +0 -0
- data/test/root/versions/file-0.1.yml +0 -0
- data/test/root/versions/file.yml +0 -0
- data/test/root_test.rb +483 -0
- data/test/support/audit_test.rb +449 -0
- data/test/support/batch_queue_test.rb +320 -0
- data/test/support/combinator_test.rb +249 -0
- data/test/support/logger_test.rb +31 -0
- data/test/support/template_test.rb +122 -0
- data/test/support/templater/erb.txt +2 -0
- data/test/support/templater/erb.yml +2 -0
- data/test/support/templater/somefile.txt +2 -0
- data/test/support/templater_test.rb +192 -0
- data/test/support/versions_test.rb +71 -0
- data/test/tap_test_helper.rb +4 -0
- data/test/tap_test_suite.rb +4 -0
- data/test/task/config/batch.yml +2 -0
- data/test/task/config/batched.yml +2 -0
- data/test/task/config/configured.yml +1 -0
- data/test/task/config/example.yml +1 -0
- data/test/task/config/overriding.yml +2 -0
- data/test/task/config/task_with_config.yml +1 -0
- data/test/task/config/template.yml +4 -0
- data/test/task_class_test.rb +118 -0
- data/test/task_execute_test.rb +233 -0
- data/test/task_test.rb +424 -0
- data/test/test/inference_methods/test_assert_expected/expected/file.txt +1 -0
- data/test/test/inference_methods/test_assert_expected/expected/folder/file.txt +1 -0
- data/test/test/inference_methods/test_assert_expected/input/file.txt +1 -0
- data/test/test/inference_methods/test_assert_expected/input/folder/file.txt +1 -0
- data/test/test/inference_methods/test_assert_files_exist/input/input_1.txt +0 -0
- data/test/test/inference_methods/test_assert_files_exist/input/input_2.txt +0 -0
- data/test/test/inference_methods/test_file_compare/expected/output_1.txt +3 -0
- data/test/test/inference_methods/test_file_compare/expected/output_2.txt +1 -0
- data/test/test/inference_methods/test_file_compare/input/input_1.txt +3 -0
- data/test/test/inference_methods/test_file_compare/input/input_2.txt +3 -0
- data/test/test/inference_methods/test_infer_glob/expected/file.yml +0 -0
- data/test/test/inference_methods/test_infer_glob/expected/file_1.txt +0 -0
- data/test/test/inference_methods/test_infer_glob/expected/file_2.txt +0 -0
- data/test/test/inference_methods/test_yml_compare/expected/output_1.yml +6 -0
- data/test/test/inference_methods/test_yml_compare/expected/output_2.yml +6 -0
- data/test/test/inference_methods/test_yml_compare/input/input_1.yml +4 -0
- data/test/test/inference_methods/test_yml_compare/input/input_2.yml +4 -0
- data/test/test/inference_methods_test.rb +311 -0
- data/test/test/subset_methods_test.rb +115 -0
- data/test/test_test.rb +233 -0
- data/test/workflow_test.rb +108 -0
- 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
|
|
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
|