Class: Pod::Installer::Analyzer::TargetInspector
- Inherits:
-
Object
- Object
- Pod::Installer::Analyzer::TargetInspector
- Defined in:
- lib/cocoapods/installer/analyzer/target_inspector.rb
Constant Summary collapse
- PLATFORM_INFO_URL =
'https://guides.cocoapods.org/syntax/podfile.html#platform'.freeze
Instance Attribute Summary collapse
-
#installation_root ⇒ Pathname
readonly
The root of the CocoaPods installation where the Podfile is located.
-
#target_definition ⇒ TargetDefinition
readonly
The target definition to inspect.
Instance Method Summary collapse
-
#compute_archs(user_targets) ⇒ Array<String>
private
Computes the architectures relevant for the user's targets.
-
#compute_build_configurations(user_targets) ⇒ Hash{String=>Symbol}
private
A hash representing the user build configurations where each key corresponds to the name of a configuration and its value to its type (
:debug
or:release
). -
#compute_platform(user_targets) ⇒ Platform
private
The platform of the user's targets.
-
#compute_project_path ⇒ Pathname
Returns the path of the user project that the #target_definition should integrate.
-
#compute_recommends_frameworks(target_definition, native_targets) ⇒ Boolean
private
Checks if any of the targets for the TargetDefinition computed before by #compute_user_project_targets is recommended to be build as a framework due the presence of Swift source code in any of the source build phases.
-
#compute_results(user_project) ⇒ TargetInspectionResult
Inspect the #target_definition.
-
#compute_swift_version_from_targets(targets) ⇒ String
private
Compute the Swift version for the target build configurations.
-
#compute_targets(user_project) ⇒ Array<PBXNativeTarget>
private
Returns a list of the targets from the project of #target_definition that needs to be integrated.
-
#initialize(target_definition, installation_root) ⇒ TargetInspector
constructor
Initialize a new instance.
Constructor Details
#initialize(target_definition, installation_root) ⇒ TargetInspector
Initialize a new instance
26 27 28 29 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 26 def initialize(target_definition, installation_root) @target_definition = target_definition @installation_root = installation_root end |
Instance Attribute Details
#installation_root ⇒ Pathname (readonly)
Returns the root of the CocoaPods installation where the Podfile is located.
16 17 18 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 16 def installation_root @installation_root end |
#target_definition ⇒ TargetDefinition (readonly)
Returns the target definition to inspect.
11 12 13 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 11 def target_definition @target_definition end |
Instance Method Details
#compute_archs(user_targets) ⇒ Array<String> (private)
Computes the architectures relevant for the user's targets.
174 175 176 177 178 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 174 def compute_archs(user_targets) user_targets.flat_map do |target| Array(target.common_resolved_build_setting('ARCHS')) end.compact.uniq.sort end |
#compute_build_configurations(user_targets) ⇒ Hash{String=>Symbol} (private)
Returns A hash representing the user build
configurations where each key corresponds to the name of a
configuration and its value to its type (:debug
or :release
).
120 121 122 123 124 125 126 127 128 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 120 def compute_build_configurations(user_targets) if user_targets user_targets.flat_map { |t| t.build_configurations.map(&:name) }.each_with_object({}) do |name, hash| hash[name] = name == 'Debug' ? :debug : :release end.merge(target_definition.build_configurations || {}) else target_definition.build_configurations || {} end end |
#compute_platform(user_targets) ⇒ Platform (private)
Is assigning the platform to the target definition the best way to go?
This resolves to the lowest deployment target across the user targets.
Returns The platform of the user's targets.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 141 def compute_platform(user_targets) return target_definition.platform if target_definition.platform name = nil deployment_target = nil user_targets.each do |target| name ||= target.platform_name raise Informative, 'Targets with different platforms' unless name == target.platform_name if !deployment_target || deployment_target > Version.new(target.deployment_target) deployment_target = Version.new(target.deployment_target) end end unless name raise Informative, "Unable to determine the platform for the `#{target_definition.name}` target." end UI.warn "Automatically assigning platform `#{Platform.string_name(name)}` with version `#{deployment_target}` " \ "on target `#{target_definition.name}` because no platform was specified. " \ "Please specify a platform for this target in your Podfile. See `#{PLATFORM_INFO_URL}`." target_definition.set_platform(name, deployment_target) Platform.new(name, deployment_target) end |
#compute_project_path ⇒ Pathname
Returns the path of the user project that the #target_definition should integrate.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 62 def compute_project_path if target_definition.user_project_path path = installation_root + target_definition.user_project_path path = "#{path}.xcodeproj" unless File.extname(path) == '.xcodeproj' path = Pathname.new(path) unless path.exist? raise Informative, 'Unable to find the Xcode project ' \ "`#{path}` for the target `#{target_definition.label}`." end else xcodeprojs = installation_root.children.select { |e| e.fnmatch('*.xcodeproj') } if xcodeprojs.size == 1 path = xcodeprojs.first else raise Informative, 'Could not automatically select an Xcode project. ' \ "Specify one in your Podfile like so:\n\n" \ " project 'path/to/Project.xcodeproj'\n" end end path end |
#compute_recommends_frameworks(target_definition, native_targets) ⇒ Boolean (private)
Checks if any of the targets for the TargetDefinition computed before by #compute_user_project_targets is recommended to be build as a framework due the presence of Swift source code in any of the source build phases.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 193 def compute_recommends_frameworks(target_definition, native_targets) file_predicate = nil file_predicate = proc do |file_ref| if file_ref.respond_to?(:last_known_file_type) file_ref.last_known_file_type == 'sourcecode.swift' elsif file_ref.respond_to?(:files) file_ref.files.any?(&file_predicate) else false end end target_definition.platform.supports_dynamic_frameworks? || native_targets.any? do |target| target.source_build_phase.files.any? do |build_file| file_predicate.call(build_file.file_ref) end end end |
#compute_results(user_project) ⇒ TargetInspectionResult
Inspect the #target_definition
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 37 def compute_results(user_project) raise ArgumentError, 'Cannot compute results without a user project set' unless user_project targets = compute_targets(user_project) project_target_uuids = targets.map(&:uuid) build_configurations = compute_build_configurations(targets) platform = compute_platform(targets) archs = compute_archs(targets) swift_version = compute_swift_version_from_targets(targets) result = TargetInspectionResult.new(target_definition, user_project, project_target_uuids, build_configurations, platform, archs) result.target_definition.swift_version = swift_version result end |
#compute_swift_version_from_targets(targets) ⇒ String (private)
Compute the Swift version for the target build configurations. If more than one Swift version is defined for a given target, then it will raise.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 219 def compute_swift_version_from_targets(targets) versions_to_targets = targets.inject({}) do |memo, target| # User project may have an xcconfig that specifies the `SWIFT_VERSION`. # Xcodeproj handles that xcconfig either not being set or the file not being present on disk. # After the first integration the xcconfig set is most probably # the one that was generated from CocoaPods. See https://github.com/CocoaPods/CocoaPods/issues/7731 for # more details. versions = target.resolved_build_setting('SWIFT_VERSION', true).values versions.each do |version| memo[version] = [] if memo[version].nil? memo[version] << target.name unless memo[version].include? target.name end memo end case versions_to_targets.count when 0 nil when 1 versions_to_targets.keys.first else target_version_pairs = versions_to_targets.map do |version_names, target_names| target_names.map { |target_name| [target_name, version_names] } end sorted_pairs = target_version_pairs.flat_map { |i| i }.sort_by do |target_name, version_name| "#{target_name} #{version_name}" end formatted_output = sorted_pairs.map do |target, version_name| "#{target}: Swift #{version_name}" end.join("\n") raise Informative, "There may only be up to 1 unique SWIFT_VERSION per target. Found target(s) with multiple Swift versions:\n#{formatted_output}" end end |
#compute_targets(user_project) ⇒ Array<PBXNativeTarget> (private)
The method first looks if there is a target specified with
the link_with
option of the TargetDefinition. Otherwise
it looks for the target that has the same name of the target
definition. Finally if no target was found the first
encountered target is returned (it is assumed to be the one
to integrate in simple projects).
Returns a list of the targets from the project of #target_definition that needs to be integrated.
103 104 105 106 107 108 109 110 111 |
# File 'lib/cocoapods/installer/analyzer/target_inspector.rb', line 103 def compute_targets(user_project) native_targets = user_project.native_targets target = native_targets.find { |t| t.name == target_definition.name.to_s } unless target found = native_targets.map { |t| "`#{t.name}`" }.to_sentence raise Informative, "Unable to find a target named `#{target_definition.name}` in project `#{Pathname(user_project.path).basename}`, did find #{found}." end [target] end |