Class: Pod::Installer::Xcode::TargetValidator
- Inherits:
-
Object
- Object
- Pod::Installer::Xcode::TargetValidator
- Defined in:
- lib/cocoapods/installer/xcode/target_validator.rb
Overview
The TargetValidator ensures that the pod and aggregate target configuration is valid for installation.
Instance Attribute Summary collapse
-
#aggregate_targets ⇒ Array<AggregateTarget>
readonly
The aggregate targets that should be validated.
-
#installation_options ⇒ InstallationOptions
readonly
The installation options used during this installation.
-
#pod_targets ⇒ Array<PodTarget>
readonly
The pod targets that should be validated.
Instance Method Summary collapse
-
#initialize(aggregate_targets, pod_targets, installation_options) ⇒ TargetValidator
constructor
Create a new TargetValidator with aggregate and pod targets to validate.
-
#validate! ⇒ Object
Perform the validation steps for the provided aggregate and pod targets.
- #verify_no_duplicate_framework_and_library_names ⇒ Object private
- #verify_no_duplicate_names(names, label, type) ⇒ Object private
- #verify_no_multiple_project_names ⇒ Object private
- #verify_no_static_framework_transitive_dependencies ⇒ Object private
- #verify_swift_pods_have_module_dependencies ⇒ Object private
- #verify_swift_pods_swift_version ⇒ Object private
Constructor Details
#initialize(aggregate_targets, pod_targets, installation_options) ⇒ TargetValidator
Create a new TargetValidator with aggregate and pod targets to validate.
27 28 29 30 31 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 27 def initialize(aggregate_targets, pod_targets, ) @aggregate_targets = aggregate_targets @pod_targets = pod_targets @installation_options = end |
Instance Attribute Details
#aggregate_targets ⇒ Array<AggregateTarget> (readonly)
Returns The aggregate targets that should be validated.
10 11 12 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 10 def aggregate_targets @aggregate_targets end |
#installation_options ⇒ InstallationOptions (readonly)
Returns The installation options used during this installation.
18 19 20 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 18 def @installation_options end |
#pod_targets ⇒ Array<PodTarget> (readonly)
Returns The pod targets that should be validated.
14 15 16 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 14 def pod_targets @pod_targets end |
Instance Method Details
#validate! ⇒ Object
Perform the validation steps for the provided aggregate and pod targets.
36 37 38 39 40 41 42 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 36 def validate! verify_no_duplicate_framework_and_library_names verify_no_static_framework_transitive_dependencies verify_swift_pods_swift_version verify_swift_pods_have_module_dependencies verify_no_multiple_project_names if .generate_multiple_pod_projects? end |
#verify_no_duplicate_framework_and_library_names ⇒ Object (private)
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 46 def verify_no_duplicate_framework_and_library_names aggregate_targets.each do |aggregate_target| aggregate_target.user_build_configurations.each_key do |config| pod_targets = aggregate_target.pod_targets_for_build_configuration(config) file_accessors = pod_targets.flat_map(&:file_accessors).select { |fa| fa.spec.library_specification? } frameworks = file_accessors.flat_map(&:vendored_frameworks).uniq.map(&:basename) frameworks += pod_targets.select { |pt| pt.should_build? && pt.build_as_framework? }.map(&:product_module_name).uniq verify_no_duplicate_names(frameworks, aggregate_target.label, 'frameworks') libraries = file_accessors.flat_map(&:vendored_libraries).uniq.map(&:basename) libraries += pod_targets.select { |pt| pt.should_build? && pt.build_as_library? }.map(&:product_name) verify_no_duplicate_names(libraries, aggregate_target.label, 'libraries') end end end |
#verify_no_duplicate_names(names, label, type) ⇒ Object (private)
63 64 65 66 67 68 69 70 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 63 def verify_no_duplicate_names(names, label, type) duplicates = names.group_by { |n| n.to_s.downcase }.select { |_, v| v.size > 1 }.keys unless duplicates.empty? raise Informative, "The '#{label}' target has " \ "#{type} with conflicting names: #{duplicates.to_sentence}." end end |
#verify_no_multiple_project_names ⇒ Object (private)
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 155 def verify_no_multiple_project_names = pod_targets.map do |pod_target| project_names = pod_target.target_definitions.map { |td| td.project_name_for_pod(pod_target.pod_name) }.compact.uniq next unless project_names.count > 1 "- `#{pod_target.name}` specifies multiple project names (#{project_names.map { |pn| "`#{pn}`" }.to_sentence}) " \ "in different targets (#{pod_target.target_definitions.map { |td| "`#{td.name}`" }.to_sentence})." end.compact return if .empty? raise Informative, 'The following pods cannot be integrated:' \ "\n\n#{.join("\n\n")}" end |
#verify_no_static_framework_transitive_dependencies ⇒ Object (private)
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 72 def verify_no_static_framework_transitive_dependencies aggregate_targets.each do |aggregate_target| aggregate_target.user_build_configurations.each_key do |config| pod_targets = aggregate_target.pod_targets_for_build_configuration(config) built_targets, unbuilt_targets = pod_targets.partition(&:should_build?) dynamic_pod_targets = built_targets.select(&:build_as_dynamic?) dependencies = dynamic_pod_targets.flat_map(&:dependent_targets).uniq depended_upon_targets = unbuilt_targets & dependencies static_libs = depended_upon_targets.flat_map(&:file_accessors).flat_map(&:vendored_static_artifacts) unless static_libs.empty? raise Informative, "The '#{aggregate_target.label}' target has " \ "transitive dependencies that include statically linked binaries: (#{static_libs.to_sentence})" end static_deps = dynamic_pod_targets.flat_map(&:recursive_dependent_targets).uniq.select(&:build_as_static?) unless static_deps.empty? raise Informative, "The '#{aggregate_target.label}' target has " \ "transitive dependencies that include statically linked binaries: (#{static_deps.flat_map(&:name).to_sentence})" end end end end |
#verify_swift_pods_have_module_dependencies ⇒ Object (private)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 129 def verify_swift_pods_have_module_dependencies = [] pod_targets.each do |pod_target| next unless pod_target.uses_swift? && pod_target.should_build? non_module_dependencies = [] pod_target.dependent_targets.each do |dependent_target| next if !dependent_target.should_build? || dependent_target.defines_module? non_module_dependencies << dependent_target.name end next if non_module_dependencies.empty? << "The Swift pod `#{pod_target.name}` depends upon #{non_module_dependencies.map { |d| "`#{d}`" }.to_sentence}, " \ "which #{non_module_dependencies.count == 1 ? 'does' : 'do'} not define modules. " \ 'To opt into those targets generating module maps '\ '(which is necessary to import them from Swift when building as static libraries), ' \ 'you may set `use_modular_headers!` globally in your Podfile, '\ 'or specify `:modular_headers => true` for particular dependencies.' end return if .empty? raise Informative, 'The following Swift pods cannot yet be integrated '\ "as static libraries:\n\n#{.join("\n\n")}" end |
#verify_swift_pods_swift_version ⇒ Object (private)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/cocoapods/installer/xcode/target_validator.rb', line 97 def verify_swift_pods_swift_version = lambda do |target_definition| "`#{target_definition.name}` (Swift #{target_definition.swift_version})" end swift_pod_targets = pod_targets.select(&:uses_swift?) = swift_pod_targets.map do |swift_pod_target| # Legacy targets that do not specify Swift versions derive their Swift version from the target definitions # they are integrated with. An error is displayed if the target definition Swift versions collide or none # of target definitions specify the `SWIFT_VERSION` attribute. if swift_pod_target.spec_swift_versions.empty? swift_target_definitions = swift_pod_target.target_definitions.reject { |target| target.swift_version.blank? } next if swift_target_definitions.uniq(&:swift_version).count == 1 if swift_target_definitions.empty? "- `#{swift_pod_target.name}` does not specify a Swift version and none of the targets " \ "(#{swift_pod_target.target_definitions.map { |td| "`#{td.name}`" }.to_sentence}) integrating it have the " \ '`SWIFT_VERSION` attribute set. Please contact the author or set the `SWIFT_VERSION` attribute in at ' \ 'least one of the targets that integrate this pod.' else target_errors = swift_target_definitions.map(&).to_sentence "- `#{swift_pod_target.name}` is integrated by multiple targets that use a different Swift version: #{target_errors}." end elsif !swift_pod_target.swift_version.nil? && swift_pod_target.swift_version.empty? "- `#{swift_pod_target.name}` does not specify a Swift version (#{swift_pod_target.spec_swift_versions.map { |v| "`#{v}`" }.to_sentence}) " \ "that is satisfied by any of targets (#{swift_pod_target.target_definitions.map { |td| "`#{td.name}`" }.to_sentence}) integrating it." end end.compact unless .empty? raise Informative, "Unable to determine Swift version for the following pods:\n\n#{.join("\n")}" end end |