xcocoapods 1.5.3
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 +7 -0
- data/CHANGELOG.md +6303 -0
- data/LICENSE +28 -0
- data/README.md +80 -0
- data/bin/pod +56 -0
- data/bin/sandbox-pod +168 -0
- data/lib/cocoapods.rb +73 -0
- data/lib/cocoapods/command.rb +175 -0
- data/lib/cocoapods/command/cache.rb +28 -0
- data/lib/cocoapods/command/cache/clean.rb +90 -0
- data/lib/cocoapods/command/cache/list.rb +69 -0
- data/lib/cocoapods/command/env.rb +66 -0
- data/lib/cocoapods/command/init.rb +128 -0
- data/lib/cocoapods/command/install.rb +45 -0
- data/lib/cocoapods/command/ipc.rb +19 -0
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -0
- data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
- data/lib/cocoapods/command/ipc/repl.rb +51 -0
- data/lib/cocoapods/command/ipc/spec.rb +29 -0
- data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
- data/lib/cocoapods/command/lib.rb +11 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +121 -0
- data/lib/cocoapods/command/list.rb +39 -0
- data/lib/cocoapods/command/options/project_directory.rb +36 -0
- data/lib/cocoapods/command/options/repo_update.rb +34 -0
- data/lib/cocoapods/command/outdated.rb +140 -0
- data/lib/cocoapods/command/repo.rb +29 -0
- data/lib/cocoapods/command/repo/add.rb +103 -0
- data/lib/cocoapods/command/repo/lint.rb +82 -0
- data/lib/cocoapods/command/repo/list.rb +93 -0
- data/lib/cocoapods/command/repo/push.rb +281 -0
- data/lib/cocoapods/command/repo/remove.rb +36 -0
- data/lib/cocoapods/command/repo/update.rb +28 -0
- data/lib/cocoapods/command/setup.rb +103 -0
- data/lib/cocoapods/command/spec.rb +112 -0
- data/lib/cocoapods/command/spec/cat.rb +51 -0
- data/lib/cocoapods/command/spec/create.rb +283 -0
- data/lib/cocoapods/command/spec/edit.rb +87 -0
- data/lib/cocoapods/command/spec/env_spec.rb +53 -0
- data/lib/cocoapods/command/spec/lint.rb +137 -0
- data/lib/cocoapods/command/spec/which.rb +43 -0
- data/lib/cocoapods/command/update.rb +101 -0
- data/lib/cocoapods/config.rb +347 -0
- data/lib/cocoapods/core_overrides.rb +1 -0
- data/lib/cocoapods/downloader.rb +190 -0
- data/lib/cocoapods/downloader/cache.rb +233 -0
- data/lib/cocoapods/downloader/request.rb +86 -0
- data/lib/cocoapods/downloader/response.rb +16 -0
- data/lib/cocoapods/executable.rb +222 -0
- data/lib/cocoapods/external_sources.rb +57 -0
- data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods/external_sources/path_source.rb +55 -0
- data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods/gem_version.rb +5 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods/generator/app_target_helper.rb +244 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/constant.rb +19 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
- data/lib/cocoapods/generator/dummy_source.rb +31 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
- data/lib/cocoapods/generator/header.rb +103 -0
- data/lib/cocoapods/generator/info_plist_file.rb +116 -0
- data/lib/cocoapods/generator/module_map.rb +99 -0
- data/lib/cocoapods/generator/prefix_header.rb +60 -0
- data/lib/cocoapods/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods/hooks_manager.rb +132 -0
- data/lib/cocoapods/installer.rb +703 -0
- data/lib/cocoapods/installer/analyzer.rb +972 -0
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
- data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
- data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
- data/lib/cocoapods/installer/installation_options.rb +158 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
- data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods/installer/podfile_validator.rb +139 -0
- data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
- data/lib/cocoapods/installer/xcode.rb +8 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
- data/lib/cocoapods/open-uri.rb +33 -0
- data/lib/cocoapods/project.rb +414 -0
- data/lib/cocoapods/resolver.rb +585 -0
- data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
- data/lib/cocoapods/sandbox.rb +404 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
- data/lib/cocoapods/sandbox/headers_store.rb +146 -0
- data/lib/cocoapods/sandbox/path_list.rb +220 -0
- data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
- data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods/sources_manager.rb +157 -0
- data/lib/cocoapods/target.rb +261 -0
- data/lib/cocoapods/target/aggregate_target.rb +338 -0
- data/lib/cocoapods/target/build_settings.rb +1075 -0
- data/lib/cocoapods/target/pod_target.rb +559 -0
- data/lib/cocoapods/user_interface.rb +459 -0
- data/lib/cocoapods/user_interface/error_report.rb +187 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/validator.rb +981 -0
- metadata +533 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module Pod
|
|
2
|
+
class Installer
|
|
3
|
+
class Analyzer
|
|
4
|
+
# A simple container produced after a analysis is completed by the {Analyzer}.
|
|
5
|
+
#
|
|
6
|
+
class AnalysisResult
|
|
7
|
+
# @return [SpecsState] the states of the Podfile specs.
|
|
8
|
+
#
|
|
9
|
+
attr_reader :podfile_state
|
|
10
|
+
|
|
11
|
+
# @return [Hash{TargetDefinition => Array<Specification>}] the specifications grouped by target.
|
|
12
|
+
#
|
|
13
|
+
attr_reader :specs_by_target
|
|
14
|
+
|
|
15
|
+
# @return [Hash{Source => Array<Specification>}] the specifications grouped by spec repo source.
|
|
16
|
+
#
|
|
17
|
+
attr_reader :specs_by_source
|
|
18
|
+
|
|
19
|
+
# @return [Array<Specification>] the specifications of the resolved version of Pods that should be installed.
|
|
20
|
+
#
|
|
21
|
+
attr_reader :specifications
|
|
22
|
+
|
|
23
|
+
# @return [SpecsState] the states of the {Sandbox} respect the resolved specifications.
|
|
24
|
+
#
|
|
25
|
+
attr_accessor :sandbox_state
|
|
26
|
+
|
|
27
|
+
# @return [Array<AggregateTarget>] The aggregate targets created for each {TargetDefinition} from the {Podfile}.
|
|
28
|
+
#
|
|
29
|
+
attr_reader :targets
|
|
30
|
+
|
|
31
|
+
# @return [Array<PodTarget>] The pod targets created for all the aggregate targets.
|
|
32
|
+
#
|
|
33
|
+
attr_reader :pod_targets
|
|
34
|
+
|
|
35
|
+
# @return [PodfileDependencyCache] the cache of all dependencies in the podfile.
|
|
36
|
+
#
|
|
37
|
+
attr_reader :podfile_dependency_cache
|
|
38
|
+
|
|
39
|
+
def initialize(podfile_state, specs_by_target, specs_by_source, specifications, sandbox_state, targets, pod_targets,
|
|
40
|
+
podfile_dependency_cache)
|
|
41
|
+
@podfile_state = podfile_state
|
|
42
|
+
@specs_by_target = specs_by_target
|
|
43
|
+
@specs_by_source = specs_by_source
|
|
44
|
+
@specifications = specifications
|
|
45
|
+
@sandbox_state = sandbox_state
|
|
46
|
+
@targets = targets
|
|
47
|
+
@pod_targets = pod_targets
|
|
48
|
+
@podfile_dependency_cache = podfile_dependency_cache
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @return [Hash{String=>Symbol}] A hash representing all the user build
|
|
52
|
+
# configurations across all integration targets. Each key
|
|
53
|
+
# corresponds to the name of a configuration and its value to
|
|
54
|
+
# its type (`:debug` or `:release`).
|
|
55
|
+
#
|
|
56
|
+
def all_user_build_configurations
|
|
57
|
+
targets.reduce({}) do |result, target|
|
|
58
|
+
result.merge(target.user_build_configurations)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @return [Bool] Whether an installation should be performed or this
|
|
63
|
+
# CocoaPods project is already up to date.
|
|
64
|
+
#
|
|
65
|
+
def needs_install?
|
|
66
|
+
podfile_needs_install? || sandbox_needs_install?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @return [Bool] Whether the podfile has changes respect to the lockfile.
|
|
70
|
+
#
|
|
71
|
+
def podfile_needs_install?
|
|
72
|
+
state = podfile_state
|
|
73
|
+
needing_install = state.added.length + state.changed.length + state.deleted.length
|
|
74
|
+
needing_install > 0
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [Bool] Whether the sandbox is in synch with the lockfile.
|
|
78
|
+
#
|
|
79
|
+
def sandbox_needs_install?
|
|
80
|
+
state = sandbox_state
|
|
81
|
+
needing_install = state.added.length + state.changed.length + state.deleted.length
|
|
82
|
+
needing_install > 0
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'molinillo/dependency_graph'
|
|
2
|
+
|
|
3
|
+
module Pod
|
|
4
|
+
class Installer
|
|
5
|
+
class Analyzer
|
|
6
|
+
# Generates dependencies that require the specific version of the Pods
|
|
7
|
+
# that haven't changed in the {Lockfile}.
|
|
8
|
+
module LockingDependencyAnalyzer
|
|
9
|
+
# Generates dependencies that require the specific version of the Pods
|
|
10
|
+
# that haven't changed in the {Lockfile}.
|
|
11
|
+
#
|
|
12
|
+
# These dependencies are passed to the {Resolver}, unless the installer
|
|
13
|
+
# is in update mode, to prevent it from upgrading the Pods that weren't
|
|
14
|
+
# changed in the {Podfile}.
|
|
15
|
+
#
|
|
16
|
+
# @param [Lockfile] lockfile the lockfile containing dependency constraints
|
|
17
|
+
#
|
|
18
|
+
# @param [Array<String>] pods_to_update
|
|
19
|
+
# List of pod names which needs to be updated because installer is
|
|
20
|
+
# in update mode for these pods. Pods in this list and all their recursive dependencies
|
|
21
|
+
# will not be included in generated dependency graph
|
|
22
|
+
#
|
|
23
|
+
# @param [Array<String>] pods_to_unlock
|
|
24
|
+
# List of pod names whose version constraints will be removed from the generated dependency graph.
|
|
25
|
+
# Recursive dependencies of the pods won't be affected. This is currently used to force local pods
|
|
26
|
+
# to be evaluated again whenever checksum of the specification of the local pods changes.
|
|
27
|
+
#
|
|
28
|
+
# @return [Molinillo::DependencyGraph<Dependency>] the dependencies
|
|
29
|
+
# generated by the lockfile that prevent the resolver to update
|
|
30
|
+
# a Pod.
|
|
31
|
+
#
|
|
32
|
+
def self.generate_version_locking_dependencies(lockfile, pods_to_update, pods_to_unlock = [])
|
|
33
|
+
dependency_graph = Molinillo::DependencyGraph.new
|
|
34
|
+
|
|
35
|
+
if lockfile
|
|
36
|
+
added_dependency_strings = Set.new
|
|
37
|
+
|
|
38
|
+
explicit_dependencies = lockfile.dependencies
|
|
39
|
+
explicit_dependencies.each do |dependency|
|
|
40
|
+
dependency_graph.add_vertex(dependency.name, dependency, true)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
pods = lockfile.to_hash['PODS'] || []
|
|
44
|
+
pods.each do |pod|
|
|
45
|
+
add_to_dependency_graph(pod, [], dependency_graph, pods_to_unlock, added_dependency_strings)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
pods_to_update = pods_to_update.flat_map do |u|
|
|
49
|
+
root_name = Specification.root_name(u).downcase
|
|
50
|
+
dependency_graph.vertices.each_key.select { |n| Specification.root_name(n).downcase == root_name }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
pods_to_update.each do |u|
|
|
54
|
+
dependency_graph.detach_vertex_named(u)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
dependency_graph
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Generates a completely 'unlocked' dependency graph.
|
|
62
|
+
#
|
|
63
|
+
# @return [Molinillo::DependencyGraph<Dependency>] an empty dependency
|
|
64
|
+
# graph
|
|
65
|
+
#
|
|
66
|
+
def self.unlocked_dependency_graph
|
|
67
|
+
Molinillo::DependencyGraph.new
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def self.add_child_vertex_to_graph(dependency_string, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
|
|
73
|
+
return unless added_dependency_strings.add?(dependency_string)
|
|
74
|
+
dependency = Dependency.from_string(dependency_string)
|
|
75
|
+
if pods_to_unlock.include?(dependency.root_name)
|
|
76
|
+
dependency = Dependency.new(dependency.name)
|
|
77
|
+
end
|
|
78
|
+
vertex = dependency_graph.add_child_vertex(dependency.name, nil, parents, nil)
|
|
79
|
+
dependency = vertex.payload.merge(dependency) if vertex.payload
|
|
80
|
+
vertex.payload = dependency
|
|
81
|
+
dependency
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.add_to_dependency_graph(object, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
|
|
85
|
+
case object
|
|
86
|
+
when String
|
|
87
|
+
add_child_vertex_to_graph(object, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
|
|
88
|
+
when Hash
|
|
89
|
+
object.each do |key, value|
|
|
90
|
+
dependency = add_child_vertex_to_graph(key, parents, dependency_graph, pods_to_unlock, added_dependency_strings)
|
|
91
|
+
value.each { |v| add_to_dependency_graph(v, [dependency.name], dependency_graph, pods_to_unlock, added_dependency_strings) }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Pod
|
|
2
|
+
class Installer
|
|
3
|
+
class Analyzer
|
|
4
|
+
# Bundles the information needed to setup a {PodTarget}.
|
|
5
|
+
class PodVariant
|
|
6
|
+
# @return [Array<Specification>] the spec and subspecs for the target
|
|
7
|
+
#
|
|
8
|
+
attr_reader :specs
|
|
9
|
+
|
|
10
|
+
# @return [Array<Specification>] the test specs for the target
|
|
11
|
+
#
|
|
12
|
+
attr_reader :test_specs
|
|
13
|
+
|
|
14
|
+
# @return [Platform] the platform
|
|
15
|
+
#
|
|
16
|
+
attr_reader :platform
|
|
17
|
+
|
|
18
|
+
# @return [Bool] whether this pod should be built as framework
|
|
19
|
+
#
|
|
20
|
+
attr_reader :requires_frameworks
|
|
21
|
+
alias_method :requires_frameworks?, :requires_frameworks
|
|
22
|
+
|
|
23
|
+
# @return [Specification] the root specification
|
|
24
|
+
#
|
|
25
|
+
def root_spec
|
|
26
|
+
specs.first.root
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Initialize a new instance from its attributes.
|
|
30
|
+
#
|
|
31
|
+
# @param [Array<Specification>] specs @see #specs
|
|
32
|
+
# @param [Array<Specification>] test_specs @see #test_specs
|
|
33
|
+
# @param [Platform] platform @see #platform
|
|
34
|
+
# @param [Bool] requires_frameworks @see #requires_frameworks?
|
|
35
|
+
#
|
|
36
|
+
def initialize(specs, test_specs, platform, requires_frameworks = false)
|
|
37
|
+
@specs = specs
|
|
38
|
+
@test_specs = test_specs
|
|
39
|
+
@platform = platform
|
|
40
|
+
@requires_frameworks = requires_frameworks
|
|
41
|
+
@hash = [specs, platform, requires_frameworks].hash
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @note Test specs are intentionally not included as part of the equality for pod variants since a
|
|
45
|
+
# pod variant should not be affected by the number of test specs included.
|
|
46
|
+
#
|
|
47
|
+
# @return [Bool] whether the {PodVariant} is equal to another taking all
|
|
48
|
+
# all their attributes into account
|
|
49
|
+
#
|
|
50
|
+
def ==(other)
|
|
51
|
+
self.class == other.class &&
|
|
52
|
+
requires_frameworks == other.requires_frameworks &&
|
|
53
|
+
platform == other.platform &&
|
|
54
|
+
specs == other.specs
|
|
55
|
+
end
|
|
56
|
+
alias_method :eql?, :==
|
|
57
|
+
|
|
58
|
+
# Hashes the instance by all its attributes.
|
|
59
|
+
#
|
|
60
|
+
# This adds support to make instances usable as Hash keys.
|
|
61
|
+
#
|
|
62
|
+
# @!visibility private
|
|
63
|
+
attr_reader :hash
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module Pod
|
|
4
|
+
class Installer
|
|
5
|
+
class Analyzer
|
|
6
|
+
# Collects all {PodVariant}.
|
|
7
|
+
class PodVariantSet
|
|
8
|
+
# @return [Array<PodVariant>] the different variants within this set.
|
|
9
|
+
#
|
|
10
|
+
attr_reader :variants
|
|
11
|
+
|
|
12
|
+
# Initialize a new instance.
|
|
13
|
+
#
|
|
14
|
+
# @param [Array<PodVariant>] variants @see #variants
|
|
15
|
+
#
|
|
16
|
+
def initialize(variants)
|
|
17
|
+
@variants = variants
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Describes what makes each {PodVariant} distinct among the others.
|
|
21
|
+
#
|
|
22
|
+
# @return [Hash<PodVariant, String>]
|
|
23
|
+
#
|
|
24
|
+
def scope_suffixes
|
|
25
|
+
return { variants.first => nil } if variants.count == 1
|
|
26
|
+
Hash[scope_by_specs.map do |variant, scope|
|
|
27
|
+
require 'digest'
|
|
28
|
+
scope = Digest::MD5.hexdigest(scope)[0..7] if !scope.nil? && scope.length >= 50
|
|
29
|
+
[variant, scope]
|
|
30
|
+
end]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Groups the collection by result of the block.
|
|
34
|
+
#
|
|
35
|
+
# @param [Block<Variant, #hash>] block
|
|
36
|
+
# @return [Array<PodVariantSet>]
|
|
37
|
+
#
|
|
38
|
+
def group_by(&block)
|
|
39
|
+
variants.group_by(&block).map { |_, v| PodVariantSet.new(v) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @private
|
|
43
|
+
#
|
|
44
|
+
# Prepends the given scoped {PodVariant}s with another scoping label, if there
|
|
45
|
+
# was more than one group of {PodVariant}s given.
|
|
46
|
+
#
|
|
47
|
+
# @param [Array<Hash<PodVariant, String>>] scoped_variants
|
|
48
|
+
# {PodVariant}s, which where grouped on base of a criteria, which is used
|
|
49
|
+
# in the block argument to generate a descriptive label.
|
|
50
|
+
#
|
|
51
|
+
# @param [Block<PodVariant, String>] block
|
|
52
|
+
# takes a {PodVariant} and returns a scope suffix which is prepended, if
|
|
53
|
+
# necessary.
|
|
54
|
+
#
|
|
55
|
+
# @return [Hash<PodVariant, String>]
|
|
56
|
+
#
|
|
57
|
+
def scope_if_necessary(scoped_variants, &block)
|
|
58
|
+
if scoped_variants.count == 1
|
|
59
|
+
return scoped_variants.first
|
|
60
|
+
end
|
|
61
|
+
Hash[scoped_variants.flat_map do |variants|
|
|
62
|
+
variants.map do |variant, suffix|
|
|
63
|
+
prefix = block.call(variant)
|
|
64
|
+
scope = [prefix, suffix].compact.join('-')
|
|
65
|
+
[variant, !scope.empty? ? scope : nil]
|
|
66
|
+
end
|
|
67
|
+
end]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @private
|
|
71
|
+
# @return [Hash<PodVariant, String>]
|
|
72
|
+
#
|
|
73
|
+
def scope_by_build_type
|
|
74
|
+
scope_if_necessary(group_by(&:requires_frameworks).map(&:scope_by_platform)) do |variant|
|
|
75
|
+
variant.requires_frameworks? ? 'framework' : 'library'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @private
|
|
80
|
+
# @return [Hash<PodVariant, String>]
|
|
81
|
+
#
|
|
82
|
+
def scope_by_platform
|
|
83
|
+
grouped_variants = group_by { |v| v.platform.name }
|
|
84
|
+
if grouped_variants.all? { |set| set.variants.count == 1 }
|
|
85
|
+
# => Platform name
|
|
86
|
+
platform_name_proc = proc { |v| Platform.string_name(v.platform.symbolic_name).tr(' ', '') }
|
|
87
|
+
else
|
|
88
|
+
grouped_variants = group_by(&:platform)
|
|
89
|
+
# => Platform name + SDK version
|
|
90
|
+
platform_name_proc = proc { |v| v.platform.to_s.tr(' ', '') }
|
|
91
|
+
end
|
|
92
|
+
scope_if_necessary(grouped_variants.map(&:scope_without_suffix), &platform_name_proc)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @private
|
|
96
|
+
# @return [Hash<PodVariant, String>]
|
|
97
|
+
#
|
|
98
|
+
def scope_by_specs
|
|
99
|
+
root_spec = variants.first.root_spec
|
|
100
|
+
specs = [root_spec]
|
|
101
|
+
specs += if root_spec.default_subspecs.empty?
|
|
102
|
+
root_spec.subspecs.compact
|
|
103
|
+
else
|
|
104
|
+
root_spec.default_subspecs.map do |subspec_name|
|
|
105
|
+
root_spec.subspec_by_name("#{root_spec.name}/#{subspec_name}")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
default_specs = Set.new(specs)
|
|
109
|
+
grouped_variants = group_by(&:specs)
|
|
110
|
+
all_spec_variants = grouped_variants.map { |set| set.variants.first.specs }
|
|
111
|
+
common_specs = all_spec_variants.map(&:to_set).flatten.inject(&:&)
|
|
112
|
+
omit_common_specs = common_specs.any? && common_specs.proper_superset?(default_specs)
|
|
113
|
+
scope_if_necessary(grouped_variants.map(&:scope_by_build_type)) do |variant|
|
|
114
|
+
specs = variant.specs.to_set
|
|
115
|
+
|
|
116
|
+
# The current variant contains all default specs
|
|
117
|
+
omit_default_specs = default_specs.any? && default_specs.subset?(specs)
|
|
118
|
+
if omit_default_specs
|
|
119
|
+
specs -= default_specs
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# There are common specs, which are different from the default specs
|
|
123
|
+
if omit_common_specs
|
|
124
|
+
specs -= common_specs
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
spec_names = specs.map do |spec|
|
|
128
|
+
spec.root? ? '.root' : spec.name.split('/')[1..-1].join('_')
|
|
129
|
+
end.sort
|
|
130
|
+
if spec_names.empty?
|
|
131
|
+
omit_common_specs ? '.common' : nil
|
|
132
|
+
else
|
|
133
|
+
if omit_common_specs
|
|
134
|
+
spec_names.unshift('.common')
|
|
135
|
+
elsif omit_default_specs
|
|
136
|
+
spec_names.unshift('.default')
|
|
137
|
+
end
|
|
138
|
+
spec_names.reduce('') do |acc, name|
|
|
139
|
+
"#{acc}#{acc.empty? || name[0] == '.' ? '' : '-'}#{name}"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @private
|
|
146
|
+
#
|
|
147
|
+
# Helps to define scope suffixes recursively.
|
|
148
|
+
#
|
|
149
|
+
# @return [Hash<PodVariant, String>]
|
|
150
|
+
#
|
|
151
|
+
def scope_without_suffix
|
|
152
|
+
Hash[variants.map { |v| [v, nil] }]
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Pod
|
|
2
|
+
class Installer
|
|
3
|
+
class Analyzer
|
|
4
|
+
# Caches podfile & target definition dependencies, so they do not need to be re-computed
|
|
5
|
+
# from the internal hash on each access
|
|
6
|
+
#
|
|
7
|
+
class PodfileDependencyCache
|
|
8
|
+
# @return [Array<Pod::Dependency>]
|
|
9
|
+
# All the dependencies in the podfile
|
|
10
|
+
#
|
|
11
|
+
attr_reader :podfile_dependencies
|
|
12
|
+
|
|
13
|
+
def initialize(podfile_dependencies, dependencies_by_target_definition)
|
|
14
|
+
@podfile_dependencies = podfile_dependencies
|
|
15
|
+
@dependencies_by_target_definition = dependencies_by_target_definition
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the dependencies for the given target definition
|
|
19
|
+
#
|
|
20
|
+
def target_definition_dependencies(target_definition)
|
|
21
|
+
@dependencies_by_target_definition[target_definition] ||
|
|
22
|
+
raise(ArgumentError, "dependencies for #{target_definition.inspect} do not exist in the cache")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Returns a list of all of the target definitions in the Podfile
|
|
26
|
+
#
|
|
27
|
+
def target_definition_list
|
|
28
|
+
@dependencies_by_target_definition.keys
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Creates a {PodfileDependencyCache} from the given {Podfile}
|
|
32
|
+
#
|
|
33
|
+
# @param [Podfile] podfile
|
|
34
|
+
# The {Podfile} from which dependencies should be cached
|
|
35
|
+
#
|
|
36
|
+
# @return [PodfileDependencyCache]
|
|
37
|
+
# A warmed, immutable cache of all the dependencies in the {Podfile}
|
|
38
|
+
#
|
|
39
|
+
def self.from_podfile(podfile)
|
|
40
|
+
podfile_dependencies = []
|
|
41
|
+
dependencies_by_target_definition = {}
|
|
42
|
+
podfile.target_definition_list.each do |target_definition|
|
|
43
|
+
deps = target_definition.dependencies.freeze
|
|
44
|
+
podfile_dependencies.concat deps
|
|
45
|
+
dependencies_by_target_definition[target_definition] = deps
|
|
46
|
+
end
|
|
47
|
+
podfile_dependencies.uniq!
|
|
48
|
+
|
|
49
|
+
new(podfile_dependencies.freeze, dependencies_by_target_definition.freeze)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|