sprout 0.7.220-x86-darwin-10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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