335 lines
7.8 KiB
Ruby
Executable File
335 lines
7.8 KiB
Ruby
Executable File
#
|
|
# file.rb
|
|
# OS File Utilities
|
|
#
|
|
# Greg Smith <greg@rockstarnorth.com>
|
|
# Luke Openshaw <luke.openshaw@rockstarnorth.com>
|
|
#
|
|
|
|
require 'pipeline/os/path'
|
|
require 'fileutils'
|
|
|
|
module Pipeline
|
|
module OS
|
|
|
|
class FileEx
|
|
|
|
#---------------------------------------------------------------------
|
|
# Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# File.directory? returns incorrect results if the directory
|
|
# name contains full stops
|
|
#
|
|
#
|
|
def FileEx.directory?(filename)
|
|
|
|
ret = true
|
|
|
|
begin
|
|
|
|
Dir.open(filename) { |check|
|
|
|
|
}
|
|
rescue
|
|
|
|
ret = false
|
|
|
|
end
|
|
|
|
ret
|
|
|
|
end
|
|
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# Collection of file utilities above those built in to ruby
|
|
#
|
|
#
|
|
class FileUtilsEx
|
|
|
|
#---------------------------------------------------------------------
|
|
# Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
def FileUtilsEx.make_sure_path_exists( filename )
|
|
|
|
destpath = Path.remove_filename(filename)
|
|
FileUtils.mkdir_p destpath if File.directory?(destpath) == false
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# Copies a file, taking care of housekeeping such as directory creation
|
|
#
|
|
#
|
|
def FileUtilsEx.copy_file(src, dest, preserve = false, dereference = true)
|
|
|
|
return false if FileTest.directory?(src) == true
|
|
return false if File.exist?(src) == false
|
|
|
|
destpath = Path.remove_filename(dest)
|
|
|
|
FileUtils.mkdir_p destpath if File.directory?(destpath) == false
|
|
File.delete(dest) if File.exist?(dest)
|
|
|
|
return FileUtils.copy_file(src,dest,preserve, dereference)
|
|
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# Copys a file if the destination is out of date
|
|
#
|
|
#
|
|
def FileUtilsEx.install_file(src, dest)
|
|
|
|
if FileUtils.uptodate?(dest, %w(src)) == false then
|
|
|
|
copy_file(src,dest,true)
|
|
return true
|
|
|
|
end
|
|
|
|
false
|
|
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# Copies a file, taking care of housekeeping such as directory creation
|
|
#
|
|
#
|
|
def FileUtilsEx.move_file(src, dest, preserve = false, dereference = true)
|
|
|
|
return false if copy_file(src, dest, preserve, dereference) == false
|
|
|
|
File.delete(src)
|
|
|
|
true
|
|
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
#
|
|
# deletes all files found by the passed in wildcards
|
|
#
|
|
#
|
|
def FileUtilsEx.delete_files( wildcard )
|
|
|
|
file_list = FindEx.find_files(wildcard)
|
|
file_list.each { |f|
|
|
|
|
File.delete(f)
|
|
}
|
|
end
|
|
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# File and directory find functions.
|
|
#
|
|
class FindEx
|
|
|
|
#
|
|
# Return an arry of files given a wildcard search path. If the
|
|
# search path directory does not exist then an empty array is returned.
|
|
#
|
|
# The search is done recursively on sub-directories.
|
|
#
|
|
# The +prefix+ argument should not be used by user-code, it is used
|
|
# to capture the initial directory prefix to fetch relative paths
|
|
# correctly.
|
|
#
|
|
# See: http://www.ruby-doc.org/core/classes/File.html, fnmatch.
|
|
#
|
|
def FindEx.find_files_recurse( wildcard, relative = false, prefix = '' )
|
|
pattern = Path::get_filename( wildcard )
|
|
path = Path::remove_filename( wildcard )
|
|
prefix = path if ( '' == prefix )
|
|
return [] unless ( File.directory?( path ) )
|
|
|
|
file_list = []
|
|
|
|
Dir.open( path ) do |dir|
|
|
dir.each( ) do |filename|
|
|
next if ( filename == '.' )
|
|
next if ( filename == '..' )
|
|
|
|
fullpath = Path.combine( path, filename )
|
|
|
|
if ( ::File::directory?( fullpath ) ) then
|
|
# Recursive part
|
|
wildcard_recurse = Path::combine( fullpath, pattern )
|
|
file_list += FindEx::find_files_recurse( wildcard_recurse, relative, prefix )
|
|
|
|
next # Never add directories to output list.
|
|
else
|
|
# Case-insensitive filename wildcard match.
|
|
next unless ::File.fnmatch( pattern, filename, File::FNM_CASEFOLD )
|
|
|
|
file_list << fullpath unless relative
|
|
file_list << fullpath.gsub( prefix, '' ) if relative
|
|
end
|
|
end
|
|
end
|
|
|
|
file_list
|
|
end
|
|
|
|
#
|
|
# Return an array of directories. If leafonly is true then only
|
|
# leaf direectories are added to the array
|
|
#
|
|
# The search is done recursively on sub-directories.
|
|
#
|
|
# The +prefix+ argument should not be used by user-code, it is used
|
|
# to capture the initial directory prefix to fetch relative paths
|
|
# correctly.
|
|
#
|
|
#
|
|
def FindEx.find_dirs_recurse( path, leafonly = false, prefix = '' )
|
|
|
|
prefix = path if ( '' == prefix )
|
|
return [] unless ( File.directory?( path ) )
|
|
|
|
dir_list = []
|
|
|
|
Dir.open( path ) do |dir|
|
|
leafnode = true
|
|
dir.each( ) do |filename|
|
|
next if ( filename == '.' )
|
|
next if ( filename == '..' )
|
|
|
|
fullpath = Path.combine( path, filename, '/' )
|
|
|
|
if ( ::File::directory?( fullpath ) ) then
|
|
# Recursive part
|
|
leafnode = false
|
|
dir_list += FindEx::find_dirs_recurse( fullpath, leafonly, prefix )
|
|
|
|
end
|
|
|
|
end
|
|
dir_list << path if leafonly == false or leafnode == true
|
|
end
|
|
|
|
dir_list
|
|
end
|
|
|
|
#
|
|
# Return an array of files given a wildcard search path. If the
|
|
# search path directory does not exist then an empty array is returned.
|
|
#
|
|
# The +prefix+ argument should not be used by user-code, it is used
|
|
# to capture the initial directory prefix to fetch relative paths
|
|
# correctly.
|
|
#
|
|
# See: http://www.ruby-doc.org/core/classes/File.html, fnmatch.
|
|
#
|
|
def FindEx.find_files( wildcard, relative = false )
|
|
pattern = Path::get_filename( wildcard )
|
|
path = Path::remove_filename( wildcard )
|
|
return [] unless ( File.directory?( path ) )
|
|
|
|
file_list = []
|
|
|
|
Dir.open( path ) do |dir|
|
|
|
|
dir.each( ) do |filename|
|
|
next if ( filename == '.' )
|
|
next if ( filename == '..' )
|
|
next unless ( ::File::file?( OS::Path.combine( path, filename ) ) )
|
|
|
|
fullpath = Path.combine( path, filename )
|
|
|
|
# Case-insensitive filename wildcard match.
|
|
next unless ::File.fnmatch( pattern, filename, File::FNM_CASEFOLD )
|
|
|
|
file_list << fullpath unless relative
|
|
file_list << fullpath.gsub( path, '' ) if relative
|
|
end
|
|
end
|
|
|
|
file_list
|
|
end
|
|
|
|
#
|
|
# Return an array of directories given a search path. If the directory
|
|
# does not exist then an empty array is returned.
|
|
#
|
|
def FindEx.find_dirs( rootpath, relative = false )
|
|
return [] unless ( File.directory?( rootpath ) )
|
|
|
|
dir_list = Array.new()
|
|
Dir.open(rootpath) { |dir|
|
|
|
|
dir.each() { |f|
|
|
|
|
next if f == "."
|
|
next if f == ".."
|
|
next if FileEx.directory?(Path.combine( rootpath, f, '/' )) == false
|
|
|
|
if relative then
|
|
|
|
dir_list << f
|
|
else
|
|
|
|
dir_list << Path.combine( rootpath, f, '/' )
|
|
end
|
|
}
|
|
}
|
|
|
|
dir_list
|
|
end
|
|
|
|
#
|
|
# Return an array of directories given a search path. If the directory
|
|
# does not exist then an empty array is returned.
|
|
#
|
|
def FindEx.find_dirs_recurse( rootpath, relative = false, first = true)
|
|
return [] unless ( File.directory?( rootpath ) )
|
|
|
|
dir_list = Array.new()
|
|
dir_list << rootpath if first == true
|
|
|
|
Dir.open(rootpath) { |dir|
|
|
|
|
dir.each() { |f|
|
|
|
|
next if f == "."
|
|
next if f == ".."
|
|
next if FileEx.directory?(Path.combine( rootpath, f, '/' )) == false
|
|
|
|
if relative then
|
|
|
|
dir_list << f
|
|
else
|
|
|
|
dir_list << Path.combine( rootpath, f, '/' )
|
|
end
|
|
|
|
|
|
dir_full_path = Path.combine(rootpath, f, '/')
|
|
dir_list += find_dirs_recurse(dir_full_path, relative, false)
|
|
}
|
|
}
|
|
|
|
dir_list
|
|
end
|
|
end
|
|
|
|
end # OS module
|
|
end # Pipeline module
|