cocoapods 1.5.2 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +365 -1
  3. data/bin/pod +1 -1
  4. data/lib/cocoapods/command/cache/clean.rb +1 -1
  5. data/lib/cocoapods/command/init.rb +4 -2
  6. data/lib/cocoapods/command/install.rb +7 -0
  7. data/lib/cocoapods/command/lib/lint.rb +8 -1
  8. data/lib/cocoapods/command/outdated.rb +4 -9
  9. data/lib/cocoapods/command/repo/add.rb +1 -1
  10. data/lib/cocoapods/command/repo/list.rb +1 -1
  11. data/lib/cocoapods/command/repo/push.rb +17 -12
  12. data/lib/cocoapods/command/repo/remove.rb +1 -1
  13. data/lib/cocoapods/command/repo/update.rb +1 -1
  14. data/lib/cocoapods/command/setup.rb +1 -1
  15. data/lib/cocoapods/command/spec/create.rb +39 -39
  16. data/lib/cocoapods/command/spec/lint.rb +8 -1
  17. data/lib/cocoapods/command.rb +3 -1
  18. data/lib/cocoapods/config.rb +13 -2
  19. data/lib/cocoapods/downloader/cache.rb +1 -1
  20. data/lib/cocoapods/executable.rb +3 -3
  21. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  22. data/lib/cocoapods/external_sources.rb +7 -4
  23. data/lib/cocoapods/gem_version.rb +1 -1
  24. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  25. data/lib/cocoapods/generator/acknowledgements/plist.rb +13 -2
  26. data/lib/cocoapods/generator/app_target_helper.rb +141 -17
  27. data/lib/cocoapods/generator/copy_resources_script.rb +14 -3
  28. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  29. data/lib/cocoapods/generator/embed_frameworks_script.rb +37 -20
  30. data/lib/cocoapods/generator/header.rb +1 -1
  31. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  32. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  33. data/lib/cocoapods/hooks_manager.rb +28 -17
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +14 -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 +27 -14
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/analyzer.rb +391 -284
  42. data/lib/cocoapods/installer/installation_options.rb +2 -0
  43. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  44. data/lib/cocoapods/installer/post_install_hooks_context.rb +72 -47
  45. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  46. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +69 -29
  49. data/lib/cocoapods/installer/user_project_integrator.rb +6 -4
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +104 -0
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +23 -50
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +296 -177
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +51 -33
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +62 -69
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +130 -122
  59. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  60. data/lib/cocoapods/installer.rb +140 -63
  61. data/lib/cocoapods/project.rb +16 -14
  62. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  63. data/lib/cocoapods/resolver.rb +79 -98
  64. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  65. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  66. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  67. data/lib/cocoapods/sandbox.rb +31 -43
  68. data/lib/cocoapods/sources_manager.rb +1 -1
  69. data/lib/cocoapods/target/aggregate_target.rb +143 -85
  70. data/lib/cocoapods/target/build_settings.rb +1124 -0
  71. data/lib/cocoapods/target/framework_paths.rb +36 -0
  72. data/lib/cocoapods/target/pod_target.rb +198 -295
  73. data/lib/cocoapods/target.rb +92 -37
  74. data/lib/cocoapods/user_interface.rb +5 -0
  75. data/lib/cocoapods/validator.rb +149 -44
  76. data/lib/cocoapods.rb +0 -1
  77. metadata +31 -23
  78. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  79. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  80. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
  81. data/lib/cocoapods/generator/xcconfig.rb +0 -13
@@ -6,16 +6,22 @@ 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
+ # @return [InstallationOptions] the installation options from the Podfile.
14
14
  #
15
- # @param [PodTarget] target @see #target
15
+ attr_reader :installation_options
16
+
17
+ # Initialize a new instance
18
+ #
19
+ # @param [TargetInstallationResult] target_installation_result @see #target_installation_result
20
+ # @param [InstallationOptions] installation_options @see #installation_options
16
21
  #
17
- def initialize(target)
18
- @target = target
22
+ def initialize(target_installation_result, installation_options)
23
+ @target_installation_result = target_installation_result
24
+ @installation_options = installation_options
19
25
  end
20
26
 
21
27
  # Integrates the pod target.
@@ -24,13 +30,15 @@ module Pod
24
30
  #
25
31
  def integrate!
26
32
  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)
33
+ target_installation_result.test_specs_by_native_target.each do |test_native_target, test_specs|
34
+ test_specs.each do |test_spec|
35
+ add_embed_frameworks_script_phase(test_native_target, test_spec)
36
+ add_copy_resources_script_phase(test_native_target, test_spec)
37
+ end
38
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(test_specs), test_native_target)
31
39
  end
32
40
  specs = target.non_test_specs
33
- UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(specs), target.native_target)
41
+ UserProjectIntegrator::TargetIntegrator.create_or_update_user_script_phases(script_phases_for_specs(specs), target_installation_result.native_target)
34
42
  end
35
43
  end
36
44
 
@@ -49,19 +57,21 @@ module Pod
49
57
  #
50
58
  # @return [void]
51
59
  #
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)
58
- end
60
+ def add_copy_resources_script_phase(native_target, test_spec)
61
+ script_path = "${PODS_ROOT}/#{target.copy_resources_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
59
62
  input_paths = []
60
63
  output_paths = []
61
- unless resource_paths.empty?
62
- resource_paths_flattened = resource_paths.flatten.uniq
63
- input_paths = [script_path, *resource_paths_flattened]
64
- output_paths = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths_flattened)
64
+ unless installation_options.disable_input_output_paths?
65
+ resource_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
66
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
67
+ spec_paths_to_include << test_spec.name if dependent_target == target
68
+ dependent_target.resource_paths.values_at(*spec_paths_to_include).flatten.compact
69
+ end
70
+ unless resource_paths.empty?
71
+ resource_paths_flattened = resource_paths.flatten.uniq
72
+ input_paths = [script_path, *resource_paths_flattened]
73
+ output_paths = UserProjectIntegrator::TargetIntegrator.resource_output_paths(resource_paths_flattened)
74
+ end
65
75
  end
66
76
  UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
67
77
  UserProjectIntegrator::TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
@@ -71,20 +81,22 @@ module Pod
71
81
  #
72
82
  # @return [void]
73
83
  #
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)
81
- end
84
+ def add_embed_frameworks_script_phase(native_target, test_spec)
85
+ script_path = "${PODS_ROOT}/#{target.embed_frameworks_script_path_for_test_spec(test_spec).relative_path_from(target.sandbox.root)}"
82
86
  input_paths = []
83
87
  output_paths = []
84
- unless framework_paths.empty?
85
- input_paths = [script_path, *framework_paths.flat_map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.compact]
86
- output_paths = framework_paths.flat_map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.compact
88
+ unless installation_options.disable_input_output_paths?
89
+ framework_paths = target.dependent_targets_for_test_spec(test_spec).flat_map do |dependent_target|
90
+ spec_paths_to_include = dependent_target.non_test_specs.map(&:name)
91
+ spec_paths_to_include << test_spec.name if dependent_target == target
92
+ dependent_target.framework_paths.values_at(*spec_paths_to_include).flatten.compact.uniq
93
+ end
94
+ unless framework_paths.empty?
95
+ input_paths = [script_path, *framework_paths.flat_map { |fw| [fw.source_path, fw.dsym_path] }.compact]
96
+ output_paths = UserProjectIntegrator::TargetIntegrator.framework_output_paths(framework_paths)
97
+ end
87
98
  end
99
+
88
100
  UserProjectIntegrator::TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
89
101
  UserProjectIntegrator::TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
90
102
  end
@@ -96,6 +108,12 @@ module Pod
96
108
  "Integrating target `#{target.name}`"
97
109
  end
98
110
 
111
+ # @return [PodTarget] the target part of the installation result.
112
+ #
113
+ def target
114
+ target_installation_result.target
115
+ end
116
+
99
117
  # @param [Array<Specification] specs
100
118
  # the specs to return script phrases from.
101
119
  #
@@ -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,36 @@ 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
+ source = path.relative_path_from(linked_path.dirname)
167
+ FileUtils.ln_sf(source, linked_path)
168
+ end
169
+
170
+ relative_path_string = target.module_map_path.relative_path_from(sandbox.root).to_s
180
171
  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
172
+ c.build_settings['MODULEMAP_FILE'] = relative_path_string
183
173
  end
184
174
  end
185
175
  end
@@ -187,11 +177,16 @@ module Pod
187
177
  # Generates a header which ensures that all header files are exported
188
178
  # in the module map
189
179
  #
180
+ # @param [PBXNativeTarget] native_target
181
+ # the native target to link the umbrella header file into.
182
+ #
190
183
  # @yield_param [Generator::UmbrellaHeader]
191
184
  # yielded once to configure the imports
192
185
  #
193
- def create_umbrella_header
194
- path = target.umbrella_header_path
186
+ # @return [void]
187
+ #
188
+ def create_umbrella_header(native_target)
189
+ path = target.umbrella_header_path_to_write
195
190
  UI.message "- Generating umbrella header at #{UI.path(path)}" do
196
191
  generator = Generator::UmbrellaHeader.new(target)
197
192
  yield generator if block_given?
@@ -200,10 +195,16 @@ module Pod
200
195
  # Add the file to the support group and the native target,
201
196
  # so it will been added to the header build phase
202
197
  file_ref = add_file_to_support_group(path)
203
- native_target.add_file_references([file_ref])
198
+ build_file = native_target.headers_build_phase.add_file_reference(file_ref)
199
+
200
+ linked_path = target.umbrella_header_path
201
+ if path != linked_path
202
+ linked_path.dirname.mkpath
203
+ source = path.relative_path_from(linked_path.dirname)
204
+ FileUtils.ln_sf(source, linked_path)
205
+ end
204
206
 
205
207
  acl = target.requires_frameworks? ? 'Public' : 'Project'
206
- build_file = native_target.headers_build_phase.build_file(file_ref)
207
208
  build_file.settings ||= {}
208
209
  build_file.settings['ATTRIBUTES'] = [acl]
209
210
  end
@@ -212,35 +213,27 @@ module Pod
212
213
  # Generates a dummy source file for each target so libraries that contain
213
214
  # only categories build.
214
215
  #
216
+ # @param [PBXNativeTarget] native_target
217
+ # the native target to link the dummy source file into.
218
+ #
215
219
  # @return [void]
216
220
  #
217
- def create_dummy_source
221
+ def create_dummy_source(native_target)
218
222
  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)
223
+ UI.message "- Generating dummy source at #{UI.path(path)}" do
224
+ generator = Generator::DummySource.new(target.label)
225
+ update_changed_file(generator, path)
226
+ file_reference = add_file_to_support_group(path)
227
+ native_target.source_build_phase.add_file_reference(file_reference)
228
+ end
223
229
  end
224
230
 
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
231
  private
233
232
 
234
233
  #-----------------------------------------------------------------------#
235
234
 
236
235
  # @!group Private helpers.
237
236
 
238
- # @return [Project] the Pods project of the sandbox.
239
- #
240
- def project
241
- sandbox.project
242
- end
243
-
244
237
  # @return [PBXGroup] the group where the file references to the support
245
238
  # files should be stored.
246
239
  #
@@ -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