xcocoapods 1.5.3

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