xcocoapods 1.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|