Ascend a directory path.
a = [] Dir.ascend("/var/log") do |path| a << path end a #=> ['/var/log', '/var', '/']
CREDIT: Daniel Berger, Jeffrey Schwab
TODO: make it work with windows too use FileTest.root?
# File lib/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 a directory path.
d = [] Dir.descend("/var/log") do |path| d << path end d #=> ['/', '/var', '/var/log']
CREDIT: Daniel Berger, Jeffrey Schwab
# File lib/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
Same as Dir#recurse.
# File lib/facets/dir/recurse.rb, line 30 def self.ls_r(path='.', &block) recurse(path, &block) end
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/**/*')
# File lib/facets/dir/multiglob.rb, line 28 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
The same as multiglob, but recusively includes directories.
Dir.multiglob_r('tmp')
is equivalent to
Dir.multiglob('tmp', :recurse=>true)
The effect of which is
Dir.multiglob('tmp', 'tmp/**/**')
# File lib/facets/dir/multiglob.rb, line 66 def self.multiglob_r(*patterns) options = Hash === patterns.last ? patterns.pop : {} matches = multiglob(*patterns) directories = matches.select{ |m| File.directory?(m) } matches += directories.map{ |d| multiglob_r(File.join(d, '**'), options) }.flatten matches.uniq ##options = (Hash === patterns.last ? patterns.pop : {}) ##options[:recurse] = true ##patterns << options ##multiglob(*patterns) end
Is a path parental to another?
Dir.parent?('parent', 'parent/child') #=> true
TODO: Needs improvement.
TODO: Instance version?
# File lib/facets/dir/parent.rb, line 11 def self.parent?(parent_path, child_path) %^#{Regexp.escape(parent_path)}| =~ child_path ? true : false end
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.
# File lib/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
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
# File lib/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
Generated with the Darkfish Rdoc Generator 2.