Class: Pod::Sandbox::PathList

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods/sandbox/path_list.rb

Overview

Note:

A PathList once it has generated the list of the paths this is updated only if explicitly requested by calling #read_file_system

The PathList class is designed to perform multiple glob matches against a given directory. Basically, it generates a list of all the children paths and matches the globs patterns against them, resulting in just one access to the file system.

Instance Attribute Summary collapse

Globbing collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ PathList

Initialize a new instance

Parameters:

  • root (Pathname)

    The root of the PathList.



22
23
24
25
# File 'lib/cocoapods/sandbox/path_list.rb', line 22

def initialize(root)
  @root = root
  @glob_cache = {}
end

Instance Attribute Details

#rootPathname

Returns The root of the list whose files and directories are used to perform the matching operations.

Returns:

  • (Pathname)

    The root of the list whose files and directories are used to perform the matching operations.



16
17
18
# File 'lib/cocoapods/sandbox/path_list.rb', line 16

def root
  @root
end

Instance Method Details

#dirsArray<String>

Returns The list of absolute the path of all the directories contained in #root.

Returns:

  • (Array<String>)

    The list of absolute the path of all the directories contained in #root.



38
39
40
41
# File 'lib/cocoapods/sandbox/path_list.rb', line 38

def dirs
  read_file_system unless @dirs
  @dirs
end

#filesArray<String>

Returns The list of absolute the path of all the files contained in #root.

Returns:

  • (Array<String>)

    The list of absolute the path of all the files contained in #root.



30
31
32
33
# File 'lib/cocoapods/sandbox/path_list.rb', line 30

def files
  read_file_system unless @files
  @files
end

#glob(patterns, options = {}) ⇒ Array<Pathname>

Similar to #glob but returns the absolute paths.

Parameters:

  • patterns (String, Array<String>)

    @see #relative_glob

  • options (Hash) (defaults to: {})

    @see #relative_glob

Returns:

  • (Array<Pathname>)


78
79
80
# File 'lib/cocoapods/sandbox/path_list.rb', line 78

def glob(patterns, options = {})
  relative_glob(patterns, options).map { |p| root + p }
end

#read_file_systemvoid

This method returns an undefined value.

Returns Reads the file system and populates the files and paths lists.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/cocoapods/sandbox/path_list.rb', line 46

def read_file_system
  unless root.exist?
    raise Informative, "Attempt to read non existent folder `#{root}`."
  end
  root_length  = root.to_s.length + 1
  escaped_root = escape_path_for_glob(root)
  paths  = Dir.glob(escaped_root + '**/*', File::FNM_DOTMATCH)
  absolute_dirs  = paths.select { |path| File.directory?(path) }
  relative_dirs  = absolute_dirs.map  { |p| p[root_length..-1] }
  absolute_paths = paths.reject { |p| p == "#{root}/." || p == "#{root}/.." }
  relative_paths = absolute_paths.map { |p| p[root_length..-1] }
  @files = relative_paths - relative_dirs
  @dirs  = relative_dirs.map { |d| d.gsub(/\/\.\.?$/, '') }.reject { |d| d == '.' || d == '..' } .uniq
  @glob_cache = {}
end

#relative_glob(patterns, options = {}) ⇒ Array<Pathname>

The list of relative paths that are case insensitively matched by a given pattern. This method emulates Dir#glob with the File::FNM_CASEFOLD option.

Parameters:

  • patterns (String, Array<String>)

    A single Dir#glob like pattern, or a list of patterns.

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :dir_pattern (String)

    An optional pattern to append to a pattern, if it is the path to a directory.

  • :exclude_patterns (Array<String>)

    Exclude specific paths given by those patterns.

  • :include_dirs (Array<String>)

    Additional paths to take into account for matching.

Returns:

  • (Array<Pathname>)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/cocoapods/sandbox/path_list.rb', line 103

def relative_glob(patterns, options = {})
  return [] if patterns.empty?

  cache_key = options.merge(:patterns => patterns)
  cached_value = @glob_cache[cache_key]
  return cached_value if cached_value

  dir_pattern = options[:dir_pattern]
  exclude_patterns = options[:exclude_patterns]
  include_dirs = options[:include_dirs]

  if include_dirs
    full_list = files + dirs
  else
    full_list = files
  end

  list = Array(patterns).map do |pattern|
    if directory?(pattern) && dir_pattern
      pattern += '/' unless pattern.end_with?('/')
      pattern += dir_pattern
    end
    expanded_patterns = dir_glob_equivalent_patterns(pattern)
    full_list.select do |path|
      expanded_patterns.any? do |p|
        File.fnmatch(p, path, File::FNM_CASEFOLD | File::FNM_PATHNAME)
      end
    end
  end.flatten

  list = list.map { |path| Pathname.new(path) }
  if exclude_patterns
    exclude_options = { :dir_pattern => '**/*', :include_dirs => include_dirs }
    list -= relative_glob(exclude_patterns, exclude_options)
  end
  @glob_cache[cache_key] = list
end