lib/ftools.rb


DEFINITIONS

This source file includes following functions.


   1  class << File
   2  
   3    BUFSIZE = 8 * 1024
   4  
   5    def catname from, to
   6      if FileTest.directory? to
   7        File.join to.sub(%r([/\\]$), ''), basename(from)
   8      else
   9        to
  10      end
  11    end
  12  
  13  # copy file
  14  
  15    def syscopy from, to
  16      to = catname(from, to)
  17  
  18      fmode = stat(from).mode
  19      tpath = to
  20      not_exist = !exist?(tpath)
  21  
  22      from = open(from, "rb")
  23      to = open(to, "wb")
  24  
  25      begin
  26        while true
  27          to.syswrite from.sysread(BUFSIZE)
  28        end
  29      rescue EOFError
  30        ret = true
  31      rescue
  32        ret = false
  33      ensure
  34        to.close
  35        from.close
  36      end
  37      chmod(fmode, tpath) if not_exist
  38      ret
  39    end
  40  
  41    def copy from, to, verbose = false
  42      $stderr.print from, " -> ", catname(from, to), "\n" if verbose
  43      syscopy from, to
  44    end
  45  
  46    alias cp copy
  47  
  48  # move file
  49  
  50    def move from, to, verbose = false
  51      to = catname(from, to)
  52      $stderr.print from, " -> ", to, "\n" if verbose
  53  
  54      if RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/ and FileTest.file? to
  55        unlink to
  56      end
  57      fstat = stat(from)
  58      begin
  59        rename from, to
  60      rescue
  61        begin
  62          symlink File.readlink(from), to and unlink from
  63        rescue
  64          from_stat = stat(from)
  65          syscopy from, to and unlink from
  66          utime(from_stat.atime, from_stat.mtime, to)
  67          begin
  68            chown(fstat.uid, fstat.gid, to)
  69          rescue
  70          end
  71        end
  72      end
  73    end
  74  
  75    alias mv move
  76  
  77  #  compare two files
  78  #   true:  identical
  79  #   false: not identical
  80  
  81    def compare from, to, verbose = false
  82      $stderr.print from, " <=> ", to, "\n" if verbose
  83  
  84      return false if stat(from).size != stat(to).size
  85  
  86      from = open(from, "rb")
  87      to = open(to, "rb")
  88  
  89      ret = false
  90      fr = tr = ''
  91  
  92      begin
  93        while fr == tr
  94          fr = from.read(BUFSIZE)
  95          if fr
  96            tr = to.read(fr.size)
  97          else
  98            ret = to.read(BUFSIZE)
  99            ret = !ret || ret.length == 0
 100            break
 101          end
 102        end
 103      rescue
 104        ret = false
 105      ensure
 106        to.close
 107        from.close
 108      end
 109      ret
 110    end
 111  
 112    alias cmp compare
 113  
 114  #  unlink files safely
 115  
 116    def safe_unlink(*files)
 117      verbose = if files[-1].is_a? String then false else files.pop end
 118      begin
 119        $stderr.print files.join(" "), "\n" if verbose
 120        chmod 0777, *files
 121        unlink(*files)
 122      rescue
 123  #      STDERR.print "warning: Couldn't unlink #{files.join ' '}\n"
 124      end
 125    end
 126  
 127    alias rm_f safe_unlink
 128  
 129    def makedirs(*dirs)
 130      verbose = if dirs[-1].is_a? String then false else dirs.pop end
 131  #    mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
 132      mode = 0755
 133      for dir in dirs
 134        next if FileTest.directory? dir
 135        parent = dirname(dir)
 136        makedirs parent unless FileTest.directory? parent
 137        $stderr.print "mkdir ", dir, "\n" if verbose
 138        if basename(dir) != ""
 139          Dir.mkdir dir, mode
 140        end
 141      end
 142    end
 143  
 144    alias mkpath makedirs
 145  
 146    alias o_chmod chmod
 147  
 148    vsave, $VERBOSE = $VERBOSE, false
 149    def chmod(mode, *files)
 150      verbose = if files[-1].is_a? String then false else files.pop end
 151      $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
 152      o_chmod mode, *files
 153    end
 154    $VERBOSE = vsave
 155  
 156    def install(from, to, mode = nil, verbose = false)
 157      to = catname(from, to)
 158      unless FileTest.exist? to and cmp from, to
 159        safe_unlink to if FileTest.exist? to
 160        cp from, to, verbose
 161        chmod mode, to, verbose if mode
 162      end
 163    end
 164  
 165  end
 166  # vi:set sw=2: