Module: VirtFS::FindClassMethods

Included in:
VirtFS
Defined in:
lib/virtfs/find_class_methods.rb

Overview

VirtFS Find Class representation - implements the core Ruby Find methods, dispatching to underlying mounted VirtFS filesystems

Constant Summary collapse

GLOB_CHARS =
'*?[{'

Instance Method Summary collapse

Instance Method Details

#dir_and_glob(glob_pattern) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns files matching glob pattern

Parameters:

  • glob_pattern (String, Regex)

    pattern to search for

Returns:

  • (String)

    paths to files found



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/virtfs/find_class_methods.rb', line 68

def dir_and_glob(glob_pattern)
  glob_path = Pathname.new(glob_pattern)

  if glob_path.absolute?
    search_path    = VfsRealFile::SEPARATOR
    specified_path = VfsRealFile::SEPARATOR
  else
    search_path    = dir_getwd
    specified_path = nil
  end

  components = glob_path.each_filename.to_a
  while (comp = components.shift)
    if glob_str?(comp)
      components.unshift(comp)
      break
    end
    search_path = VfsRealFile.join(search_path, comp)
    if specified_path
      specified_path = VfsRealFile.join(specified_path, comp)
    else
      specified_path = comp
    end
  end
  return normalize_path(search_path), specified_path, VfsRealFile.join(components)
end

#find(path, max_depth = nil) { ... } ⇒ Object

Modified version of Find.find:

  • Accepts only a single path.

  • Can be restricted by depth - optimization for glob searches.

  • Will work with VirtFS, even when it’s not active.

Parameters:

  • path (String)

    starting directory of the find

  • max_depth (Integer) (defaults to: nil)

    max number of levels to decend befroelookup

Yields:

  • files found

Raises:

  • (SystemCallError)


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/virtfs/find_class_methods.rb', line 15

def find(path, max_depth = nil)
  raise SystemCallError.new(path, Errno::ENOENT::Errno) unless VirtFS::VFile.exist?(path)
  block_given? || (return enum_for(__method__, path, max_depth))

  depths = [0]
  paths  = [path.dup]

  while (file = paths.shift)
    depth = depths.shift
    catch(:prune) do
      yield file.dup.taint
      begin
        s = VirtFS::VFile.lstat(file)
      rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
        next
      end
      if s.directory?
        next if depth + 1 > max_depth if max_depth
        begin
          fs = VirtFS::VDir.entries(file)
        rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
          next
        end
        fs.sort!
        fs.reverse_each do |f|
          next if f == "." || f == ".."
          f = VfsRealFile.join(file, f)
          paths.unshift f.untaint
          depths.unshift depth + 1
        end
      end
    end
  end
end

#glob_depth(glob_pattern) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return max levels which glob pattern may resolve to

Parameters:

  • glob_pattern (String, Regex)

    pattern to search for

Returns:

  • (Integer)

    max levels which pattern may match



100
101
102
103
104
# File 'lib/virtfs/find_class_methods.rb', line 100

def glob_depth(glob_pattern)
  path_components = Pathname(glob_pattern).each_filename.to_a
  return nil if path_components.include?('**')
  path_components.length
end

#glob_str?(str) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/virtfs/find_class_methods.rb', line 58

def glob_str?(str)
  str.gsub(/\\./, "X").count(GLOB_CHARS) != 0
end

#pruneObject

Implementation of Find.prune

Raises:

  • (RuntimeError)

    always



53
54
55
# File 'lib/virtfs/find_class_methods.rb', line 53

def prune
  throw :prune
end