Class: Rant::FileList

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/rant.rb,
lib/rant/import/filelist/std.rb,
lib/rant/import/filelist/core.rb,
lib/rant/import/filelist/more.rb,
lib/rant/import/filelist/inspect.rb

Direct Known Subclasses

RacFileList

Constant Summary collapse

ESC_SEPARATOR =
Regexp.escape(File::SEPARATOR)
ESC_ALT_SEPARATOR =
File::ALT_SEPARATOR ?
Regexp.escape(File::ALT_SEPARATOR) : nil
FN_DOTFILE_RX_ =

Dir.glob of Ruby releases before 1.8.2 returned dotfiles even if File::FNM_DOTMATCH was not set.

ESC_ALT_SEPARATOR ?
/(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..*
    ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x :
/(^|#{ESC_SEPARATOR}+)\..* (#{ESC_SEPARATOR}+|$)/x
@@__send_private__ =
Object.method_defined?(:fcall) ? :fcall : :funcall

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#inject, #select_map

Constructor Details

#initialize(store = []) ⇒ FileList

Returns a new instance of FileList.


41
42
43
44
45
46
47
48
# File 'lib/rant/import/filelist/core.rb', line 41

def initialize(store = [])
    @pending = false
    @def_glob_dotfiles = true
    @items = store
    @ignore_rx = nil
    @keep = {}
    @actions = []
end

Class Method Details

.[](*patterns) ⇒ Object


28
29
30
# File 'lib/rant/import/filelist/core.rb', line 28

def [](*patterns)
    new.hide_dotfiles.include(*patterns)
end

.glob(*patterns) ⇒ Object


31
32
33
34
# File 'lib/rant/import/filelist/core.rb', line 31

def glob(*patterns)
    fl = new.hide_dotfiles.ignore(".", "..").include(*patterns)
    if block_given? then yield fl else fl end
end

.glob_all(*patterns) ⇒ Object


35
36
37
38
# File 'lib/rant/import/filelist/core.rb', line 35

def glob_all(*patterns)
    fl = new.ignore(".", "..").include(*patterns)
    if block_given? then yield fl else fl end
end

Instance Method Details

#+(other) ⇒ Object


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/rant/import/filelist/core.rb', line 122

def +(other)
    if other.respond_to? :to_rant_filelist
        c = other.to_rant_filelist.dup
        c.actions.concat(@actions)
        c.items.concat(@items)
        c.pending = !c.actions.empty?
        c
    elsif other.respond_to? :to_ary
        c = dup
        c.actions <<
            [:apply_ary_method_1, :concat, other.to_ary.dup]
        c.pending = true
        c
    else
        raise TypeError,
            "cannot add #{other.class} to Rant::FileList"
    end
end

#<<(file) ⇒ Object

Use this method to append file to this list. file will stay in this list even if it matches an exclude or ignore pattern.

Returns self.


145
146
147
148
149
150
# File 'lib/rant/import/filelist/core.rb', line 145

def <<(file)
    @actions << [:apply_ary_method_1, :push, file]
    @keep[file] = true
    @pending = true
    self
end

#apply_exclude_path(pattern) ⇒ Object


346
347
348
349
350
351
# File 'lib/rant/import/filelist/core.rb', line 346

def apply_exclude_path(pattern)
    flags = File::FNM_DOTMATCH|File::FNM_PATHNAME
    @items.reject! { |elem|
        File.fnmatch?(pattern, elem, flags) && !@keep[elem]
    }
end

#arglistObject Also known as: to_s

Get a string with all entries. This is very usefull if you invoke a shell:

files # => ["foo/bar", "with space"]
sh "rdoc #{files.arglist}"

will result on windows:

rdoc foo\bar "with space"

on other systems:

rdoc foo/bar with\ space

385
386
387
# File 'lib/rant/import/filelist/core.rb', line 385

def arglist
    Rant::Sys.sp to_ary
end

#concat(ary) ⇒ Object

Append the entries of ary (an array like object) to this list.


164
165
166
167
168
169
170
171
172
173
# File 'lib/rant/import/filelist/core.rb', line 164

def concat(ary)
    if @pending
        ary = ary.to_ary.dup
        @actions << [:apply_ary_method_1, :concat, ary]
    else
        ix = ignore_rx and ary = ary.to_ary.reject { |f| f =~ ix }
        @items.concat(ary)
    end
    self
end

#copyObject


59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/rant/import/filelist/core.rb', line 59

def copy
    c = _object_dup
    c.items = @items.map { |entry| entry.dup }
    c.actions = @actions.dup
    c.ignore_rx = @ignore_rx.dup if @ignore_rx
    # alternative approach: copy & freeze "keep" entries on
    # inclusion in the keep hash
    h_keep = {}
    @keep.each_key { |entry| h_keep[entry] = true }
    c.instance_variable_set(:@keep, h_keep)
    c
end

#dirsObject

Get a new filelist containing only the existing directories from this filelist.


60
61
62
# File 'lib/rant/import/filelist/std.rb', line 60

def dirs
    select { |entry| test ?d, entry }
end

#dupObject


51
52
53
54
55
56
57
58
# File 'lib/rant/import/filelist/core.rb', line 51

def dup
    c = _object_dup
    c.items = @items.dup
    c.actions = @actions.dup
    c.ignore_rx = @ignore_rx.dup if @ignore_rx
    c.instance_variable_set(:@keep, @keep.dup)
    c
end

#each(&block) ⇒ Object


108
109
110
111
112
# File 'lib/rant/import/filelist/core.rb', line 108

def each(&block)
    resolve if @pending
    @items.each(&block)
    self
end

#empty?Boolean

Returns:

  • (Boolean)

180
181
182
183
# File 'lib/rant/import/filelist/core.rb', line 180

def empty?
    resolve if @pending
    @items.empty?
end

#exclude(*patterns) ⇒ Object

Exclude all entries matching one of patterns from this filelist.

Note: Only applies to entries previousely included.


279
280
281
282
283
284
285
286
287
288
289
# File 'lib/rant/import/filelist/core.rb', line 279

def exclude(*patterns)
    patterns.each { |pat|
        if Regexp === pat
            @actions << [:apply_exclude_rx, pat]
        else
            @actions << [:apply_exclude, pat]
        end
    }
    @pending = true
    self
end

#exclude_name(*names) ⇒ Object Also known as: shun


318
319
320
321
322
323
324
# File 'lib/rant/import/filelist/core.rb', line 318

def exclude_name(*names)
    names.each { |name|
        @actions << [:apply_exclude_rx, mk_all_rx(name)]
    }
    @pending = true
    self
end

#exclude_path(*patterns) ⇒ Object


339
340
341
342
343
344
345
# File 'lib/rant/import/filelist/core.rb', line 339

def exclude_path(*patterns)
    patterns.each { |pat|
        @actions << [:apply_exclude_path, pat]
    }
    @pending = true
    self
end

#ext(ext_str) ⇒ Object


374
375
376
# File 'lib/rant/import/filelist/core.rb', line 374

def ext(ext_str)
    sub_ext(ext_str)
end

#filesObject

Get a new filelist containing only the existing files from this filelist.


55
56
57
# File 'lib/rant/import/filelist/std.rb', line 55

def files
    select { |entry| test ?f, entry }
end

#glob_all(*patterns) ⇒ Object


242
243
244
245
246
247
248
# File 'lib/rant/import/filelist/core.rb', line 242

def glob_all(*patterns)
    patterns.flatten.each { |pat|
        @actions << [:apply_glob_all, pat]
    }
    @pending = true
    self
end

#glob_dotfilesObject

Has the same effect as glob_dotfiles = true.

Returns self.

Currently for Rant internal use only. Might go in future releases.


97
98
99
100
# File 'lib/rant/import/filelist/core.rb', line 97

def glob_dotfiles
    @def_glob_dotfiles = true
    self
end

#glob_dotfiles=(flag) ⇒ Object

Currently for Rant internal use only. Might go in future releases.


78
79
80
# File 'lib/rant/import/filelist/core.rb', line 78

def glob_dotfiles=(flag)
    @def_glob_dotfiles = flag ? true : false
end

#glob_dotfiles?Boolean

Currently for Rant internal use only. Might go in future releases.

Returns:

  • (Boolean)

73
74
75
# File 'lib/rant/import/filelist/core.rb', line 73

def glob_dotfiles?
    @def_glob_dotfiles
end

#glob_unix(*patterns) ⇒ Object

Unix style glob: hide files starting with a dot


235
236
237
238
239
240
241
# File 'lib/rant/import/filelist/core.rb', line 235

def glob_unix(*patterns)
    patterns.flatten.each { |pat|
        @actions << [:apply_glob_unix, pat]
    }
    @pending = true
    self
end

#hide_dotfilesObject

Has the same effect as glob_dotfiles = false.

Returns self.

Currently for Rant internal use only. Might go in future releases.


87
88
89
90
# File 'lib/rant/import/filelist/core.rb', line 87

def hide_dotfiles
    @def_glob_dotfiles = false
    self
end

#ignore(*patterns) ⇒ Object


290
291
292
293
294
295
296
# File 'lib/rant/import/filelist/core.rb', line 290

def ignore(*patterns)
    patterns.each { |pat|
        add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat))
    }
    @pending = true
    self
end

#include(*pats) ⇒ Object Also known as: glob

Include entries matching one of patterns in this filelist.


230
231
232
# File 'lib/rant/import/filelist/core.rb', line 230

def include(*pats)
    @def_glob_dotfiles ? glob_all(*pats) : glob_unix(*pats)
end

#inspectObject

Note that the default Object#inspect implementation is available as object_inspect.


10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/rant/import/filelist/inspect.rb', line 10

def inspect
    # what's the right encoding for object_id ?
    s = "#<#{self.class}:0x#{"%x" % object_id} "
    s << "#{@actions.size} actions, #{@items.size} entries"
    if @ignore_rx
        is = @ignore_rx.inspect.gsub(/\n|\t/, ' ')
        s << ", ignore#{is.squeeze ' '}"
    end
    if @glob_flags != 0
        s << ", flags:#@glob_flags"
    end
    s << ">"
end

#join(sep = ' ') ⇒ Object


184
185
186
187
# File 'lib/rant/import/filelist/core.rb', line 184

def join(sep = ' ')
    resolve if @pending
    @items.join(sep)
end

#keep(entry) ⇒ Object

Add entry to this filelist. Position of entry in this list is undefined. More efficient than #<<. entry will stay in this list even if it matches an exclude or ignore pattern.

Returns self.


157
158
159
160
161
# File 'lib/rant/import/filelist/core.rb', line 157

def keep(entry)
    @keep[entry] = true
    @items << entry
    self
end

#map(&block) ⇒ Object Also known as: collect


364
365
366
367
368
369
# File 'lib/rant/import/filelist/core.rb', line 364

def map(&block)
    d = dup
    d.actions << [:apply_ary_method, :map!, block]
    d.pending = true
    d
end

#map!(&block) ⇒ Object

Same as #map! but evaluation is delayed until the next read access (e.g. by calling #each). Always returns self.


406
407
408
409
410
# File 'lib/rant/import/filelist/core.rb', line 406

def map!(&block)
    @actions << [:apply_ary_method, :map!, block]
    @pending = true
    self
end

#no_dir(name = nil) ⇒ Object

Remove all entries which contain a directory with the given name. If no argument or nil given, remove all directories.

Example:

file_list.no_dir "CVS"

would remove the following entries from file_list:

CVS/
src/CVS/lib.c
CVS/foo/bar/

26
27
28
29
30
# File 'lib/rant/import/filelist/std.rb', line 26

def no_dir(name = nil)
    @actions << [:apply_no_dir, name]
    @pending = true
    self
end

#no_file(name) ⇒ Object

Remove all files which have the given name.


9
10
11
12
13
14
15
16
# File 'lib/rant/import/filelist/more.rb', line 9

def no_file(name)
           @actions << [:apply_ary_method, :reject!,
               lambda { |entry|
                   entry == name && !@keep[entry] && test(?f, entry)
               }]
    @pending = true
    self
end

#no_prefix(prefix) ⇒ Object

Remove all entries which contain an element with the given prefix.


40
41
42
43
44
# File 'lib/rant/import/filelist/more.rb', line 40

def no_prefix(prefix)
    @actions << [:no_prefix, prefix]
    @pending = true
    self
end

#no_suffix(suffix) ⇒ Object

Remove all entries which contain an element with the given suffix.


20
21
22
23
24
# File 'lib/rant/import/filelist/more.rb', line 20

def no_suffix(suffix)
    @actions << [:no_suffix, suffix]
    @pending = true
    self
end

#object_inspectObject


389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/rant/import/filelist/core.rb', line 389

def inspect
    # what's the right encoding for object_id ?
    s = "#<#{self.class}:0x#{"%x" % object_id} "
    s << "#{@actions.size} actions, #{@items.size} entries"
    if @ignore_rx
        is = @ignore_rx.inspect.gsub(/\n|\t/, ' ')
        s << ", ignore#{is.squeeze ' '}"
    end
    if @glob_flags != 0
        s << ", flags:#@glob_flags"
    end
    s << ">"
end

#popObject


188
189
190
191
# File 'lib/rant/import/filelist/core.rb', line 188

def pop
    resolve if @pending
    @items.pop
end

#push(entry) ⇒ Object


192
193
194
195
196
# File 'lib/rant/import/filelist/core.rb', line 192

def push(entry)
    resolve if @pending
    @items.push(entry) if entry !~ ignore_rx
    self
end

#reject!(&block) ⇒ Object


411
412
413
414
415
# File 'lib/rant/import/filelist/core.rb', line 411

def reject!(&block)
    @actions << [:apply_ary_method, :reject!, block]
    @pending = true
    self
end

#resolveObject

Force evaluation of all patterns.


219
220
221
222
223
224
225
226
227
# File 'lib/rant/import/filelist/core.rb', line 219

def resolve
    @pending = false
    @actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear
    ix = ignore_rx
    if ix
        @items.reject! { |f| f =~ ix && !@keep[f] }
    end
    self
end

#select(&block) ⇒ Object Also known as: find_all


353
354
355
356
357
358
# File 'lib/rant/import/filelist/core.rb', line 353

def select(&block)
    d = dup
    d.actions << [:apply_select, block]
    d.pending = true
    d
end

#shiftObject


197
198
199
200
# File 'lib/rant/import/filelist/core.rb', line 197

def shift
    resolve if @pending
    @items.shift
end

#sizeObject Also known as: length

Number of entries in this filelist.


175
176
177
178
# File 'lib/rant/import/filelist/core.rb', line 175

def size
    resolve if @pending
    @items.size
end

#sort!Object

Same as #sort! but evaluation is delayed until the next read access (e.g. by calling #each). Always returns self.


399
400
401
402
403
# File 'lib/rant/import/filelist/core.rb', line 399

def sort!
    @actions << [:apply_ary_method, :sort!]
    @pending = true
    self
end

#sub_ext(ext, new_ext = nil) ⇒ Object


371
372
373
# File 'lib/rant/import/filelist/core.rb', line 371

def sub_ext(ext, new_ext=nil)
    map { |f| f._rant_sub_ext ext, new_ext }
end

#to_aryObject Also known as: to_a, entries


113
114
115
116
# File 'lib/rant/import/filelist/core.rb', line 113

def to_ary
    resolve if @pending
    @items
end

#to_rant_filelistObject


119
120
121
# File 'lib/rant/import/filelist/core.rb', line 119

def to_rant_filelist
    self
end

#uniq!Object

Same as #uniq! but evaluation is delayed until the next read access (e.g. by calling #each). Always returns self.


392
393
394
395
396
# File 'lib/rant/import/filelist/core.rb', line 392

def uniq!
    @actions << [:apply_ary_method, :uniq!]
    @pending = true
    self
end

#unshift(entry) ⇒ Object


201
202
203
204
205
# File 'lib/rant/import/filelist/core.rb', line 201

def unshift(entry)
    resolve if @pending
    @items.unshift(entry) if entry !~ ignore_rx
    self
end