class Rake::FileList
FileList
本质上是一个数组,定义了一些辅助方法以简化文件操作。
FileLists 是延迟加载的。当给定一个可能包含在文件列表中的文件 glob 模式列表时,FileList
不会搜索文件结构来查找文件,而是保存模式供以后使用。
这允许我们定义任意数量的 FileList
来匹配任意数量的文件,但只在实际使用 FileList
本身时才搜索实际文件。关键在于,第一次请求 FileList/Array 的元素时,待处理的模式会被解析为实际的文件名列表。
常量
- ARRAY_METHODS
需要委托的数组方法列表(不在
Object
中)。- DEFAULT_IGNORE_PATTERNS
- DEFAULT_IGNORE_PROCS
- DELEGATING_METHODS
- GLOB_PATTERN
- MUST_DEFINE
必须委托的其他方法列表。
- MUST_NOT_DEFINE
不应在此处委托的方法列表(我们在下面显式定义了它们的特殊版本)。
- SPECIAL_RETURN
返回需要包装的新数组值的委托方法列表。
公共类方法
创建一个包含所列文件的新文件列表。类似于
FileList.new(*args)
# File rake-13.2.1/lib/rake/file_list.rb, line 400 def [](*args) new(*args) end
获取与模式匹配的排序文件列表。此方法应优先于 Dir 和 Dir.glob(pattern),因为返回的文件保证已排序。
# File rake-13.2.1/lib/rake/file_list.rb, line 407 def glob(pattern, *args) Dir.glob(pattern, *args).sort end
根据给定的可 glob 模式创建一个文件列表。如果希望在对象构建时执行多个包含或排除操作,请使用 “yield self” 模式。
示例
file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') pkg_files = FileList.new('lib/**/*') do |fl| fl.exclude(/\bCVS\b/) end
# File rake-13.2.1/lib/rake/file_list.rb, line 99 def initialize(*patterns) @pending_add = [] @pending = false @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup @exclude_procs = DEFAULT_IGNORE_PROCS.dup @items = [] patterns.each { |pattern| include(pattern) } yield self if block_given? end
公共实例方法
重新定义 * 以返回字符串或新的文件列表。
# File rake-13.2.1/lib/rake/file_list.rb, line 193 def *(other) result = @items * other case result when Array self.class.new.import(result) else result end end
# File rake-13.2.1/lib/rake/file_list.rb, line 203 def <<(obj) resolve @items << Rake.from_pathname(obj) self end
通过数组相等性判断 FileList
是否相等。
# File rake-13.2.1/lib/rake/file_list.rb, line 171 def ==(array) to_ary == array end
清除所有排除模式,以便我们不排除任何内容。
# File rake-13.2.1/lib/rake/file_list.rb, line 164 def clear_exclude @exclude_patterns = [] @exclude_procs = [] self end
使用给定的模式 grep 文件列表中的每个文件。如果给定一个块,则在每个匹配的行上调用该块,并传递文件名、行号和匹配的文本行。如果没有给定块,则会将标准的 emacs 样式 file:linenumber:line 消息打印到标准输出。返回匹配项的数量。
# File rake-13.2.1/lib/rake/file_list.rb, line 293 def egrep(pattern, *options) matched = 0 each do |fn| begin File.open(fn, "r", *options) do |inf| count = 0 inf.each do |line| count += 1 if pattern.match(line) matched += 1 if block_given? yield fn, count, line else puts "#{fn}:#{count}:#{line}" end end end end rescue StandardError => ex $stderr.puts "Error while processing '#{fn}': #{ex}" end end matched end
注册一个应从列表中排除的文件名模式列表。模式可以是正则表达式、glob 模式或常规字符串。此外,传递给 exclude 的块将删除给定块时返回 true 的条目。
请注意,glob 模式是针对文件系统展开的。如果将某个文件显式添加到文件列表,但该文件不存在于文件系统中,则排除列表中的 glob 模式将不会排除该文件。
示例
FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c']
如果 “a.c” 是一个文件,则 ...
FileList['a.c', 'b.c'].exclude("a.*") => ['b.c']
如果 “a.c” 不是一个文件,则 ...
FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c']
# File rake-13.2.1/lib/rake/file_list.rb, line 150 def exclude(*patterns, &block) patterns.each do |pat| if pat.respond_to? :to_ary exclude(*pat.to_ary) else @exclude_patterns << Rake.from_pathname(pat) end end @exclude_procs << block if block_given? resolve_exclude unless @pending self end
给定的文件名是否应从列表中排除?
注意:此方法以前名为 “exclude?”,但 Rails 引入了 exclude? 方法作为数组方法,并设置了与文件列表的冲突。我们重命名了该方法以避免混淆。如果您在用户代码中使用了 “FileList#exclude?”,则需要更新。
# File rake-13.2.1/lib/rake/file_list.rb, line 364 def excluded_from_list?(fn) return true if @exclude_patterns.any? do |pat| case pat when Regexp fn =~ pat when GLOB_PATTERN flags = File::FNM_PATHNAME # Ruby <= 1.9.3 does not support File::FNM_EXTGLOB flags |= File::FNM_EXTGLOB if defined? File::FNM_EXTGLOB File.fnmatch?(pat, fn, flags) else fn == pat end end @exclude_procs.any? { |p| p.call(fn) } end
返回一个新的文件列表,其中仅包含当前文件列表中存在于文件系统上的文件名。
# File rake-13.2.1/lib/rake/file_list.rb, line 320 def existing select { |fn| File.exist?(fn) }.uniq end
修改当前文件列表,使其仅包含文件系统中存在的文件名。
# File rake-13.2.1/lib/rake/file_list.rb, line 326 def existing! resolve @items = @items.select { |fn| File.exist?(fn) }.uniq self end
返回一个新的 FileList
,其中 String#ext
方法应用于数组的每个成员。
此方法是以下内容的快捷方式
array.collect { |item| item.ext(newext) }
ext
是为 Array 类添加的用户方法。
# File rake-13.2.1/lib/rake/file_list.rb, line 284 def ext(newext="") collect { |fn| fn.ext(newext) } end
返回一个新的 FileList
,其中包含对原始列表的每个元素运行 gsub
的结果。
示例
FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") => ['lib\\test\\file', 'x\\y']
# File rake-13.2.1/lib/rake/file_list.rb, line 253 def gsub(pat, rep) inject(self.class.new) { |res, fn| res << fn.gsub(pat, rep) } end
与 gsub
相同,但会修改原始文件列表。
# File rake-13.2.1/lib/rake/file_list.rb, line 264 def gsub!(pat, rep) each_with_index { |fn, i| self[i] = fn.gsub(pat, rep) } self end
将由 glob 模式定义的文件名添加到文件列表。如果给定一个数组,则添加数组的每个元素。
示例
file_list.include("*.java", "*.cfg") file_list.include %w( math.c lib.h *.o )
# File rake-13.2.1/lib/rake/file_list.rb, line 116 def include(*filenames) # TODO: check for pending filenames.each do |fn| if fn.respond_to? :to_ary include(*fn.to_ary) else @pending_add << Rake.from_pathname(fn) end end @pending = true self end
谎报我们的类。
# File rake-13.2.1/lib/rake/file_list.rb, line 187 def is_a?(klass) klass == Array || super(klass) end
将 pathmap 规范应用于每个包含的文件名,返回一个新的文件列表,其中包含修改后的路径。(有关详细信息,请参阅 String#pathmap
。)
# File rake-13.2.1/lib/rake/file_list.rb, line 272 def pathmap(spec=nil, &block) collect { |fn| fn.pathmap(spec, &block) } end
现在解析所有待添加项。
# File rake-13.2.1/lib/rake/file_list.rb, line 210 def resolve if @pending @pending = false @pending_add.each do |fn| resolve_add(fn) end @pending_add = [] resolve_exclude end self end
返回一个新的 FileList
,其中包含对原始列表的每个元素运行 sub
的结果。
示例
FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o']
# File rake-13.2.1/lib/rake/file_list.rb, line 242 def sub(pat, rep) inject(self.class.new) { |res, fn| res << fn.sub(pat, rep) } end
与 sub
相同,但会修改原始文件列表。
# File rake-13.2.1/lib/rake/file_list.rb, line 258 def sub!(pat, rep) each_with_index { |fn, i| self[i] = fn.sub(pat, rep) } self end
返回内部数组对象。
# File rake-13.2.1/lib/rake/file_list.rb, line 176 def to_a resolve @items end
返回内部数组对象。
# File rake-13.2.1/lib/rake/file_list.rb, line 182 def to_ary to_a end
通过将所有元素与空格连接起来,将 FileList
转换为字符串。
# File rake-13.2.1/lib/rake/file_list.rb, line 344 def to_s resolve self.join(" ") end
私有实例方法
添加匹配的 glob 模式。
# File rake-13.2.1/lib/rake/file_list.rb, line 350 def add_matching(pattern) self.class.glob(pattern).each do |fn| self << fn unless excluded_from_list?(fn) end end