cocoapods 1.6.2 → 1.7.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +101 -7
  3. data/README.md +9 -9
  4. data/lib/cocoapods.rb +2 -0
  5. data/lib/cocoapods/command.rb +1 -1
  6. data/lib/cocoapods/command/init.rb +2 -12
  7. data/lib/cocoapods/command/install.rb +3 -0
  8. data/lib/cocoapods/command/lib/create.rb +1 -1
  9. data/lib/cocoapods/command/lib/lint.rb +5 -1
  10. data/lib/cocoapods/command/list.rb +3 -5
  11. data/lib/cocoapods/command/repo.rb +1 -0
  12. data/lib/cocoapods/command/repo/add.rb +4 -5
  13. data/lib/cocoapods/command/repo/add_cdn.rb +58 -0
  14. data/lib/cocoapods/command/repo/list.rb +5 -6
  15. data/lib/cocoapods/command/repo/push.rb +6 -5
  16. data/lib/cocoapods/command/spec/create.rb +12 -12
  17. data/lib/cocoapods/command/spec/lint.rb +1 -1
  18. data/lib/cocoapods/command/update.rb +3 -0
  19. data/lib/cocoapods/config.rb +1 -0
  20. data/lib/cocoapods/executable.rb +32 -7
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/app_target_helper.rb +1 -1
  23. data/lib/cocoapods/generator/embed_frameworks_script.rb +13 -0
  24. data/lib/cocoapods/generator/file_list.rb +39 -0
  25. data/lib/cocoapods/generator/module_map.rb +1 -1
  26. data/lib/cocoapods/installer.rb +188 -46
  27. data/lib/cocoapods/installer/analyzer.rb +64 -39
  28. data/lib/cocoapods/installer/analyzer/pod_variant.rb +14 -9
  29. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +11 -2
  30. data/lib/cocoapods/installer/installation_options.rb +70 -44
  31. data/lib/cocoapods/installer/pod_source_installer.rb +9 -4
  32. data/lib/cocoapods/installer/podfile_validator.rb +9 -0
  33. data/lib/cocoapods/installer/post_install_hooks_context.rb +5 -2
  34. data/lib/cocoapods/installer/project_cache/project_cache.rb +11 -0
  35. data/lib/cocoapods/installer/project_cache/project_cache_analysis_result.rb +53 -0
  36. data/lib/cocoapods/installer/project_cache/project_cache_analyzer.rb +156 -0
  37. data/lib/cocoapods/installer/project_cache/project_cache_version.rb +43 -0
  38. data/lib/cocoapods/installer/project_cache/project_installation_cache.rb +77 -0
  39. data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +63 -0
  40. data/lib/cocoapods/installer/project_cache/target_cache_key.rb +134 -0
  41. data/lib/cocoapods/installer/project_cache/target_metadata.rb +70 -0
  42. data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +89 -0
  43. data/lib/cocoapods/installer/sandbox_header_paths_installer.rb +45 -0
  44. data/lib/cocoapods/installer/target_uuid_generator.rb +32 -0
  45. data/lib/cocoapods/installer/user_project_integrator.rb +8 -6
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +128 -63
  47. data/lib/cocoapods/installer/xcode.rb +3 -0
  48. data/lib/cocoapods/installer/xcode/multi_pods_project_generator.rb +72 -0
  49. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +102 -218
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +75 -0
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +1 -1
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +29 -17
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +31 -65
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +155 -0
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +265 -110
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +70 -43
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/pods_project_writer.rb +75 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +119 -0
  59. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +44 -7
  60. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +5 -7
  61. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +32 -0
  62. data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +35 -0
  63. data/lib/cocoapods/installer/xcode/single_pods_project_generator.rb +38 -0
  64. data/lib/cocoapods/installer/xcode/target_validator.rb +32 -25
  65. data/lib/cocoapods/native_target_extension.rb +54 -0
  66. data/lib/cocoapods/open-uri.rb +1 -1
  67. data/lib/cocoapods/podfile.rb +13 -0
  68. data/lib/cocoapods/project.rb +88 -10
  69. data/lib/cocoapods/resolver.rb +11 -8
  70. data/lib/cocoapods/resolver/resolver_specification.rb +7 -7
  71. data/lib/cocoapods/sandbox.rb +38 -9
  72. data/lib/cocoapods/sandbox/file_accessor.rb +21 -0
  73. data/lib/cocoapods/sandbox/headers_store.rb +18 -3
  74. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +1 -14
  75. data/lib/cocoapods/sources_manager.rb +11 -3
  76. data/lib/cocoapods/target.rb +67 -7
  77. data/lib/cocoapods/target/aggregate_target.rb +70 -8
  78. data/lib/cocoapods/target/build_settings.rb +124 -65
  79. data/lib/cocoapods/target/build_type.rb +139 -0
  80. data/lib/cocoapods/target/framework_paths.rb +12 -7
  81. data/lib/cocoapods/target/pod_target.rb +322 -65
  82. data/lib/cocoapods/user_interface.rb +2 -2
  83. data/lib/cocoapods/user_interface/error_report.rb +3 -0
  84. data/lib/cocoapods/user_interface/inspector_reporter.rb +1 -1
  85. data/lib/cocoapods/validator.rb +74 -39
  86. data/lib/cocoapods/version_metadata.rb +7 -0
  87. metadata +30 -6
@@ -65,6 +65,11 @@ module Pod
65
65
 
66
66
  # Cleans the installations if appropriate.
67
67
  #
68
+ # Cleaning the installation will remove any files that are not used during the build process, based on
69
+ # the podspec and platforms of the target that the pod is integrated into.
70
+ #
71
+ # @see {#clean_installation}
72
+ #
68
73
  # @return [void]
69
74
  #
70
75
  def clean!
@@ -137,6 +142,10 @@ module Pod
137
142
  )
138
143
  end
139
144
 
145
+ #-----------------------------------------------------------------------#
146
+
147
+ private
148
+
140
149
  # Removes all the files not needed for the installation according to the
141
150
  # specs by platform.
142
151
  #
@@ -147,10 +156,6 @@ module Pod
147
156
  cleaner.clean!
148
157
  end
149
158
 
150
- #-----------------------------------------------------------------------#
151
-
152
- private
153
-
154
159
  # @!group Convenience methods.
155
160
 
156
161
  # @return [Array<Specifications>] the specification of the Pod used in
@@ -36,6 +36,7 @@ module Pod
36
36
  # Errors are added to the errors array
37
37
  #
38
38
  def validate
39
+ validate_installation_options
39
40
  validate_pod_directives
40
41
  validate_no_abstract_only_pods!
41
42
  validate_dependencies_are_present!
@@ -71,6 +72,14 @@ module Pod
71
72
  warnings << warning
72
73
  end
73
74
 
75
+ def validate_installation_options
76
+ installation_options = podfile.installation_options
77
+
78
+ # Validate `incremental_installation` depends on `generate_multiple_pod_projects`
79
+ invalid = installation_options.incremental_installation? && installation_options.incremental_installation != installation_options.generate_multiple_pod_projects
80
+ add_error 'The installation option `incremental_installation` requires the option `generate_multiple_pod_projects` to also be enabled.' if invalid
81
+ end
82
+
74
83
  def validate_pod_directives
75
84
  @podfile_dependency_cache.podfile_dependencies.each do |dependency|
76
85
  validate_conflicting_external_sources!(dependency)
@@ -40,6 +40,9 @@ module Pod
40
40
  # @param [Sandbox] sandbox
41
41
  # The sandbox
42
42
  #
43
+ # @param [Project] pods_project
44
+ # The pods project.
45
+ #
43
46
  # @param [Array<AggregateTarget>] aggregate_targets
44
47
  # The aggregate targets, which will been presented by an adequate
45
48
  # {UmbrellaTargetDescription} in the generated context.
@@ -47,7 +50,7 @@ module Pod
47
50
  # @return [HooksContext] Convenience class method to generate the
48
51
  # static context.
49
52
  #
50
- def self.generate(sandbox, aggregate_targets)
53
+ def self.generate(sandbox, pods_project, aggregate_targets)
51
54
  umbrella_targets_descriptions = aggregate_targets.map do |umbrella|
52
55
  user_project = umbrella.user_project
53
56
  user_targets = umbrella.user_targets
@@ -58,7 +61,7 @@ module Pod
58
61
  UmbrellaTargetDescription.new(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
59
62
  end
60
63
 
61
- new(sandbox, sandbox.root.to_s, sandbox.project, umbrella_targets_descriptions)
64
+ new(sandbox, sandbox.root.to_s, pods_project, umbrella_targets_descriptions)
62
65
  end
63
66
 
64
67
  # Pure data class which describes an umbrella target.
@@ -0,0 +1,11 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ autoload :ProjectCacheAnalyzer, 'cocoapods/installer/project_cache/project_cache_analyzer'
5
+ autoload :ProjectInstallationCache, 'cocoapods/installer/project_cache/project_installation_cache'
6
+ autoload :ProjectMetadataCache, 'cocoapods/installer/project_cache/project_metadata_cache'
7
+ autoload :ProjectCacheAnalysisResult, 'cocoapods/installer/project_cache/project_cache_analysis_result'
8
+ autoload :ProjectCacheVersion, 'cocoapods/installer/project_cache/project_cache_version'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ # The result object from analyzing the project cache.
5
+ #
6
+ class ProjectCacheAnalysisResult
7
+ # @return [Array<PodTarget>]
8
+ # The list of pod targets that need to be regenerated.
9
+ #
10
+ attr_reader :pod_targets_to_generate
11
+
12
+ # @return [Array<AggregateTarget>]
13
+ # The list of aggregate targets that need to be regenerated. This can be nil if we don't want to
14
+ # generate ANY aggregate targets since we still want to be able to generate an empty list of aggregate
15
+ # targets.
16
+ #
17
+ attr_reader :aggregate_targets_to_generate
18
+
19
+ # @return [Hash{String => TargetCacheKey}]
20
+ # Updated hash of target cache key by target label for all targets.
21
+ #
22
+ attr_reader :cache_key_by_target_label
23
+
24
+ # @return [Hash{String => Symbol}]
25
+ # The build configurations to install with each target.
26
+ #
27
+ attr_reader :build_configurations
28
+
29
+ # @return [String]
30
+ # The project object version to install with each target.
31
+ #
32
+ attr_reader :project_object_version
33
+
34
+ # Initialize a new instance.
35
+ #
36
+ # @param [Array<PodTarget>] pod_targets_to_generate @see #pod_targets_to_generate
37
+ # @param [Array<AggregateTarget] aggregate_targets_to_generate @see #aggregate_targets_to_generate
38
+ # @param [Hash{String => TargetCacheKey}] cache_key_by_target_label @see #cache_key_by_target_label
39
+ # @param [Hash{String => Symbol}] build_configurations @see #build_configurations
40
+ # @param [String] project_object_version @see #project_object_version
41
+ #
42
+ def initialize(pod_targets_to_generate, aggregate_targets_to_generate, cache_key_by_target_label,
43
+ build_configurations, project_object_version)
44
+ @pod_targets_to_generate = pod_targets_to_generate
45
+ @aggregate_targets_to_generate = aggregate_targets_to_generate
46
+ @cache_key_by_target_label = cache_key_by_target_label
47
+ @build_configurations = build_configurations
48
+ @project_object_version = project_object_version
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,156 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ # Analyzes the project cache and computes which pod targets need to be generated.
5
+ #
6
+ class ProjectCacheAnalyzer
7
+ require 'cocoapods/installer/project_cache/project_cache_analysis_result'
8
+
9
+ # @return [Sandbox] Project sandbox.
10
+ #
11
+ attr_reader :sandbox
12
+
13
+ # @return [ProjectInstallationCache] The cache of targets that were previously installed.
14
+ #
15
+ attr_reader :cache
16
+
17
+ # @return [Hash{String => Symbol}] The hash of user build configurations.
18
+ #
19
+ attr_reader :build_configurations
20
+
21
+ # @return [String] The object version from the user project.
22
+ #
23
+ attr_reader :project_object_version
24
+
25
+ # @return [Array<PodTarget>] The list of pod targets.
26
+ #
27
+ attr_reader :pod_targets
28
+
29
+ # @return [Array<AggregateTarget>] The list of aggregate targets.
30
+ #
31
+ attr_reader :aggregate_targets
32
+
33
+ # @return [Bool] Flag indicating if we want to ignore the cache and force a clean installation.
34
+ #
35
+ attr_reader :clean_install
36
+
37
+ # Initialize a new instance.
38
+ #
39
+ # @param [Sandbox] sandbox @see #sandbox
40
+ # @param [ProjectInstallationCache] cache @see #cache
41
+ # @param [Hash{String => Symbol}] build_configurations @see #build_configurations
42
+ # @param [String] project_object_version @see #project_object_version
43
+ # @param [Array<PodTarget>] pod_targets @see #pod_targets
44
+ # @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
45
+ # @param [Bool] clean_install @see #clean_install
46
+ #
47
+ def initialize(sandbox, cache, build_configurations, project_object_version, pod_targets, aggregate_targets,
48
+ clean_install: false)
49
+ @sandbox = sandbox
50
+ @cache = cache
51
+ @build_configurations = build_configurations
52
+ @pod_targets = pod_targets
53
+ @aggregate_targets = aggregate_targets
54
+ @project_object_version = project_object_version
55
+ @clean_install = clean_install
56
+ end
57
+
58
+ # @return [ProjectCacheAnalysisResult]
59
+ # Compares all targets stored against the cache and computes which targets need to be regenerated.
60
+ #
61
+ def analyze
62
+ target_by_label = Hash[(pod_targets + aggregate_targets).map { |target| [target.label, target] }]
63
+ cache_key_by_target_label = create_cache_key_mappings(target_by_label)
64
+
65
+ full_install_results = ProjectCacheAnalysisResult.new(pod_targets, aggregate_targets, cache_key_by_target_label,
66
+ build_configurations, project_object_version)
67
+ if clean_install
68
+ UI.message 'Ignoring project cache from the provided `--clean-install` flag.'
69
+ return full_install_results
70
+ end
71
+
72
+ # Bail out early since these properties affect all targets and their associate projects.
73
+ if cache.build_configurations != build_configurations || cache.project_object_version != project_object_version
74
+ UI.message 'Ignoring project cache due to project configuration changes.'
75
+ return full_install_results
76
+ end
77
+
78
+ added_targets, removed_targets = compute_added_and_removed_targets(target_by_label,
79
+ cache_key_by_target_label.keys,
80
+ cache.cache_key_by_target_label.keys)
81
+ added_pod_targets, added_aggregate_targets = added_targets.partition { |target| target.is_a?(PodTarget) }
82
+ removed_aggregate_targets = removed_targets.select { |target| target.is_a?(AggregateTarget) }
83
+
84
+ changed_targets = compute_changed_targets_from_cache(cache_key_by_target_label, target_by_label, cache)
85
+ changed_pod_targets, changed_aggregate_targets = changed_targets.partition { |target| target.is_a?(PodTarget) }
86
+
87
+ dirty_targets = compute_dirty_targets(pod_targets + aggregate_targets)
88
+ dirty_pod_targets, dirty_aggregate_targets = dirty_targets.partition { |target| target.is_a?(PodTarget) }
89
+
90
+ pod_targets_to_generate = (changed_pod_targets + added_pod_targets + dirty_pod_targets).uniq
91
+
92
+ # We either return the full list of aggregate targets or none since the aggregate targets go into the Pods.xcodeproj
93
+ # and so we need to regenerate all aggregate targets when regenerating Pods.xcodeproj.
94
+ aggregate_target_to_generate =
95
+ unless (changed_aggregate_targets + added_aggregate_targets + removed_aggregate_targets + dirty_aggregate_targets).empty?
96
+ aggregate_targets
97
+ end
98
+
99
+ ProjectCacheAnalysisResult.new(pod_targets_to_generate, aggregate_target_to_generate, cache_key_by_target_label,
100
+ build_configurations, project_object_version)
101
+ end
102
+
103
+ private
104
+
105
+ def create_cache_key_mappings(target_by_label)
106
+ Hash[target_by_label.map do |label, target|
107
+ case target
108
+ when PodTarget
109
+ local = sandbox.local?(target.pod_name)
110
+ checkout_options = sandbox.checkout_sources[target.pod_name]
111
+ [label, TargetCacheKey.from_pod_target(target, :is_local_pod => local, :checkout_options => checkout_options)]
112
+ when AggregateTarget
113
+ [label, TargetCacheKey.from_aggregate_target(target)]
114
+ else
115
+ raise "[BUG] Unknown target type #{target}"
116
+ end
117
+ end]
118
+ end
119
+
120
+ def compute_added_and_removed_targets(target_by_label, target_labels, cached_target_labels)
121
+ added_targets = (target_labels - cached_target_labels).map do |label|
122
+ target_by_label[label]
123
+ end
124
+ removed_targets = (cached_target_labels - target_labels).map do |label|
125
+ target_by_label[label]
126
+ end
127
+ [added_targets, removed_targets]
128
+ end
129
+
130
+ def compute_changed_targets_from_cache(cache_key_by_target_label, target_by_label, cache)
131
+ cache_key_by_target_label.each_with_object([]) do |(label, cache_key), changed_targets|
132
+ next unless cache.cache_key_by_target_label[label]
133
+ if cache_key.key_difference(cache.cache_key_by_target_label[label]) == :project
134
+ changed_targets << target_by_label[label]
135
+ end
136
+ end
137
+ end
138
+
139
+ def compute_dirty_targets(targets)
140
+ targets.reject do |target|
141
+ support_files_dir_exists = File.exist? target.support_files_dir
142
+ xcodeproj_exists = case target
143
+ when PodTarget
144
+ File.exist? sandbox.pod_target_project_path(target.pod_name)
145
+ when AggregateTarget
146
+ File.exist? sandbox.project_path
147
+ else
148
+ raise "[BUG] Unknown target type #{target}"
149
+ end
150
+ support_files_dir_exists && xcodeproj_exists
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,43 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ # Object that stores, loads, and holds the version of the project cache.
5
+ #
6
+ class ProjectCacheVersion
7
+ # @return [Version] The version of the project cache.
8
+ #
9
+ attr_reader :version
10
+
11
+ # Initialize a new instance.
12
+ #
13
+ # @param [Version] version @see #version
14
+ #
15
+ def initialize(version = Version.create('0'))
16
+ @version = version
17
+ end
18
+
19
+ # Constructs a ProjectCacheVersion from a file.
20
+ #
21
+ # @param [String] path
22
+ # The path of the project cache
23
+ #
24
+ # @return [ProjectCacheVersion]
25
+ #
26
+ def self.from_file(path)
27
+ return ProjectCacheVersion.new unless File.exist?(path)
28
+ cached_version = Version.create(File.read(path))
29
+ ProjectCacheVersion.new(cached_version)
30
+ end
31
+
32
+ # @return [void]
33
+ #
34
+ # @param [String] path
35
+ # The path of the project cache to save.
36
+ #
37
+ def save_as(path)
38
+ open(path, 'w') { |f| f.puts version.to_s }
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,77 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ # Represents the cache stored at Pods/.project/installation_cache
5
+ #
6
+ class ProjectInstallationCache
7
+ require 'cocoapods/installer/project_cache/target_cache_key'
8
+
9
+ # @return [Hash{String => TargetCacheKey}]
10
+ # Stored hash of target cache key objects for every pod target.
11
+ #
12
+ attr_reader :cache_key_by_target_label
13
+
14
+ # @return [Hash{String => Symbol}]
15
+ # Build configurations stored in the cache.
16
+ #
17
+ attr_reader :build_configurations
18
+
19
+ # @return [String]
20
+ # Project object stored in the cache.
21
+ #
22
+ attr_reader :project_object_version
23
+
24
+ # Initializes a new instance.
25
+ #
26
+ # @param [Hash{String => TargetCacheKey}] cache_key_by_target_label @see #cache_key_by_target_label
27
+ # @param [Hash{String => Symbol}] build_configurations @see #build_configurations
28
+ # @param [String] project_object_version @see #project_object_version
29
+ #
30
+ def initialize(cache_key_by_target_label = {}, build_configurations = nil, project_object_version = nil)
31
+ @cache_key_by_target_label = cache_key_by_target_label
32
+ @build_configurations = build_configurations
33
+ @project_object_version = project_object_version
34
+ end
35
+
36
+ def update_cache_key_by_target_label!(cache_key_by_target_label)
37
+ @cache_key_by_target_label = cache_key_by_target_label
38
+ end
39
+
40
+ def update_build_configurations!(build_configurations)
41
+ @build_configurations = build_configurations
42
+ end
43
+
44
+ def update_project_object_version!(project_object_version)
45
+ @project_object_version = project_object_version
46
+ end
47
+
48
+ def save_as(path)
49
+ Pathname(path).dirname.mkpath
50
+ path.open('w') { |f| f.puts YAMLHelper.convert(to_hash) }
51
+ end
52
+
53
+ def self.from_file(path)
54
+ return ProjectInstallationCache.new unless File.exist?(path)
55
+ contents = YAMLHelper.load_file(path)
56
+ cache_keys = contents.fetch('CACHE_KEYS', {})
57
+ cache_key_by_target_label = Hash[cache_keys.map do |name, key_hash|
58
+ [name, TargetCacheKey.from_cache_hash(key_hash)]
59
+ end]
60
+ project_object_version = contents['OBJECT_VERSION']
61
+ build_configurations = contents['BUILD_CONFIGURATIONS']
62
+ ProjectInstallationCache.new(cache_key_by_target_label, build_configurations, project_object_version)
63
+ end
64
+
65
+ def to_hash
66
+ cache_key_contents = Hash[cache_key_by_target_label.map do |label, key|
67
+ [label, key.to_h]
68
+ end]
69
+ contents = { 'CACHE_KEYS' => cache_key_contents }
70
+ contents['BUILD_CONFIGURATIONS'] = build_configurations if build_configurations
71
+ contents['OBJECT_VERSION'] = project_object_version if project_object_version
72
+ contents
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ module Pod
2
+ class Installer
3
+ module ProjectCache
4
+ # Represents the metadata cache
5
+ #
6
+ class ProjectMetadataCache
7
+ require 'cocoapods/installer/project_cache/target_metadata.rb'
8
+
9
+ # @return [Hash{String => TargetMetadata}]
10
+ # Hash of string by target metadata.
11
+ #
12
+ attr_reader :target_label_by_metadata
13
+
14
+ # Initialize a new instance.
15
+ #
16
+ # @param [Hash{String => TargetMetadata}] target_label_by_metadata @see #target_label_by_metadata
17
+ #
18
+ def initialize(target_label_by_metadata = {})
19
+ @target_label_by_metadata = target_label_by_metadata
20
+ end
21
+
22
+ def to_hash
23
+ Hash[target_label_by_metadata.map do |target_label, metdata|
24
+ [target_label, metdata.to_hash]
25
+ end]
26
+ end
27
+
28
+ # Rewrites the entire cache to the given path.
29
+ #
30
+ # @param [String] path
31
+ #
32
+ # @return [void]
33
+ #
34
+ def save_as(path)
35
+ path.open('w') { |f| f.puts YAMLHelper.convert_hash(to_hash, nil) }
36
+ end
37
+
38
+ # Updates the metadata cache based on installation results.
39
+ #
40
+ # @param [Hash{String => TargetInstallationResult}] pod_target_installation_results
41
+ # The installation results for pod targets installed.
42
+ #
43
+ # @param [Hash{String => TargetInstallationResult}] aggregate_target_installation_results
44
+ # The installation results for aggregate targets installed.
45
+ #
46
+ def update_metadata!(pod_target_installation_results, aggregate_target_installation_results)
47
+ installation_results = pod_target_installation_results.values + aggregate_target_installation_results.values
48
+ installation_results.each do |installation_result|
49
+ native_target = installation_result.native_target
50
+ target_label_by_metadata[native_target.name] = TargetMetadata.from_native_target(native_target)
51
+ end
52
+ end
53
+
54
+ def self.from_file(path)
55
+ return ProjectMetadataCache.new unless File.exist?(path)
56
+ contents = YAMLHelper.load_file(path)
57
+ target_by_label_metadata = Hash[contents.map { |target_label, hash| [target_label, TargetMetadata.from_hash(hash)] }]
58
+ ProjectMetadataCache.new(target_by_label_metadata)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end