rant 0.5.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@
4
4
  # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
5
 
6
6
  require 'fileutils'
7
- require 'rant/rantenv'
7
+ require 'rant/import/filelist/core'
8
8
 
9
9
  # Fix FileUtils::Verbose visibility issue
10
10
  if RUBY_VERSION == "1.8.3"
@@ -20,421 +20,63 @@ if RUBY_VERSION == "1.8.3"
20
20
  end
21
21
  end
22
22
 
23
- module Rant
24
-
25
- class FileList
26
- include Enumerable
27
-
28
- ESC_SEPARATOR = Regexp.escape(File::SEPARATOR)
29
- ESC_ALT_SEPARATOR = File::ALT_SEPARATOR ?
30
- Regexp.escape(File::ALT_SEPARATOR) : nil
31
-
32
- # Flags for the File::fnmatch method.
33
- # Initialized to 0.
34
- attr_accessor :glob_flags
35
-
36
- attr_accessor :ignore_rx
37
- protected :ignore_rx=
38
-
39
- class << self
40
- def [](*patterns)
41
- new(*patterns)
42
- end
43
- end
44
-
45
- def initialize(*patterns)
46
- @glob_flags = 0
47
- @files = []
48
- @actions = patterns.map { |pat| [:apply_include, pat] }
49
- @ignore_rx = nil
50
- @pending = true
51
- @keep = {}
52
- yield self if block_given?
53
- end
54
-
55
- def dup
56
- c = super
57
- c.files = @files.dup
58
- c.actions = @actions.dup
59
- c.ignore_rx = @ignore_rx.dup if @ignore_rx
60
- c.instance_variable_set(:@keep, @keep.dup)
61
- c
62
- end
63
-
64
- protected
65
- attr_accessor :actions, :files
66
- attr_accessor :pending
67
-
68
- public
69
- ### Methods having an equivalent in the Array class. #########
70
-
71
- def each(&block)
72
- resolve if @pending
73
- @files.each(&block)
74
- end
75
-
76
- def to_ary
77
- #puts caller
78
- resolve if @pending
79
- @files
80
- end
81
-
82
- def to_a
83
- to_ary
84
- end
85
-
86
- def +(other)
87
- if FileList === other
88
- c = other.dup
89
- c.actions.concat(@actions)
90
- c.files.concat(@files)
91
- c.pending = !c.actions.empty?
92
- c
93
- elsif other.respond_to? :to_ary
94
- c = dup
95
- c.actions <<
96
- [:apply_ary_method_1, :concat, other.to_ary.dup]
97
- c.pending = true
98
- c
99
- else
100
- raise "argument has to be an Array or FileList"
101
- end
102
- end
103
-
104
- # Use this method to append +file+ to this list. +file+ will
105
- # stay in this list even if it matches an exclude or ignore
106
- # pattern.
107
- #
108
- # Returns self.
109
- def <<(file)
110
- @actions << [:apply_ary_method_1, :push, file]
111
- @keep[file] = true
112
- @pending = true
113
- self
114
- end
115
-
116
- def concat(ary)
117
- resolve if @pending
118
- ix = ignore_rx
119
- @files.concat(ary.to_ary.reject { |f| f =~ ix })
120
- self
121
- end
122
-
123
- def size
124
- resolve if @pending
125
- @files.size
126
- end
127
-
128
- alias _object_respond_to? respond_to?
129
- private :_object_respond_to?
130
- def respond_to?(msg)
131
- _object_respond_to?(msg) or @files.respond_to?(msg)
23
+ if RUBY_VERSION < "1.8.1"
24
+ module FileUtils
25
+ undef_method :fu_list
26
+ def fu_list(arg)
27
+ arg.respond_to?(:to_ary) ? arg.to_ary : [arg]
132
28
  end
133
-
134
- def method_missing(sym, *args, &block)
135
- if @files.respond_to? sym
136
- resolve if @pending
137
- fh = @files.hash
138
- rv = @files.send(sym, *args, &block)
139
- @pending = true unless @files.hash == fh
140
- rv.equal?(@files) ? self : rv
141
- else
142
- super
143
- end
144
- end
145
- ##############################################################
146
-
147
- if Object.method_defined?(:fcall) || Object.method_defined?(:funcall) # in Ruby 1.9 like __send__
148
- @@__send_private__ = Object.method_defined?(:fcall) ? :fcall : :funcall
149
- def resolve
150
- @pending = false
151
- @actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear
152
- ix = ignore_rx
153
- if ix
154
- @files.reject! { |f| f =~ ix && !@keep[f] }
155
- end
156
- end
157
- elsif RUBY_VERSION < "1.8.2"
158
- def resolve
159
- @pending = false
160
- @actions.each{ |action| self.__send__(*action) }.clear
161
- ix = ignore_rx
162
- @files.reject! { |f|
163
- unless @keep[f]
164
- next(true) if ix && f =~ ix
165
- if @glob_flags & File::FNM_DOTMATCH != File::FNM_DOTMATCH
166
- if ESC_ALT_SEPARATOR
167
- f =~ /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..*
168
- ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x
169
- else
170
- f =~ /(^|#{ESC_SEPARATOR}+)\..*
171
- (#{ESC_SEPARATOR}+|$)/x
172
- end
173
- end
174
- end
175
- }
176
- end
177
- else
178
- def resolve
179
- @pending = false
180
- @actions.each{ |action| self.__send__(*action) }.clear
181
- ix = ignore_rx
182
- if ix
183
- @files.reject! { |f| f =~ ix && !@keep[f] }
184
- end
185
- end
29
+ end
186
30
  end
187
31
 
188
- def include(*patterns)
189
- patterns.flatten.each { |pat|
190
- @actions << [:apply_include, pat]
191
- }
192
- @pending = true
193
- self
194
- end
195
- alias glob include
196
-
197
- def apply_include(pattern)
198
- @files.concat Dir.glob(pattern, @glob_flags)
199
- end
200
- private :apply_include
201
-
202
- def exclude(*patterns)
203
- patterns.each { |pat|
204
- if Regexp === pat
205
- @actions << [:apply_exclude_rx, pat]
206
- else
207
- @actions << [:apply_exclude, pat]
208
- end
209
- }
210
- @pending = true
211
- self
212
- end
213
-
214
- def ignore(*patterns)
215
- patterns.each { |pat|
216
- add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat))
217
- }
218
- @pending = true
219
- self
220
- end
221
-
222
- def add_ignore_rx(rx)
223
- @ignore_rx =
224
- if @ignore_rx
225
- Regexp.union(@ignore_rx, rx)
226
- else
227
- rx
228
- end
229
- end
230
- private :add_ignore_rx
231
-
232
- def apply_exclude(pattern)
233
- @files.reject! { |elem|
234
- File.fnmatch?(pattern, elem, @glob_flags) && !@keep[elem]
235
- }
236
- end
237
- private :apply_exclude
238
-
239
- def apply_exclude_rx(rx)
240
- @files.reject! { |elem|
241
- elem =~ rx && !@keep[elem]
242
- }
243
- end
244
- private :apply_exclude_rx
245
-
246
- def exclude_all(*files)
247
- files.each { |file|
248
- @actions << [:apply_exclude_rx, mk_all_rx(file)]
249
- }
250
- @pending = true
251
- self
252
- end
253
- alias shun exclude_all
254
-
255
- if File::ALT_SEPARATOR
256
- # TODO: check for FS case sensitivity?
257
- def mk_all_rx(file)
258
- /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)#{Regexp.escape(file)}
259
- ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x
260
- end
261
- else
262
- def mk_all_rx(file)
263
- /(^|#{ESC_SEPARATOR}+)#{Regexp.escape(file)}
264
- (#{ESC_SEPARATOR}+|$)/x
265
- end
266
- end
267
- private :mk_all_rx
268
-
269
- def select(&block)
270
- d = dup
271
- d.actions << [:apply_select, block]
272
- d.pending = true
273
- d
274
- end
275
- alias find_all select
276
-
277
- def apply_select blk
278
- @files = @files.select(&blk)
279
- end
280
- private :apply_select
281
-
282
- def map(&block)
283
- d = dup
284
- d.actions << [:apply_ary_method, :map!, block]
285
- d.pending = true
286
- d
287
- end
288
- alias collect map
289
-
290
- def sub_ext(ext, new_ext=nil)
291
- map { |f| f.sub_ext ext, new_ext }
292
- end
293
-
294
- # Remove all entries which contain a directory with the
295
- # given name.
296
- # If no argument or +nil+ given, remove all directories.
297
- #
298
- # Example:
299
- # file_list.no_dir "CVS"
300
- # would remove the following entries from file_list:
301
- # CVS/
302
- # src/CVS/lib.c
303
- # CVS/foo/bar/
304
- def no_dir(name = nil)
305
- @actions << [:apply_no_dir, name]
306
- @pending = true
307
- self
308
- end
309
-
310
- def apply_no_dir(name)
311
- entry = nil
312
- unless name
313
- @files.reject! { |entry|
314
- test(?d, entry) && !@keep[entry]
315
- }
316
- return
317
- end
318
- elems = nil
319
- @files.reject! { |entry|
320
- next if @keep[entry]
321
- elems = Sys.split_all(entry)
322
- i = elems.index(name)
323
- if i
324
- path = File.join(*elems[0..i])
325
- test(?d, path)
326
- else
327
- false
328
- end
329
- }
330
- end
331
- private :apply_no_dir
332
-
333
- # Get a string with all entries. This is very usefull
334
- # if you invoke a shell:
335
- # files # => ["foo/bar", "with space"]
336
- # sh "rdoc #{files.arglist}"
337
- # will result on windows:
338
- # rdoc foo\bar "with space"
339
- # on other systems:
340
- # rdoc foo/bar with\ space
341
- def arglist
342
- Rant::Sys.sp to_ary
343
- end
344
- alias to_s arglist
345
-
346
- # Same as #uniq! but evaluation is delayed until the next read
347
- # access (e.g. by calling #each). Always returns self.
348
- def lazy_uniq!
349
- @actions << [:apply_ary_method, :uniq!]
350
- @pending = true
351
- self
352
- end
353
-
354
- # Same as #sort! but evaluation is delayed until the next read
355
- # access (e.g. by calling #each). Always returns self.
356
- def lazy_sort!
357
- @actions << [:apply_ary_method, :sort!]
358
- @pending = true
359
- self
360
- end
361
-
362
- # Same as #map! but evaluation is delayed until the next read
363
- # access (e.g. by calling #each). Always returns self.
364
- def lazy_map!(&block)
365
- @actions << [:apply_ary_method, :map!, block]
366
- @pending = true
367
- self
368
- end
369
-
370
- private
371
- def apply_ary_method(meth, block=nil)
372
- @files.send meth, &block
373
- end
374
- def apply_ary_method_1(meth, arg1, block=nil)
375
- @files.send meth, arg1, &block
376
- end
377
- =begin
378
- def apply_lazy_operation(meth, args, block)
379
- @files.send(meth, *args, &block)
380
- end
381
- =end
382
- end # class FileList
383
-
32
+ module Rant
384
33
  class RacFileList < FileList
385
34
 
386
- # Returns files if <tt>FileList === files</tt>, otherwise
387
- # a new RacFileList with <tt>file.to_ary</tt> as initial set
388
- # of files.
389
- def self.filelist(rac, files)
390
- return files if FileList === files
391
- fl = self.new(rac)
392
- fl.instance_eval {
393
- @pending = false
394
- @files = files.to_ary
395
- }
396
- fl
397
- end
398
-
399
35
  attr_reader :subdir
400
36
  attr_reader :basedir
401
37
 
402
- def initialize(rac, *patterns)
38
+ def initialize(rac, store = [])
39
+ super(store)
403
40
  @rac = rac
404
41
  @subdir = @rac.current_subdir
405
42
  @basedir = Dir.pwd
406
- super(*patterns)
407
43
  @ignore_hash = nil
408
44
  @add_ignore_args = []
409
45
  update_ignore_rx
410
46
  end
411
-
47
+ def dup
48
+ c = super
49
+ c.instance_variable_set(
50
+ :@add_ignore_args, @add_ignore_args.dup)
51
+ c
52
+ end
53
+ def copy
54
+ c = super
55
+ c.instance_variable_set(
56
+ :@add_ignore_args, @add_ignore_args.map { |e| e.dup })
57
+ c
58
+ end
412
59
  alias filelist_ignore ignore
413
60
  def ignore(*patterns)
414
61
  @add_ignore_args.concat patterns
415
62
  self
416
63
  end
417
-
418
64
  def ignore_rx
419
65
  update_ignore_rx
420
66
  @ignore_rx
421
67
  end
422
-
423
68
  alias filelist_resolve resolve
424
69
  def resolve
425
- Dir.chdir(@basedir) { filelist_resolve }
70
+ Sys.cd(@basedir) { filelist_resolve }
426
71
  end
427
-
428
- def each(&block)
72
+ def each_cd(&block)
429
73
  old_pwd = Dir.pwd
430
- resolve if @pending
431
- Dir.chdir(@basedir)
432
- filelist_resolve
433
- @files.each(&block)
74
+ Sys.cd(@basedir)
75
+ filelist_resolve if @pending
76
+ @items.each(&block)
434
77
  ensure
435
- Dir.chdir(old_pwd)
78
+ Sys.cd(old_pwd)
436
79
  end
437
-
438
80
  private
439
81
  def update_ignore_rx
440
82
  ri = @rac.var[:ignore]
@@ -460,7 +102,7 @@ end
460
102
 
461
103
  def each_entry(&block)
462
104
  @lists.each { |list|
463
- list.each(&block)
105
+ list.each_cd(&block)
464
106
  }
465
107
  end
466
108
 
@@ -565,45 +207,23 @@ end
565
207
  sh(args.unshift(Env::RUBY_EXE), &block)
566
208
  end
567
209
  end
568
-
569
- # Returns a string that can be used as a valid path argument
570
- # on the shell respecting portability issues.
571
- def sp(arg)
572
- if arg.respond_to? :to_ary
573
- arg.to_ary.map{ |e| sp e }.join(' ')
574
- else
575
- _escaped_path arg
576
- end
577
- end
578
-
579
- # Escape special shell characters (currently only spaces).
580
- # Flattens arrays and returns always a single string.
581
- def escape(arg)
582
- if arg.respond_to? :to_ary
583
- arg.to_ary.map{ |e| escape e }.join(' ')
210
+ # Returns the value of +block+ if a block is given, a true
211
+ # value otherwise.
212
+ def cd(dir, &block)
213
+ fu_output_message "cd #{dir}"
214
+ orig_pwd = Dir.pwd
215
+ Dir.chdir dir
216
+ if block
217
+ begin
218
+ block.arity == 0 ? block.call : block.call(Dir.pwd)
219
+ ensure
220
+ fu_output_message "cd -"
221
+ Dir.chdir orig_pwd
222
+ end
584
223
  else
585
- _escaped arg
586
- end
587
- end
588
-
589
- if Env.on_windows?
590
- def _escaped_path(path)
591
- _escaped(path.to_s.tr("/", "\\"))
592
- end
593
- def _escaped(arg)
594
- sarg = arg.to_s
595
- return sarg unless sarg.include?(" ")
596
- sarg << "\\" if sarg[-1].chr == "\\"
597
- "\"#{sarg}\""
598
- end
599
- else
600
- def _escaped_path(path)
601
- path.to_s.gsub(/(?=\s)/, "\\")
224
+ self
602
225
  end
603
- alias _escaped _escaped_path
604
226
  end
605
- private :_escaped_path
606
- private :_escaped
607
227
 
608
228
  # If supported, make a hardlink, otherwise
609
229
  # fall back to copying.
@@ -626,19 +246,11 @@ end
626
246
  ln(src, dest, :force => true)
627
247
  end
628
248
 
629
- # Split a path in all elements.
630
- def split_all(path)
631
- base, last = File.split(path)
632
- return [last] if base == "." || last == "/"
633
- return [base, last] if base == "/"
634
- split_all(base) + [last]
635
- end
636
-
637
249
  def split_path(str)
638
250
  str.split(Env.on_windows? ? ";" : ":")
639
251
  end
640
252
 
641
- extend self
253
+ extend self
642
254
 
643
255
  if RUBY_VERSION >= "1.8.4" # needed by 1.9.0, too
644
256
  class << self
@@ -656,38 +268,57 @@ end
656
268
  # instance of this class.
657
269
  class SysObject
658
270
  include Sys
659
-
660
- def initialize(rac)
661
- @rac = rac or
662
- raise ArgumentError, "controller required"
271
+ def initialize(rant)
272
+ @rant = rant or
273
+ raise ArgumentError, "rant application required"
663
274
  end
664
-
275
+ # Preferred over directly modifying var[:ignore]. var[:ignore]
276
+ # might go in future.
277
+ def ignore(*patterns)
278
+ @rant.var[:ignore].concat(patterns)
279
+ nil
280
+ end
281
+ # <code>sys.filelist(arg)</code>::
282
+ # corresponds to <code>Rant::FileList(arg)</code>
283
+ # <code>sys.filelist</code>::
284
+ # corresponds to <code>Rant::FileList.new</code>
285
+ def filelist(arg = Rant.__rant_no_value__)
286
+ if Rant.__rant_no_value__.equal?(arg)
287
+ RacFileList.new(@rant)
288
+ elsif arg.respond_to?(:to_rant_filelist)
289
+ arg.to_rant_filelist
290
+ elsif arg.respond_to?(:to_ary)
291
+ RacFileList.new(@rant, arg.to_ary)
292
+ else
293
+ raise TypeError,
294
+ "cannot convert #{arg.class} into Rant::FileList"
295
+ end
296
+ end
297
+ # corresponds to <code>Rant::FileList[*patterns]</code>.
298
+ def [](*patterns)
299
+ RacFileList.new(@rant).hide_dotfiles.include(*patterns)
300
+ end
301
+ # corresponds to <code>Rant::FileList.glob(*patterns,
302
+ # &block)</code>.
665
303
  def glob(*patterns, &block)
666
- fl = RacFileList.new(@rac, *patterns)
667
- fl.instance_eval(&block) if block
668
- fl
304
+ fl = RacFileList.new(@rant).hide_dotfiles.include(*patterns)
305
+ fl.ignore(".", "..")
306
+ if block_given? then yield fl else fl end
669
307
  end
670
-
308
+ # corresponds to <code>Rant::FileList.glob_all(*patterns,
309
+ # &block)</code>.
671
310
  def glob_all(*patterns, &block)
672
- fl = RacFileList.new(@rac, *patterns)
673
- fl.ignore(".", "..")
674
- fl.glob_flags |= File::FNM_DOTMATCH
675
- fl.instance_eval(&block) if block
676
- fl
311
+ fl = RacFileList.new(@rant).include(*patterns)
312
+ fl.ignore(".", "..") # use case: "*.*" as pattern
313
+ if block_given? then yield fl else fl end
677
314
  end
678
-
679
- def [](*patterns)
680
- RacFileList.new(@rac, *patterns)
681
- end
682
-
683
315
  def expand_path(path)
684
- File.expand_path(@rac.project_to_fs_path(path))
316
+ File.expand_path(@rant.project_to_fs_path(path))
685
317
  end
686
-
687
318
  private
688
- # Delegates FileUtils messages to +rac+.
319
+ # Delegates FileUtils messages to +rant+.
689
320
  def fu_output_message(cmd)
690
- @rac.cmd_msg cmd
321
+ @rant.cmd_msg cmd
691
322
  end
692
323
  end
693
324
  end # module Rant