class Pod::Installer::Xcode::PodsProjectGenerator
The {PodsProjectGenerator} handles generation of the 'Pods/Pods.xcodeproj'
Constants
- AppHostKey
- InstallationResults
Attributes
@return [Array<AggregateTarget>] The model representations of an
aggregation of pod targets generated for a target definition in the Podfile.
@return [Analyzer] the analyzer which provides the information about what
needs to be installed.
@return [Config] the global CocoaPods configuration.
@return [InstallationOptions] the installation options from the Podfile.
@return [Array<PodTarget>] The model representations of pod targets.
@return [Pod::Project] the `Pods/Pods.xcodeproj` project.
@return [Sandbox] The sandbox where the Pods should be installed.
Public Class Methods
Initialize a new instance
@param [Sandbox] sandbox @see sandbox
@param [Array<AggregateTarget>] aggregate_targets
@see aggregate_targets
@param [Array<PodTarget>] pod_targets
@see pod_targets
@param [Analyzer] analysis_result
@see analysis_result
@param [InstallationOptions] installation_options
@see installation_options
@param [Config] config @see config
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 56 def initialize(sandbox, aggregate_targets, pod_targets, analysis_result, installation_options, config) @sandbox = sandbox @aggregate_targets = aggregate_targets @pod_targets = pod_targets @analysis_result = analysis_result @installation_options = installation_options @config = config end
Public Instance Methods
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 65 def generate! prepare install_file_references @target_installation_results = install_targets integrate_targets(@target_installation_results.pod_target_installation_results) app_hosts_by_host_key = install_app_hosts wire_target_dependencies(@target_installation_results, app_hosts_by_host_key) @target_installation_results end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 75 def write UI.message "- Writing Xcode project file to #{UI.path sandbox.project_path}" do project.pods.remove_from_project if project.pods.empty? project.development_pods.remove_from_project if project.development_pods.empty? project.sort(:groups_position => :below) if installation_options.deterministic_uuids? UI.message('- Generating deterministic UUIDs') { project.predictabilize_uuids } end library_product_types = [:framework, :dynamic_library, :static_library] pod_target_installation_results = @target_installation_results.pod_target_installation_results results_by_native_target = Hash[pod_target_installation_results.map do |_, result| [result.native_target, result] end] project.recreate_user_schemes(false) do |scheme, target| next unless target.respond_to?(:symbol_type) next unless library_product_types.include? target.symbol_type installation_result = results_by_native_target[target] next unless installation_result installation_result.test_native_targets.each do |test_native_target| scheme.add_test_target(test_native_target) end end project.save end end
Private Instance Methods
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 385 def add_framework_file_reference_to_native_target(native_target, pod_target, dependent_target, frameworks_group) if pod_target.should_build? && pod_target.requires_frameworks? && !pod_target.static_framework? && dependent_target.should_build? product_ref = frameworks_group.files.find { |f| f.path == dependent_target.product_name } || frameworks_group.new_product_ref_for_target(dependent_target.product_basename, dependent_target.product_type) native_target.frameworks_build_phase.add_file_reference(product_ref, true) end end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 254 def add_system_framework_dependencies(pod_target_installation_results) sorted_installation_results = pod_target_installation_results.sort_by do |pod_target_installation_result| pod_target_installation_result.target.name end sorted_installation_results.each do |target_installation_result| pod_target = target_installation_result.target next unless pod_target.should_build? next if !pod_target.requires_frameworks? || pod_target.static_framework? pod_target.file_accessors.each do |file_accessor| native_target = target_installation_result.native_target_for_spec(file_accessor.spec) add_system_frameworks_to_native_target(native_target, file_accessor) end end end
@! group Private Helpers
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 379 def add_system_frameworks_to_native_target(native_target, file_accessor) file_accessor.spec_consumer.frameworks.each do |framework| native_target.add_system_framework(framework) end end
Sets the APPLICATION_EXTENSION_API_ONLY build setting to YES for all configurations of the given native target.
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 396 def configure_app_extension_api_only_to_native_target(native_target) native_target.build_configurations.each do |config| config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES' end end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 402 def configure_app_host_to_native_target(app_host_target, test_native_target) test_native_target.build_configurations.each do |configuration| test_host = "$(BUILT_PRODUCTS_DIR)/#{app_host_target.name}.app/" test_host << 'Contents/MacOS/' if app_host_target.platform_name == :osx test_host << app_host_target.name.to_s configuration.build_settings['TEST_HOST'] = test_host end target_attributes = project.root_object.attributes['TargetAttributes'] || {} target_attributes[test_native_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s } project.root_object.attributes['TargetAttributes'] = target_attributes end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 123 def create_project if object_version = aggregate_targets.map(&:user_project).compact.map { |p| p.object_version.to_i }.min Pod::Project.new(sandbox.project_path, false, object_version) else Pod::Project.new(sandbox.project_path) end end
@return [Array<Library>] The targets of the development pods generated by
the installation process.
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 369 def development_pod_targets pod_targets.select do |pod_target| sandbox.local?(pod_target.pod_name) end end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 210 def install_app_hosts pod_target_with_test_specs = pod_targets.reject do |pod_target| pod_target.test_specs.empty? || pod_target.test_spec_consumers.none?(&:requires_app_host?) end return if pod_target_with_test_specs.empty? UI.message '- Installing app hosts' do app_host_keys = pod_target_with_test_specs.flat_map do |pod_target| pod_target.supported_test_types.flat_map do |test_type| AppHostKey.new(test_type, pod_target.platform) end.uniq end app_host_keys_by_test_type = app_host_keys.group_by do |app_host_key| [app_host_key.test_type, app_host_key.platform.symbolic_name] end app_host_keys_by_test_type.map do |(test_type, platform_symbol), keys| deployment_target = keys.map { |k| k.platform.deployment_target }.max platform = Platform.new(platform_symbol, deployment_target) AppHostKey.new(test_type, platform) end Hash[app_host_keys.map do |app_host_key| [app_host_key, AppHostInstaller.new(sandbox, project, app_host_key.platform, app_host_key.test_type).install!] end] end end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 177 def install_file_references installer = FileReferencesInstaller.new(sandbox, pod_targets, project) installer.install! end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 182 def install_targets UI.message '- Installing targets' do umbrella_headers_by_dir = pod_targets.map do |pod_target| next unless pod_target.should_build? && pod_target.defines_module? pod_target.umbrella_header_path end.compact.group_by(&:dirname) pod_target_installation_results = Hash[pod_targets.sort_by(&:name).map do |pod_target| umbrella_headers_in_header_dir = umbrella_headers_by_dir[pod_target.module_map_path.dirname] target_installer = PodTargetInstaller.new(sandbox, @project, pod_target, umbrella_headers_in_header_dir) [pod_target.name, target_installer.install!] end] # Hook up system framework dependencies for the pod targets that were just installed. pod_target_installation_result_values = pod_target_installation_results.values.compact unless pod_target_installation_result_values.empty? add_system_framework_dependencies(pod_target_installation_result_values) end aggregate_target_installation_results = Hash[aggregate_targets.sort_by(&:name).map do |target| target_installer = AggregateTargetInstaller.new(sandbox, @project, target) [target.name, target_installer.install!] end] InstallationResults.new(pod_target_installation_results, aggregate_target_installation_results) end end
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 240 def integrate_targets(pod_target_installation_results) pod_installations_to_integrate = pod_target_installation_results.values.select do |pod_target_installation_result| pod_target = pod_target_installation_result.target !pod_target_installation_result.test_native_targets.empty? || pod_target.contains_script_phases? end unless pod_installations_to_integrate.empty? UI.message '- Integrating targets' do pod_installations_to_integrate.each do |pod_target_installation_result| PodTargetIntegrator.new(pod_target_installation_result).integrate! end end end end
Creates the Pods project from scratch if it doesn't exists.
@return [void]
@todo Clean and modify the project if it exists.
# File lib/cocoapods/installer/xcode/pods_project_generator.rb, line 137 def prepare UI.message '- Creating Pods project' do @project = create_project analysis_result.all_user_build_configurations.each do |name, type| @project.add_build_configuration(name, type) end # Reset symroot just in case the user has added a new build configuration other than 'Debug' or 'Release'. @project.symroot = Pod::Project::LEGACY_BUILD_ROOT pod_names = pod_targets.map(&:pod_name).uniq pod_names.each do |pod_name| local = sandbox.local?(pod_name) path = sandbox.pod_dir(pod_name) was_absolute = sandbox.local_path_was_absolute?(pod_name) @project.add_pod_group(pod_name, path, local, was_absolute) end if config.podfile_path @project.add_podfile(config.podfile_path) end sandbox.project = @project platforms = aggregate_targets.map(&:platform) osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min ios_deployment_target = platforms.select { |p| p.name == :ios }.map(&:deployment_target).min watchos_deployment_target = platforms.select { |p| p.name == :watchos }.map(&:deployment_target).min tvos_deployment_target = platforms.select { |p| p.name == :tvos }.map(&:deployment_target).min @project.build_configurations.each do |build_configuration| build_configuration.build_settings['MACOSX_DEPLOYMENT_TARGET'] = osx_deployment_target.to_s if osx_deployment_target build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ios_deployment_target.to_s if ios_deployment_target build_configuration.build_settings['WATCHOS_DEPLOYMENT_TARGET'] = watchos_deployment_target.to_s if watchos_deployment_target build_configuration.build_settings['TVOS_DEPLOYMENT_TARGET'] = tvos_deployment_target.to_s if tvos_deployment_target build_configuration.build_settings['STRIP_INSTALLED_PRODUCT'] = 'NO' build_configuration.build_settings['CLANG_ENABLE_OBJC_ARC'] = 'YES' build_configuration.build_settings['CODE_SIGNING_REQUIRED'] = 'NO' build_configuration.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' end end end