class Pod::DyInstaller::Xcode::PodsProjectGenerator::FileReferencesInstaller

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

Attributes

pod_targets[R]

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

pods_project[R]

@return [Project] The Pods project.

sandbox[R]

@return [Sandbox] The sandbox of the installation.

Public Class Methods

new(sandbox, pod_targets, pods_project) 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 pod_project

# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 27
def initialize(sandbox, pod_targets, pods_project)
  @sandbox = sandbox
  @pod_targets = pod_targets
  @pods_project = pods_project
end

Public Instance Methods

install!() click to toggle source

Installs the file references.

@return [void]

# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 37
def install!
  refresh_file_accessors
  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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 111
def add_developer_files
  UI.message '- Adding development pod helper files to Pods project' 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
      paths.each do |path|
        group = pods_project.group_for_spec(root_name, :developer)
        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_for_development = 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_for_development

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

@return [void]

# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 204
def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false)
  file_accessors.each do |file_accessor|
    pod_name = file_accessor.spec.name
    local = sandbox.local?(pod_name)
    paths = file_accessor.send(file_accessor_key)
    paths = allowable_project_paths(paths)
    base_path = local ? common_path(paths) : nil
    paths.each do |path|
      group = pods_project.group_for_spec(pod_name, group_key)
      pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
    end
  end
end
add_frameworks_bundles() click to toggle source

Adds the bundled frameworks to the Pods project

@return [void]

# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 81
def add_frameworks_bundles
  UI.message '- Adding frameworks to Pods project' do
    add_file_accessors_paths_to_pods_group(:vendored_frameworks, :frameworks)
  end
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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 104
def add_resources
  UI.message '- Adding resources to Pods project' 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_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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 71
def add_source_files_references
  UI.message '- Adding source files to Pods project' 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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 91
def add_vendored_libraries
  UI.message '- Adding libraries to Pods project' 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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 228
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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 277
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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 184
def file_accessors
  @file_accessors ||= pod_targets.flat_map(&:file_accessors).compact
end
header_mappings(headers_sandbox, file_accessor, headers) click to toggle source

Computes the destination sub-directory in the sandbox

@param [Pathname] headers_sandbox

The sandbox where the header links should be stored for this
Pod.

@param [Sandbox::FileAccessor] file_accessor

The consumer file accessor for which the headers need to be
linked.

@param [Array<Pathname>] headers

The absolute paths of the headers which need to be mapped.

@return [Hash{Pathname => Array<Pathname>}] A hash containing the

headers folders as the keys and the absolute paths of the
header files as the values.
# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 311
def header_mappings(headers_sandbox, file_accessor, headers)
  consumer = file_accessor.spec_consumer
  header_mappings_dir = consumer.header_mappings_dir
  dir = headers_sandbox
  dir += consumer.header_dir if consumer.header_dir

  mappings = {}
  headers.each do |header|
    next if header.to_s.include?('.framework/')

    sub_dir = dir
    if header_mappings_dir
      relative_path = header.relative_path_from(file_accessor.path_list.root + header_mappings_dir)
      sub_dir += relative_path.dirname
    end
    mappings[sub_dir] ||= []
    mappings[sub_dir] << header
  end
  mappings
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/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 60
def refresh_file_accessors
  file_accessors.map(&:path_list).uniq.each(&:read_file_system)
end
vendored_frameworks_header_mappings(headers_sandbox, file_accessor) click to toggle source

Computes the destination sub-directory in the sandbox for headers from inside vendored frameworks.

@param [Pathname] headers_sandbox

The sandbox where the header links should be stored for this
Pod.

@param [Sandbox::FileAccessor] file_accessor

The consumer file accessor for which the headers need to be
linked.
# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 343
def vendored_frameworks_header_mappings(headers_sandbox, file_accessor)
  mappings = {}
  file_accessor.vendored_frameworks.each do |framework|
    headers_dir = Sandbox::FileAccessor.vendored_frameworks_headers_dir(framework)
    headers = Sandbox::FileAccessor.vendored_frameworks_headers(framework)
    framework_name = framework.basename(framework.extname)
    dir = headers_sandbox + framework_name
    headers.each do |header|
      # the relative path of framework headers should be kept,
      # not flattened like is done for most public headers.
      relative_path = header.relative_path_from(headers_dir)
      sub_dir = dir + relative_path.dirname
      mappings[sub_dir] ||= []
      mappings[sub_dir] << header
    end
  end
  mappings
end