Files

FileUtils

Public Instance Methods

amass(include_globs, exclude_globs=[], ignore=[]) click to toggle source

An intergrated glob like method that take a set of include globs, exclude globs and ignore globs to produce a collection of paths.

The ignore_globs differ from exclude_globs in that they match by the basename of the path rather than the whole pathname.

TODO: Should ignore be based on any portion of the path, not just the basename?

# File lib/facets/standard/facets/fileutils/amass.rb, line 13
def amass(include_globs, exclude_globs=[], ignore=[])
  include_files = include_globs.flatten.map{ |g| Dir.glob(g) }.flatten.uniq
  exclude_files = exclude_globs.flatten.map{ |g| Dir.glob(g) }.flatten.uniq

  include_globs = include_globs.map{ |f| File.directory?(f) ? File.join(f, '**/*') : f } # Recursive!
  exclude_globs = exclude_globs.map{ |f| File.directory?(f) ? File.join(f, '**/*') : f } # Recursive!

  include_files = include_globs.flatten.map{ |g| Dir.glob(g) }.flatten.uniq
  exclude_files = exclude_globs.flatten.map{ |g| Dir.glob(g) }.flatten.uniq

  files = include_files - exclude_files

  files = files.reject{ |f| ignore.any?{ |x| File.fnmatch?(x, File.basename(f)) } }

  files
end
copy_entryx(src, dest, filter, preserve = false, dereference_root = false, remove_destination = false) click to toggle source

Like FileUtils.copy_entry, but takes a filter proc that can return false to skip a file.

Note that if the filter rejects a subdirectory then everything within that subdirectory is automatically skipped as well.

# File lib/facets/standard/facets/fileutils/cp_rx.rb, line 32
def copy_entryx(src, dest, filter, preserve = false, dereference_root = false, remove_destination = false)
        Entry_.new(src, nil, dereference_root).traverse do |ent|
                if filter.call(ent.path) then
                        destent = Entry_.new(dest, ent.rel, false)
                        File.unlink destent.path if remove_destination && File.file?(destent.path)
                        ent.copy destent.path
                        ent.copy_metadata(destent.path) if preserve
                end
        end
end
cp_rx(src, dest, options = {}, &filter) click to toggle source

Like FileUtils.cp_r, but takes a filter proc that can return false to skip a file:

cp_rx "bigDirectoryTree", "dest", {:noop => true} do |name|
   /dontCopyThis$/.match(name)
end

Note that if the filter rejects a subdirectory then everything within that subdirectory is automatically skipped as well.

# File lib/facets/standard/facets/fileutils/cp_rx.rb, line 16
def cp_rx(src, dest, options = {}, &filter)
        fu_check_options(options, OPT_TABLE['cp_r'])
  if options[:verbose]
          fu_output_message("cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}")
  end
        return if options[:noop]
        fu_each_src_dest(src, dest) do |s, d|
                copy_entryx(s, d, filter, options[:preserve], options[:dereference_root], options[:remove_destination])
        end
end
head(filename,lines) click to toggle source

In block form, yields the first number of lines of file filename. In non-block form, it returns an array of the first number of lines:

# Returns first 10 lines of 'myfile'
FileUtils.head("myfile", 10)
# File lib/facets/standard/facets/fileutils/slice.rb, line 25
def head(filename,lines) #:yield:
  a = []
  IO.foreach(filename){|line|
      break if lines <= 0
      lines -= 1
      if block_given?
        yield line
      else
        a << line
      end
  }
  return a.empty? ? nil : a
end
link_entry(src, dest, dereference_root = false, remove_destination = false) click to toggle source

Hard links a file system entry src to dest. If src is a directory, this method links its contents recursively.

Both of src and dest must be a path name. src must exist, dest must not exist.

If dereference_root is true, this method dereference tree root.

If remove_destination is true, this method removes each destination file before copy.

# File lib/facets/standard/facets/fileutils/ln_r.rb, line 55
def link_entry(src, dest, dereference_root = false, remove_destination = false)
  Entry_.new(src, nil, dereference_root).traverse do |ent|
    destent = Entry_.new(dest, ent.rel, false)
    File.unlink destent.path if remove_destination && File.file?(destent.path)
    ent.link destent.path
  end
end
ln_r(src, dest, options = {}) click to toggle source

Options: noop verbose dereference_root remove_destination

Hard link src to dest. If src is a directory, this method links all its contents recursively. If dest is a directory, links src to dest/src.

src can be a list of files.

# Installing ruby library "mylib" under the site_ruby
FileUtils.rm_r site_ruby + '/mylib', :force
FileUtils.ln_r 'lib/', site_ruby + '/mylib'

# Examples of copying several files to target directory.
FileUtils.ln_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
FileUtils.ln_r Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true

# If you want to copy all contents of a directory instead of the
# directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
# use following code.
FileUtils.ln_r 'src/.', 'dest'     # cp_r('src', 'dest') makes src/dest,
                                   # but this doesn't.

TODO: Why --remove-destination and not just --force?

# File lib/facets/standard/facets/fileutils/ln_r.rb, line 29
def ln_r(src, dest, options = {})
  fu_check_options options, OPT_TABLE['ln_r']
  fu_output_message "ln -r#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
  return if options[:noop]
  options = options.dup
  options[:dereference_root] = true unless options.key?(:dereference_root)
  fu_each_src_dest(src, dest) do |s, d|
    link_entry s, d, options[:dereference_root], options[:remove_destination]
  end
end
out_of_date?(path, *sources) click to toggle source

Alias for outofdate?

Alias for: outofdate?
outofdate?(path, *sources) click to toggle source

The opposite of uptodate?

# File lib/facets/standard/facets/fileutils/outofdate.rb, line 7
def outofdate?(path, *sources)
  #return true unless File.exist?(path)
  ! uptodate?(path, sources.flatten)
end
Also aliased as: out_of_date?
safe_ln(*args) click to toggle source

Attempt to do a normal file link, but fall back to a copy if the link fails.

CREDIT: Jim Weirich

# File lib/facets/standard/facets/fileutils/safe_ln.rb, line 13
def safe_ln(*args)
  unless LINKING_SUPPORTED[0]
    cp(*args)
  else
    begin
      ln(*args)
    rescue Errno::EOPNOTSUPP
      LINKING_SUPPORTED[0] = false
      cp(*args)
    end
  end
end
slice(filename,from,to) click to toggle source

In block form, yields lines from-to. In non-block form, returns an array of lines from-to:

# Returns lines 8-12 of 'myfile'
FileUtils.body("myfile",8,12)

CREDIT Shashank Date, via Daniel Berger.

# File lib/facets/standard/facets/fileutils/slice.rb, line 15
def slice(filename,from,to) #:yield:
  IO.readlines(filename)[from-1..to-1]
end
stage(stage_directory, source_directory, files, options={}) click to toggle source

Stage by hard linking included files to a stage directory.

stage_directory - Where to stage the files source_directory - Where to find files to stage files - Files to link in stage relative to source

TODO: Rename to link_stage or something less likely to name clash? TODO: Add options for :verbose, :noop and :dryrun ?

# File lib/facets/standard/facets/fileutils/stage.rb, line 15
def stage(stage_directory, source_directory, files, options={})
  return stage_directory if options[:noop] || options[:dryrun]

  stage_directory, source_directory = stage_directory.to_s, source_directory.to_s
  ## ensure existance of staging area
  rm_r(stage_directory) if File.directory?(stage_directory)
  mkdir_p(stage_directory)
  ## link files into staging area
  files.each do |f|
    src  = File.join(source_directory, f)
    file = File.join(stage_directory, f)
    if File.directory?(src)
      mkdir_p(file) unless File.exist?(file)
    else
      fdir = File.dirname(file)
      mkdir_p(fdir) unless File.exist?(fdir)
      unless File.exist?(file) and File.mtime(file) >= File.mtime(src)
        ln(src, file) #safe_ln ?
      end
    end
  end
  return stage_directory
end
tail(filename,lines) click to toggle source

In block form, yields the last number of lines of file filename. In non-block form, it returns the lines as an array.

Note that this method slurps the entire file, so I don't recommend it for very large files. If you want an advanced form of tail, I suggest using file-tail, by Florian Frank (available on the RAA):

# Returns last 3 lines of 'myfile'
FileUtils.tail("myfile",3)

And no tail -f.

# File lib/facets/standard/facets/fileutils/slice.rb, line 50
def tail(filename,lines) #:yield
  IO.readlines(filename).reverse[0..lines-1].reverse
end
wc(filename,option='all') click to toggle source

With no arguments, returns a four element array consisting of the number of bytes, characters, words and lines in filename, respectively.

Valid options are bytes, characters (or just 'chars'), words and lines:

# Return the number of words in 'myfile'
FileUtils.wc("myfile",'words')

CREDIT: Daniel J. Berger

# File lib/facets/standard/facets/fileutils/wc.rb, line 17
def wc(filename,option='all')
  option.downcase!
  valid = %all bytes characters chars lines words/

  unless valid.include?(option)
      raise "Invalid option: '#{option}'"
  end

  n = 0
  if option == 'lines'
      IO.foreach(filename){ n += 1 }
      return n
  elsif option == 'bytes'
      File.open(filename){ |f|
        f.each_byte{ n += 1 }
      }
      return n
  elsif option == 'characters' || option == 'chars'
      File.open(filename){ |f|
        while f.getc
            n += 1
        end
      }
      return n
  elsif option == 'words'
      IO.foreach(filename){ |line|
        n += line.split.length
      }
      return n
  else
      bytes,chars,lines,words = 0,0,0,0
      IO.foreach(filename){ |line|
        lines += 1
        words += line.split.length
        chars += line.split('').length
      }
      File.open(filename){ |f|
        while f.getc
            bytes += 1
        end
      }
      return [bytes,chars,words,lines]
  end
end
whereis(prog, path=ENV['PATH']) click to toggle source

In block form, yields each ((program)) within ((path)). In non-block form, returns an array of each ((program)) within ((path)). Returns (({nil})) if not found.

On the MS Windows platform, it looks for executables ending with .exe, .bat and .com, which you may optionally include in the program name:

FileUtils.whereis("ruby")  #=> ['/usr/local/bin/ruby','/opt/bin/ruby']

CREDIT: Daniel J. Berger

# File lib/facets/standard/facets/fileutils/whereis.rb, line 25
def whereis(prog, path=ENV['PATH']) #:yield:
  dirs = []
  path.split(File::PATH_SEPARATOR).each{|dir|
      # Windows checks against specific extensions
      if File::ALT_SEPARATOR
        if prog.include?('.')
            f = File.join(dir,prog)
            if File.executable?(f) && !File.directory?(f)
              if block_given?
                  yield f.gsub(/\//,'\')
              else
                  dirs << f.gsub(/\//,'\')
              end
            end
        else
            Win32Exts.find_all{|ext|
              f = File.join(dir,prog+ext)
              if File.executable?(f) && !File.directory?(f)
                  if block_given?
                    yield f.gsub(/\//,'\')
                  else
                    dirs << f.gsub(/\//,'\')
                  end
              end
            }
        end
      else
        f = File.join(dir,prog)
        # Avoid /usr/lib/ruby, for example
        if File.executable?(f) && !File.directory?(f)
            if block_given?
              yield f
            else
              dirs << f
            end
        end
      end
  }
  dirs.empty? ? nil : dirs
end
which(prog, path=ENV['PATH']) click to toggle source

Looks for the first occurrence of program within path.

On the MS Windows platform, it looks for executables ending with .exe, .bat and .com, which you may optionally include in the program name. Returns nil if not found.

CREDIT: Daniel J. Berger, Michael Granger

# File lib/facets/standard/facets/fileutils/which.rb, line 27
def which(prog, path=ENV['PATH'])
  path.split(File::PATH_SEPARATOR).each {|dir|
    # Windows checks against specific extensions
    if File::ALT_SEPARATOR
      ext = Win32Exts.find{|ext|
        if prog.include?('.') # Assume extension already included
          f = File.join(dir,prog)
        else
          f = File.join(dir,prog+ext)
        end
        File.executable?(f) && !File.directory?(f)
      }
      if ext
        # Use backslashes, not forward slashes
        if prog.include?('.') # Assume extension already included
          f = File.join( dir, prog ).gsub(/\//,'\')
        else
          f = File.join( dir, prog + ext ).gsub(/\//,'\')
        end
        return f
      end
    else
      f = File.join(dir,prog)
      # Avoid /usr/lib/ruby, for example
      if File.executable?(f) && !File.directory?(f)
        return File::join( dir, prog )
      end
    end
  }
  nil
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.