cocoapods 0.34.4 → 0.35.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +108 -1
- data/bin/pod +20 -2
- data/lib/cocoapods.rb +1 -0
- data/lib/cocoapods/command.rb +17 -11
- data/lib/cocoapods/command/repo/push.rb +1 -1
- data/lib/cocoapods/command/search.rb +1 -0
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/acknowledgements/plist.rb +4 -10
- data/lib/cocoapods/generator/header.rb +75 -0
- data/lib/cocoapods/generator/prefix_header.rb +15 -34
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +2 -2
- data/lib/cocoapods/generator/xcconfig/private_pod_xcconfig.rb +4 -1
- data/lib/cocoapods/hooks/library_representation.rb +1 -1
- data/lib/cocoapods/installer.rb +3 -3
- data/lib/cocoapods/installer/analyzer.rb +35 -37
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +72 -0
- data/lib/cocoapods/installer/file_references_installer.rb +10 -9
- data/lib/cocoapods/installer/target_installer.rb +21 -21
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +17 -17
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +19 -19
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +7 -3
- data/lib/cocoapods/project.rb +1 -1
- data/lib/cocoapods/resolver.rb +235 -98
- data/lib/cocoapods/resolver/lazy_specification.rb +60 -0
- data/lib/cocoapods/sandbox.rb +2 -1
- data/lib/cocoapods/sandbox/file_accessor.rb +26 -19
- data/lib/cocoapods/sandbox/headers_store.rb +12 -7
- data/lib/cocoapods/sources_manager.rb +6 -6
- data/lib/cocoapods/target.rb +1 -1
- data/lib/cocoapods/target/pod_target.rb +2 -2
- data/lib/cocoapods/user_interface.rb +1 -1
- data/lib/cocoapods/user_interface/error_report.rb +3 -0
- data/lib/cocoapods/validator.rb +2 -2
- metadata +21 -26
- data/lib/cocoapods/command/push.rb +0 -21
@@ -9,7 +9,7 @@ module Pod
|
|
9
9
|
# @return [void]
|
10
10
|
#
|
11
11
|
def install!
|
12
|
-
UI.message "- Installing target `#{
|
12
|
+
UI.message "- Installing target `#{target.name}` #{target.platform}" do
|
13
13
|
add_target
|
14
14
|
create_support_files_dir
|
15
15
|
add_files_to_build_phases
|
@@ -33,15 +33,15 @@ module Pod
|
|
33
33
|
# @return [void]
|
34
34
|
#
|
35
35
|
def add_files_to_build_phases
|
36
|
-
|
36
|
+
target.file_accessors.each do |file_accessor|
|
37
37
|
consumer = file_accessor.spec_consumer
|
38
38
|
flags = compiler_flags_for_consumer(consumer)
|
39
39
|
all_source_files = file_accessor.source_files
|
40
40
|
regular_source_files = all_source_files.reject { |sf| sf.extname == '.d' }
|
41
41
|
regular_file_refs = regular_source_files.map { |sf| project.reference_for_path(sf) }
|
42
|
-
|
42
|
+
native_target.add_file_references(regular_file_refs, flags)
|
43
43
|
other_file_refs = (all_source_files - regular_source_files).map { |sf| project.reference_for_path(sf) }
|
44
|
-
|
44
|
+
native_target.add_file_references(other_file_refs, nil)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -53,22 +53,22 @@ module Pod
|
|
53
53
|
# @return [void]
|
54
54
|
#
|
55
55
|
def add_resources_bundle_targets
|
56
|
-
|
56
|
+
target.file_accessors.each do |file_accessor|
|
57
57
|
file_accessor.resource_bundles.each do |bundle_name, paths|
|
58
58
|
# Add a dependency on an existing Resource Bundle target if possible
|
59
59
|
if bundle_target = project.targets.find { |target| target.name == bundle_name }
|
60
|
-
|
60
|
+
native_target.add_dependency(bundle_target)
|
61
61
|
next
|
62
62
|
end
|
63
63
|
file_references = paths.map { |sf| project.reference_for_path(sf) }
|
64
64
|
bundle_target = project.new_resources_bundle(bundle_name, file_accessor.spec_consumer.platform_name)
|
65
65
|
bundle_target.add_resources(file_references)
|
66
66
|
|
67
|
-
|
67
|
+
target.user_build_configurations.each do |bc_name, type|
|
68
68
|
bundle_target.add_build_configuration(bc_name, type)
|
69
69
|
end
|
70
70
|
|
71
|
-
|
71
|
+
native_target.add_dependency(bundle_target)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -78,17 +78,17 @@ module Pod
|
|
78
78
|
# @return [void]
|
79
79
|
#
|
80
80
|
def create_xcconfig_file
|
81
|
-
path =
|
82
|
-
public_gen = Generator::XCConfig::PublicPodXCConfig.new(
|
81
|
+
path = target.xcconfig_path
|
82
|
+
public_gen = Generator::XCConfig::PublicPodXCConfig.new(target)
|
83
83
|
public_gen.save_as(path)
|
84
84
|
add_file_to_support_group(path)
|
85
85
|
|
86
|
-
path =
|
87
|
-
private_gen = Generator::XCConfig::PrivatePodXCConfig.new(
|
86
|
+
path = target.xcconfig_private_path
|
87
|
+
private_gen = Generator::XCConfig::PrivatePodXCConfig.new(target, public_gen.xcconfig)
|
88
88
|
private_gen.save_as(path)
|
89
89
|
xcconfig_file_ref = add_file_to_support_group(path)
|
90
90
|
|
91
|
-
|
91
|
+
native_target.build_configurations.each do |c|
|
92
92
|
c.base_configuration_reference = xcconfig_file_ref
|
93
93
|
end
|
94
94
|
end
|
@@ -100,13 +100,13 @@ module Pod
|
|
100
100
|
# @return [void]
|
101
101
|
#
|
102
102
|
def create_prefix_header
|
103
|
-
path =
|
104
|
-
generator = Generator::PrefixHeader.new(
|
105
|
-
generator.imports <<
|
103
|
+
path = target.prefix_header_path
|
104
|
+
generator = Generator::PrefixHeader.new(target.file_accessors, target.platform)
|
105
|
+
generator.imports << target.target_environment_header_path.basename
|
106
106
|
generator.save_as(path)
|
107
107
|
add_file_to_support_group(path)
|
108
108
|
|
109
|
-
|
109
|
+
native_target.build_configurations.each do |c|
|
110
110
|
relative_path = path.relative_path_from(project.path.dirname)
|
111
111
|
c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
|
112
112
|
end
|
@@ -176,8 +176,8 @@ module Pod
|
|
176
176
|
# @return [PBXFileReference] the file reference of the added file.
|
177
177
|
#
|
178
178
|
def add_file_to_support_group(path)
|
179
|
-
pod_name =
|
180
|
-
dir =
|
179
|
+
pod_name = target.pod_name
|
180
|
+
dir = target.support_files_dir
|
181
181
|
group = project.pod_support_files_group(pod_name, dir)
|
182
182
|
group.new_file(path)
|
183
183
|
end
|
data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb
CHANGED
@@ -83,22 +83,26 @@ module Pod
|
|
83
83
|
# @param [Xcodeproj::XCBuildConfiguration] config
|
84
84
|
# The build configuration.
|
85
85
|
#
|
86
|
+
# @return [Boolean] Indicates whether or not any changes were made.
|
87
|
+
#
|
86
88
|
def self.set_target_xcconfig(pod_bundle, target, config)
|
87
89
|
path = pod_bundle.xcconfig_relative_path(config.name)
|
88
90
|
group = config.project['Pods'] || config.project.new_group('Pods')
|
89
91
|
file_ref = group.files.find { |f| f.path == path }
|
90
|
-
if config.base_configuration_reference
|
92
|
+
if config.base_configuration_reference &&
|
93
|
+
config.base_configuration_reference != file_ref
|
91
94
|
UI.warn 'CocoaPods did not set the base configuration of your ' \
|
92
95
|
'project because your project already has a custom ' \
|
93
96
|
'config set. In order for CocoaPods integration to work at ' \
|
94
97
|
'all, please either set the base configurations of the target ' \
|
95
98
|
"`#{target.name}` to `#{path}` or include the `#{path}` in your " \
|
96
99
|
'build configuration.'
|
97
|
-
|
98
|
-
elsif !file_ref
|
100
|
+
elsif config.base_configuration_reference.nil? || file_ref.nil?
|
99
101
|
file_ref ||= group.new_file(path)
|
100
102
|
config.base_configuration_reference = file_ref
|
103
|
+
return true
|
101
104
|
end
|
105
|
+
false
|
102
106
|
end
|
103
107
|
|
104
108
|
private
|
data/lib/cocoapods/project.rb
CHANGED
@@ -209,7 +209,7 @@ module Pod
|
|
209
209
|
#
|
210
210
|
def add_build_configuration(name, type)
|
211
211
|
build_configuration = super
|
212
|
-
values = ["#{name.gsub(/[^a-zA-Z0-9_]/, '_').upcase}=1"]
|
212
|
+
values = ["#{name.gsub(/[^a-zA-Z0-9_]/, '_').sub(/(^[0-9])/, '_\1').upcase}=1"]
|
213
213
|
settings = build_configuration.build_settings
|
214
214
|
definitions = Array(settings['GCC_PREPROCESSOR_DEFINITIONS'])
|
215
215
|
values.each do |value|
|
data/lib/cocoapods/resolver.rb
CHANGED
@@ -1,18 +1,10 @@
|
|
1
|
+
require 'molinillo'
|
2
|
+
require 'cocoapods/resolver/lazy_specification'
|
3
|
+
|
1
4
|
module Pod
|
2
5
|
# The resolver is responsible of generating a list of specifications grouped
|
3
6
|
# by target for a given Podfile.
|
4
7
|
#
|
5
|
-
# @todo Its current implementation is naive, in the sense that it can't do full
|
6
|
-
# automatic resolves like Bundler:
|
7
|
-
# [how-does-bundler-bundle](http://patshaughnessy.net/2011/9/24/how-does-bundler-bundle)
|
8
|
-
#
|
9
|
-
# @todo Another limitation is that the order of the dependencies matter. The
|
10
|
-
# current implementation could create issues, for example, if a
|
11
|
-
# specification is loaded for a target definition and later for another
|
12
|
-
# target is set in head mode. The first specification will not be in head
|
13
|
-
# mode.
|
14
|
-
#
|
15
|
-
#
|
16
8
|
class Resolver
|
17
9
|
# @return [Sandbox] the Sandbox used by the resolver to find external
|
18
10
|
# dependencies.
|
@@ -58,23 +50,12 @@ module Pod
|
|
58
50
|
# definition.
|
59
51
|
#
|
60
52
|
def resolve
|
61
|
-
|
62
|
-
@
|
63
|
-
@
|
64
|
-
|
65
|
-
target_definitions = podfile.target_definition_list
|
66
|
-
target_definitions.each do |target|
|
67
|
-
title = "Resolving dependencies for target `#{target.name}' " \
|
68
|
-
"(#{target.platform})"
|
69
|
-
UI.section(title) do
|
70
|
-
@loaded_specs = []
|
71
|
-
find_dependency_specs(podfile, target.dependencies, target)
|
72
|
-
specs = cached_specs.values_at(*@loaded_specs).sort_by(&:name)
|
73
|
-
specs_by_target[target] = specs
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
53
|
+
dependencies = @podfile.target_definition_list.map(&:dependencies).flatten
|
54
|
+
@cached_sets = {}
|
55
|
+
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
|
77
56
|
specs_by_target
|
57
|
+
rescue Molinillo::ResolverError => e
|
58
|
+
raise Informative, e.message
|
78
59
|
end
|
79
60
|
|
80
61
|
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}]
|
@@ -82,113 +63,237 @@ module Pod
|
|
82
63
|
#
|
83
64
|
# @note The returned specifications can be subspecs.
|
84
65
|
#
|
85
|
-
|
66
|
+
def specs_by_target
|
67
|
+
@specs_by_target ||= begin
|
68
|
+
specs_by_target = {}
|
69
|
+
podfile.target_definition_list.each do |target|
|
70
|
+
specs = target.dependencies.map(&:name).map do |name|
|
71
|
+
node = @activated.vertex_named(name)
|
72
|
+
valid_dependencies_for_target_from_node(target, node) << node
|
73
|
+
end
|
74
|
+
|
75
|
+
specs_by_target[target] = specs.
|
76
|
+
flatten.
|
77
|
+
map(&:payload).
|
78
|
+
uniq.
|
79
|
+
sort_by(&:name).
|
80
|
+
each do |spec|
|
81
|
+
validate_platform(spec, target)
|
82
|
+
sandbox.store_head_pod(spec.name) if spec.version.head
|
83
|
+
end
|
84
|
+
end
|
85
|
+
specs_by_target
|
86
|
+
end
|
87
|
+
end
|
86
88
|
|
87
89
|
#-------------------------------------------------------------------------#
|
88
90
|
|
89
|
-
|
91
|
+
public
|
90
92
|
|
91
|
-
#
|
93
|
+
# @!group Specification Provider
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
+
include Molinillo::SpecificationProvider
|
96
|
+
|
97
|
+
# Returns (and caches) the specification that satisfy the given dependency.
|
95
98
|
#
|
96
|
-
# @
|
97
|
-
#
|
98
|
-
# globally and not per target definition because there can be just
|
99
|
-
# one Pod installation, so different version of the same Pods for
|
100
|
-
# target definitions are not allowed.
|
99
|
+
# @return [Array<Specification>] the specifications that satisfy the given
|
100
|
+
# `dependency`.
|
101
101
|
#
|
102
|
-
|
102
|
+
# @param [Dependency] dependency the dependency that is being searched for.
|
103
|
+
#
|
104
|
+
def search_for(dependency)
|
105
|
+
@search ||= {}
|
106
|
+
@search[dependency] ||= begin
|
107
|
+
specs = find_cached_set(dependency).
|
108
|
+
all_specifications.
|
109
|
+
select { |s| dependency.requirement.satisfied_by? s.version }.
|
110
|
+
map { |s| s.subspec_by_name(dependency.name, false) }.
|
111
|
+
compact
|
112
|
+
|
113
|
+
specs.
|
114
|
+
reverse.
|
115
|
+
each { |s| s.version.head = dependency.head? }
|
116
|
+
end
|
117
|
+
@search[dependency].dup
|
118
|
+
end
|
103
119
|
|
104
|
-
#
|
105
|
-
# by name.
|
120
|
+
# Returns the dependencies of `specification`.
|
106
121
|
#
|
107
|
-
|
122
|
+
# @return [Array<Specification>] all dependencies of `specification`.
|
123
|
+
#
|
124
|
+
# @param [Specification] specification the specification whose own
|
125
|
+
# dependencies are being asked for.
|
126
|
+
#
|
127
|
+
def dependencies_for(specification)
|
128
|
+
specification.all_dependencies.map do |dependency|
|
129
|
+
if dependency.root_name == Specification.root_name(specification.name)
|
130
|
+
dependency.dup.tap { |d| d.specific_version = specification.version }
|
131
|
+
else
|
132
|
+
dependency
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
108
136
|
|
109
|
-
|
137
|
+
# Returns the name for the given `dependency`.
|
138
|
+
#
|
139
|
+
# @return [String] the name for the given `dependency`.
|
140
|
+
#
|
141
|
+
# @param [Dependency] dependency the dependency whose name is being
|
142
|
+
# queried.
|
143
|
+
#
|
144
|
+
def name_for(dependency)
|
145
|
+
dependency.name
|
146
|
+
end
|
110
147
|
|
111
|
-
|
148
|
+
# @return [String] the user-facing name for a {Podfile}.
|
149
|
+
#
|
150
|
+
def name_for_explicit_dependency_source
|
151
|
+
'Podfile'
|
152
|
+
end
|
112
153
|
|
113
|
-
#
|
154
|
+
# @return [String] the user-facing name for a {Lockfile}.
|
155
|
+
#
|
156
|
+
def name_for_locking_dependency_source
|
157
|
+
'Podfile.lock'
|
158
|
+
end
|
114
159
|
|
115
|
-
#
|
116
|
-
# in the
|
160
|
+
# Determines whether the given `requirement` is satisfied by the given
|
161
|
+
# `spec`, in the context of the current `activated` dependency graph.
|
162
|
+
#
|
163
|
+
# @return [Boolean] whether `requirement` is satisfied by `spec` in the
|
164
|
+
# context of the current `activated` dependency graph.
|
117
165
|
#
|
118
|
-
# @param [
|
119
|
-
# the specification whose dependencies are being resolved. Used
|
120
|
-
# only for UI purposes.
|
166
|
+
# @param [Dependency] requirement the dependency in question.
|
121
167
|
#
|
122
|
-
# @param [
|
123
|
-
#
|
168
|
+
# @param [Molinillo::DependencyGraph] activated the current dependency
|
169
|
+
# graph in the resolution process.
|
124
170
|
#
|
125
|
-
# @param [
|
126
|
-
#
|
171
|
+
# @param [Specification] spec the specification in question.
|
172
|
+
#
|
173
|
+
def requirement_satisfied_by?(requirement, activated, spec)
|
174
|
+
existing_vertices = activated.vertices.values.select do |v|
|
175
|
+
Specification.root_name(v.name) == requirement.root_name
|
176
|
+
end
|
177
|
+
existing = existing_vertices.map(&:payload).compact.first
|
178
|
+
requirement_satisfied =
|
179
|
+
if existing
|
180
|
+
existing.version == spec.version && requirement.requirement.satisfied_by?(spec.version)
|
181
|
+
else
|
182
|
+
requirement.requirement.satisfied_by? spec.version
|
183
|
+
end
|
184
|
+
requirement_satisfied && !(spec.version.prerelease? && existing_vertices.flat_map(&:requirements).none?(&:prerelease?))
|
185
|
+
end
|
186
|
+
|
187
|
+
# Sort dependencies so that the ones that are easiest to resolve are first.
|
188
|
+
# Easiest to resolve is (usually) defined by:
|
189
|
+
# 1) Is this dependency already activated?
|
190
|
+
# 2) How relaxed are the requirements?
|
191
|
+
# 3) Are there any conflicts for this dependency?
|
192
|
+
# 4) How many possibilities are there to satisfy this dependency?
|
127
193
|
#
|
128
|
-
# @
|
129
|
-
# given dependency the locked one is used in place of the
|
130
|
-
# dependency of the specification. In this way it is possible to
|
131
|
-
# prevent the update of the version of installed pods not changed
|
132
|
-
# in the Podfile.
|
194
|
+
# @return [Array<Dependency>] the sorted dependencies.
|
133
195
|
#
|
134
|
-
# @
|
135
|
-
# loaded to prevent an infinite loop.
|
196
|
+
# @param [Array<Dependency>] dependencies the unsorted dependencies.
|
136
197
|
#
|
137
|
-
# @
|
138
|
-
#
|
139
|
-
# mode or from an external source because {Dependency#merge}
|
140
|
-
# preserves this information.
|
198
|
+
# @param [Molinillo::DependencyGraph] activated the dependency graph of
|
199
|
+
# currently activated specs.
|
141
200
|
#
|
142
|
-
# @
|
201
|
+
# @param [{String => Array<Conflict>}] conflicts the current conflicts.
|
143
202
|
#
|
144
|
-
def
|
145
|
-
dependencies.
|
146
|
-
|
147
|
-
|
203
|
+
def sort_dependencies(dependencies, activated, conflicts)
|
204
|
+
dependencies.sort_by do |dependency|
|
205
|
+
name = name_for(dependency)
|
206
|
+
[
|
207
|
+
activated.vertex_named(name).payload ? 0 : 1,
|
208
|
+
dependency.prerelease? ? 0 : 1,
|
209
|
+
conflicts[name] ? 0 : 1,
|
210
|
+
search_for(dependency).count,
|
211
|
+
]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
#-------------------------------------------------------------------------#
|
148
216
|
|
149
|
-
|
150
|
-
set = find_cached_set(dependency, dependent_spec)
|
151
|
-
set.required_by(dependency, dependent_spec.to_s)
|
217
|
+
public
|
152
218
|
|
153
|
-
|
154
|
-
UI.warn "Found multiple specifications for #{dependency}:\n" \
|
155
|
-
"- #{paths.join("\n")}"
|
156
|
-
end
|
219
|
+
# @!group Resolver UI
|
157
220
|
|
158
|
-
|
159
|
-
spec = set.specification.subspec_by_name(dependency.name)
|
160
|
-
@loaded_specs << spec.name
|
161
|
-
cached_specs[spec.name] = spec
|
162
|
-
validate_platform(spec, target_definition)
|
163
|
-
if dependency.head? || sandbox.head_pod?(spec.name)
|
164
|
-
spec.version.head = true
|
165
|
-
sandbox.store_head_pod(spec.name)
|
166
|
-
end
|
221
|
+
include Molinillo::UI
|
167
222
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
223
|
+
include Config::Mixin
|
224
|
+
|
225
|
+
# The UI object the resolver should use for displaying user-facing output.
|
226
|
+
#
|
227
|
+
# @return [UserInterface] the normal CocoaPods UI object.
|
228
|
+
#
|
229
|
+
def output
|
230
|
+
UI
|
173
231
|
end
|
174
232
|
|
233
|
+
# Called before resolution starts. We print out `Resolving dependencies` in
|
234
|
+
# the analyzer, so here we just want to print out a starting `.` in verbose
|
235
|
+
# mode.
|
236
|
+
#
|
237
|
+
# @return [Void]
|
238
|
+
#
|
239
|
+
def before_resolution
|
240
|
+
UI.print '.' if config.verbose
|
241
|
+
end
|
242
|
+
|
243
|
+
# Called after resolution ends. We don't want to {#indicate_progress}
|
244
|
+
# unless in verbose mode, so we only use the default implementation then.
|
245
|
+
#
|
246
|
+
# @return [Void]
|
247
|
+
#
|
248
|
+
def after_resolution
|
249
|
+
super if config.verbose
|
250
|
+
end
|
251
|
+
|
252
|
+
# Called during resolution to indicate progress.
|
253
|
+
# We only use the default implementation in verbose mode.
|
254
|
+
#
|
255
|
+
# @return [Void]
|
256
|
+
#
|
257
|
+
def indicate_progress
|
258
|
+
super if config.verbose
|
259
|
+
end
|
260
|
+
|
261
|
+
#-------------------------------------------------------------------------#
|
262
|
+
|
263
|
+
private
|
264
|
+
|
265
|
+
# !@ Resolution context
|
266
|
+
|
267
|
+
# @return [Hash<String => Set>] A cache that keeps tracks of the sets
|
268
|
+
# loaded by the resolution process.
|
269
|
+
#
|
270
|
+
# @note Sets store the resolved dependencies and return the highest
|
271
|
+
# available specification found in the sources. This is done
|
272
|
+
# globally and not per target definition because there can be just
|
273
|
+
# one Pod installation, so different version of the same Pods for
|
274
|
+
# target definitions are not allowed.
|
275
|
+
#
|
276
|
+
attr_accessor :cached_sets
|
277
|
+
|
278
|
+
#-------------------------------------------------------------------------#
|
279
|
+
|
280
|
+
private
|
281
|
+
|
282
|
+
# @!group Private helpers
|
283
|
+
|
175
284
|
# @return [Set] Loads or returns a previously initialized set for the Pod
|
176
285
|
# of the given dependency.
|
177
286
|
#
|
178
287
|
# @param [Dependency] dependency
|
179
288
|
# The dependency for which the set is needed.
|
180
289
|
#
|
181
|
-
# @param [#to_s] dependent_spec
|
182
|
-
# the specification whose dependencies are being resolved. Used
|
183
|
-
# only for UI purposes.
|
184
|
-
#
|
185
290
|
# @return [Set] the cached set for a given dependency.
|
186
291
|
#
|
187
|
-
def find_cached_set(dependency
|
292
|
+
def find_cached_set(dependency)
|
188
293
|
name = dependency.root_name
|
189
294
|
unless cached_sets[name]
|
190
295
|
if dependency.external_source
|
191
|
-
spec = sandbox.specification(
|
296
|
+
spec = sandbox.specification(name)
|
192
297
|
unless spec
|
193
298
|
raise StandardError, '[Bug] Unable to find the specification ' \
|
194
299
|
"for `#{dependency}`."
|
@@ -199,8 +304,7 @@ module Pod
|
|
199
304
|
end
|
200
305
|
cached_sets[name] = set
|
201
306
|
unless set
|
202
|
-
raise
|
203
|
-
"`#{dependency}` depended upon by #{dependent_spec}."
|
307
|
+
raise Molinillo::NoSuchDependencyError.new(dependency) # rubocop:disable Style/RaiseArgs
|
204
308
|
end
|
205
309
|
end
|
206
310
|
cached_sets[name]
|
@@ -239,5 +343,38 @@ module Pod
|
|
239
343
|
"a minimum requirement of #{spec.available_platforms.join(' - ')}."
|
240
344
|
end
|
241
345
|
end
|
346
|
+
|
347
|
+
# Returns the target-appropriate nodes that are `successors` of `node`,
|
348
|
+
# rejecting those that are {Dependency#from_subspec_dependency?} and have
|
349
|
+
# and incompatible platform.
|
350
|
+
#
|
351
|
+
# @return [Array<Molinillo::DependencyGraph::Vertex>]
|
352
|
+
# An array of target-appropriate nodes whose `payload`s are
|
353
|
+
# dependencies for `target`.
|
354
|
+
#
|
355
|
+
def valid_dependencies_for_target_from_node(target, node)
|
356
|
+
dependency_nodes = node.outgoing_edges.select do |edge|
|
357
|
+
edge_is_valid_for_target?(edge, target)
|
358
|
+
end.map(&:destination)
|
359
|
+
|
360
|
+
dependency_nodes + dependency_nodes.flat_map { |n| valid_dependencies_for_target_from_node(target, n) }
|
361
|
+
end
|
362
|
+
|
363
|
+
# Whether the given `edge` should be followed to find dependencies for the
|
364
|
+
# given `target`.
|
365
|
+
#
|
366
|
+
# @note At the moment, this method only checks whether the edge's
|
367
|
+
# requirements are normal dependencies _or_ whether they are
|
368
|
+
# dependencies that come from {Specification#subspec_dependencies}
|
369
|
+
# and, if so, that their platforms are compatible with the target's.
|
370
|
+
#
|
371
|
+
# @return [Bool]
|
372
|
+
#
|
373
|
+
def edge_is_valid_for_target?(edge, target)
|
374
|
+
edge.requirements.any? do |dependency|
|
375
|
+
!dependency.from_subspec_dependency? ||
|
376
|
+
edge.destination.payload.available_platforms.any? { |p| target.platform.supports?(p) }
|
377
|
+
end
|
378
|
+
end
|
242
379
|
end
|
243
380
|
end
|