Class: Pod::Installer::Xcode::PodsProjectGenerator::FileReferencesInstaller

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb

Overview

Controller class responsible of installing the file references of the specifications in the Pods project.

Instance Attribute Summary collapse

Installation Steps collapse

Private Helpers collapse

Instance Method Summary collapse

Constructor Details

#initialize(sandbox, pod_targets, pods_project, preserve_pod_file_structure = false) ⇒ FileReferencesInstaller

Initialize a new instance

Parameters:

  • sandbox (Sandbox)

    @see #sandbox

  • pod_targets (Array<PodTarget>)

    @see #pod_targets

  • pods_project (Project)

    @see #pods_project

  • preserve_pod_file_structure (Bool) (defaults to: false)

    @see #preserve_pod_file_structure


32
33
34
35
36
37
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 32

def initialize(sandbox, pod_targets, pods_project, preserve_pod_file_structure = false)
  @sandbox = sandbox
  @pod_targets = pod_targets
  @pods_project = pods_project
  @preserve_pod_file_structure = preserve_pod_file_structure
end

Instance Attribute Details

#pod_targetsArray<PodTarget> (readonly)

Returns The pod targets of the installation.

Returns:

  • (Array<PodTarget>)

    The pod targets of the installation.


15
16
17
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 15

def pod_targets
  @pod_targets
end

#pods_projectProject (readonly)

Returns The project to install the file references into.

Returns:

  • (Project)

    The project to install the file references into.


19
20
21
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 19

def pods_project
  @pods_project
end

#preserve_pod_file_structureBool (readonly)

Returns add support for preserving the file structure of externally sourced pods, in addition to local pods.

Returns:

  • (Bool)

    add support for preserving the file structure of externally sourced pods, in addition to local pods.


23
24
25
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 23

def preserve_pod_file_structure
  @preserve_pod_file_structure
end

#sandboxSandbox (readonly)

Returns The sandbox of the installation.

Returns:

  • (Sandbox)

    The sandbox of the installation.


11
12
13
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 11

def sandbox
  @sandbox
end

Instance Method Details

#add_developer_filesObject (private)


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 134

def add_developer_files
  UI.message '- Adding development pod helper files' do
    file_accessors.each do |file_accessor|
      pod_name = file_accessor.spec.name
      next unless sandbox.local?(pod_name)
      root_name = Specification.root_name(pod_name)
      paths = file_accessor.developer_files
      next if paths.empty?
      group = pods_project.group_for_spec(root_name, :developer)
      paths.each do |path|
        ref = pods_project.add_file_reference(path, group, false)
        if path.extname == '.podspec'
          pods_project.mark_ruby_file_ref(ref)
        end
      end
    end
  end
end

#add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure = false) ⇒ void (private)

This method returns an undefined value.

Adds file references to the list of the paths returned by the file accessor with the given key to the given group of the Pods project.

Parameters:

  • file_accessor_key (Symbol)

    The method of the file accessor which would return the list of the paths.

  • group_key (Symbol) (defaults to: nil)

    The key of the group of the Pods project.

  • reflect_file_system_structure (Bool) (defaults to: false)

    Whether organizing a local pod's files in subgroups inside the pod's group is allowed.


212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 212

def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure = false)
  file_accessors.each do |file_accessor|
    paths = file_accessor.send(file_accessor_key)
    paths = allowable_project_paths(paths)
    next if paths.empty?

    pod_name = file_accessor.spec.name
    preserve_pod_file_structure_flag = (sandbox.local?(pod_name) || preserve_pod_file_structure) && reflect_file_system_structure
    base_path = preserve_pod_file_structure_flag ? common_path(paths) : nil
    actual_group_key = preserve_pod_file_structure_flag ? nil : group_key
    group = pods_project.group_for_spec(pod_name, actual_group_key)
    paths.each do |path|
      pods_project.add_file_reference(path, group, preserve_pod_file_structure_flag, base_path)
    end
  end
end

#add_frameworks_bundlesvoid (private)

This method returns an undefined value.

Adds the bundled frameworks to the Pods project


104
105
106
107
108
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 104

def add_frameworks_bundles
  UI.message '- Adding frameworks' do
    add_file_accessors_paths_to_pods_group(:vendored_frameworks, :frameworks)
  end
end

#add_resourcesvoid (private)

Note:

The source files are grouped by Pod and in turn by subspec (recursively) in the resources group.

This method returns an undefined value.

Adds the resources of the Pods to the Pods project.


127
128
129
130
131
132
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 127

def add_resources
  UI.message '- Adding resources' do
    add_file_accessors_paths_to_pods_group(:resources, :resources, true)
    add_file_accessors_paths_to_pods_group(:resource_bundle_files, :resources, true)
  end
end

#add_source_files_referencesvoid (private)

Note:

The source files are grouped by Pod and in turn by subspec (recursively).

This method returns an undefined value.

Adds the source files of the Pods to the Pods project.


94
95
96
97
98
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 94

def add_source_files_references
  UI.message '- Adding source files' do
    add_file_accessors_paths_to_pods_group(:source_files, nil, true)
  end
end

#add_vendored_librariesvoid (private)

This method returns an undefined value.

Adds the bundled libraries to the Pods project


114
115
116
117
118
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 114

def add_vendored_libraries
  UI.message '- Adding libraries' do
    add_file_accessors_paths_to_pods_group(:vendored_libraries, :frameworks)
  end
end

#allowable_project_paths(paths) ⇒ Array<Pathname> (private)

Filters a list of paths down to those paths which can be added to the Xcode project. Some paths are intermediates and only their children should be added, while some paths are treated as bundles and their children should not be added directly.

Parameters:

  • paths (Array<Pathname>)

    The paths to files or directories on disk.

Returns:

  • (Array<Pathname>)

    The paths which can be added to the Xcode project


239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 239

def allowable_project_paths(paths)
  lproj_paths = Set.new
  lproj_paths_with_files = Set.new
  allowable_paths = paths.select do |path|
    path_str = path.to_s

    # We add the directory for a Core Data model, but not the items in it.
    next if path_str =~ /.*\.xcdatamodeld\/.+/i

    # We add the directory for a Core Data migration mapping, but not the items in it.
    next if path_str =~ /.*\.xcmappingmodel\/.+/i

    # We add the directory for an asset catalog, but not the items in it.
    next if path_str =~ /.*\.xcassets\/.+/i

    if path_str =~ /\.lproj(\/|$)/i
      # If the element is an .lproj directory then save it and potentially
      # add it later if we don't find any contained items.
      if path_str =~ /\.lproj$/i && path.directory?
        lproj_paths << path
        next
      end

      # Collect the paths for the .lproj directories that contain files.
      lproj_path = /(^.*\.lproj)\/.*/i.match(path_str)[1]
      lproj_paths_with_files << Pathname(lproj_path)

      # Directories nested within an .lproj directory are added as file
      # system references so their contained items are not added directly.
      next if path.dirname.dirname == lproj_path
    end

    true
  end

  # Only add the path for the .lproj directories that do not have anything
  # within them added as well. This generally happens if the glob within the
  # resources directory was not a recursive glob.
  allowable_paths + lproj_paths.subtract(lproj_paths_with_files).to_a
end

#common_path(paths) ⇒ Pathname (private)

Returns a Pathname of the nearest parent from which all the given paths descend. Converts each Pathname to a list of path components and finds the longest common prefix

Parameters:

  • paths (Array<Pathname>)

    The paths to files or directories on disk. Must be absolute paths

Returns:

  • (Pathname)

    Pathname of the nearest parent shared by paths, or nil if none exists


288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 288

def common_path(paths)
  return nil if paths.empty?
  strs = paths.map do |path|
    unless path.absolute?
      raise ArgumentError, "Paths must be absolute #{path}"
    end
    path.dirname.to_s
  end
  min, max = strs.minmax
  min = min.split('/')
  max = max.split('/')
  idx = min.size.times { |i| break i if min[i] != max[i] }
  result = Pathname.new(min[0...idx].join('/'))
  # Don't consider "/" a common path
  return result unless result.to_s == '' || result.to_s == '/'
end

#file_accessorsArray<Sandbox::FileAccessor> (private)

Returns The file accessors for all the specs platform combinations.

Returns:


192
193
194
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 192

def file_accessors
  @file_accessors ||= pod_targets.flat_map(&:file_accessors).compact
end

#install!void

This method returns an undefined value.

Installs the file references.


43
44
45
46
47
48
49
50
51
52
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 43

def install!
  refresh_file_accessors
  prepare_pod_groups
  add_source_files_references
  add_frameworks_bundles
  add_vendored_libraries
  add_resources
  add_developer_files unless sandbox.development_pods.empty?
  link_headers
end

This method returns an undefined value.

Creates the link to the headers of the Pod in the sandbox.


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 157

def link_headers
  UI.message '- Linking headers' do
    pod_targets.each do |pod_target|
      # When integrating Pod as frameworks, built Pods are built into
      # frameworks, whose headers are included inside the built
      # framework. Those headers do not need to be linked from the
      # sandbox.
      next if pod_target.build_as_framework? && pod_target.should_build?

      pod_target_header_mappings = pod_target.header_mappings_by_file_accessor.values
      pod_target_header_mappings.each do |header_mappings|
        header_mappings.each do |namespaced_path, files|
          pod_target.build_headers.add_files(namespaced_path, files)
        end
      end

      public_header_mappings = pod_target.public_header_mappings_by_file_accessor.values
      public_header_mappings.each do |header_mappings|
        header_mappings.each do |namespaced_path, files|
          sandbox.public_headers.add_files(namespaced_path, files)
        end
      end
    end
  end
end

#prepare_pod_groupsObject (private)

Prepares the main groups to which all files will be added for the respective target


76
77
78
79
80
81
82
83
84
85
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 76

def prepare_pod_groups
  file_accessors.each do |file_accessor|
    pod_name = file_accessor.spec.name
    next unless sandbox.local?(pod_name)
    root_name = Specification.root_name(pod_name)
    path = file_accessor.root
    group = pods_project.group_for_spec(root_name)
    group.set_path(path) unless group.path == path
  end
end

#refresh_file_accessorsvoid (private)

Note:

The contents of the file accessors are modified by the clean step of the #PodSourceInstaller and by the pre install hooks.

This method returns an undefined value.

Reads the file accessors contents from the file system.


67
68
69
70
71
72
# File 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb', line 67

def refresh_file_accessors
  file_accessors.reject do |file_accessor|
    pod_name = file_accessor.spec.name
    sandbox.local?(pod_name)
  end.map(&:path_list).uniq.each(&:read_file_system)
end