class Pod::DyInstaller::UserProjectIntegrator
The {UserProjectIntegrator} integrates the libraries generated by TargetDefinitions of the {Podfile} with their correspondent user projects.
Constants
- IGNORED_KEYS
- INHERITED_FLAGS
Attributes
@return [Pathname] the path of the installation.
@todo This is only used to compute the workspace path in case that it
should be inferred by the project. If the workspace should be in the same dir of the project, this could be removed.
@return [Podfile] the podfile that should be integrated with the user
projects.
@return [Project] the pods project which contains the libraries to
integrate.
attr_reader :pods_project
@return [Array<AggregateTarget>] the targets represented in the Podfile.
Public Class Methods
Init a new UserProjectIntegrator
@param [Podfile] podfile @see podfile
@param [Sandbox] sandbox @see sandbox
@param [Pathname] installation_root
@see installation_root
@param [Array<AggregateTarget>] targets @see targets
@todo Too many initialization arguments
# File lib/pod/installer/user_project_integrator.rb, line 49 def initialize(podfile, sandbox, installation_root, targets) @podfile = podfile @sandbox = sandbox @installation_root = installation_root @targets = targets end
Public Instance Methods
Integrates the user projects associated with the {TargetDefinitions} with the Pods project and its products.
@return [void]
# File lib/pod/installer/user_project_integrator.rb, line 61 def integrate! create_workspace integrate_user_targets warn_about_xcconfig_overrides save_projects end
Private Instance Methods
Creates and saved the workspace containing the Pods project and the user projects, if needed.
@note If the workspace already contains the projects it is not saved
to avoid Xcode from displaying the revert dialog: `Do you want to keep the Xcode version or revert to the version on disk?`
@return [void]
# File lib/pod/installer/user_project_integrator.rb, line 83 def create_workspace all_projects = user_project_paths.sort.push(sandbox.project_path).uniq file_references = all_projects.map do |path| relative_path = path.relative_path_from(workspace_path.dirname).to_s Xcodeproj::Workspace::FileReference.new(relative_path, 'group') end if workspace_path.exist? workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path) new_file_references = file_references - workspace.file_references unless new_file_references.empty? new_file_references.each { |fr| workspace << fr } workspace.save_as(workspace_path) end else UI.notice "Please close any current Xcode sessions and use `#{workspace_path.basename}` for this project from now on." workspace = Xcodeproj::Workspace.new(*file_references) workspace.save_as(workspace_path) end end
Integrates the targets of the user projects with the libraries generated from the {Podfile}.
@note {TargetDefinition} without dependencies are skipped prevent
creating empty libraries for targets definitions which are only wrappers for others.
@return [void]
# File lib/pod/installer/user_project_integrator.rb, line 114 def integrate_user_targets target_integrators = targets_to_integrate.sort_by(&:name).map do |target| puts "target --> #{target}" TargetIntegrator.new(target) end Config.instance.with_changes(:silent => true) do deintegrator = Deintegrator.new all_project_targets = user_projects.flat_map(&:native_targets).uniq all_native_targets = targets_to_integrate.flat_map(&:user_targets).uniq targets_to_deintegrate = all_project_targets - all_native_targets targets_to_deintegrate.each do |target| deintegrator.deintegrate_target(target) end end target_integrators.each(&:integrate!) end
Prints a warning informing the user that a build configuration of the integrated target is overriding the CocoaPods build settings.
@param [Target::AggregateTarget] aggregate_target
The umbrella target.
@param [XcodeProj::PBXNativeTarget] user_target
The native target.
@param [Xcodeproj::XCBuildConfiguration] config
The build configuration.
@param [String] key
The key of the overridden build setting.
# File lib/pod/installer/user_project_integrator.rb, line 238 def print_override_warning(aggregate_target, user_target, config, key) actions = [ 'Use the `$(inherited)` flag, or', 'Remove the build settings from the target.', ] message = "The `#{user_target.name} [#{config.name}]` " \ "target overrides the `#{key}` build setting defined in " \ "`#{aggregate_target.xcconfig_relative_path(config.name)}'. " \ 'This can lead to problems with the CocoaPods installation' UI.warn(message, actions) end
Save all user projects.
@return [void]
# File lib/pod/installer/user_project_integrator.rb, line 137 def save_projects user_projects.each do |project| if project.dirty? project.save else # There is a bug in Xcode where the process of deleting and # re-creating the xcconfig files used in the build # configuration cause building the user project to fail until # Xcode is relaunched. # # Touching/saving the project causes Xcode to reload these. # # https://github.com/CocoaPods/CocoaPods/issues/2665 FileUtils.touch(project.path + 'project.pbxproj') end end end
# File lib/pod/installer/user_project_integrator.rb, line 219 def targets_to_integrate targets end
@return [Array<Pathname>] the paths of all the user projects referenced
by the target definitions.
@note Empty target definitions are ignored.
# File lib/pod/installer/user_project_integrator.rb, line 211 def user_project_paths targets.map(&:user_project_path).compact.uniq end
# File lib/pod/installer/user_project_integrator.rb, line 215 def user_projects targets.map(&:user_project).compact.uniq end
Checks whether the settings of the CocoaPods generated xcconfig are overridden by the build configuration of a target and prints a warning to inform the user if needed.
# File lib/pod/installer/user_project_integrator.rb, line 162 def warn_about_xcconfig_overrides targets.each do |aggregate_target| aggregate_target.user_targets.each do |user_target| user_target.build_configurations.each do |config| xcconfig = aggregate_target.xcconfigs[config.name] if xcconfig (xcconfig.to_hash.keys - IGNORED_KEYS).each do |key| target_values = config.build_settings[key] if target_values && !INHERITED_FLAGS.any? { |flag| target_values.include?(flag) } print_override_warning(aggregate_target, user_target, config, key) end end end end end end end
@return [Pathname] the path where the workspace containing the Pods
project and the user projects should be saved.
# File lib/pod/installer/user_project_integrator.rb, line 189 def workspace_path if podfile.workspace_path declared_path = podfile.workspace_path path_with_ext = File.extname(declared_path) == '.xcworkspace' ? declared_path : "#{declared_path}.xcworkspace" podfile_dir = File.dirname(podfile.defined_in_file || '') absolute_path = File.expand_path(path_with_ext, podfile_dir) Pathname.new(absolute_path) elsif user_project_paths.count == 1 project = user_project_paths.first.basename('.xcodeproj') installation_root + "#{project}.xcworkspace" else raise Informative, 'Could not automatically select an Xcode ' \ "workspace. Specify one in your Podfile like so:\n\n" \ " workspace 'path/to/Workspace.xcworkspace'\n" end end