Methods
ascend descend ls_r multiglob multiglob_r parent? recurse
Public Class methods
ascend(dir, inclusive=true, &blk)

Ascend a directory path.

  Dir.ascend("/var/log") do |path|
    p path
  end

produces

  /var/log
  /var
  /

CREDIT: Daniel Berger, Jeffrey Schwab

# File lib/core/facets/dir/ascend.rb, line 19
  def self.ascend(dir, inclusive=true, &blk)
    dir = dir.dup
    blk.call(dir) if inclusive
    ri = dir.rindex('/')
    while ri
      dir = dir.slice(0...ri)
      if dir == ""
        blk.call('/') ; break
      end
      blk.call( dir )
      ri = dir.rindex('/')
    end
  end
descend(path) {|| ...}

Descend a directory path.

  Dir.descend("/var/log") do |path|
    p path
  end

produces

  /
  /var
  /var/log

CREDIT: Daniel Berger, Jeffrey Schwab

# File lib/core/facets/dir/ascend.rb, line 47
  def self.descend(path) #:yield:
    paths = path.split('/')
    paths.size.times do |n|
      pth = File.join(*paths[0..n])
      pth = "/" if pth == ""
      yield(pth)
    end
  end
ls_r(path='.', &block)

Same as Dir#recurse.

# File lib/core/facets/dir/recurse.rb, line 23
  def self.ls_r(path='.', &block)
    recurse(path, &block)
  end
multiglob(*patterns)

Like glob but can take multiple patterns.

  Dir.multiglob( '*.rb', '*.py' )

Rather then constants for options multiglob accepts a trailing options hash of symbol keys.

  :noescape    File::FNM_NOESCAPE
  :casefold    File::FNM_CASEFOLD
  :pathname    File::FNM_PATHNAME
  :dotmatch    File::FNM_DOTMATCH
  :strict      File::FNM_PATHNAME && File::FNM_DOTMATCH

It also has an option for recurse.

  :recurse     Recurively include contents of directories.

For example

  Dir.multiglob( '*', :recurse => true )

would have the same result as

  Dir.multiglob('**/*')
# File lib/core/facets/dir/multiglob.rb, line 40
  def self.multiglob(*patterns)
    options  = (Hash === patterns.last ? patterns.pop : {})

    if options.delete(:recurse)
      #patterns += patterns.collect{ |f| File.join(f, '**', '**') }
      multiglob_r(*patterns)
    end

    bitflags = 0
    bitflags |= File::FNM_NOESCAPE if options[:noescape]
    bitflags |= File::FNM_CASEFOLD if options[:casefold]
    bitflags |= File::FNM_PATHNAME if options[:pathname] or options[:strict]
    bitflags |= File::FNM_DOTMATCH if options[:dotmatch] or options[:strict]

    patterns = [patterns].flatten.compact

    if options[:recurse]
      patterns += patterns.collect{ |f| File.join(f, '**', '**') }
    end

    files = []
    files += patterns.collect{ |pattern| Dir.glob(pattern, bitflags) }.flatten.uniq

    return files
  end
multiglob_r(*patterns)

The same as multiglob, but recusively includes directories.

  Dir.multiglob_r( 'folder' )

is equivalent to

  Dir.multiglob( 'folder', :recurse=>true )

The effect of which is

  Dir.multiglob( 'folder', 'folder/**/**' )
# File lib/core/facets/dir/multiglob.rb, line 78
  def self.multiglob_r(*patterns)
    options = (Hash === patterns.last ? patterns.pop : {})
    matches = multiglob(*patterns)
    directories = matches.select{ |m| File.directory?(m) }
    matches += directories.collect{ |d| multiglob_r(File.join(d, '**'), options) }.flatten
    matches.uniq
    #options = (Hash === patterns.last ? patterns.pop : {})
    #options[:recurse] = true
    #patterns << options
    #multiglob(*patterns)
  end
parent?(parent_path, child_path)

Is a path parental to another?

TODO: Needs improvement. TODO: Instance version?

# File lib/core/facets/dir/parent.rb, line 8
  def self.parent?(parent_path, child_path)
    %r|^#{Regexp.escape(parent_path)}| =~ child_path
  end
recurse(path='.', &block)

Recursively scan a directory and pass each file to the given block.

CREDIT: George Moschovitis

# File lib/core/facets/dir/recurse.rb, line 7
  def self.recurse(path='.', &block)
    list = []
    stoplist = ['.', '..']
    Dir.foreach(path) do |f|
      next if stoplist.include?(f)
      filename = (path == '.' ? f : path + '/' + f)
      list << filename
      block.call(filename) if block
      if FileTest.directory?(filename) and not FileTest.symlink?(filename)
        list.concat( Dir.recurse(filename, &block) )
      end
    end
    list
  end