Class: Rake::FileList

Inherits:
Object
  • Object
show all
Includes:
Cloneable
Defined in:
lib/rake.rb

Overview

A FileList is essentially an array with a few helper methods defined to make file manipulation a bit easier.

FileLists are lazy. When given a list of glob patterns for possible files to be included in the file list, instead of searching the file structures to find the files, a FileList holds the pattern for latter use.

This allows us to define a number of FileList to match any number of files, but only search out the actual files when then FileList itself is actually used. The key is that the first time an element of the FileList/Array is requested, the pending patterns are resolved into a real list of file names.

Constant Summary collapse

ARRAY_METHODS =

List of array methods (that are not in Object) that need to be delegated.

Array.instance_methods - Object.instance_methods
MUST_DEFINE =

List of additional methods that must be delegated.

%w[to_a inspect]
MUST_NOT_DEFINE =

List of methods that should not be delegated here (we define special versions of them explicitly below).

%w[to_a to_ary partition *]
SPECIAL_RETURN =

List of delegated methods that return new array values which need wrapping.

%w[
  map collect sort sort_by select find_all reject grep
  compact flatten uniq values_at
  + - & |
]
DELEGATING_METHODS =
(ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).sort.uniq
DEFAULT_IGNORE_PATTERNS =
[
  /(^|[\/\\])CVS([\/\\]|$)/,
  /(^|[\/\\])\.svn([\/\\]|$)/,
  /\.bak$/,
  /~$/,
  /(^|[\/\\])core$/
]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Cloneable

#clone

Constructor Details

#initialize(*patterns) {|_self| ... } ⇒ FileList

Create a file list from the globbable patterns given. If you wish to perform multiple includes or excludes at object build time, use the “yield self” pattern.

Example:

file_list = FileList.new['lib/**/*.rb', 'test/test*.rb']

pkg_files = FileList.new['lib/**/*'] do |fl|
  fl.exclude(/\bCVS\b/)
end

Yields:

  • (_self)

Yield Parameters:



1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'lib/rake.rb', line 1017

def initialize(*patterns)
  @pending_add = []
  @pending = false
  @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
  @exclude_re = nil
  @items = []
  patterns.each { |pattern| include(pattern) }
  yield self if block_given?
end

Class Method Details

.[](*args) ⇒ Object

Create a new file list including the files listed. Similar to:

FileList.new(*args)


1295
1296
1297
# File 'lib/rake.rb', line 1295

def [](*args)
  new(*args)
end

.clear_ignore_patternsObject

Clear the ignore patterns.



1315
1316
1317
# File 'lib/rake.rb', line 1315

def clear_ignore_patterns
  @exclude_patterns = [ /^$/ ]
end

.select_default_ignore_patternsObject

Set the ignore patterns back to the default value. The default patterns will ignore files

  • containing “CVS” in the file path

  • containing “.svn” in the file path

  • ending with “.bak”

  • ending with “~”

  • named “core”

Note that file names beginning with “.” are automatically ignored by Ruby’s glob patterns and are not specifically listed in the ignore patterns.



1310
1311
1312
# File 'lib/rake.rb', line 1310

def select_default_ignore_patterns
  @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup
end

Instance Method Details

#*(other) ⇒ Object

Redefine * to return either a string or a new file list.



1101
1102
1103
1104
1105
1106
1107
1108
1109
# File 'lib/rake.rb', line 1101

def *(other)
  result = @items * other
  case result
  when Array
	FileList.new.import(result)
  else
	result
  end
end

#==(array) ⇒ Object

Define equality.



1084
1085
1086
# File 'lib/rake.rb', line 1084

def ==(array)
  to_ary == array
end

#calculate_exclude_regexpObject



1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
# File 'lib/rake.rb', line 1122

def calculate_exclude_regexp
  ignores = []
  @exclude_patterns.each do |pat|
    case pat
    when Regexp
      ignores << pat
    when /[*.]/
      Dir[pat].each do |p| ignores << p end
    else
      ignores << Regexp.quote(pat)
    end
  end
  if ignores.empty?
    @exclude_re = /^$/
  else
    re_str = ignores.collect { |p| "(" + p.to_s + ")" }.join("|")
    @exclude_re = Regexp.new(re_str)
  end
end

#clear_excludeObject

Clear all the exclude patterns so that we exclude nothing.



1078
1079
1080
1081
# File 'lib/rake.rb', line 1078

def clear_exclude
  @exclude_patterns = []
  calculate_exclude_regexp if ! @pending
end

#egrep(pattern) ⇒ Object

Grep each of the files in the filelist using the given pattern. If a block is given, call the block on each matching line, passing the file name, line number, and the matching line of text. If no block is given, a standard emac style file:linenumber:line message will be printed to standard out.



1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
# File 'lib/rake.rb', line 1228

def egrep(pattern)
  each do |fn|
	open(fn) do |inf|
	  count = 0
	  inf.each do |line|
 count += 1
 if pattern.match(line)
   if block_given?
		yield fn, count, line
   else
		puts "#{fn}:#{count}:#{line}"
   end		
 end
	  end
	end
  end
end

#exclude(*patterns) ⇒ Object

Register a list of file name patterns that should be excluded from the list. Patterns may be regular expressions, glob patterns or regular strings.

Note that glob patterns are expanded against the file system. If a file is explicitly added to a file list, but does not exist in the file system, then an glob pattern in the exclude list will not exclude the file.

Examples:

FileList['a.c', 'b.c'].exclude("a.c") => ['b.c']
FileList['a.c', 'b.c'].exclude(/^a/)  => ['b.c']

If “a.c” is a file, then …

FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']

If “a.c” is not a file, then …

FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']


1067
1068
1069
1070
1071
1072
1073
1074
# File 'lib/rake.rb', line 1067

def exclude(*patterns)
  patterns.each do |pat| @exclude_patterns << pat end
  if ! @pending
    calculate_exclude_regexp
    reject! { |fn| fn =~ @exclude_re }
  end
  self
end

#exclude?(fn) ⇒ Boolean

Should the given file name be excluded?

Returns:

  • (Boolean)


1272
1273
1274
1275
# File 'lib/rake.rb', line 1272

def exclude?(fn)
  calculate_exclude_regexp unless @exclude_re
  fn =~ @exclude_re
end

#ext(newext = '') ⇒ Object

Return a new array with String#ext method applied to each member of the array.

This method is a shortcut for:

array.collect { |item| item.ext(newext) }

ext is a user added method for the Array class.



1218
1219
1220
# File 'lib/rake.rb', line 1218

def ext(newext='')
  collect { |fn| fn.ext(newext) }
end

#gsub(pat, rep) ⇒ Object

Return a new FileList with the results of running gsub against each element of the original list.

Example:

FileList['lib/test/file', 'x/y'].gsub(/\//, "\\")
   => ['lib\\test\\file', 'x\\y']


1187
1188
1189
# File 'lib/rake.rb', line 1187

def gsub(pat, rep)
  inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) }
end

#gsub!(pat, rep) ⇒ Object

Same as gsub except that the original file list is modified.



1198
1199
1200
1201
# File 'lib/rake.rb', line 1198

def gsub!(pat, rep)
  each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) }
  self
end

#import(array) ⇒ Object



1286
1287
1288
1289
# File 'lib/rake.rb', line 1286

def import(array)
  @items = array
  self
end

#include(*filenames) ⇒ Object Also known as: add

Add file names defined by glob patterns to the file list. If an array is given, add each element of the array.

Example:

file_list.include("*.java", "*.cfg")
file_list.include %w( math.c lib.h *.o )


1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
# File 'lib/rake.rb', line 1034

def include(*filenames)
  # TODO: check for pending
  filenames.each do |fn|
	if fn.respond_to? :to_ary
	  include(*fn.to_ary)
	else
	  @pending_add << fn
	end
  end
  @pending = true
  self
end

#partition(&block) ⇒ Object

FileList version of partition. Needed because the nested arrays should be FileLists in this version.



1248
1249
1250
1251
1252
1253
1254
1255
# File 'lib/rake.rb', line 1248

def partition(&block)	# :nodoc:
  resolve
  result = @items.partition(&block)
  [
    FileList.new.import(result[0]),
    FileList.new.import(result[1]),
  ]
end

#pathmap(spec = nil) ⇒ Object

Apply the pathmap spec to each of the included file names, returning a new file list with the modified paths. (See String#pathmap for details.)



1206
1207
1208
# File 'lib/rake.rb', line 1206

def pathmap(spec=nil)
  collect { |fn| fn.pathmap(spec) }
end

#resolveObject

Resolve all the pending adds now.



1112
1113
1114
1115
1116
1117
1118
1119
1120
# File 'lib/rake.rb', line 1112

def resolve
  if @pending
    @pending = false
    @pending_add.each do |fn| resolve_add(fn) end
    @pending_add = []
    resolve_exclude
  end
  self
end

#sub(pat, rep) ⇒ Object

Return a new FileList with the results of running sub against each element of the oringal list.

Example:

FileList['a.c', 'b.c'].sub(/\.c$/, '.o')  => ['a.o', 'b.o']


1176
1177
1178
# File 'lib/rake.rb', line 1176

def sub(pat, rep)
  inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) }
end

#sub!(pat, rep) ⇒ Object

Same as sub except that the oringal file list is modified.



1192
1193
1194
1195
# File 'lib/rake.rb', line 1192

def sub!(pat, rep)
  each_with_index { |fn, i| self[i] = fn.sub(pat,rep) }
  self
end

#to_aObject

Return the internal array object.



1089
1090
1091
1092
# File 'lib/rake.rb', line 1089

def to_a
  resolve
  @items
end

#to_aryObject

Return the internal array object.



1095
1096
1097
1098
# File 'lib/rake.rb', line 1095

def to_ary
  resolve
  @items
end

#to_sObject

Convert a FileList to a string by joining all elements with a space.



1258
1259
1260
1261
# File 'lib/rake.rb', line 1258

def to_s
  resolve if @pending
  self.join(' ')
end