cocoapods 1.7.5 → 1.8.0.beta.1
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 +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
|