Class: Dir
- Defined in:
- lib/core/facets/dir/ascend.rb,
lib/core/facets/dir/lookup.rb,
lib/core/facets/dir/parent.rb,
lib/core/facets/dir/recurse.rb,
lib/core/facets/dir/multiglob.rb,
lib/core/facets/dir/each_child.rb
Class Method Summary collapse
-
.ascend(dir, inclusive = true, &blk) ⇒ Object
Ascend a directory path.
-
.descend(path) ⇒ Object
Descend a directory path.
-
.lookup(rel_path, parent_path = '.') ⇒ Object
Lookup directory tree for a path.
-
.ls_r(path = '.', &block) ⇒ Object
Same as Dir#recurse.
-
.multiglob(*patterns) ⇒ Object
Like
glob
but can take multiple patterns. -
.multiglob_r(*patterns) ⇒ Object
The same as
multiglob
, but recusively includes directories. -
.parent?(parent_path, child_path) ⇒ Boolean
Is a path parental to another?.
-
.recurse(path = '.', &block) ⇒ Object
Recursively scan a directory and pass each file to the given block.
Instance Method Summary collapse
-
#each_child(*ignore) ⇒ Object
Like #each, except the “.” and “..” special files are ignored.
Class Method Details
.ascend(dir, inclusive = true, &blk) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/core/facets/dir/ascend.rb', line 20 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.
d = []
Dir.descend("/var/log") do |path|
d << path
end
d #=> ['/', '/var', '/var/log']
CREDIT: Daniel Berger, Jeffrey Schwab
46 47 48 49 50 51 52 53 |
# File 'lib/core/facets/dir/ascend.rb', line 46 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 |
.lookup(rel_path, parent_path = '.') ⇒ Object
Lookup directory tree for a path.
TODO: Make a non class method version of this?
Returns full path or ‘nil` if not found. [String,nil]
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/core/facets/dir/lookup.rb', line 9 def self.lookup(rel_path, parent_path='.') while true path = File.(rel_path, parent_path) return path if File.exists?(path) return nil if path == '/' parent_path = File.('..', parent_path) end end |
.ls_r(path = '.', &block) ⇒ Object
Same as Dir#recurse.
30 31 32 |
# File 'lib/core/facets/dir/recurse.rb', line 30 def self.ls_r(path='.', &block) recurse(path, &block) end |
.multiglob(*patterns) ⇒ Object
Like glob
but can take multiple patterns.
Dir.multiglob('tmp/*.rb', 'tmp/*.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('tmp/*', :recurse => true)
would have the same result as
Dir.multiglob('tmp/**/*')
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/core/facets/dir/multiglob.rb', line 28 def self.multiglob(*patterns) = (Hash === patterns.last ? patterns.pop : {}) if .delete(:recurse) ##patterns += patterns.collect{ |f| File.join(f, '**', '**') } multiglob_r(*patterns) end bitflags = 0 bitflags |= File::FNM_NOESCAPE if [:noescape] bitflags |= File::FNM_CASEFOLD if [:casefold] bitflags |= File::FNM_PATHNAME if [:pathname] or [:strict] bitflags |= File::FNM_DOTMATCH if [:dotmatch] or [:strict] patterns = [patterns].flatten.compact if [: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
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/core/facets/dir/multiglob.rb', line 66 def self.multiglob_r(*patterns) = Hash === patterns.last ? patterns.pop : {} matches = multiglob(*patterns) directories = matches.select{ |m| File.directory?(m) } matches += directories.map{ |d| multiglob_r(File.join(d, '**'), ) }.flatten matches.uniq ##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?
Dir.parent?('parent', 'parent/child') #=> true
TODO: Needs improvement.
TODO: Instance version?
11 12 13 |
# File 'lib/core/facets/dir/parent.rb', line 11 def self.parent?(parent_path, child_path) %r|^#{Regexp.escape(parent_path)}| =~ child_path ? true : false end |
.recurse(path = '.', &block) ⇒ Object
Recursively scan a directory and pass each file to the given block.
Dir.recurse('.') do |path|
# ...
end
CREDIT: George Moschovitis
TODO: If fully compatible, reimplement as alias of Find.find, or just copy and paste Find.find code here if it looks more robust.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/core/facets/dir/recurse.rb', line 14 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 |
Instance Method Details
#each_child(*ignore) ⇒ Object
Like #each, except the “.” and “..” special files are ignored. You can use ignore
to override ‘.’ and ‘..’ and ignore other entries via a exact match or regular expression.
CREDIT: Tyler Rick
8 9 10 11 12 13 |
# File 'lib/core/facets/dir/each_child.rb', line 8 def each_child(*ignore) ignore = ['.', '..'] if ignore.empty? each do |file| yield file unless ignore.any?{ |i| i === file } end end |