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)

    @see #root


25
26
27
28
29
# File 'lib/cocoapods/sandbox/path_list.rb', line 25

def initialize(root)
  root_dir = ActiveSupport::Multibyte::Unicode.normalize(root.to_s)
  @root = Pathname.new(root_dir)
  @glob_cache = {}
end

Instance Attribute Details

#rootPathname (readonly)

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.


19
20
21
# File 'lib/cocoapods/sandbox/path_list.rb', line 19

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.


42
43
44
45
# File 'lib/cocoapods/sandbox/path_list.rb', line 42

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.


34
35
36
37
# File 'lib/cocoapods/sandbox/path_list.rb', line 34

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

90
91
92
93
# File 'lib/cocoapods/sandbox/path_list.rb', line 90

def glob(patterns, options = {})
  cache_key = options.merge(:patterns => patterns)
  @glob_cache[cache_key] ||= relative_glob(patterns, options).map { |p| root.join(p) }
end

#read_file_systemvoid

This method returns an undefined value.

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


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cocoapods/sandbox/path_list.rb', line 50

def read_file_system
  unless root.exist?
    raise Informative, "Attempt to read non existent folder `#{root}`."
  end

  dirs = []
  files = []
  root_length = root.cleanpath.to_s.length + File::SEPARATOR.length
  Find.find(root.to_s) do |f|
    directory = File.directory?(f)
    f = f.slice(root_length, f.length - root_length)
    next if f.nil?

    (directory ? dirs : files) << f
  end

  dirs.sort_by!(&:upcase)
  files.sort_by!(&:upcase)

  @dirs = dirs
  @files = files
  @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>)

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/cocoapods/sandbox/path_list.rb', line 116

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

  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
  patterns_array = Array(patterns)
  exact_matches = (full_list & patterns_array).to_set

  unless patterns_array.empty?
    list = patterns_array.flat_map do |pattern|
      if exact_matches.include?(pattern)
        pattern
      else
        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
    end
  end

  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
  list
end