Files
2025-09-29 00:52:08 +02:00

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