Class: Dir

Inherits:
Object show all
Defined in:
lib/core/facets/dir/traverse.rb,
lib/core/facets/dir/multiglob.rb

Overview

TODO:

- Make instance method versions.

Class Method Summary collapse

Class Method Details

.ancestor?(parent_path, child_path) ⇒ Boolean

Is a path parental to another?

TODO: Needs improvement.

Returns:

  • (Boolean)


10
11
12
# File 'lib/core/facets/dir/traverse.rb', line 10

def self.ancestor?(parent_path, child_path)
  %r|^#{Regexp.escape(parent_path)}| =~ child_path
end

.ascend(dir, inclusive = true, &blk) ⇒ Object

Ascend a directory path.

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

produces

/var/log
/var
/

CREDIT: Daniel Berger
CREDIT: Jeffrey Schwab


37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/core/facets/dir/traverse.rb', line 37

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) ⇒ Object

Descend a directory path.

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

produces

/
/var
/var/log

CREDIT: Daniel Berger
CREDIT: Jeffrey Schwab


66
67
68
69
70
71
# File 'lib/core/facets/dir/traverse.rb', line 66

def self.descend(path) #:yield:
  paths = path.split('/')
  paths.size.times do |n|
    yield File.join(*paths[0..n])
  end
end

.ls_r(path = '.', &block) ⇒ Object Also known as: recurse

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

CREDIT: George Moschovitis


78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/core/facets/dir/traverse.rb', line 78

def self.ls_r(path='.', &block)
  list = []
  stoplist = ['.', '..']
  Dir.foreach(path) do |f|
    next if stoplist.include?(f)
    filename = 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

.multiglob(*patterns) ⇒ Object

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('**/*')

Multiglob also accepts ‘+’ and ‘-’ prefixes. Any entry that begins with a ‘-’ is treated as an exclusion glob and will be removed from the final result. For example, to collect all files in the current directory, less ruby scripts:

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

This is very useful in collecting files as specificed by a configuration parameter.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/core/facets/dir/multiglob.rb', line 37

def self.multiglob(*patterns)
  options  = (Hash === patterns.last ? patterns.pop : {})

  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) ⇒ Object

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/**/*' )


70
71
72
73
74
75
# File 'lib/core/facets/dir/multiglob.rb', line 70

def self.multiglob_r(*patterns)
  options = (Hash === patterns.last ? patterns.pop : {})
  options[:recurse] = true
  patterns << options
  multiglob(*patterns)
end

.parent?(parent_path, child_path) ⇒ Boolean

Is a path parental to another?

TODO: Needs improvement.

Returns:

  • (Boolean)


18
19
20
# File 'lib/core/facets/dir/traverse.rb', line 18

def self.parent?(parent_path, child_path)
  %r|^#{Regexp.escape(parent_path)}| =~ child_path
end