cocoapods 1.5.3 → 1.6.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +200 -0
  3. data/lib/cocoapods.rb +0 -1
  4. data/lib/cocoapods/command/init.rb +1 -1
  5. data/lib/cocoapods/command/install.rb +7 -0
  6. data/lib/cocoapods/command/lib/lint.rb +8 -1
  7. data/lib/cocoapods/command/outdated.rb +2 -7
  8. data/lib/cocoapods/command/repo/add.rb +1 -1
  9. data/lib/cocoapods/command/repo/list.rb +1 -1
  10. data/lib/cocoapods/command/repo/push.rb +17 -12
  11. data/lib/cocoapods/command/repo/remove.rb +1 -1
  12. data/lib/cocoapods/command/repo/update.rb +1 -1
  13. data/lib/cocoapods/command/setup.rb +1 -1
  14. data/lib/cocoapods/command/spec/create.rb +39 -39
  15. data/lib/cocoapods/command/spec/lint.rb +8 -1
  16. data/lib/cocoapods/config.rb +13 -2
  17. data/lib/cocoapods/downloader/cache.rb +1 -1
  18. data/lib/cocoapods/executable.rb +2 -2
  19. data/lib/cocoapods/external_sources.rb +7 -4
  20. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  21. data/lib/cocoapods/gem_version.rb +1 -1
  22. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  23. data/lib/cocoapods/generator/acknowledgements/plist.rb +11 -0
  24. data/lib/cocoapods/generator/app_target_helper.rb +102 -16
  25. data/lib/cocoapods/generator/copy_resources_script.rb +6 -0
  26. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  27. data/lib/cocoapods/generator/embed_frameworks_script.rb +13 -2
  28. data/lib/cocoapods/generator/header.rb +1 -1
  29. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  30. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  31. data/lib/cocoapods/hooks_manager.rb +28 -17
  32. data/lib/cocoapods/installer.rb +103 -42
  33. data/lib/cocoapods/installer/analyzer.rb +362 -277
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +9 -6
  36. data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
  37. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
  38. data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
  39. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +24 -16
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  42. data/lib/cocoapods/installer/post_install_hooks_context.rb +71 -46
  43. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  44. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  45. data/lib/cocoapods/installer/user_project_integrator.rb +0 -2
  46. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +38 -28
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +129 -119
  49. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +95 -0
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +12 -45
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +277 -169
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +31 -24
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +60 -69
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  57. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  58. data/lib/cocoapods/project.rb +14 -14
  59. data/lib/cocoapods/resolver.rb +38 -50
  60. data/lib/cocoapods/sandbox.rb +22 -38
  61. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  62. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  63. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  64. data/lib/cocoapods/sources_manager.rb +1 -1
  65. data/lib/cocoapods/target.rb +92 -37
  66. data/lib/cocoapods/target/aggregate_target.rb +140 -84
  67. data/lib/cocoapods/target/build_settings.rb +1076 -0
  68. data/lib/cocoapods/target/pod_target.rb +198 -294
  69. data/lib/cocoapods/user_interface.rb +5 -0
  70. data/lib/cocoapods/validator.rb +133 -41
  71. metadata +18 -18
  72. data/lib/cocoapods/generator/xcconfig.rb +0 -13
  73. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  74. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  75. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
@@ -6,16 +6,16 @@ module Pod
6
6
  # the test targets included by each pod target.
7
7
  #
8
8
  class PodTargetIntegrator
9
- # @return [PodTarget] the target that should be integrated.
9
+ # @return [TargetInstallationResult] the installation result of the target that should be integrated.
10
10
  #
11
- attr_reader :target
11
+ attr_reader :target_installation_result
12
12
 
13
- # Init a new PodTargetIntegrator.
13
+ # Initialize a new instance
14
14
  #
15
- # @param [PodTarget] target @see #target
15
+ # @param [TargetInstallationResult] target_installation_result @see #target_installation_result
16
16
  #
17
- def initialize(target)
18
- @target = target
17
+ def initialize(target_installation_result)
18
+ @target_installation_result = target_installation_result
19
19
  end
20
20
 
21
21
  # Integrates the pod target.
@@ -24,13 +24,15 @@ module Pod
24
24
  #
25
25
  def integrate!
26
26
  UI.section(integration_message) do
27
- target.test_specs_by_native_target.each do |native_target, test_specs|
28
- add_embed_frameworks_script_phase(native_target)
29
- add_copy_resources_script_phase(native_target)
30
- UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(test_specs), native_target)
27
+ target_installation_result.test_specs_by_native_target.each do |test_native_target, test_specs|
28
+ test_specs.each do |test_spec|
29
+ add_embed_frameworks_script_phase(test_native_target, test_spec)
30
+ add_copy_resources_script_phase(test_native_target, test_spec)
31
+ end
32
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(test_specs), test_native_target)
31
33
  end
32
34
  specs = target.non_test_specs
33
- UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(specs), target.native_target)
35
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(specs), target_installation_result.native_target)
34
36
  end
35
37
  end
36
38
 
@@ -49,12 +51,12 @@ module Pod
49
51
  #
50
52
  # @return [void]
51
53
  #
52
- def add_copy_resources_script_phase(native_target)
53
- test_type = target.test_type_for_product_type(native_target.symbol_type)
54
- script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_test_type(test_type).relative_path_from(target.sandbox.root)}"
55
- resource_paths = target.all_dependent_targets.flat_map do |dependent_target|
56
- include_test_spec_paths = dependent_target == target
57
- dependent_target.resource_paths(include_test_spec_paths)
54
+ def add_copy_resources_script_phase(native_target, test_spec)
55
+ script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
56
+ resource_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
57
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
58
+ spec_paths_to_include << test_spec.name if dependent_target == target
59
+ dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
58
60
  end
59
61
  input_paths = []
60
62
  output_paths = []
@@ -71,13 +73,12 @@ module Pod
71
73
  #
72
74
  # @return [void]
73
75
  #
74
- def add_embed_frameworks_script_phase(native_target)
75
- test_type = target.test_type_for_product_type(native_target.symbol_type)
76
- script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_test_type(test_type).relative_path_from(target.sandbox.root)}"
77
- all_dependent_targets = target.all_dependent_targets
78
- framework_paths = all_dependent_targets.flat_map do |dependent_target|
79
- include_test_spec_paths = dependent_target == target
80
- dependent_target.framework_paths(include_test_spec_paths)
76
+ def add_embed_frameworks_script_phase(native_target, test_spec)
77
+ script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
78
+ framework_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
79
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
80
+ spec_paths_to_include << test_spec.name if dependent_target == target
81
+ dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
81
82
  end
82
83
  input_paths = []
83
84
  output_paths = []
@@ -96,6 +97,12 @@ module Pod
96
97
  "Integrating target `#{target.name}`"
97
98
  end
98
99
 
100
+ # @return [PodTarget] the target part of the installation result.
101
+ #
102
+ def target
103
+ target_installation_result.target
104
+ end
105
+
99
106
  # @param [Array<Specification] specs
100
107
  # the specs to return script phrases from.
101
108
  #
@@ -0,0 +1,93 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # A simple container produced after a target installation is completed.
6
+ #
7
+ class TargetInstallationResult
8
+ # @return [Target] target
9
+ # The target this installation result is for.
10
+ #
11
+ attr_reader :target
12
+
13
+ # @return [PBXNativeTarget] native_target
14
+ # The native target that was produced for this target.
15
+ #
16
+ attr_reader :native_target
17
+
18
+ # @return [Array<PBXNativeTarget>] resource_bundle_targets
19
+ # The resource bundle targets that were produced for this target. Can be empty if the target had
20
+ # no resource bundles.
21
+ #
22
+ attr_reader :resource_bundle_targets
23
+
24
+ # @return [Array<PBXNativeTarget>] test_native_targets
25
+ # The test native targets that were produced for this target. Can be empty if there were no test
26
+ # native targets created (e.g. no test specs present).
27
+ #
28
+ attr_reader :test_native_targets
29
+
30
+ # @return [Hash{String=>Array<PBXNativeTarget>}] test_resource_bundle_targets
31
+ # The test resource bundle targets that were produced for this target keyed by test spec name.
32
+ # Can be empty if the target had no resource bundles for any tests.
33
+ #
34
+ attr_reader :test_resource_bundle_targets
35
+
36
+ # @return [Array<PBXNativeTarget>] test_app_host_targets
37
+ # The test app host native targets that were produced for this target. Can be empty.
38
+ #
39
+ attr_reader :test_app_host_targets
40
+
41
+ # Initialize a new instance
42
+ #
43
+ # @param [Target] target @see #target
44
+ # @param [PBXNativeTarget] native_target @see #native_target
45
+ # @param [Array<PBXNativeTarget>] resource_bundle_targets @see #resource_bundle_targets
46
+ # @param [Array<PBXNativeTarget>] test_native_targets @see #test_native_targets
47
+ # @param [Hash{String=>Array<PBXNativeTarget>}] test_resource_bundle_targets @see #test_resource_bundle_targets
48
+ # @param [Array<PBXNativeTarget>] test_app_host_targets @see #test_app_host_targets
49
+ #
50
+ def initialize(target, native_target, resource_bundle_targets = [], test_native_targets = [],
51
+ test_resource_bundle_targets = {}, test_app_host_targets = [])
52
+ @target = target
53
+ @native_target = native_target
54
+ @resource_bundle_targets = resource_bundle_targets
55
+ @test_native_targets = test_native_targets
56
+ @test_resource_bundle_targets = test_resource_bundle_targets
57
+ @test_app_host_targets = test_app_host_targets
58
+ end
59
+
60
+ # Returns the corresponding native target to use based on the provided specification.
61
+ #
62
+ # @param [Specification] spec
63
+ # The specification to base from in order to find the native target.
64
+ #
65
+ # @return [PBXNativeTarget] the native target to use or `nil` if none is found.
66
+ #
67
+ def native_target_for_spec(spec)
68
+ return native_target unless spec.test_specification?
69
+ test_native_target_from_spec(spec)
70
+ end
71
+
72
+ # @return [Hash{PBXNativeTarget => Specification}] a hash where the keys are the test native targets and the value
73
+ # an array of all the test specs associated with this native target.
74
+ #
75
+ def test_specs_by_native_target
76
+ test_specs_by_native_target = target.test_specs.group_by do |test_spec|
77
+ test_native_target_from_spec(test_spec)
78
+ end
79
+ test_specs_by_native_target.delete_if { |k, _| k.nil? }
80
+ end
81
+
82
+ private
83
+
84
+ def test_native_target_from_spec(spec)
85
+ test_native_targets.find do |test_native_target|
86
+ test_native_target.name == target.test_target_label(spec)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,3 +1,5 @@
1
+ require 'stringio'
2
+
1
3
  module Pod
2
4
  class Installer
3
5
  class Xcode
@@ -7,11 +9,18 @@ module Pod
7
9
  # by the target.
8
10
  #
9
11
  class TargetInstaller
12
+ include TargetInstallerHelper
13
+
10
14
  # @return [Sandbox] sandbox
11
15
  # The sandbox where the support files should be generated.
12
16
  #
13
17
  attr_reader :sandbox
14
18
 
19
+ # @return [Pod::Project]
20
+ # The `Pods/Pods.xcodeproj` to install the target into.
21
+ #
22
+ attr_reader :project
23
+
15
24
  # @return [Target] target
16
25
  # The library whose target needs to be generated.
17
26
  #
@@ -19,11 +28,13 @@ module Pod
19
28
 
20
29
  # Initialize a new instance
21
30
  #
22
- # @param [Sandbox] sandbox @see sandbox
23
- # @param [Target] target @see target
31
+ # @param [Sandbox] sandbox @see #sandbox
32
+ # @param [Pod::Project] project @see #project
33
+ # @param [Target] target @see #target
24
34
  #
25
- def initialize(sandbox, target)
35
+ def initialize(sandbox, project, target)
26
36
  @sandbox = sandbox
37
+ @project = project
27
38
  @target = target
28
39
  end
29
40
 
@@ -38,28 +49,28 @@ module Pod
38
49
  #
39
50
  # @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
40
51
  #
41
- # @return [void]
52
+ # @return [PBXNativeTarget] the native target that was added.
42
53
  #
43
54
  def add_target
44
55
  product_type = target.product_type
45
56
  name = target.label
46
57
  platform = target.platform.name
47
58
  language = target.uses_swift? ? :swift : :objc
48
- @native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
59
+ native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
49
60
 
50
61
  product_name = target.product_name
51
- product = @native_target.product_reference
62
+ product = native_target.product_reference
52
63
  product.name = product_name
53
64
 
54
65
  target.user_build_configurations.each do |bc_name, type|
55
- @native_target.add_build_configuration(bc_name, type)
66
+ native_target.add_build_configuration(bc_name, type)
56
67
  end
57
68
 
58
- @native_target.build_configurations.each do |configuration|
69
+ native_target.build_configurations.each do |configuration|
59
70
  configuration.build_settings.merge!(custom_build_settings)
60
71
  end
61
72
 
62
- target.native_target = @native_target
73
+ native_target
63
74
  end
64
75
 
65
76
  # @return [String] The deployment target.
@@ -91,29 +102,6 @@ module Pod
91
102
  settings
92
103
  end
93
104
 
94
- # @param [Generator] generator
95
- # the generator to use for generating the content.
96
- #
97
- # @param [Pathname] path
98
- # the pathname to save the content into.
99
- #
100
- # Saves the content the provided path unless the path exists and the contents are exactly the same.
101
- #
102
- # @return [Void]
103
- #
104
- def update_changed_file(generator, path)
105
- path.dirname.mkpath
106
- if path.exist?
107
- generator.save_as(support_files_temp_dir)
108
- unless FileUtils.identical?(support_files_temp_dir, path)
109
- FileUtils.mv(support_files_temp_dir, path)
110
- end
111
- else
112
- generator.save_as(path)
113
- end
114
- clean_support_files_temp_dir if support_files_temp_dir.exist?
115
- end
116
-
117
105
  # Creates the directory where to store the support files of the target.
118
106
  #
119
107
  def create_support_files_dir
@@ -123,7 +111,7 @@ module Pod
123
111
  # Remove temp file whose store .prefix/config/dummy file.
124
112
  #
125
113
  def clean_support_files_temp_dir
126
- support_files_temp_dir.rmtree
114
+ support_files_temp_dir.rmtree if support_files_temp_dir.exist?
127
115
  end
128
116
 
129
117
  # @return [String] The temp file path to store temporary files.
@@ -152,34 +140,35 @@ module Pod
152
140
  # @return [void]
153
141
  #
154
142
  def create_info_plist_file(path, native_target, version, platform, bundle_package_type = :fmwk)
155
- UI.message "- Generating Info.plist file at #{UI.path(path)}" do
156
- generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type)
157
- update_changed_file(generator, path)
158
- add_file_to_support_group(path)
159
-
160
- native_target.build_configurations.each do |c|
161
- relative_path = path.relative_path_from(sandbox.root)
162
- c.build_settings['INFOPLIST_FILE'] = relative_path.to_s
163
- end
164
- end
143
+ create_info_plist_file_with_sandbox(@sandbox, path, native_target, version, platform, bundle_package_type)
144
+ add_file_to_support_group(path)
165
145
  end
166
146
 
167
147
  # Creates the module map file which ensures that the umbrella header is
168
148
  # recognized with a customized path
169
149
  #
150
+ # @param [PBXNativeTarget] native_target
151
+ # the native target to link the module map file into.
152
+ #
170
153
  # @return [void]
171
154
  #
172
- def create_module_map
173
- path = target.module_map_path
155
+ def create_module_map(native_target)
156
+ path = target.module_map_path_to_write
174
157
  UI.message "- Generating module map file at #{UI.path(path)}" do
175
158
  generator = Generator::ModuleMap.new(target)
176
159
  yield generator if block_given?
177
160
  update_changed_file(generator, path)
178
161
  add_file_to_support_group(path)
179
162
 
163
+ linked_path = target.module_map_path
164
+ if path != linked_path
165
+ linked_path.dirname.mkpath
166
+ FileUtils.ln_sf(path, linked_path)
167
+ end
168
+
169
+ relative_path_string = target.module_map_path.relative_path_from(sandbox.root).to_s
180
170
  native_target.build_configurations.each do |c|
181
- relative_path = path.relative_path_from(sandbox.root)
182
- c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
171
+ c.build_settings['MODULEMAP_FILE'] = relative_path_string
183
172
  end
184
173
  end
185
174
  end
@@ -187,11 +176,16 @@ module Pod
187
176
  # Generates a header which ensures that all header files are exported
188
177
  # in the module map
189
178
  #
179
+ # @param [PBXNativeTarget] native_target
180
+ # the native target to link the umbrella header file into.
181
+ #
190
182
  # @yield_param [Generator::UmbrellaHeader]
191
183
  # yielded once to configure the imports
192
184
  #
193
- def create_umbrella_header
194
- path = target.umbrella_header_path
185
+ # @return [void]
186
+ #
187
+ def create_umbrella_header(native_target)
188
+ path = target.umbrella_header_path_to_write
195
189
  UI.message "- Generating umbrella header at #{UI.path(path)}" do
196
190
  generator = Generator::UmbrellaHeader.new(target)
197
191
  yield generator if block_given?
@@ -200,10 +194,15 @@ module Pod
200
194
  # Add the file to the support group and the native target,
201
195
  # so it will been added to the header build phase
202
196
  file_ref = add_file_to_support_group(path)
203
- native_target.add_file_references([file_ref])
197
+ build_file = native_target.headers_build_phase.add_file_reference(file_ref)
198
+
199
+ linked_path = target.umbrella_header_path
200
+ if path != linked_path
201
+ linked_path.dirname.mkpath
202
+ FileUtils.ln_sf(path, linked_path)
203
+ end
204
204
 
205
205
  acl = target.requires_frameworks? ? 'Public' : 'Project'
206
- build_file = native_target.headers_build_phase.build_file(file_ref)
207
206
  build_file.settings ||= {}
208
207
  build_file.settings['ATTRIBUTES'] = [acl]
209
208
  end
@@ -212,35 +211,27 @@ module Pod
212
211
  # Generates a dummy source file for each target so libraries that contain
213
212
  # only categories build.
214
213
  #
214
+ # @param [PBXNativeTarget] native_target
215
+ # the native target to link the dummy source file into.
216
+ #
215
217
  # @return [void]
216
218
  #
217
- def create_dummy_source
219
+ def create_dummy_source(native_target)
218
220
  path = target.dummy_source_path
219
- generator = Generator::DummySource.new(target.label)
220
- update_changed_file(generator, path)
221
- file_reference = add_file_to_support_group(path)
222
- native_target.source_build_phase.add_file_reference(file_reference)
221
+ UI.message "- Generating dummy source at #{UI.path(path)}" do
222
+ generator = Generator::DummySource.new(target.label)
223
+ update_changed_file(generator, path)
224
+ file_reference = add_file_to_support_group(path)
225
+ native_target.source_build_phase.add_file_reference(file_reference)
226
+ end
223
227
  end
224
228
 
225
- # @return [PBXNativeTarget] the target generated by the installation
226
- # process.
227
- #
228
- # @note Generated by the {#add_target} step.
229
- #
230
- attr_reader :native_target
231
-
232
229
  private
233
230
 
234
231
  #-----------------------------------------------------------------------#
235
232
 
236
233
  # @!group Private helpers.
237
234
 
238
- # @return [Project] the Pods project of the sandbox.
239
- #
240
- def project
241
- sandbox.project
242
- end
243
-
244
235
  # @return [PBXGroup] the group where the file references to the support
245
236
  # files should be stored.
246
237
  #
@@ -0,0 +1,72 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ module TargetInstallerHelper
6
+ # @param [Generator] generator
7
+ # the generator to use for generating the content.
8
+ #
9
+ # @param [Pathname] path
10
+ # the pathname to save the content into.
11
+ #
12
+ # Saves the content the provided path unless the path exists and the contents are exactly the same.
13
+ #
14
+ def update_changed_file(generator, path)
15
+ if path.exist?
16
+ contents = generator.generate.to_s
17
+ content_stream = StringIO.new(contents)
18
+ identical = File.open(path, 'rb') { |f| FileUtils.compare_stream(f, content_stream) }
19
+ return if identical
20
+
21
+ File.open(path, 'w') { |f| f.write(contents) }
22
+ else
23
+ path.dirname.mkpath
24
+ generator.save_as(path)
25
+ end
26
+ end
27
+
28
+ # Creates the Info.plist file which sets public framework attributes
29
+ #
30
+ # @param [Sandbox] sandbox @see #sandbox
31
+ # The sandbox where the generated Info.plist file should be saved.
32
+ #
33
+ # @param [Pathname] path
34
+ # the path to save the generated Info.plist file.
35
+ #
36
+ # @param [PBXNativeTarget] native_target
37
+ # the native target to link the generated Info.plist file into.
38
+ #
39
+ # @param [Version] version
40
+ # the version to use for when generating this Info.plist file.
41
+ #
42
+ # @param [Platform] platform
43
+ # the platform to use for when generating this Info.plist file.
44
+ #
45
+ # @param [Symbol] bundle_package_type
46
+ # the CFBundlePackageType of the target this Info.plist file is for.
47
+ #
48
+ # @param [Hash] additional_entries
49
+ # any additional entries to include in this Info.plist file.
50
+ #
51
+ # @return [void]
52
+ #
53
+ def create_info_plist_file_with_sandbox(sandbox, path, native_target, version, platform,
54
+ bundle_package_type = :fmwk, additional_entries = {})
55
+ UI.message "- Generating Info.plist file at #{UI.path(path)}" do
56
+ generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type, additional_entries)
57
+ update_changed_file(generator, path)
58
+
59
+ relative_path_string = path.relative_path_from(sandbox.root).to_s
60
+ native_target.build_configurations.each do |c|
61
+ c.build_settings['INFOPLIST_FILE'] = relative_path_string
62
+ end
63
+ end
64
+ end
65
+
66
+ module_function :update_changed_file
67
+ module_function :create_info_plist_file_with_sandbox
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end