sprout 0.7.220-x86-darwin-10
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprout might be problematic. Click here for more details.
- data/MIT-LICENSE +20 -0
- data/TODO +12 -0
- data/bin/sprout +128 -0
- data/doc/Bundle +14 -0
- data/doc/Generator +35 -0
- data/doc/Library +63 -0
- data/doc/Task +21 -0
- data/doc/Tool +20 -0
- data/lib/platform.rb +109 -0
- data/lib/progress_bar.rb +354 -0
- data/lib/sprout/archive_unpacker.rb +225 -0
- data/lib/sprout/builder.rb +44 -0
- data/lib/sprout/commands/generate.rb +9 -0
- data/lib/sprout/dynamic_accessors.rb +34 -0
- data/lib/sprout/general_tasks.rb +6 -0
- data/lib/sprout/generator/base_mixins.rb +186 -0
- data/lib/sprout/generator/named_base.rb +227 -0
- data/lib/sprout/generator.rb +7 -0
- data/lib/sprout/log.rb +46 -0
- data/lib/sprout/process_runner.rb +111 -0
- data/lib/sprout/project_model.rb +278 -0
- data/lib/sprout/remote_file_loader.rb +71 -0
- data/lib/sprout/remote_file_target.rb +151 -0
- data/lib/sprout/simple_resolver.rb +88 -0
- data/lib/sprout/tasks/erb_resolver.rb +118 -0
- data/lib/sprout/tasks/gem_wrap_task.rb +200 -0
- data/lib/sprout/tasks/git_task.rb +134 -0
- data/lib/sprout/tasks/library_task.rb +118 -0
- data/lib/sprout/tasks/sftp_task.rb +248 -0
- data/lib/sprout/tasks/ssh_task.rb +153 -0
- data/lib/sprout/tasks/tool_task.rb +793 -0
- data/lib/sprout/tasks/zip_task.rb +158 -0
- data/lib/sprout/template_resolver.rb +207 -0
- data/lib/sprout/user.rb +383 -0
- data/lib/sprout/version.rb +12 -0
- data/lib/sprout/version_file.rb +89 -0
- data/lib/sprout/zip_util.rb +61 -0
- data/lib/sprout.rb +496 -0
- data/rakefile.rb +150 -0
- data/samples/gem_wrap/rakefile.rb +17 -0
- metadata +174 -0
@@ -0,0 +1,793 @@
|
|
1
|
+
|
2
|
+
module Sprout
|
3
|
+
|
4
|
+
class ToolTaskError < StandardError #:nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
# The ToolTask provides some base functionality for any Command Line Interface (CLI) tool.
|
8
|
+
# It also provides support for GUI tools that you would like to expose from the
|
9
|
+
# Command Line (Like the Flash Player for example).
|
10
|
+
#
|
11
|
+
# ToolTask extends Rake::FileTask, and should be thought of in the same way.
|
12
|
+
# Martin Fowler did a much better job of describing Rake and specifically FileTasks than
|
13
|
+
# I can in his (now classic) Rake article[http://martinfowler.com/articles/rake.html#FileTasks] from 2005.
|
14
|
+
#
|
15
|
+
# What this means is that most tool task instances should be named for the file that they will create.
|
16
|
+
# For example, an Sprout::MXMLCTask instance should be named for the SWF that it will generate.
|
17
|
+
#
|
18
|
+
# mxmlc 'bin/SomeProject.swf' => :corelib do |t|
|
19
|
+
# t.input = 'src/SomeProject.as'
|
20
|
+
# t.default_size = '800 600'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# In general, a tool task will only be executed if it's output file (name) does not exist or
|
24
|
+
# if the output file is older than any file identified as a prerequisite.
|
25
|
+
#
|
26
|
+
# Many of the compiler tasks take advantage of this feature by opting out of unnecessary compilation.
|
27
|
+
#
|
28
|
+
# Subclasses can add and configure command line parameters by calling the protected add_param method
|
29
|
+
# that is implemented on this class.
|
30
|
+
#
|
31
|
+
class ToolTask < Rake::FileTask
|
32
|
+
@@preprocessed_tasks = Hash.new
|
33
|
+
|
34
|
+
def self.add_preprocessed_task(name)
|
35
|
+
@@preprocessed_tasks[name] = true
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.has_preprocessed_task?(name)
|
39
|
+
!@@preprocessed_tasks[name].nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.clear_preprocessed_tasks
|
43
|
+
@@preprocessed_tasks.clear
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(name, app) # :nodoc:
|
47
|
+
super
|
48
|
+
@preprocessed_path = nil
|
49
|
+
@prepended_args = nil
|
50
|
+
@appended_args = nil
|
51
|
+
@default_gem_name = nil
|
52
|
+
@default_gem_path = nil
|
53
|
+
initialize_task
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.define_task(args, &block)
|
57
|
+
t = super
|
58
|
+
if(t.is_a?(ToolTask))
|
59
|
+
yield t if block_given?
|
60
|
+
t.define
|
61
|
+
t.prepare
|
62
|
+
end
|
63
|
+
return t
|
64
|
+
end
|
65
|
+
|
66
|
+
# Full name of the sprout tool gem that this tool task will use. For example, the MXMLCTask
|
67
|
+
# uses the sprout-flex3sdk-tool at the time of this writing, but will at some point
|
68
|
+
# change to use the sprout-flex3sdk-tool. You can combine this value with gem_version
|
69
|
+
# in order to specify exactly which gem your tool task is executing.
|
70
|
+
def gem_name
|
71
|
+
return @gem_name ||= @default_gem_name
|
72
|
+
end
|
73
|
+
|
74
|
+
def gem_name=(name)
|
75
|
+
@gem_name = name
|
76
|
+
end
|
77
|
+
|
78
|
+
# The exact gem version that you would like the ToolTask to execute. By default this value
|
79
|
+
# should be nil and will download the latest version of the gem that is available unless
|
80
|
+
# there is a version already installed on your system.
|
81
|
+
#
|
82
|
+
# This attribute could be an easy
|
83
|
+
# way to update your local gem to the latest version without leaving your build file,
|
84
|
+
# but it's primary purpose is to allow you to specify very specific versions of the tools
|
85
|
+
# that your project depends on. This way your team can rest assured that they are all
|
86
|
+
# working with the same tools.
|
87
|
+
def gem_version
|
88
|
+
return @gem_version ||= nil
|
89
|
+
end
|
90
|
+
|
91
|
+
def gem_version=(version)
|
92
|
+
@gem_version = version
|
93
|
+
end
|
94
|
+
|
95
|
+
# The path inside the installed gem where an executable can be found. For the MXMLCTask, this
|
96
|
+
# value is 'bin/mxmlc'.
|
97
|
+
def gem_path
|
98
|
+
return @gem_path ||= @default_gem_path
|
99
|
+
end
|
100
|
+
|
101
|
+
# Create a string that can be turned into a file
|
102
|
+
# that rdoc can parse to describe the customized
|
103
|
+
# or generated task using param name, type and
|
104
|
+
# description
|
105
|
+
def to_rdoc
|
106
|
+
result = ''
|
107
|
+
parts = self.class.to_s.split('::')
|
108
|
+
class_name = parts.pop
|
109
|
+
module_count = 0
|
110
|
+
while(module_name = parts.shift)
|
111
|
+
result << "module #{module_name}\n"
|
112
|
+
module_count += 1
|
113
|
+
end
|
114
|
+
|
115
|
+
result << "class #{class_name} < ToolTask\n"
|
116
|
+
|
117
|
+
params.each do |param|
|
118
|
+
result << param.to_rdoc
|
119
|
+
end
|
120
|
+
|
121
|
+
while((module_count -= 1) >= 0)
|
122
|
+
result << "end\nend\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
return result
|
126
|
+
end
|
127
|
+
|
128
|
+
# Arguments to be prepended in front of the command line output
|
129
|
+
def prepended_args=(args)
|
130
|
+
@prepended_args = args
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns arguments that were prepended in front of the command line output
|
134
|
+
def prepended_args
|
135
|
+
@prepended_args
|
136
|
+
end
|
137
|
+
|
138
|
+
# Arguments to appended at the end of the command line output
|
139
|
+
def appended_args=(args)
|
140
|
+
@appended_args = args
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns arguments that were appended at the end of the command line output
|
144
|
+
def appended_args
|
145
|
+
@appended_args
|
146
|
+
end
|
147
|
+
|
148
|
+
# Command line arguments to execute preprocessor.
|
149
|
+
# The preprocessor execution should accept text via STDIN and return its processed content via STDOUT.
|
150
|
+
#
|
151
|
+
# In the following example, the +MXMLCTask+ has been configured to use the C preprocessor (cpp) and
|
152
|
+
# place the processed output into a +_preprocessed+ folder, instead of the hidden default folder at
|
153
|
+
# .preprocessed.
|
154
|
+
#
|
155
|
+
# One side effect of the cpp tool is that it adds 2 carriage returns to the top of any processed files,
|
156
|
+
# so we have simply piped its output to the tail command which then strips those carriage returns from
|
157
|
+
# all files - which retains accurate line numbers for any compiler error messages.
|
158
|
+
#
|
159
|
+
# mxmlc 'bin/SomeProject.swf' => :corelib do |t|
|
160
|
+
# t.input = 'src/SomeProject.as'
|
161
|
+
# t.default_size = '800 600'
|
162
|
+
# t.preprocessor = 'cpp -D__DEBUG=true -P - - | tail -c +3'
|
163
|
+
# t.preprocessed_path = '_preprocessed'
|
164
|
+
# end
|
165
|
+
#
|
166
|
+
# Any source files found in this example project can now take advantage of any tools, macros or syntax
|
167
|
+
# available to CPP. For example, the +__DEBUG+ variable is now defined and can be accessed in ActionScript
|
168
|
+
# source code as follows:
|
169
|
+
#
|
170
|
+
# public static const DEBUG:Boolean = __DEBUG;
|
171
|
+
#
|
172
|
+
# Any commandline tool identified on this attribute will be provided the content of each file on STDIN and
|
173
|
+
# whatever it returns to STDOUT will be written into the +preprocessed_path+. This means that we can
|
174
|
+
# take advantage of the entire posix tool chain by piping inputs and outputs from one tool to another.
|
175
|
+
# Whatever the last tool returns will be handed off to the concrete compiler.
|
176
|
+
def preprocessor=(preprocessor)
|
177
|
+
@preprocessor = preprocessor
|
178
|
+
end
|
179
|
+
|
180
|
+
def preprocessor
|
181
|
+
@preprocessor
|
182
|
+
end
|
183
|
+
|
184
|
+
# Path where preprocessed files are stored. Defaults to '.preprocessed'
|
185
|
+
def preprocessed_path=(preprocessed_path)
|
186
|
+
@preprocessed_path = preprocessed_path
|
187
|
+
end
|
188
|
+
|
189
|
+
def preprocessed_path
|
190
|
+
@preprocessed_path ||= '.preprocessed'
|
191
|
+
end
|
192
|
+
|
193
|
+
def display_preprocess_message # :nodoc:
|
194
|
+
if(!preprocessor.nil?)
|
195
|
+
puts ">> Preprocessed text files in: #{File.join(Dir.pwd, preprocessed_path)} with #{preprocessor}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def execute(*args)
|
200
|
+
display_preprocess_message
|
201
|
+
#puts ">> Executing #{File.basename(exe)} #{to_shell}"
|
202
|
+
exe = Sprout.get_executable(gem_name, gem_path, gem_version)
|
203
|
+
User.execute(exe, to_shell)
|
204
|
+
end
|
205
|
+
|
206
|
+
# Create a string that represents this configured tool for shell execution
|
207
|
+
def to_shell
|
208
|
+
return @to_shell_proc.call(self) if(!@to_shell_proc.nil?)
|
209
|
+
|
210
|
+
result = []
|
211
|
+
result << @prepended_args unless @prepended_args.nil?
|
212
|
+
params.each do |param|
|
213
|
+
if(param.visible?)
|
214
|
+
result << param.to_shell
|
215
|
+
end
|
216
|
+
end
|
217
|
+
result << @appended_args unless @appended_args.nil?
|
218
|
+
return result.join(' ')
|
219
|
+
end
|
220
|
+
|
221
|
+
# An Array of all parameters that have been added to this Tool.
|
222
|
+
def params
|
223
|
+
@params ||= []
|
224
|
+
end
|
225
|
+
|
226
|
+
# Called after initialize and define, usually subclasses should
|
227
|
+
# only override define.
|
228
|
+
def prepare
|
229
|
+
# Get each added param to inject prerequisites as necessary
|
230
|
+
params.each do |param|
|
231
|
+
param.prepare
|
232
|
+
end
|
233
|
+
# Ensure there are no duplicates in the prerequisite collection
|
234
|
+
@prerequisites = prerequisites.uniq
|
235
|
+
end
|
236
|
+
|
237
|
+
def define
|
238
|
+
resolve_libraries(prerequisites)
|
239
|
+
end
|
240
|
+
|
241
|
+
# The default file expression to append to each PathParam
|
242
|
+
# in order to build file change prerequisites.
|
243
|
+
#
|
244
|
+
# Defaults to '/**/**/*'
|
245
|
+
#
|
246
|
+
def default_file_expression
|
247
|
+
@default_file_expression ||= '/**/**/*'
|
248
|
+
end
|
249
|
+
|
250
|
+
protected
|
251
|
+
|
252
|
+
def initialize_task
|
253
|
+
end
|
254
|
+
|
255
|
+
def validate
|
256
|
+
params.each do |param|
|
257
|
+
param.validate
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# +add_param+ is the workhorse of the ToolTask.
|
262
|
+
# This method is used to add new shell parameters to the task.
|
263
|
+
# +name+ is a symbol or string that represents the parameter that you would like to add
|
264
|
+
# such as :debug or :source_path.
|
265
|
+
# +type+ is usually sent as a Ruby symbol and can be one of the following:
|
266
|
+
#
|
267
|
+
# [:string] Any string value
|
268
|
+
# [:boolean] true or false
|
269
|
+
# [:number] Any number
|
270
|
+
# [:file] Path to a file
|
271
|
+
# [:url] Basic URL
|
272
|
+
# [:path] Path to a directory
|
273
|
+
# [:files] Collection of files
|
274
|
+
# [:paths] Collection of directories
|
275
|
+
# [:strings] Collection of arbitrary strings
|
276
|
+
# [:urls] Collection of URLs
|
277
|
+
#
|
278
|
+
# Be sure to check out the Sprout::TaskParam class to learn more about
|
279
|
+
# block editing the parameters.
|
280
|
+
#
|
281
|
+
# Once parameters have been added using the +add_param+ method, clients
|
282
|
+
# can set and get those parameters from the newly created task.
|
283
|
+
#
|
284
|
+
def add_param(name, type, &block) # :yields: Sprout::TaskParam
|
285
|
+
name = name.to_s
|
286
|
+
|
287
|
+
# First ensure the named accessor doesn't yet exist...
|
288
|
+
if(param_hash[name])
|
289
|
+
raise ToolTaskError.new("TaskBase.add_param called with existing parameter name: #{name}")
|
290
|
+
end
|
291
|
+
|
292
|
+
param = create_param(type)
|
293
|
+
param.init do |p|
|
294
|
+
p.belongs_to = self
|
295
|
+
p.name = name
|
296
|
+
p.type = type
|
297
|
+
yield p if block_given?
|
298
|
+
end
|
299
|
+
|
300
|
+
param_hash[name] = param
|
301
|
+
params << param
|
302
|
+
end
|
303
|
+
|
304
|
+
# Alias an existing parameter with another name. For example, the
|
305
|
+
# existing parameter :source_path might be given an alias '-sp' as follows:
|
306
|
+
#
|
307
|
+
# add_param_alias(:sp, :source_path)
|
308
|
+
#
|
309
|
+
# Alias parameters cannot be configured differently from the parameter
|
310
|
+
# that they alias
|
311
|
+
#
|
312
|
+
def add_param_alias(name, other_param)
|
313
|
+
if(param_hash.has_key? other_param.to_s)
|
314
|
+
param_hash[name.to_s] = param_hash[other_param.to_s]
|
315
|
+
else
|
316
|
+
raise ToolTaskError.new("TaskBase.add_param_alis called with")
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
protected
|
321
|
+
|
322
|
+
def create_param(type)
|
323
|
+
return eval("#{type.to_s.capitalize}Param.new")
|
324
|
+
end
|
325
|
+
|
326
|
+
def param_hash
|
327
|
+
@param_hash ||= {}
|
328
|
+
end
|
329
|
+
|
330
|
+
def respond_to?(name)
|
331
|
+
result = super
|
332
|
+
if(!result)
|
333
|
+
result = param_hash.has_key? name
|
334
|
+
end
|
335
|
+
return result
|
336
|
+
end
|
337
|
+
|
338
|
+
def clean_name(name)
|
339
|
+
name.gsub(/=$/, '')
|
340
|
+
end
|
341
|
+
|
342
|
+
def method_missing(name,*args)
|
343
|
+
name = name.to_s
|
344
|
+
cleaned = clean_name(name)
|
345
|
+
if(!respond_to?(cleaned))
|
346
|
+
raise NoMethodError.new("undefined method '#{name}' for #{self.class}", name)
|
347
|
+
end
|
348
|
+
param = param_hash[cleaned]
|
349
|
+
|
350
|
+
if(name =~ /=$/)
|
351
|
+
param.value = args.shift
|
352
|
+
elsif(param)
|
353
|
+
param.value
|
354
|
+
else
|
355
|
+
raise ToolTaskError.new("method_missing called with undefined parameter [#{name}]")
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
# Iterate over all prerequisites looking for any
|
360
|
+
# that are a LibraryTask.
|
361
|
+
# Concrete ToolTask implementations should
|
362
|
+
# override resolve_library in order to add
|
363
|
+
# the library sources or binaries appropriately.
|
364
|
+
def resolve_libraries(prerequisites)
|
365
|
+
prerequisites.each do |prereq|
|
366
|
+
instance = Rake::application[prereq]
|
367
|
+
if(instance.is_a?(LibraryTask))
|
368
|
+
resolve_library(instance)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# Concrete ToolTasks should override this method
|
374
|
+
# and add any dependent libraries appropriately
|
375
|
+
def resolve_library(library_task)
|
376
|
+
end
|
377
|
+
|
378
|
+
# If the provided path contains spaces, wrap it in quotes so that
|
379
|
+
# shell tools won't choke on the spaces
|
380
|
+
def clean_path(path)
|
381
|
+
if(path.index(' '))
|
382
|
+
path = %{"#{path}"}
|
383
|
+
end
|
384
|
+
return path
|
385
|
+
end
|
386
|
+
|
387
|
+
end
|
388
|
+
|
389
|
+
#######################################################
|
390
|
+
# Parameter Implementations
|
391
|
+
|
392
|
+
# The base class for all ToolTask parameters. This class is extended by a variety
|
393
|
+
# of concrete implementations.
|
394
|
+
#
|
395
|
+
# At the time of this writing, only the :boolean TaskParam modifies the interface by
|
396
|
+
# adding the +show_on_false+ attribute.
|
397
|
+
#
|
398
|
+
# Some other helpful features are as follows:
|
399
|
+
#
|
400
|
+
# :file, :files, :path and :paths will all add any items that have been added to
|
401
|
+
# their values as file task prerequisites. This is especially helpful when writing
|
402
|
+
# rake tasks for Command Line Interface (CLI) compilers.
|
403
|
+
#
|
404
|
+
class TaskParam
|
405
|
+
attr_accessor :belongs_to
|
406
|
+
attr_accessor :description
|
407
|
+
attr_accessor :hidden_name
|
408
|
+
attr_accessor :hidden_value
|
409
|
+
attr_accessor :name
|
410
|
+
attr_accessor :preprocessable
|
411
|
+
attr_accessor :required
|
412
|
+
attr_accessor :type
|
413
|
+
attr_accessor :validator
|
414
|
+
attr_accessor :visible
|
415
|
+
|
416
|
+
attr_writer :prefix
|
417
|
+
attr_writer :value
|
418
|
+
attr_writer :delimiter
|
419
|
+
attr_writer :shell_name
|
420
|
+
attr_writer :to_shell_proc
|
421
|
+
|
422
|
+
# Set the file_expression (blob) to append to each path
|
423
|
+
# in order to build the prerequisites FileList.
|
424
|
+
#
|
425
|
+
# Defaults to parent ToolTask.default_file_expression
|
426
|
+
attr_writer :file_expression
|
427
|
+
|
428
|
+
def init
|
429
|
+
yield self if block_given?
|
430
|
+
end
|
431
|
+
|
432
|
+
# By default, ToolParams only appear in the shell
|
433
|
+
# output when they are not nil
|
434
|
+
def visible?
|
435
|
+
@visible ||= value
|
436
|
+
end
|
437
|
+
|
438
|
+
def required?
|
439
|
+
(required == true)
|
440
|
+
end
|
441
|
+
|
442
|
+
def validate
|
443
|
+
if(required? && !visible?)
|
444
|
+
raise ToolTaskError.new("#{name} is required and must not be nil")
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def prepare
|
449
|
+
prepare_prerequisites
|
450
|
+
end
|
451
|
+
|
452
|
+
def prepare_prerequisites
|
453
|
+
end
|
454
|
+
|
455
|
+
# Should the param name be hidden from the shell?
|
456
|
+
# Used for params like 'input' on mxmlc
|
457
|
+
def hidden_name?
|
458
|
+
@hidden_name ||= false
|
459
|
+
end
|
460
|
+
|
461
|
+
# Should the param value be hidden from the shell?
|
462
|
+
# Usually used for Boolean toggles like '-debug'
|
463
|
+
def hidden_value?
|
464
|
+
@hidden_value ||= false
|
465
|
+
end
|
466
|
+
|
467
|
+
# Leading character for each parameter
|
468
|
+
# Can sometimes be an empty string,
|
469
|
+
# other times it's a double dash '--'
|
470
|
+
# but usually it's just a single dash '-'
|
471
|
+
def prefix
|
472
|
+
@prefix ||= '-'
|
473
|
+
end
|
474
|
+
|
475
|
+
def value
|
476
|
+
@value ||= nil
|
477
|
+
end
|
478
|
+
|
479
|
+
def shell_value
|
480
|
+
value.to_s
|
481
|
+
end
|
482
|
+
|
483
|
+
def file_expression # :nodoc:
|
484
|
+
@file_expression ||= belongs_to.default_file_expression
|
485
|
+
end
|
486
|
+
|
487
|
+
# ToolParams join their name/value pair with an
|
488
|
+
# equals sign by default, this can be modified
|
489
|
+
# To a space or whatever you wish
|
490
|
+
def delimiter
|
491
|
+
@delimiter ||= '='
|
492
|
+
end
|
493
|
+
|
494
|
+
# Return the name with a single leading dash
|
495
|
+
# and underscores replaced with dashes
|
496
|
+
def shell_name
|
497
|
+
@shell_name ||= prefix + name.split('_').join('-')
|
498
|
+
end
|
499
|
+
|
500
|
+
def to_shell
|
501
|
+
if(!@to_shell_proc.nil?)
|
502
|
+
return @to_shell_proc.call(self)
|
503
|
+
elsif(hidden_name?)
|
504
|
+
return shell_value
|
505
|
+
elsif(hidden_value?)
|
506
|
+
return shell_name
|
507
|
+
else
|
508
|
+
return "#{shell_name}#{delimiter}#{shell_value}"
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
# Create a string that can be turned into a file
|
513
|
+
# that rdoc can parse to describe the customized
|
514
|
+
# or generated task using param name, type and
|
515
|
+
# description
|
516
|
+
def to_rdoc
|
517
|
+
result = ''
|
518
|
+
parts = description.split("\n") unless description.nil?
|
519
|
+
result << "# #{parts.join("\n# ")}\n" unless description.nil?
|
520
|
+
result << "def #{name}=(#{type})\n @#{name} = #{type}\nend\n\n"
|
521
|
+
return result
|
522
|
+
end
|
523
|
+
|
524
|
+
protected
|
525
|
+
|
526
|
+
def should_preprocess?
|
527
|
+
return preprocessable && !belongs_to.preprocessor.nil?
|
528
|
+
end
|
529
|
+
|
530
|
+
def prepare_preprocessor_paths(paths)
|
531
|
+
processed = []
|
532
|
+
paths.each do |path|
|
533
|
+
processed << prepare_preprocessor_path(path)
|
534
|
+
end
|
535
|
+
return processed
|
536
|
+
end
|
537
|
+
|
538
|
+
def prepare_preprocessor_files(files)
|
539
|
+
processed = []
|
540
|
+
files.each do |file|
|
541
|
+
processed << prepare_preprocessor_file(file)
|
542
|
+
end
|
543
|
+
return processed
|
544
|
+
end
|
545
|
+
|
546
|
+
def cleaned_preprocessed_path(path)
|
547
|
+
File.join(belongs_to.preprocessed_path, path.gsub('../', 'backslash/'))
|
548
|
+
end
|
549
|
+
|
550
|
+
def prepare_preprocessor_path(path)
|
551
|
+
processed_path = cleaned_preprocessed_path(path)
|
552
|
+
FileUtils.mkdir_p(processed_path)
|
553
|
+
files = FileList[path + file_expression]
|
554
|
+
files.each do |input_file|
|
555
|
+
prepare_preprocessor_file(input_file)
|
556
|
+
end
|
557
|
+
|
558
|
+
return processed_path
|
559
|
+
end
|
560
|
+
|
561
|
+
def prepare_preprocessor_file(input_file)
|
562
|
+
output_file = cleaned_preprocessed_path(input_file)
|
563
|
+
setup_preprocessing_file_tasks(input_file, output_file)
|
564
|
+
return output_file
|
565
|
+
end
|
566
|
+
|
567
|
+
def text_file?(file_name)
|
568
|
+
[/\.as$/, /\.txt$/, /\.mxml$/, /\.xml$/, /\.js$/, /\.html$/, /\.htm$/].select do |regex|
|
569
|
+
if (file_name.match(regex))
|
570
|
+
return true
|
571
|
+
end
|
572
|
+
end.size > 0
|
573
|
+
end
|
574
|
+
|
575
|
+
def setup_preprocessing_file_tasks(input_file, output_file)
|
576
|
+
return if(File.directory?(input_file))
|
577
|
+
CLEAN.add(belongs_to.preprocessed_path) if(!CLEAN.index(belongs_to.preprocessed_path))
|
578
|
+
|
579
|
+
# Only create the preprocessed action if one does not
|
580
|
+
# already exist. There were many being created before...
|
581
|
+
|
582
|
+
file input_file
|
583
|
+
file output_file => input_file do
|
584
|
+
# Couldn't return, b/c Rake complained...
|
585
|
+
if(!ToolTask::has_preprocessed_task?(output_file))
|
586
|
+
dir = File.dirname(output_file)
|
587
|
+
if(!File.exists?(dir))
|
588
|
+
FileUtils.mkdir_p(dir)
|
589
|
+
end
|
590
|
+
|
591
|
+
content = nil
|
592
|
+
# Open the input file and read its content:
|
593
|
+
File.open(input_file, 'r') do |readable|
|
594
|
+
content = readable.read
|
595
|
+
end
|
596
|
+
|
597
|
+
# Preprocess the content if it's a known text file type:
|
598
|
+
if(text_file?(input_file))
|
599
|
+
content = preprocess_content(content, belongs_to.preprocessor, input_file)
|
600
|
+
end
|
601
|
+
|
602
|
+
# Write the content to the output file:
|
603
|
+
File.open(output_file, 'w+') do |writable|
|
604
|
+
writable.write(content)
|
605
|
+
end
|
606
|
+
|
607
|
+
ToolTask::add_preprocessed_task(output_file)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
belongs_to.prerequisites << output_file
|
612
|
+
end
|
613
|
+
|
614
|
+
def preprocess_content(content, statement, file_name)
|
615
|
+
process = ProcessRunner.new(statement)
|
616
|
+
process.puts(content)
|
617
|
+
process.close_write
|
618
|
+
result = process.read
|
619
|
+
error = process.read_err
|
620
|
+
if(error.size > 0)
|
621
|
+
belongs_to.display_preprocess_message
|
622
|
+
FileUtils.rm_rf(belongs_to.preprocessed_path)
|
623
|
+
raise ExecutionError.new("[ERROR] Preprocessor failed on file #{file_name} #{error}")
|
624
|
+
end
|
625
|
+
process.kill
|
626
|
+
Log.puts ">> Preprocessed and created: #{belongs_to.preprocessed_path}/#{file_name}"
|
627
|
+
return result
|
628
|
+
end
|
629
|
+
|
630
|
+
end
|
631
|
+
|
632
|
+
# Concrete param object for :string values
|
633
|
+
class StringParam < TaskParam # :nodoc:
|
634
|
+
|
635
|
+
def shell_value
|
636
|
+
value.gsub(/ /, "\ ")
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
# Concrete param object for :symbol values
|
641
|
+
# like class names
|
642
|
+
class SymbolParam < TaskParam # :nodoc:
|
643
|
+
end
|
644
|
+
|
645
|
+
# Concrete param object for :url values
|
646
|
+
class UrlParam < TaskParam # :nodoc:
|
647
|
+
end
|
648
|
+
|
649
|
+
# Concrete param object for :number values
|
650
|
+
class NumberParam < TaskParam # :nodoc:
|
651
|
+
end
|
652
|
+
|
653
|
+
# Concrete param object for :file values
|
654
|
+
class FileParam < TaskParam # :nodoc:
|
655
|
+
|
656
|
+
def prepare_prerequisites
|
657
|
+
if(value && value != belongs_to.name.to_s)
|
658
|
+
if(should_preprocess?)
|
659
|
+
@value = prepare_preprocessor_file(value)
|
660
|
+
else
|
661
|
+
file value
|
662
|
+
belongs_to.prerequisites << value
|
663
|
+
end
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
# Concrete param object for :path values
|
669
|
+
class PathParam < TaskParam # :nodoc:
|
670
|
+
|
671
|
+
def prepare_prerequisites
|
672
|
+
if(value && value != belongs_to.name.to_s)
|
673
|
+
if should_preprocess?
|
674
|
+
@value = prepare_preprocessor_path(value)
|
675
|
+
else
|
676
|
+
file value
|
677
|
+
belongs_to.prerequisites << value
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
# Concrete param object for :boolean values
|
684
|
+
class BooleanParam < TaskParam # :nodoc:
|
685
|
+
attr_writer :show_on_false
|
686
|
+
|
687
|
+
def visible?
|
688
|
+
@visible ||= value
|
689
|
+
if(show_on_false)
|
690
|
+
return true unless value
|
691
|
+
else
|
692
|
+
return @visible
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
def show_on_false
|
697
|
+
@show_on_false ||= false
|
698
|
+
end
|
699
|
+
|
700
|
+
def value
|
701
|
+
@value ||= false
|
702
|
+
end
|
703
|
+
|
704
|
+
end
|
705
|
+
|
706
|
+
# Concrete param object for collections of strings
|
707
|
+
class StringsParam < TaskParam # :nodoc:
|
708
|
+
|
709
|
+
# Files lists are initialized to an empty array by default
|
710
|
+
def value
|
711
|
+
@value ||= []
|
712
|
+
end
|
713
|
+
|
714
|
+
# By default, the FilesParams will not appear in the shell
|
715
|
+
# output if there are zero items in the collection
|
716
|
+
def visible?
|
717
|
+
@visible ||= (value && value.size > 0)
|
718
|
+
end
|
719
|
+
|
720
|
+
# Default delimiter is +=
|
721
|
+
# This is what will appear between each name/value pair as in:
|
722
|
+
# "source_path+=src source_path+=test source_path+=lib"
|
723
|
+
def delimiter
|
724
|
+
@delimiter ||= "+="
|
725
|
+
end
|
726
|
+
|
727
|
+
# Returns a shell formatted string of the collection
|
728
|
+
def to_shell
|
729
|
+
return @to_shell_proc.call(self) if(!@to_shell_proc.nil?)
|
730
|
+
|
731
|
+
result = []
|
732
|
+
value.each do |str|
|
733
|
+
result << "#{shell_name}#{delimiter}#{str}"
|
734
|
+
end
|
735
|
+
return result.join(' ')
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
# Concrete param object for collections of symbols (like class names)
|
740
|
+
class SymbolsParam < StringsParam # :nodoc:
|
741
|
+
end
|
742
|
+
|
743
|
+
# Concrete param object for collections of files
|
744
|
+
class FilesParam < StringsParam # :nodoc:
|
745
|
+
|
746
|
+
def prepare
|
747
|
+
super
|
748
|
+
usr = User.new
|
749
|
+
path = nil
|
750
|
+
value.each_index do |index|
|
751
|
+
path = value[index]
|
752
|
+
value[index] = usr.clean_path path
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
756
|
+
def prepare_prerequisites
|
757
|
+
if should_preprocess?
|
758
|
+
@value = prepare_preprocessor_files(value)
|
759
|
+
else
|
760
|
+
value.each do |f|
|
761
|
+
file f
|
762
|
+
belongs_to.prerequisites << f
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
end
|
768
|
+
|
769
|
+
# Concrete param object for collections of paths
|
770
|
+
class PathsParam < FilesParam # :nodoc:
|
771
|
+
|
772
|
+
def prepare_prerequisites
|
773
|
+
if should_preprocess?
|
774
|
+
@value = prepare_preprocessor_paths(value)
|
775
|
+
else
|
776
|
+
value.each do |path|
|
777
|
+
files = FileList[path + file_expression]
|
778
|
+
files.each do |f|
|
779
|
+
file f
|
780
|
+
belongs_to.prerequisites << f
|
781
|
+
end
|
782
|
+
end
|
783
|
+
end
|
784
|
+
end
|
785
|
+
|
786
|
+
|
787
|
+
end
|
788
|
+
|
789
|
+
# Concrete param object for collections of files
|
790
|
+
class UrlsParam < StringsParam # :nodoc:
|
791
|
+
end
|
792
|
+
|
793
|
+
end
|