class Pod::DyInstaller::Xcode::PodsProjectGenerator::FileReferencesInstaller
Controller class responsible of installing the file references of the specifications in the Pods project.
Attributes
@return [Array<PodTarget>] The pod targets of the installation.
@return [Project] The Pods project.
@return [Sandbox] The sandbox of the installation.
Public Class Methods
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
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
# 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
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
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
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
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
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
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
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
@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
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
Creates the link to the headers of the Pod
in the sandbox.
@return [void]
# File lib/pod/installer/xcode/pods_project_generator/file_references_installer.rb, line 133 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.requires_frameworks? && pod_target.should_build? headers_sandbox = Pathname.new(pod_target.pod_name) added_build_headers = false added_public_headers = false pod_target.file_accessors.each do |file_accessor| # Private headers will always end up in Pods/Headers/Private/PodA/*.h # This will allow for `""` imports to work. header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files| added_build_headers = true pod_target.build_headers.add_files(namespaced_path, files) end # Public headers on the other hand will be added in Pods/Headers/Public/PodA/PodA/*.h # The extra folder is intentional in order for `<>` imports to work. header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files| added_public_headers = true sandbox.public_headers.add_files(namespaced_path, files) end unless pod_target.requires_frameworks? vendored_frameworks_header_mappings(headers_sandbox, file_accessor).each do |namespaced_path, files| added_public_headers = true sandbox.public_headers.add_files(namespaced_path, files) end end end pod_target.build_headers.add_search_path(headers_sandbox, pod_target.platform) if added_build_headers sandbox.public_headers.add_search_path(headers_sandbox, pod_target.platform) if added_public_headers end end end
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
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