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.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6303 -0
  3. data/LICENSE +28 -0
  4. data/README.md +80 -0
  5. data/bin/pod +56 -0
  6. data/bin/sandbox-pod +168 -0
  7. data/lib/cocoapods.rb +73 -0
  8. data/lib/cocoapods/command.rb +175 -0
  9. data/lib/cocoapods/command/cache.rb +28 -0
  10. data/lib/cocoapods/command/cache/clean.rb +90 -0
  11. data/lib/cocoapods/command/cache/list.rb +69 -0
  12. data/lib/cocoapods/command/env.rb +66 -0
  13. data/lib/cocoapods/command/init.rb +128 -0
  14. data/lib/cocoapods/command/install.rb +45 -0
  15. data/lib/cocoapods/command/ipc.rb +19 -0
  16. data/lib/cocoapods/command/ipc/list.rb +40 -0
  17. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  18. data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
  19. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  20. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  21. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  22. data/lib/cocoapods/command/lib.rb +11 -0
  23. data/lib/cocoapods/command/lib/create.rb +105 -0
  24. data/lib/cocoapods/command/lib/lint.rb +121 -0
  25. data/lib/cocoapods/command/list.rb +39 -0
  26. data/lib/cocoapods/command/options/project_directory.rb +36 -0
  27. data/lib/cocoapods/command/options/repo_update.rb +34 -0
  28. data/lib/cocoapods/command/outdated.rb +140 -0
  29. data/lib/cocoapods/command/repo.rb +29 -0
  30. data/lib/cocoapods/command/repo/add.rb +103 -0
  31. data/lib/cocoapods/command/repo/lint.rb +82 -0
  32. data/lib/cocoapods/command/repo/list.rb +93 -0
  33. data/lib/cocoapods/command/repo/push.rb +281 -0
  34. data/lib/cocoapods/command/repo/remove.rb +36 -0
  35. data/lib/cocoapods/command/repo/update.rb +28 -0
  36. data/lib/cocoapods/command/setup.rb +103 -0
  37. data/lib/cocoapods/command/spec.rb +112 -0
  38. data/lib/cocoapods/command/spec/cat.rb +51 -0
  39. data/lib/cocoapods/command/spec/create.rb +283 -0
  40. data/lib/cocoapods/command/spec/edit.rb +87 -0
  41. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  42. data/lib/cocoapods/command/spec/lint.rb +137 -0
  43. data/lib/cocoapods/command/spec/which.rb +43 -0
  44. data/lib/cocoapods/command/update.rb +101 -0
  45. data/lib/cocoapods/config.rb +347 -0
  46. data/lib/cocoapods/core_overrides.rb +1 -0
  47. data/lib/cocoapods/downloader.rb +190 -0
  48. data/lib/cocoapods/downloader/cache.rb +233 -0
  49. data/lib/cocoapods/downloader/request.rb +86 -0
  50. data/lib/cocoapods/downloader/response.rb +16 -0
  51. data/lib/cocoapods/executable.rb +222 -0
  52. data/lib/cocoapods/external_sources.rb +57 -0
  53. data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
  54. data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
  55. data/lib/cocoapods/external_sources/path_source.rb +55 -0
  56. data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
  57. data/lib/cocoapods/gem_version.rb +5 -0
  58. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  59. data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
  60. data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
  61. data/lib/cocoapods/generator/app_target_helper.rb +244 -0
  62. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  63. data/lib/cocoapods/generator/constant.rb +19 -0
  64. data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
  65. data/lib/cocoapods/generator/dummy_source.rb +31 -0
  66. data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
  67. data/lib/cocoapods/generator/header.rb +103 -0
  68. data/lib/cocoapods/generator/info_plist_file.rb +116 -0
  69. data/lib/cocoapods/generator/module_map.rb +99 -0
  70. data/lib/cocoapods/generator/prefix_header.rb +60 -0
  71. data/lib/cocoapods/generator/umbrella_header.rb +46 -0
  72. data/lib/cocoapods/hooks_manager.rb +132 -0
  73. data/lib/cocoapods/installer.rb +703 -0
  74. data/lib/cocoapods/installer/analyzer.rb +972 -0
  75. data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
  76. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
  77. data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
  78. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
  79. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  80. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
  81. data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
  82. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
  83. data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
  84. data/lib/cocoapods/installer/installation_options.rb +158 -0
  85. data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
  86. data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
  87. data/lib/cocoapods/installer/podfile_validator.rb +139 -0
  88. data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
  89. data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
  90. data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
  91. data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
  92. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
  93. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
  94. data/lib/cocoapods/installer/xcode.rb +8 -0
  95. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
  96. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
  97. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
  98. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
  99. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
  100. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
  101. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
  102. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
  103. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
  104. data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
  105. data/lib/cocoapods/open-uri.rb +33 -0
  106. data/lib/cocoapods/project.rb +414 -0
  107. data/lib/cocoapods/resolver.rb +585 -0
  108. data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
  109. data/lib/cocoapods/sandbox.rb +404 -0
  110. data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
  111. data/lib/cocoapods/sandbox/headers_store.rb +146 -0
  112. data/lib/cocoapods/sandbox/path_list.rb +220 -0
  113. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
  114. data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
  115. data/lib/cocoapods/sources_manager.rb +157 -0
  116. data/lib/cocoapods/target.rb +261 -0
  117. data/lib/cocoapods/target/aggregate_target.rb +338 -0
  118. data/lib/cocoapods/target/build_settings.rb +1075 -0
  119. data/lib/cocoapods/target/pod_target.rb +559 -0
  120. data/lib/cocoapods/user_interface.rb +459 -0
  121. data/lib/cocoapods/user_interface/error_report.rb +187 -0
  122. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  123. data/lib/cocoapods/validator.rb +981 -0
  124. 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