diff options
Diffstat (limited to 'ruby_1_8_5/lib/ftools.rb')
-rw-r--r-- | ruby_1_8_5/lib/ftools.rb | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/ruby_1_8_5/lib/ftools.rb b/ruby_1_8_5/lib/ftools.rb new file mode 100644 index 0000000000..5f082331fb --- /dev/null +++ b/ruby_1_8_5/lib/ftools.rb @@ -0,0 +1,261 @@ +# +# = ftools.rb: Extra tools for the File class +# +# Author:: WATANABE, Hirofumi +# Documentation:: Zachary Landau +# +# This library can be distributed under the terms of the Ruby license. +# You can freely distribute/modify this library. +# +# It is included in the Ruby standard library. +# +# == Description +# +# ftools adds several (class, not instance) methods to the File class, for +# copying, moving, deleting, installing, and comparing files, as well as +# creating a directory path. See the File class for details. +# +# FileUtils contains all or nearly all the same functionality and more, and +# is a recommended option over ftools +# +# When you +# +# require 'ftools' +# +# then the File class aquires some utility methods for copying, moving, and +# deleting files, and more. +# +# See the method descriptions below, and consider using FileUtils as it is +# more comprehensive. +# +class File +end + +class << File + + BUFSIZE = 8 * 1024 + + # + # If +to+ is a valid directory, +from+ will be appended to +to+, adding + # and escaping backslashes as necessary. Otherwise, +to+ will be returned. + # Useful for appending +from+ to +to+ only if the filename was not specified + # in +to+. + # + def catname(from, to) + if directory? to + join to.sub(%r([/\\]$), ''), basename(from) + else + to + end + end + + # + # Copies a file +from+ to +to+. If +to+ is a directory, copies +from+ + # to <tt>to/from</tt>. + # + def syscopy(from, to) + to = catname(from, to) + + fmode = stat(from).mode + tpath = to + not_exist = !exist?(tpath) + + from = open(from, "rb") + to = open(to, "wb") + + begin + while true + to.syswrite from.sysread(BUFSIZE) + end + rescue EOFError + ret = true + rescue + ret = false + ensure + to.close + from.close + end + chmod(fmode, tpath) if not_exist + ret + end + + # + # Copies a file +from+ to +to+ using #syscopy. If +to+ is a directory, + # copies +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> to</tt> + # is printed. + # + def copy(from, to, verbose = false) + $stderr.print from, " -> ", catname(from, to), "\n" if verbose + syscopy from, to + end + + alias cp copy + + # + # Moves a file +from+ to +to+ using #syscopy. If +to+ is a directory, + # copies from +from+ to <tt>to/from</tt>. If +verbose+ is true, <tt>from -> + # to</tt> is printed. + # + def move(from, to, verbose = false) + to = catname(from, to) + $stderr.print from, " -> ", to, "\n" if verbose + + if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and file? to + unlink to + end + fstat = stat(from) + begin + rename from, to + rescue + begin + symlink readlink(from), to and unlink from + rescue + from_stat = stat(from) + syscopy from, to and unlink from + utime(from_stat.atime, from_stat.mtime, to) + begin + chown(fstat.uid, fstat.gid, to) + rescue + end + end + end + end + + alias mv move + + # + # Returns +true+ if and only if the contents of files +from+ and +to+ are + # identical. If +verbose+ is +true+, <tt>from <=> to</tt> is printed. + # + def compare(from, to, verbose = false) + $stderr.print from, " <=> ", to, "\n" if verbose + + return false if stat(from).size != stat(to).size + + from = open(from, "rb") + to = open(to, "rb") + + ret = false + fr = tr = '' + + begin + while fr == tr + fr = from.read(BUFSIZE) + if fr + tr = to.read(fr.size) + else + ret = to.read(BUFSIZE) + ret = !ret || ret.length == 0 + break + end + end + rescue + ret = false + ensure + to.close + from.close + end + ret + end + + alias cmp compare + + # + # Removes a list of files. Each parameter should be the name of the file to + # delete. If the last parameter isn't a String, verbose mode will be enabled. + # Returns the number of files deleted. + # + def safe_unlink(*files) + verbose = if files[-1].is_a? String then false else files.pop end + files.each do |file| + begin + unlink file + $stderr.print "removing ", file, "\n" if verbose + rescue Errno::EACCES # for Windows + continue if symlink? file + begin + mode = stat(file).mode + o_chmod mode | 0200, file + unlink file + $stderr.print "removing ", file, "\n" if verbose + rescue + o_chmod mode, file rescue nil + end + rescue + end + end + end + + alias rm_f safe_unlink + + # + # Creates a directory and all its parent directories. + # For example, + # + # File.makedirs '/usr/lib/ruby' + # + # causes the following directories to be made, if they do not exist. + # * /usr + # * /usr/lib + # * /usr/lib/ruby + # + # You can pass several directories, each as a parameter. If the last + # parameter isn't a String, verbose mode will be enabled. + # + def makedirs(*dirs) + verbose = if dirs[-1].is_a? String then false else dirs.pop end + mode = 0755 + for dir in dirs + parent = dirname(dir) + next if parent == dir or directory? dir + makedirs parent unless directory? parent + $stderr.print "mkdir ", dir, "\n" if verbose + if basename(dir) != "" + begin + Dir.mkdir dir, mode + rescue SystemCallError + raise unless directory? dir + end + end + end + end + + alias mkpath makedirs + + alias o_chmod chmod + + vsave, $VERBOSE = $VERBOSE, false + + # + # Changes permission bits on +files+ to the bit pattern represented + # by +mode+. If the last parameter isn't a String, verbose mode will + # be enabled. + # + # File.chmod 0755, 'somecommand' + # File.chmod 0644, 'my.rb', 'your.rb', true + # + def chmod(mode, *files) + verbose = if files[-1].is_a? String then false else files.pop end + $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose + o_chmod mode, *files + end + $VERBOSE = vsave + + # + # If +src+ is not the same as +dest+, copies it and changes the permission + # mode to +mode+. If +dest+ is a directory, destination is <tt>dest/src</tt>. + # If +mode+ is not set, default is used. If +verbose+ is set to true, the + # name of each file copied will be printed. + # + def install(from, to, mode = nil, verbose = false) + to = catname(from, to) + unless exist? to and cmp from, to + safe_unlink to if exist? to + cp from, to, verbose + chmod mode, to, verbose if mode + end + end + +end + +# vi:set sw=2: |