#!/usr/bin/ruby -w
# -*- ruby -*-
require './filetest'
require './log'
# Additions to the File built-in class.
class File
include Log
# Returns a File::Stat object, or null if there were errors (such as the file
# not existing, access denied, etc.).
def File.status(fd)
begin
return File.stat(fd)
rescue
# ignore files that could not be read, etc.
return nil
end
end
# Returns whether the given object is a file. Ignores errors.
def File.is_file?(fd)
fs = File.status(fd)
return fs && fs.file?
end
# Returns whether the given object is a directory. Ignores errors.
def File.is_directory?(fd)
fs = File.status(fd)
return fs && fs.directory?
end
# Returns an array containing each of the names for which the associated block
# returned true.
def File.find_where(dir)
names = Array.new
Find.find(dir) do |f|
names.push(f) if yield(f)
end
names
end
# Returns an array of all files under the given directory.
def File.find_files(dir)
File.find_where(dir) { |f| is_file?(f) }
end
# Returns an array of all directory under the given directory.
def File.find_directories(dir)
File.find_where(dir) { |f| is_directory?(f) }
end
# Returns an array of all files within the given directory.
def File.local_files(dir)
Dir.new(dir).find_all { |f| is_file?(f) }
end
# Strips the PWD and the leading ./
def File.clean_name(fname)
Log.log "fname: #{fname}"
file = fname.dup
file.gsub!(Dir.pwd, "")
file.gsub!(/^\//, "")
file.sub!(/^\.\//, "")
file
end
def File.is_text?(fname)
FileTester.text?(fname)
end
end
# A hash that ensures that we use file name of the form: "foo/Bar", not
# "./foo/Bar".
class FileHash < Hash
def []=(f, value)
fname = File.clean_name(f)
super(fname, value)
end
def [](f)
fname = File.clean_name(f)
super(fname)
end
end
# An array that ensures that we use file name of the form: "foo/Bar", not
# "./foo/Bar".
class FileArray < Array
def []=(index, name)
file = File.clean_name(f)
super(index, name)
end
def push(name)
fname = File.clean_name(name)
super(fname)
end
end
# Directories listed so that the parents are first in the list.
class OrderedDirectoryList < Array
def initialize(files)
files.each { |f| add(File.dirname(f)) }
end
# add a directory
def add(dir)
if dir && !File.exists?(dir + "/CVS/Entries")
# TODO: remove the CVS-icity of this:
# attempt to add the parent, unless this is "."
# note: this won't work if dir == "."
if dir == "."
puts "ERROR: Cannot process files from within a directory"
puts "not in CVS. Please move up to the parent directory"
puts "and retry."
exit
end
add(File.dirname(dir))
pos = index(dir)
if pos
# nothing to do; dir is already in the list
else
pdpos = index(File.dirname(dir))
if pdpos
# parent already in the list, so insert this dir immediately afterward
self[pdpos + 1, 0] = dir
else
# prepending
unshift(dir)
end
end
end
end
end
if __FILE__ == $0
fa = FileArray.new
fa.push("/this/is/a/test")
puts fa
fa.push("./another/test")
puts fa
end
syntax highlighted by Code2HTML, v. 0.9.1