Class: Pod::Resolver
- Inherits:
-
Object
- Object
- Pod::Resolver
- Includes:
- Molinillo::SpecificationProvider, Molinillo::UI
- Defined in:
- lib/cocoapods/resolver.rb
Overview
The resolver is responsible of generating a list of specifications grouped by target for a given Podfile.
Instance Attribute Summary collapse
-
#locked_dependencies ⇒ Array<Dependency>
readonly
The list of dependencies locked to a specific version.
-
#podfile ⇒ Podfile
readonly
The Podfile used by the resolver.
-
#sandbox ⇒ Sandbox
readonly
The Sandbox used by the resolver to find external dependencies.
-
#sources ⇒ Array<Source>
The list of the sources which will be used for the resolution.
Resolution collapse
-
#after_resolution ⇒ Void
Called after resolution ends.
-
#before_resolution ⇒ Void
Called before resolution starts.
-
#dependencies_for(specification) ⇒ Array<Specification>
Returns the dependencies of ‘specification`.
-
#indicate_progress ⇒ Void
Called during resolution to indicate progress.
-
#name_for(dependency) ⇒ String
Returns the name for the given ‘dependency`.
-
#name_for_explicit_dependency_source ⇒ String
The user-facing name for a Podfile.
-
#name_for_locking_dependency_source ⇒ String
The user-facing name for a Lockfile.
-
#output ⇒ UserInterface
The UI object the resolver should use for displaying user-facing output.
-
#requirement_satisfied_by?(requirement, activated, spec) ⇒ Boolean
Determines whether the given ‘requirement` is satisfied by the given `spec`, in the context of the current `activated` dependency graph.
-
#resolve ⇒ Hash{TargetDefinition => Array<Specification>}
Identifies the specifications that should be installed.
-
#search_for(dependency) ⇒ Array<Specification>
Returns (and caches) the specification that satisfy the given dependency.
-
#sort_dependencies(dependencies, activated, conflicts) ⇒ Array<Dependency>
Sort dependencies so that the ones that are easiest to resolve are first.
-
#specs_by_target ⇒ Hash{Podfile::TargetDefinition => Array<Specification>}
Returns the resolved specifications grouped by target.
Instance Method Summary collapse
-
#initialize(sandbox, podfile, locked_dependencies, sources) ⇒ Resolver
constructor
Init a new Resolver.
Constructor Details
#initialize(sandbox, podfile, locked_dependencies, sources) ⇒ Resolver
Init a new Resolver
35 36 37 38 39 40 41 |
# File 'lib/cocoapods/resolver.rb', line 35 def initialize(sandbox, podfile, locked_dependencies, sources) @sandbox = sandbox @podfile = podfile @locked_dependencies = locked_dependencies @sources = Array(sources) @platforms_by_dependency = Hash.new { |h, k| h[k] = [] } end |
Instance Attribute Details
#locked_dependencies ⇒ Array<Dependency> (readonly)
Returns the list of dependencies locked to a specific version.
21 22 23 |
# File 'lib/cocoapods/resolver.rb', line 21 def locked_dependencies @locked_dependencies end |
#podfile ⇒ Podfile (readonly)
Returns the Podfile used by the resolver.
16 17 18 |
# File 'lib/cocoapods/resolver.rb', line 16 def podfile @podfile end |
#sandbox ⇒ Sandbox (readonly)
Returns the Sandbox used by the resolver to find external dependencies.
12 13 14 |
# File 'lib/cocoapods/resolver.rb', line 12 def sandbox @sandbox end |
#sources ⇒ Array<Source>
Returns The list of the sources which will be used for the resolution.
26 27 28 |
# File 'lib/cocoapods/resolver.rb', line 26 def sources @sources end |
Instance Method Details
#after_resolution ⇒ Void
Called after resolution ends.
Completely silence this, as we show nothing.
251 252 |
# File 'lib/cocoapods/resolver.rb', line 251 def after_resolution end |
#before_resolution ⇒ Void
Called before resolution starts.
Completely silence this, as we show nothing.
242 243 |
# File 'lib/cocoapods/resolver.rb', line 242 def before_resolution end |
#dependencies_for(specification) ⇒ Array<Specification>
Returns the dependencies of ‘specification`.
129 130 131 132 133 134 135 136 137 |
# File 'lib/cocoapods/resolver.rb', line 129 def dependencies_for(specification) specification.all_dependencies.map do |dependency| if dependency.root_name == Specification.root_name(specification.name) dependency.dup.tap { |d| d.specific_version = specification.version } else dependency end end end |
#indicate_progress ⇒ Void
Called during resolution to indicate progress.
Completely silence this, as we show nothing.
260 261 |
# File 'lib/cocoapods/resolver.rb', line 260 def indicate_progress end |
#name_for(dependency) ⇒ String
Returns the name for the given ‘dependency`.
146 147 148 |
# File 'lib/cocoapods/resolver.rb', line 146 def name_for(dependency) dependency.name end |
#name_for_explicit_dependency_source ⇒ String
Returns the user-facing name for a Podfile.
152 153 154 |
# File 'lib/cocoapods/resolver.rb', line 152 def name_for_explicit_dependency_source 'Podfile' end |
#name_for_locking_dependency_source ⇒ String
Returns the user-facing name for a Lockfile.
158 159 160 |
# File 'lib/cocoapods/resolver.rb', line 158 def name_for_locking_dependency_source 'Podfile.lock' end |
#output ⇒ UserInterface
The UI object the resolver should use for displaying user-facing output.
232 233 234 |
# File 'lib/cocoapods/resolver.rb', line 232 def output UI end |
#requirement_satisfied_by?(requirement, activated, spec) ⇒ Boolean
Determines whether the given ‘requirement` is satisfied by the given `spec`, in the context of the current `activated` dependency graph.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/cocoapods/resolver.rb', line 175 def requirement_satisfied_by?(requirement, activated, spec) existing_vertices = activated.vertices.values.select do |v| Specification.root_name(v.name) == requirement.root_name end existing = existing_vertices.map(&:payload).compact.first requirement_satisfied = if existing existing.version == spec.version && requirement.requirement.satisfied_by?(spec.version) else requirement.requirement.satisfied_by? spec.version end requirement_satisfied && !( spec.version.prerelease? && existing_vertices.flat_map(&:requirements).none? { |r| r.prerelease? || r.external_source || r.head? } ) && spec_is_platform_compatible?(activated, requirement, spec) end |
#resolve ⇒ Hash{TargetDefinition => Array<Specification>}
Identifies the specifications that should be installed.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/cocoapods/resolver.rb', line 55 def resolve dependencies = podfile.target_definition_list.flat_map do |target| target.dependencies.each do |dep| @platforms_by_dependency[dep].push(target.platform).uniq! end end @cached_sets = {} @activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies) specs_by_target.tap do |specs_by_target| specs_by_target.values.flatten.each do |spec| sandbox.store_head_pod(spec.name) if spec.version.head? end end rescue Molinillo::ResolverError => e handle_resolver_error(e) end |
#search_for(dependency) ⇒ Array<Specification>
Returns (and caches) the specification that satisfy the given dependency.
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/cocoapods/resolver.rb', line 108 def search_for(dependency) @search ||= {} @search[dependency] ||= begin requirement = Requirement.new(dependency.requirement.as_list << requirement_for_locked_pod_named(dependency.name)) find_cached_set(dependency). all_specifications. select { |s| requirement.satisfied_by? s.version }. map { |s| s.subspec_by_name(dependency.name, false) }. compact. reverse end @search[dependency].dup end |
#sort_dependencies(dependencies, activated, conflicts) ⇒ Array<Dependency>
Sort dependencies so that the ones that are easiest to resolve are first. Easiest to resolve is (usually) defined by:
1) Is this dependency already activated?
2) How relaxed are the requirements?
3) Are there any conflicts for this dependency?
4) How many possibilities are there to satisfy this dependency?
208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/cocoapods/resolver.rb', line 208 def sort_dependencies(dependencies, activated, conflicts) dependencies.sort_by do |dependency| name = name_for(dependency) [ activated.vertex_named(name).payload ? 0 : 1, dependency.prerelease? ? 0 : 1, conflicts[name] ? 0 : 1, search_for(dependency).count, ] end end |
#specs_by_target ⇒ Hash{Podfile::TargetDefinition => Array<Specification>}
The returned specifications can be subspecs.
Returns the resolved specifications grouped by target.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/cocoapods/resolver.rb', line 77 def specs_by_target @specs_by_target ||= {}.tap do |specs_by_target| podfile.target_definition_list.each do |target| specs = target.dependencies.map(&:name).flat_map do |name| node = @activated.vertex_named(name) valid_dependencies_for_target_from_node(target, node) << node end specs_by_target[target] = specs. map(&:payload). uniq. sort_by(&:name) end end end |