class Pod::Installer::Xcode::PodsProjectGenerator::FileReferencesInstaller

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

Constants

LOCALIZATION_REGION_FILEPATTERN_REGEX

Regex for extracting the region portion of a localized file path. Ex. `Resources/en.lproj` –> `en`

Attributes

pod_targets[R]

@return [Array<PodTarget>] The pod targets of the installation.

pods_project[R]

@return [Project] The project to install the file references into.

preserve_pod_file_structure[R]

@return [Bool] add support for preserving the file structure of externally sourced pods, in addition to local pods.

sandbox[R]

@return [Sandbox] The sandbox of the installation.

Public Class Methods

new(sandbox, pod_targets, pods_project, preserve_pod_file_structure = false) click to toggle source

Initialize a new instance

@param [Sandbox] sandbox @see sandbox @param [Array<PodTarget>] pod_targets @see pod_targets @param [Project] pods_project @see pods_project @param [Bool] preserve_pod_file_structure @see preserve_pod_file_structure

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 35
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

Public Instance Methods

install!() click to toggle source

Installs the file references.

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 46
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

Private Instance Methods

add_developer_files() click to toggle source
# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 138
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) click to toggle source

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.

@param [Symbol] file_accessor_key

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

@param [Symbol] group_key

The key of the group of the Pods project.

@param [Bool] reflect_file_system_structure

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

@return [Array<PBXFileReference>] the added file references

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 216
def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure = false)
  file_accessors.flat_map 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.map do |path|
      pods_project.add_file_reference(path, group, preserve_pod_file_structure_flag, base_path)
    end
  end
end
add_frameworks_bundles() click to toggle source

Adds the bundled frameworks to the Pods project

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 107
def add_frameworks_bundles
  UI.message '- Adding frameworks' do
    add_file_accessors_paths_to_pods_group(:vendored_frameworks, :frameworks)
  end
end
add_known_regions(file_references) click to toggle source

Adds the known localization regions to the root of the project

@param [Array<PBXFileReferences>] file_references the resource file references

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 313
def add_known_regions(file_references)
  pattern = LOCALIZATION_REGION_FILEPATTERN_REGEX
  regions = file_references.map do |ref|
    if (match = ref.path.to_s.match(pattern))
      match[:region]
    end
  end.compact

  pods_project.root_object.known_regions = (pods_project.root_object.known_regions | regions).sort
end
add_resources() click to toggle source

Adds the resources of the Pods to the Pods project.

@note The source files are grouped by Pod and in turn by subspec

(recursively) in the resources group.

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 130
def add_resources
  UI.message '- Adding resources' do
    refs = add_file_accessors_paths_to_pods_group(:resources, :resources, true)
    refs.concat add_file_accessors_paths_to_pods_group(:resource_bundle_files, :resources, true)
    add_known_regions(refs)
  end
end
add_source_files_references() click to toggle source

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

@note The source files are grouped by Pod and in turn by subspec

(recursively).

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 97
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_libraries() click to toggle source

Adds the bundled libraries to the Pods project

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 117
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) click to toggle source

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.

@param [Array<Pathname>] paths

The paths to files or directories on disk.

@return [Array<Pathname>] The paths which can be added to the Xcode project

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 243
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) click to toggle source

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

@param [Array<Pathname>] paths

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

@return [Pathname] Pathname of the nearest parent shared by paths, or nil if none exists

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 292
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_accessors() click to toggle source

@return [Array<Sandbox::FileAccessor>] The file accessors for all the

specs platform combinations.
# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 196
def file_accessors
  @file_accessors ||= pod_targets.flat_map(&:file_accessors).compact
end
prepare_pod_groups() click to toggle source

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

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 79
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_accessors() click to toggle source

Reads the file accessors contents from the file system.

@note The contents of the file accessors are modified by the clean

step of the #{PodSourceInstaller} and by the pre install hooks.

@return [void]

# File lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb, line 70
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