cocoapods 1.7.5 → 1.8.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +175 -11
- data/LICENSE +13 -8
- data/README.md +2 -1
- data/lib/cocoapods/command/init.rb +18 -16
- data/lib/cocoapods/command/install.rb +2 -1
- data/lib/cocoapods/command/lib/create.rb +1 -2
- data/lib/cocoapods/command/lib/lint.rb +12 -11
- data/lib/cocoapods/command/repo/add.rb +2 -2
- data/lib/cocoapods/command/repo/list.rb +7 -5
- data/lib/cocoapods/command/repo/push.rb +15 -12
- data/lib/cocoapods/command/setup.rb +2 -88
- data/lib/cocoapods/command/spec/lint.rb +10 -9
- data/lib/cocoapods/command/update.rb +5 -4
- data/lib/cocoapods/config.rb +9 -8
- data/lib/cocoapods/external_sources/path_source.rb +1 -1
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/embed_frameworks_script.rb +1 -1
- data/lib/cocoapods/generator/info_plist_file.rb +2 -2
- data/lib/cocoapods/installer.rb +32 -12
- data/lib/cocoapods/installer/analyzer.rb +132 -97
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +6 -8
- data/lib/cocoapods/installer/installation_options.rb +4 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +17 -1
- data/lib/cocoapods/installer/podfile_validator.rb +26 -6
- data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +37 -27
- data/lib/cocoapods/installer/project_cache/project_cache_version.rb +1 -1
- data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +3 -3
- data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +12 -6
- data/lib/cocoapods/installer/project_cache/target_cache_key.rb +32 -8
- data/lib/cocoapods/installer/project_cache/target_metadata.rb +6 -2
- data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +12 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +1 -1
- data/lib/cocoapods/installer/xcode/multi_pods_project_generator.rb +3 -1
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +2 -2
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +18 -3
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +53 -11
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +92 -60
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +66 -50
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +12 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +6 -2
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +2 -2
- data/lib/cocoapods/installer/xcode/target_validator.rb +30 -14
- data/lib/cocoapods/native_target_extension.rb +11 -5
- data/lib/cocoapods/open-uri.rb +1 -1
- data/lib/cocoapods/project.rb +13 -7
- data/lib/cocoapods/resolver.rb +63 -53
- data/lib/cocoapods/resolver/lazy_specification.rb +14 -5
- data/lib/cocoapods/sandbox.rb +35 -2
- data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +3 -4
- data/lib/cocoapods/sources_manager.rb +72 -43
- data/lib/cocoapods/target.rb +7 -1
- data/lib/cocoapods/target/aggregate_target.rb +13 -8
- data/lib/cocoapods/target/build_settings.rb +33 -10
- data/lib/cocoapods/target/pod_target.rb +114 -30
- data/lib/cocoapods/user_interface/error_report.rb +9 -5
- data/lib/cocoapods/validator.rb +55 -11
- data/lib/cocoapods/version_metadata.rb +14 -1
- metadata +6 -7
- data/lib/cocoapods/command/spec/env_spec.rb +0 -53
@@ -60,32 +60,40 @@ module Pod
|
|
60
60
|
|
61
61
|
input_paths_by_config = {}
|
62
62
|
output_paths_by_config = {}
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
63
|
+
|
64
|
+
dependent_targets = if spec.test_specification?
|
65
|
+
target.dependent_targets_for_test_spec(spec)
|
66
|
+
else
|
67
|
+
target.dependent_targets_for_app_spec(spec)
|
68
|
+
end
|
69
|
+
host_target_spec_names = target.app_host_dependent_targets_for_spec(spec).flat_map do |pt|
|
70
|
+
pt.specs.map(&:name)
|
71
|
+
end.uniq
|
72
|
+
resource_paths = dependent_targets.flat_map do |dependent_target|
|
73
|
+
spec_paths_to_include = dependent_target.library_specs.map(&:name)
|
74
|
+
spec_paths_to_include -= host_target_spec_names
|
75
|
+
spec_paths_to_include << spec.name if dependent_target == target
|
76
|
+
dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
|
77
|
+
end.uniq
|
78
|
+
|
79
|
+
if use_input_output_paths? && !resource_paths.empty?
|
80
|
+
input_file_list_path = target.copy_resources_script_input_files_path_for_spec(spec)
|
81
|
+
input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
|
82
|
+
input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
|
83
|
+
input_paths_by_config[input_paths_key] = [script_path] + resource_paths
|
84
|
+
|
85
|
+
output_file_list_path = target.copy_resources_script_output_files_path_for_spec(spec)
|
86
|
+
output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
|
87
|
+
output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
|
88
|
+
output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths)
|
86
89
|
end
|
87
90
|
|
88
|
-
|
91
|
+
if resource_paths.empty?
|
92
|
+
UserProjectIntegrator::TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target)
|
93
|
+
else
|
94
|
+
UserProjectIntegrator::TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(
|
95
|
+
native_target, script_path, input_paths_by_config, output_paths_by_config)
|
96
|
+
end
|
89
97
|
end
|
90
98
|
|
91
99
|
# Find or create a 'Embed Pods Frameworks' Copy Files Build Phase
|
@@ -97,35 +105,43 @@ module Pod
|
|
97
105
|
|
98
106
|
input_paths_by_config = {}
|
99
107
|
output_paths_by_config = {}
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
|
124
|
-
output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
|
108
|
+
|
109
|
+
dependent_targets = if spec.test_specification?
|
110
|
+
target.dependent_targets_for_test_spec(spec)
|
111
|
+
else
|
112
|
+
target.dependent_targets_for_app_spec(spec)
|
113
|
+
end
|
114
|
+
host_target_spec_names = target.app_host_dependent_targets_for_spec(spec).flat_map do |pt|
|
115
|
+
pt.specs.map(&:name)
|
116
|
+
end.uniq
|
117
|
+
framework_paths = dependent_targets.flat_map do |dependent_target|
|
118
|
+
spec_paths_to_include = dependent_target.library_specs.map(&:name)
|
119
|
+
spec_paths_to_include -= host_target_spec_names
|
120
|
+
spec_paths_to_include << spec.name if dependent_target == target
|
121
|
+
dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact
|
122
|
+
end.uniq
|
123
|
+
|
124
|
+
if use_input_output_paths? && !framework_paths.empty?
|
125
|
+
input_file_list_path = target.embed_frameworks_script_input_files_path_for_spec(spec)
|
126
|
+
input_file_list_relative_path = "${PODS_ROOT}/#{input_file_list_path.relative_path_from(target.sandbox.root)}"
|
127
|
+
input_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(input_file_list_path, input_file_list_relative_path)
|
128
|
+
input_paths = input_paths_by_config[input_paths_key] = [script_path]
|
129
|
+
framework_paths.each do |path|
|
130
|
+
input_paths.concat(path.all_paths)
|
125
131
|
end
|
132
|
+
|
133
|
+
output_file_list_path = target.embed_frameworks_script_output_files_path_for_spec(spec)
|
134
|
+
output_file_list_relative_path = "${PODS_ROOT}/#{output_file_list_path.relative_path_from(target.sandbox.root)}"
|
135
|
+
output_paths_key = UserProjectIntegrator::TargetIntegrator::XCFileListConfigKey.new(output_file_list_path, output_file_list_relative_path)
|
136
|
+
output_paths_by_config[output_paths_key] = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
|
126
137
|
end
|
127
138
|
|
128
|
-
|
139
|
+
if framework_paths.empty?
|
140
|
+
UserProjectIntegrator::TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
|
141
|
+
else
|
142
|
+
UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(
|
143
|
+
native_target, script_path, input_paths_by_config, output_paths_by_config)
|
144
|
+
end
|
129
145
|
end
|
130
146
|
|
131
147
|
# @return [String] the message that should be displayed for the target
|
@@ -110,6 +110,18 @@ module Pod
|
|
110
110
|
test_specs_by_native_target.merge(app_specs_by_native_target)
|
111
111
|
end
|
112
112
|
|
113
|
+
# @param label [String] the label of the app host target.
|
114
|
+
#
|
115
|
+
# @return [PBXNativeTarget] the app host target with the given target label.
|
116
|
+
#
|
117
|
+
def app_host_target_labelled(label)
|
118
|
+
app_native_targets.find do |app_native_target|
|
119
|
+
app_native_target.name == label
|
120
|
+
end || test_app_host_targets.find do |app_native_target|
|
121
|
+
app_native_target.name == label
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
113
125
|
private
|
114
126
|
|
115
127
|
def test_native_target_from_spec(spec)
|
@@ -135,10 +135,14 @@ module Pod
|
|
135
135
|
# @param [Symbol] bundle_package_type
|
136
136
|
# the CFBundlePackageType of the target this Info.plist file is for.
|
137
137
|
#
|
138
|
+
# @param [Hash] additional_entries
|
139
|
+
# additional entries for the generated Info.plist
|
140
|
+
#
|
138
141
|
# @return [void]
|
139
142
|
#
|
140
|
-
def create_info_plist_file(path, native_target, version, platform, bundle_package_type = :fmwk)
|
141
|
-
create_info_plist_file_with_sandbox(@sandbox, path, native_target, version, platform, bundle_package_type
|
143
|
+
def create_info_plist_file(path, native_target, version, platform, bundle_package_type = :fmwk, additional_entries: {})
|
144
|
+
create_info_plist_file_with_sandbox(@sandbox, path, native_target, version, platform, bundle_package_type,
|
145
|
+
:additional_entries => additional_entries)
|
142
146
|
add_file_to_support_group(path)
|
143
147
|
end
|
144
148
|
|
@@ -36,7 +36,7 @@ module Pod
|
|
36
36
|
# @param [PBXNativeTarget] native_target
|
37
37
|
# the native target to link the generated Info.plist file into.
|
38
38
|
#
|
39
|
-
# @param [
|
39
|
+
# @param [String] version
|
40
40
|
# the version to use for when generating this Info.plist file.
|
41
41
|
#
|
42
42
|
# @param [Platform] platform
|
@@ -51,7 +51,7 @@ module Pod
|
|
51
51
|
# @return [void]
|
52
52
|
#
|
53
53
|
def create_info_plist_file_with_sandbox(sandbox, path, native_target, version, platform,
|
54
|
-
bundle_package_type = :fmwk, additional_entries
|
54
|
+
bundle_package_type = :fmwk, additional_entries: {})
|
55
55
|
UI.message "- Generating Info.plist file at #{UI.path(path)}" do
|
56
56
|
generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type, additional_entries)
|
57
57
|
update_changed_file(generator, path)
|
@@ -5,8 +5,7 @@ module Pod
|
|
5
5
|
# configuration is valid for installation.
|
6
6
|
#
|
7
7
|
class TargetValidator
|
8
|
-
# @return [Array<AggregateTarget>] The aggregate targets that should be
|
9
|
-
# validated.
|
8
|
+
# @return [Array<AggregateTarget>] The aggregate targets that should be validated.
|
10
9
|
#
|
11
10
|
attr_reader :aggregate_targets
|
12
11
|
|
@@ -14,18 +13,21 @@ module Pod
|
|
14
13
|
#
|
15
14
|
attr_reader :pod_targets
|
16
15
|
|
16
|
+
# @return [InstallationOptions] The installation options used during this installation.
|
17
|
+
#
|
18
|
+
attr_reader :installation_options
|
19
|
+
|
17
20
|
# Create a new TargetValidator with aggregate and pod targets to
|
18
21
|
# validate.
|
19
22
|
#
|
20
|
-
# @param [Array<AggregateTarget>] aggregate_targets
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# @param [Array<PodTarget>] pod_targets
|
24
|
-
# The pod targets to validate.
|
23
|
+
# @param [Array<AggregateTarget>] aggregate_targets #see #aggregate_targets
|
24
|
+
# @param [Array<PodTarget>] pod_targets see #pod_targets
|
25
|
+
# @param [InstallationOptions] installation_options see #installation_options
|
25
26
|
#
|
26
|
-
def initialize(aggregate_targets, pod_targets)
|
27
|
+
def initialize(aggregate_targets, pod_targets, installation_options)
|
27
28
|
@aggregate_targets = aggregate_targets
|
28
29
|
@pod_targets = pod_targets
|
30
|
+
@installation_options = installation_options
|
29
31
|
end
|
30
32
|
|
31
33
|
# Perform the validation steps for the provided aggregate and pod
|
@@ -36,15 +38,16 @@ module Pod
|
|
36
38
|
verify_no_static_framework_transitive_dependencies
|
37
39
|
verify_swift_pods_swift_version
|
38
40
|
verify_swift_pods_have_module_dependencies
|
41
|
+
verify_no_multiple_project_names if installation_options.generate_multiple_pod_projects?
|
39
42
|
end
|
40
43
|
|
41
44
|
private
|
42
45
|
|
43
46
|
def verify_no_duplicate_framework_and_library_names
|
44
47
|
aggregate_targets.each do |aggregate_target|
|
45
|
-
aggregate_target.user_build_configurations.
|
48
|
+
aggregate_target.user_build_configurations.each_key do |config|
|
46
49
|
pod_targets = aggregate_target.pod_targets_for_build_configuration(config)
|
47
|
-
file_accessors = pod_targets.flat_map(&:file_accessors)
|
50
|
+
file_accessors = pod_targets.flat_map(&:file_accessors).select { |fa| fa.spec.library_specification? }
|
48
51
|
|
49
52
|
frameworks = file_accessors.flat_map(&:vendored_frameworks).uniq.map(&:basename)
|
50
53
|
frameworks += pod_targets.select { |pt| pt.should_build? && pt.build_as_framework? }.map(&:product_module_name).uniq
|
@@ -58,7 +61,7 @@ module Pod
|
|
58
61
|
end
|
59
62
|
|
60
63
|
def verify_no_duplicate_names(names, label, type)
|
61
|
-
duplicates = names.
|
64
|
+
duplicates = names.group_by { |n| n.to_s.downcase }.select { |_, v| v.size > 1 }.keys
|
62
65
|
|
63
66
|
unless duplicates.empty?
|
64
67
|
raise Informative, "The '#{label}' target has " \
|
@@ -73,8 +76,8 @@ module Pod
|
|
73
76
|
built_targets, unbuilt_targets = pod_targets.partition(&:should_build?)
|
74
77
|
dynamic_pod_targets = built_targets.select(&:build_as_dynamic?)
|
75
78
|
|
76
|
-
dependencies = dynamic_pod_targets.flat_map(&:
|
77
|
-
depended_upon_targets = unbuilt_targets
|
79
|
+
dependencies = dynamic_pod_targets.flat_map(&:dependent_targets).uniq
|
80
|
+
depended_upon_targets = unbuilt_targets & dependencies
|
78
81
|
|
79
82
|
static_libs = depended_upon_targets.flat_map(&:file_accessors).flat_map(&:vendored_static_artifacts)
|
80
83
|
unless static_libs.empty?
|
@@ -82,7 +85,7 @@ module Pod
|
|
82
85
|
"transitive dependencies that include statically linked binaries: (#{static_libs.to_sentence})"
|
83
86
|
end
|
84
87
|
|
85
|
-
static_deps = dynamic_pod_targets.flat_map(&:recursive_dependent_targets).select(&:build_as_static?)
|
88
|
+
static_deps = dynamic_pod_targets.flat_map(&:recursive_dependent_targets).uniq.select(&:build_as_static?)
|
86
89
|
unless static_deps.empty?
|
87
90
|
raise Informative, "The '#{aggregate_target.label}' target has " \
|
88
91
|
"transitive dependencies that include statically linked binaries: (#{static_deps.flat_map(&:name).to_sentence})"
|
@@ -148,6 +151,19 @@ module Pod
|
|
148
151
|
raise Informative, 'The following Swift pods cannot yet be integrated '\
|
149
152
|
"as static libraries:\n\n#{error_messages.join("\n\n")}"
|
150
153
|
end
|
154
|
+
|
155
|
+
def verify_no_multiple_project_names
|
156
|
+
error_messages = pod_targets.map do |pod_target|
|
157
|
+
project_names = pod_target.target_definitions.map { |td| td.project_name_for_pod(pod_target.pod_name) }.compact.uniq
|
158
|
+
next unless project_names.count > 1
|
159
|
+
"- `#{pod_target.name}` specifies multiple project names (#{project_names.map { |pn| "`#{pn}`" }.to_sentence}) " \
|
160
|
+
"in different targets (#{pod_target.target_definitions.map { |td| "`#{td.name}`" }.to_sentence})."
|
161
|
+
end.compact
|
162
|
+
return if error_messages.empty?
|
163
|
+
|
164
|
+
raise Informative, 'The following pods cannot be integrated:' \
|
165
|
+
"\n\n#{error_messages.join("\n\n")}"
|
166
|
+
end
|
151
167
|
end
|
152
168
|
end
|
153
169
|
end
|
@@ -2,6 +2,9 @@ module Pod
|
|
2
2
|
class Project
|
3
3
|
# Adds a dependency on the given metadata cache.
|
4
4
|
#
|
5
|
+
# @param [Sandbox] sandbox
|
6
|
+
# The sandbox used for this installation.
|
7
|
+
#
|
5
8
|
# @param [AbstractTarget] target
|
6
9
|
# The parent target used to add a cached dependency.
|
7
10
|
#
|
@@ -10,11 +13,11 @@ module Pod
|
|
10
13
|
#
|
11
14
|
# @return [void]
|
12
15
|
#
|
13
|
-
def self.add_cached_dependency(target, metadata)
|
14
|
-
return if dependency_for_cached_target?(target, metadata)
|
16
|
+
def self.add_cached_dependency(sandbox, target, metadata)
|
17
|
+
return if dependency_for_cached_target?(sandbox, target, metadata)
|
15
18
|
container_proxy = target.project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
16
19
|
|
17
|
-
subproject_reference = target.project.reference_for_path(metadata.container_project_path)
|
20
|
+
subproject_reference = target.project.reference_for_path(sandbox.root + metadata.container_project_path)
|
18
21
|
raise ArgumentError, "add_dependency received target (#{target}) that belongs to a project that is not this project (#{self}) and is not a subproject of this project" unless subproject_reference
|
19
22
|
container_proxy.container_portal = subproject_reference.uuid
|
20
23
|
|
@@ -31,6 +34,9 @@ module Pod
|
|
31
34
|
|
32
35
|
# Checks whether this target has a dependency on the given target.
|
33
36
|
#
|
37
|
+
# @param [Sandbox] sandbox
|
38
|
+
# The sandbox used for this installation.
|
39
|
+
#
|
34
40
|
# @param [AbstractTarget] target
|
35
41
|
# The parent target used to add a cached dependency.
|
36
42
|
#
|
@@ -39,10 +45,10 @@ module Pod
|
|
39
45
|
#
|
40
46
|
# @return [Bool]
|
41
47
|
#
|
42
|
-
def self.dependency_for_cached_target?(target, cached_target)
|
48
|
+
def self.dependency_for_cached_target?(sandbox, target, cached_target)
|
43
49
|
target.dependencies.find do |dep|
|
44
50
|
if dep.target_proxy.remote?
|
45
|
-
subproject_reference = target.project.reference_for_path(cached_target.container_project_path)
|
51
|
+
subproject_reference = target.project.reference_for_path(sandbox.root + cached_target.container_project_path)
|
46
52
|
uuid = subproject_reference.uuid if subproject_reference
|
47
53
|
dep.target_proxy.remote_global_id_string == cached_target.native_target_uuid && dep.target_proxy.container_portal == uuid
|
48
54
|
else
|
data/lib/cocoapods/open-uri.rb
CHANGED
data/lib/cocoapods/project.rb
CHANGED
@@ -53,7 +53,7 @@ module Pod
|
|
53
53
|
@development_pods = new_group('Development Pods')
|
54
54
|
@dependencies_group = new_group('Dependencies')
|
55
55
|
@pod_target_subproject = pod_target_subproject
|
56
|
-
@project_name = Pathname(path).basename('.*')
|
56
|
+
@project_name = Pathname(path).basename('.*').to_s
|
57
57
|
self.symroot = LEGACY_BUILD_ROOT
|
58
58
|
end
|
59
59
|
|
@@ -108,10 +108,10 @@ module Pod
|
|
108
108
|
# The path to the root of the Pod.
|
109
109
|
#
|
110
110
|
# @param [Bool] development
|
111
|
-
#
|
111
|
+
# Whether the group should be added to the Development Pods group.
|
112
112
|
#
|
113
113
|
# @param [Bool] absolute
|
114
|
-
#
|
114
|
+
# Whether the path of the group should be set as absolute.
|
115
115
|
#
|
116
116
|
# @return [PBXGroup] The new group.
|
117
117
|
#
|
@@ -150,6 +150,9 @@ module Pod
|
|
150
150
|
# Creates a new subproject reference for the given cached metadata and configures its
|
151
151
|
# group location.
|
152
152
|
#
|
153
|
+
# @param [Sandbox] sandbox
|
154
|
+
# The sandbox used for installation.
|
155
|
+
#
|
153
156
|
# @param [TargetMetadata] metadata
|
154
157
|
# The project metadata to be added.
|
155
158
|
#
|
@@ -159,9 +162,9 @@ module Pod
|
|
159
162
|
#
|
160
163
|
# @return [PBXFileReference] The new file reference.
|
161
164
|
#
|
162
|
-
def add_cached_pod_subproject(metadata, development = false)
|
165
|
+
def add_cached_pod_subproject(sandbox, metadata, development = false)
|
163
166
|
parent_group = group_for_subproject_reference(development)
|
164
|
-
add_cached_subproject_reference(metadata, parent_group)
|
167
|
+
add_cached_subproject_reference(sandbox, metadata, parent_group)
|
165
168
|
end
|
166
169
|
|
167
170
|
# @return [Array<PBXGroup>] Returns all the group of the Pods.
|
@@ -291,6 +294,9 @@ module Pod
|
|
291
294
|
|
292
295
|
# Adds a file reference for a cached project as a child of the given group.
|
293
296
|
#
|
297
|
+
# @param [Sandbox] sandbox
|
298
|
+
# The sandbox used for installation.
|
299
|
+
#
|
294
300
|
# @param [MetadataCache] metadata
|
295
301
|
# The metadata holding the required properties to create a subproject reference.
|
296
302
|
#
|
@@ -299,8 +305,8 @@ module Pod
|
|
299
305
|
#
|
300
306
|
# @return [PBXFileReference] The new file reference.
|
301
307
|
#
|
302
|
-
def add_cached_subproject_reference(metadata, group)
|
303
|
-
new_subproject_file_reference(metadata.container_project_path, group)
|
308
|
+
def add_cached_subproject_reference(sandbox, metadata, group)
|
309
|
+
new_subproject_file_reference(sandbox.root + metadata.container_project_path, group)
|
304
310
|
end
|
305
311
|
|
306
312
|
# Returns the file reference for the given absolute path.
|
data/lib/cocoapods/resolver.rb
CHANGED
@@ -39,6 +39,10 @@ module Pod
|
|
39
39
|
attr_reader :specs_updated
|
40
40
|
alias specs_updated? specs_updated
|
41
41
|
|
42
|
+
# @return [Source::Manager] the manager to use for dependency resolution
|
43
|
+
#
|
44
|
+
attr_reader :sources_manager
|
45
|
+
|
42
46
|
# Init a new Resolver
|
43
47
|
#
|
44
48
|
# @param [Sandbox] sandbox @see sandbox
|
@@ -50,17 +54,19 @@ module Pod
|
|
50
54
|
# within this Resolver.
|
51
55
|
#
|
52
56
|
def initialize(sandbox, podfile, locked_dependencies, sources, specs_updated,
|
53
|
-
podfile_dependency_cache: Installer::Analyzer::PodfileDependencyCache.from_podfile(podfile)
|
57
|
+
podfile_dependency_cache: Installer::Analyzer::PodfileDependencyCache.from_podfile(podfile),
|
58
|
+
sources_manager: Config.instance.sources_manager)
|
54
59
|
@sandbox = sandbox
|
55
60
|
@podfile = podfile
|
56
61
|
@locked_dependencies = locked_dependencies
|
57
62
|
@sources = Array(sources)
|
58
63
|
@specs_updated = specs_updated
|
59
64
|
@podfile_dependency_cache = podfile_dependency_cache
|
65
|
+
@sources_manager = sources_manager
|
60
66
|
@platforms_by_dependency = Hash.new { |h, k| h[k] = [] }
|
61
67
|
|
62
68
|
@cached_sets = {}
|
63
|
-
@podfile_requirements_by_root_name = @podfile_dependency_cache.podfile_dependencies.group_by(&:root_name).each_value { |a| a.map!(&:requirement) }
|
69
|
+
@podfile_requirements_by_root_name = @podfile_dependency_cache.podfile_dependencies.group_by(&:root_name).each_value { |a| a.map!(&:requirement).freeze }.freeze
|
64
70
|
@search = {}
|
65
71
|
@validated_platforms = Set.new
|
66
72
|
end
|
@@ -83,7 +89,7 @@ module Pod
|
|
83
89
|
next unless target.platform
|
84
90
|
@platforms_by_dependency[dep].push(target.platform)
|
85
91
|
end
|
86
|
-
end
|
92
|
+
end.uniq
|
87
93
|
@platforms_by_dependency.each_value(&:uniq!)
|
88
94
|
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
|
89
95
|
resolver_specs_by_target
|
@@ -99,15 +105,32 @@ module Pod
|
|
99
105
|
def resolver_specs_by_target
|
100
106
|
@resolver_specs_by_target ||= {}.tap do |resolver_specs_by_target|
|
101
107
|
@podfile_dependency_cache.target_definition_list.each do |target|
|
108
|
+
next if target.abstract? && !target.platform
|
109
|
+
|
102
110
|
# can't use vertex.root? since that considers _all_ targets
|
103
111
|
explicit_dependencies = @podfile_dependency_cache.target_definition_dependencies(target).map(&:name).to_set
|
104
|
-
vertices = valid_dependencies_for_target(target)
|
105
112
|
|
106
|
-
|
113
|
+
used_by_aggregate_target_by_spec_name = {}
|
114
|
+
used_vertices_by_spec_name = {}
|
115
|
+
|
116
|
+
# it's safe to make a single pass here since we iterate in topological order,
|
117
|
+
# so all of the predecessors have been visited before we get to a node.
|
118
|
+
# #tsort returns no-children vertices first, and we want them last (i.e. we want no-parent vertices first)
|
119
|
+
@activated.tsort.reverse_each do |vertex|
|
120
|
+
spec_name = vertex.name
|
121
|
+
explicitly_included = explicit_dependencies.include?(spec_name)
|
122
|
+
if explicitly_included || vertex.incoming_edges.any? { |edge| used_vertices_by_spec_name.key?(edge.origin.name) && edge_is_valid_for_target_platform?(edge, target.platform) }
|
123
|
+
validate_platform(vertex.payload, target)
|
124
|
+
used_vertices_by_spec_name[spec_name] = vertex
|
125
|
+
used_by_aggregate_target_by_spec_name[spec_name] = vertex.payload.library_specification? &&
|
126
|
+
(explicitly_included || vertex.predecessors.any? { |predecessor| used_by_aggregate_target_by_spec_name.fetch(predecessor.name, false) })
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
resolver_specs_by_target[target] = used_vertices_by_spec_name.each_value.
|
107
131
|
map do |vertex|
|
108
132
|
payload = vertex.payload
|
109
|
-
non_library =
|
110
|
-
(vertex.recursive_predecessors & vertices).all? { |v| !explicit_dependencies.include?(v.name) || v.payload.non_library_specification? }
|
133
|
+
non_library = !used_by_aggregate_target_by_spec_name.fetch(vertex.name)
|
111
134
|
spec_source = payload.respond_to?(:spec_source) && payload.spec_source
|
112
135
|
ResolverSpecification.new(payload, non_library, spec_source)
|
113
136
|
end.
|
@@ -133,10 +156,13 @@ module Pod
|
|
133
156
|
#
|
134
157
|
def search_for(dependency)
|
135
158
|
@search[dependency] ||= begin
|
136
|
-
locked_requirement = requirement_for_locked_pod_named(dependency.name)
|
137
|
-
|
138
|
-
|
139
|
-
|
159
|
+
additional_requirements = if locked_requirement = requirement_for_locked_pod_named(dependency.name)
|
160
|
+
[locked_requirement]
|
161
|
+
else
|
162
|
+
Array(@podfile_requirements_by_root_name[dependency.root_name])
|
163
|
+
end
|
164
|
+
|
165
|
+
specifications_for_dependency(dependency, additional_requirements)
|
140
166
|
end
|
141
167
|
@search[dependency].dup
|
142
168
|
end
|
@@ -328,10 +354,11 @@ module Pod
|
|
328
354
|
# @return [Array<Specification>] List of specifications satisfying given requirements.
|
329
355
|
#
|
330
356
|
def specifications_for_dependency(dependency, additional_requirements = [])
|
331
|
-
|
357
|
+
requirement_list = dependency.requirement.as_list + additional_requirements.flat_map(&:as_list)
|
358
|
+
requirement_list.uniq!
|
359
|
+
requirement = Requirement.new(requirement_list)
|
332
360
|
find_cached_set(dependency).
|
333
|
-
all_specifications(warn_for_multiple_pod_sources).
|
334
|
-
select { |s| requirement.satisfied_by? s.version }.
|
361
|
+
all_specifications(warn_for_multiple_pod_sources, requirement).
|
335
362
|
map { |s| s.subspec_by_name(dependency.name, false, true) }.
|
336
363
|
compact
|
337
364
|
end
|
@@ -392,7 +419,6 @@ module Pod
|
|
392
419
|
# @return [Source::Aggregate] The aggregate of the {#sources}.
|
393
420
|
#
|
394
421
|
def aggregate_for_dependency(dependency)
|
395
|
-
sources_manager = Config.instance.sources_manager
|
396
422
|
if dependency && dependency.podspec_repo
|
397
423
|
sources_manager.aggregate_for_dependency(dependency)
|
398
424
|
elsif (locked_vertex = @locked_dependencies.vertex_named(dependency.name)) && (locked_dependency = locked_vertex.payload) && locked_dependency.podspec_repo
|
@@ -414,7 +440,7 @@ module Pod
|
|
414
440
|
unless spec.available_platforms.any? { |p| target_platform.to_sym == p.to_sym }
|
415
441
|
raise Informative, "The platform of the target `#{target.name}` " \
|
416
442
|
"(#{target.platform}) is not compatible with `#{spec}`, which does " \
|
417
|
-
"not support `#{target.platform.
|
443
|
+
"not support `#{target.platform.string_name}`."
|
418
444
|
end
|
419
445
|
end
|
420
446
|
|
@@ -427,6 +453,9 @@ module Pod
|
|
427
453
|
def handle_resolver_error(error)
|
428
454
|
message = error.message
|
429
455
|
type = Informative
|
456
|
+
unless specs_updated?
|
457
|
+
specs_update_message = "\n * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`."
|
458
|
+
end
|
430
459
|
case error
|
431
460
|
when Molinillo::VersionConflict
|
432
461
|
message = error.message_with_trees(
|
@@ -438,9 +467,9 @@ module Pod
|
|
438
467
|
if local_pod_parent && !specifications_for_dependency(conflict.requirement).empty? && !conflict.possibility && conflict.locked_requirement
|
439
468
|
# Conflict was caused by a requirement from a local dependency.
|
440
469
|
# Tell user to use `pod update`.
|
441
|
-
o << "\
|
442
|
-
|
443
|
-
|
470
|
+
o << "\n\nYou have either:#{specs_update_message}" \
|
471
|
+
"\n * changed the constraints of dependency `#{name}` inside your development pod `#{local_pod_parent.name}`." \
|
472
|
+
"\n You should run `pod update #{name}` to apply changes you've made."
|
444
473
|
elsif !conflict.possibility && conflict.locked_requirement && conflict.locked_requirement.external_source && conflict.locked_requirement.external_source[:podspec] &&
|
445
474
|
conflict.requirement && conflict.requirement.external_source && conflict.requirement.external_source[:podspec]
|
446
475
|
# The internal version of the Podspec doesn't match the external definition of a podspec
|
@@ -470,13 +499,9 @@ module Pod
|
|
470
499
|
dependencies = conflicts.count == 1 ? 'dependency' : 'dependencies'
|
471
500
|
o << "\nNone of your spec sources contain a spec satisfying "\
|
472
501
|
"the #{dependencies}: `#{conflicts.join(', ')}`." \
|
473
|
-
"\n\nYou have either
|
474
|
-
|
475
|
-
|
476
|
-
end
|
477
|
-
o << "\n * mistyped the name or version." \
|
478
|
-
"\n * not added the source repo that hosts the Podspec to your Podfile." \
|
479
|
-
"\n\nNote: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default."
|
502
|
+
"\n\nYou have either:#{specs_update_message}" \
|
503
|
+
"\n * mistyped the name or version." \
|
504
|
+
"\n * not added the source repo that hosts the Podspec to your Podfile."
|
480
505
|
|
481
506
|
else
|
482
507
|
o << "\nSpecs satisfying the `#{conflicts.join(', ')}` dependency were found, " \
|
@@ -489,12 +514,9 @@ module Pod
|
|
489
514
|
message += <<-EOS
|
490
515
|
|
491
516
|
|
492
|
-
You have either
|
493
|
-
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
|
517
|
+
You have either:#{specs_update_message}
|
494
518
|
* mistyped the name or version.
|
495
519
|
* not added the source repo that hosts the Podspec to your Podfile.
|
496
|
-
|
497
|
-
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
|
498
520
|
EOS
|
499
521
|
end
|
500
522
|
raise type.new(message).tap { |e| e.set_backtrace(error.backtrace) }
|
@@ -530,33 +552,21 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by
|
|
530
552
|
end
|
531
553
|
end
|
532
554
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
# @return [Array<Molinillo::DependencyGraph::Vertex>]
|
538
|
-
# An array of target-appropriate nodes whose `payload`s are
|
539
|
-
# dependencies for `target`.
|
540
|
-
#
|
541
|
-
def valid_dependencies_for_target(target)
|
542
|
-
dependencies = Set.new
|
543
|
-
@podfile_dependency_cache.target_definition_dependencies(target).each do |dep|
|
544
|
-
node = @activated.vertex_named(dep.name)
|
545
|
-
add_valid_dependencies_from_node(node, target, dependencies)
|
555
|
+
class EdgeAndPlatform
|
556
|
+
def initialize(edge, target_platform)
|
557
|
+
@edge = edge
|
558
|
+
@target_platform = target_platform
|
546
559
|
end
|
547
|
-
|
548
|
-
end
|
560
|
+
attr_reader :edge, :target_platform
|
549
561
|
|
550
|
-
|
551
|
-
|
552
|
-
validate_platform(node.payload, target)
|
553
|
-
node.outgoing_edges.each do |edge|
|
554
|
-
next unless edge_is_valid_for_target_platform?(edge, target.platform)
|
555
|
-
add_valid_dependencies_from_node(edge.destination, target, dependencies)
|
562
|
+
def eql?(other)
|
563
|
+
edge.equal?(other.edge) && target_platform.eql?(other.target_platform)
|
556
564
|
end
|
557
|
-
end
|
558
565
|
|
559
|
-
|
566
|
+
def hash
|
567
|
+
edge.object_id ^ target_platform.hash
|
568
|
+
end
|
569
|
+
end
|
560
570
|
private_constant :EdgeAndPlatform
|
561
571
|
|
562
572
|
# Whether the given `edge` should be followed to find dependencies for the
|