cocoapods-tt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cocoapods-tt/command/native/install.rb +56 -0
  3. data/lib/cocoapods-tt/command/native/update.rb +157 -0
  4. data/lib/cocoapods-tt/command/tt/make.rb +92 -0
  5. data/lib/cocoapods-tt/command/tt.rb +115 -0
  6. data/lib/cocoapods-tt/command.rb +1 -0
  7. data/lib/cocoapods-tt/gem_version.rb +3 -0
  8. data/lib/cocoapods-tt/native/command.rb +185 -0
  9. data/lib/cocoapods-tt/native/config.rb +366 -0
  10. data/lib/cocoapods-tt/native/core_overrides.rb +1 -0
  11. data/lib/cocoapods-tt/native/downloader/cache.rb +322 -0
  12. data/lib/cocoapods-tt/native/downloader/request.rb +86 -0
  13. data/lib/cocoapods-tt/native/downloader/response.rb +16 -0
  14. data/lib/cocoapods-tt/native/downloader.rb +192 -0
  15. data/lib/cocoapods-tt/native/executable.rb +247 -0
  16. data/lib/cocoapods-tt/native/external_sources/abstract_external_source.rb +205 -0
  17. data/lib/cocoapods-tt/native/external_sources/downloader_source.rb +30 -0
  18. data/lib/cocoapods-tt/native/external_sources/path_source.rb +55 -0
  19. data/lib/cocoapods-tt/native/external_sources/podspec_source.rb +54 -0
  20. data/lib/cocoapods-tt/native/external_sources.rb +57 -0
  21. data/lib/cocoapods-tt/native/gem_version.rb +5 -0
  22. data/lib/cocoapods-tt/native/generator/acknowledgements/markdown.rb +44 -0
  23. data/lib/cocoapods-tt/native/generator/acknowledgements/plist.rb +94 -0
  24. data/lib/cocoapods-tt/native/generator/acknowledgements.rb +107 -0
  25. data/lib/cocoapods-tt/native/generator/app_target_helper.rb +363 -0
  26. data/lib/cocoapods-tt/native/generator/bridge_support.rb +22 -0
  27. data/lib/cocoapods-tt/native/generator/constant.rb +19 -0
  28. data/lib/cocoapods-tt/native/generator/copy_dsyms_script.rb +56 -0
  29. data/lib/cocoapods-tt/native/generator/copy_resources_script.rb +223 -0
  30. data/lib/cocoapods-tt/native/generator/copy_xcframework_script.rb +227 -0
  31. data/lib/cocoapods-tt/native/generator/dummy_source.rb +31 -0
  32. data/lib/cocoapods-tt/native/generator/embed_frameworks_script.rb +196 -0
  33. data/lib/cocoapods-tt/native/generator/file_list.rb +39 -0
  34. data/lib/cocoapods-tt/native/generator/header.rb +103 -0
  35. data/lib/cocoapods-tt/native/generator/info_plist_file.rb +128 -0
  36. data/lib/cocoapods-tt/native/generator/module_map.rb +99 -0
  37. data/lib/cocoapods-tt/native/generator/prefix_header.rb +60 -0
  38. data/lib/cocoapods-tt/native/generator/script_phase_constants.rb +100 -0
  39. data/lib/cocoapods-tt/native/generator/umbrella_header.rb +46 -0
  40. data/lib/cocoapods-tt/native/hooks_manager.rb +132 -0
  41. data/lib/cocoapods-tt/native/installer/analyzer/analysis_result.rb +87 -0
  42. data/lib/cocoapods-tt/native/installer/analyzer/locking_dependency_analyzer.rb +103 -0
  43. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant.rb +87 -0
  44. data/lib/cocoapods-tt/native/installer/analyzer/pod_variant_set.rb +175 -0
  45. data/lib/cocoapods-tt/native/installer/analyzer/podfile_dependency_cache.rb +55 -0
  46. data/lib/cocoapods-tt/native/installer/analyzer/sandbox_analyzer.rb +268 -0
  47. data/lib/cocoapods-tt/native/installer/analyzer/specs_state.rb +108 -0
  48. data/lib/cocoapods-tt/native/installer/analyzer/target_inspection_result.rb +58 -0
  49. data/lib/cocoapods-tt/native/installer/analyzer/target_inspector.rb +258 -0
  50. data/lib/cocoapods-tt/native/installer/analyzer.rb +1204 -0
  51. data/lib/cocoapods-tt/native/installer/base_install_hooks_context.rb +135 -0
  52. data/lib/cocoapods-tt/native/installer/installation_options.rb +195 -0
  53. data/lib/cocoapods-tt/native/installer/pod_source_installer.rb +224 -0
  54. data/lib/cocoapods-tt/native/installer/pod_source_preparer.rb +77 -0
  55. data/lib/cocoapods-tt/native/installer/podfile_validator.rb +168 -0
  56. data/lib/cocoapods-tt/native/installer/post_install_hooks_context.rb +9 -0
  57. data/lib/cocoapods-tt/native/installer/post_integrate_hooks_context.rb +9 -0
  58. data/lib/cocoapods-tt/native/installer/pre_install_hooks_context.rb +51 -0
  59. data/lib/cocoapods-tt/native/installer/pre_integrate_hooks_context.rb +9 -0
  60. data/lib/cocoapods-tt/native/installer/project_cache/project_cache.rb +11 -0
  61. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analysis_result.rb +53 -0
  62. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_analyzer.rb +200 -0
  63. data/lib/cocoapods-tt/native/installer/project_cache/project_cache_version.rb +43 -0
  64. data/lib/cocoapods-tt/native/installer/project_cache/project_installation_cache.rb +103 -0
  65. data/lib/cocoapods-tt/native/installer/project_cache/project_metadata_cache.rb +73 -0
  66. data/lib/cocoapods-tt/native/installer/project_cache/target_cache_key.rb +176 -0
  67. data/lib/cocoapods-tt/native/installer/project_cache/target_metadata.rb +74 -0
  68. data/lib/cocoapods-tt/native/installer/sandbox_dir_cleaner.rb +105 -0
  69. data/lib/cocoapods-tt/native/installer/sandbox_header_paths_installer.rb +45 -0
  70. data/lib/cocoapods-tt/native/installer/source_provider_hooks_context.rb +34 -0
  71. data/lib/cocoapods-tt/native/installer/target_uuid_generator.rb +34 -0
  72. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +179 -0
  73. data/lib/cocoapods-tt/native/installer/user_project_integrator/target_integrator.rb +815 -0
  74. data/lib/cocoapods-tt/native/installer/user_project_integrator.rb +280 -0
  75. data/lib/cocoapods-tt/native/installer/xcode/multi_pods_project_generator.rb +82 -0
  76. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_dependency_installer.rb +66 -0
  77. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/aggregate_target_installer.rb +192 -0
  78. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/app_host_installer.rb +154 -0
  79. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/file_references_installer.rb +329 -0
  80. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +195 -0
  81. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_installer.rb +1239 -0
  82. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pod_target_integrator.rb +312 -0
  83. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/pods_project_writer.rb +90 -0
  84. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/project_generator.rb +120 -0
  85. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installation_result.rb +140 -0
  86. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer.rb +257 -0
  87. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator/target_installer_helper.rb +110 -0
  88. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator.rb +291 -0
  89. data/lib/cocoapods-tt/native/installer/xcode/pods_project_generator_result.rb +54 -0
  90. data/lib/cocoapods-tt/native/installer/xcode/single_pods_project_generator.rb +38 -0
  91. data/lib/cocoapods-tt/native/installer/xcode/target_validator.rb +170 -0
  92. data/lib/cocoapods-tt/native/installer/xcode.rb +11 -0
  93. data/lib/cocoapods-tt/native/installer.rb +1044 -0
  94. data/lib/cocoapods-tt/native/native_target_extension.rb +60 -0
  95. data/lib/cocoapods-tt/native/open-uri.rb +33 -0
  96. data/lib/cocoapods-tt/native/podfile.rb +13 -0
  97. data/lib/cocoapods-tt/native/project.rb +544 -0
  98. data/lib/cocoapods-tt/native/resolver/lazy_specification.rb +88 -0
  99. data/lib/cocoapods-tt/native/resolver/resolver_specification.rb +41 -0
  100. data/lib/cocoapods-tt/native/resolver.rb +600 -0
  101. data/lib/cocoapods-tt/native/sandbox/file_accessor.rb +532 -0
  102. data/lib/cocoapods-tt/native/sandbox/headers_store.rb +163 -0
  103. data/lib/cocoapods-tt/native/sandbox/path_list.rb +242 -0
  104. data/lib/cocoapods-tt/native/sandbox/pod_dir_cleaner.rb +71 -0
  105. data/lib/cocoapods-tt/native/sandbox/podspec_finder.rb +23 -0
  106. data/lib/cocoapods-tt/native/sandbox.rb +470 -0
  107. data/lib/cocoapods-tt/native/sources_manager.rb +221 -0
  108. data/lib/cocoapods-tt/native/target/aggregate_target.rb +558 -0
  109. data/lib/cocoapods-tt/native/target/build_settings.rb +1385 -0
  110. data/lib/cocoapods-tt/native/target/pod_target.rb +1168 -0
  111. data/lib/cocoapods-tt/native/target.rb +378 -0
  112. data/lib/cocoapods-tt/native/user_interface/error_report.rb +204 -0
  113. data/lib/cocoapods-tt/native/user_interface/inspector_reporter.rb +102 -0
  114. data/lib/cocoapods-tt/native/user_interface.rb +463 -0
  115. data/lib/cocoapods-tt/native/validator.rb +1170 -0
  116. data/lib/cocoapods-tt/native/version_metadata.rb +26 -0
  117. data/lib/cocoapods-tt/native/xcode/framework_paths.rb +54 -0
  118. data/lib/cocoapods-tt/native/xcode/linkage_analyzer.rb +22 -0
  119. data/lib/cocoapods-tt/native/xcode/xcframework/xcframework_slice.rb +138 -0
  120. data/lib/cocoapods-tt/native/xcode/xcframework.rb +99 -0
  121. data/lib/cocoapods-tt/native/xcode.rb +7 -0
  122. data/lib/cocoapods-tt.rb +1 -0
  123. data/lib/cocoapods_plugin.rb +17 -0
  124. metadata +193 -0
@@ -0,0 +1,257 @@
1
+ require 'stringio'
2
+
3
+ module Pod
4
+ class Installer
5
+ class Xcode
6
+ class PodsProjectGenerator
7
+ # Controller class responsible of creating and configuring the static
8
+ # library target in Pods project. It also creates the support file needed
9
+ # by the target.
10
+ #
11
+ class TargetInstaller
12
+ include TargetInstallerHelper
13
+
14
+ # @return [Sandbox] sandbox
15
+ # The sandbox where the support files should be generated.
16
+ #
17
+ attr_reader :sandbox
18
+
19
+ # @return [Pod::Project]
20
+ # The project to install the target into.
21
+ #
22
+ attr_reader :project
23
+
24
+ # @return [Target] target
25
+ # The library whose target needs to be generated.
26
+ #
27
+ attr_reader :target
28
+
29
+ # Initialize a new instance
30
+ #
31
+ # @param [Sandbox] sandbox @see #sandbox
32
+ # @param [Pod::Project] project @see #project
33
+ # @param [Target] target @see #target
34
+ #
35
+ def initialize(sandbox, project, target)
36
+ @sandbox = sandbox
37
+ @project = project
38
+ @target = target
39
+ end
40
+
41
+ private
42
+
43
+ #-----------------------------------------------------------------------#
44
+
45
+ # @!group Installation steps
46
+
47
+ # Adds the target for the library to the Pods project with the
48
+ # appropriate build configurations.
49
+ #
50
+ # @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
51
+ #
52
+ # @return [PBXNativeTarget] the native target that was added.
53
+ #
54
+ def add_target
55
+ product_type = target.product_type
56
+ name = target.label
57
+ platform = target.platform.name
58
+ language = target.uses_swift? ? :swift : :objc
59
+ native_target = project.new_target(product_type, name, platform, deployment_target, nil, language, target.product_basename)
60
+ native_target.product_reference.name = name
61
+
62
+ target.user_build_configurations.each do |bc_name, type|
63
+ native_target.add_build_configuration(bc_name, type)
64
+ end
65
+
66
+ native_target.build_configurations.each do |configuration|
67
+ configuration.build_settings.merge!(custom_build_settings)
68
+ end
69
+
70
+ native_target
71
+ end
72
+
73
+ # @return [String] The deployment target.
74
+ #
75
+ def deployment_target
76
+ target.platform.deployment_target.to_s
77
+ end
78
+
79
+ # Returns the customized build settings which are overridden in the build
80
+ # settings of the user target.
81
+ #
82
+ # @return [Hash{String => String}]
83
+ #
84
+ def custom_build_settings
85
+ settings = {}
86
+
87
+ unless target.archs.empty?
88
+ settings['ARCHS'] = target.archs
89
+ end
90
+
91
+ if target.build_as_static_framework?
92
+ settings['MACH_O_TYPE'] = 'staticlib'
93
+ elsif target.build_as_static_library?
94
+ settings.merge!('OTHER_LDFLAGS' => '', 'OTHER_LIBTOOLFLAGS' => '')
95
+ end
96
+
97
+ settings
98
+ end
99
+
100
+ # Creates the directory where to store the support files of the target.
101
+ #
102
+ def create_support_files_dir
103
+ target.support_files_dir.mkpath
104
+ end
105
+
106
+ # Remove temp file whose store .prefix/config/dummy file.
107
+ #
108
+ def clean_support_files_temp_dir
109
+ support_files_temp_dir.rmtree if support_files_temp_dir.exist?
110
+ end
111
+
112
+ # @return [String] The temp file path to store temporary files.
113
+ #
114
+ def support_files_temp_dir
115
+ sandbox.target_support_files_dir('generated_files_tmp')
116
+ end
117
+
118
+ # Creates the Info.plist file which sets public framework attributes
119
+ #
120
+ # @param [Pathname] path
121
+ # the path to save the generated Info.plist file.
122
+ #
123
+ # @param [PBXNativeTarget] native_target
124
+ # the native target to link the generated Info.plist file into.
125
+ #
126
+ # @param [Version] version
127
+ # the version to use for when generating this Info.plist file.
128
+ #
129
+ # @param [Platform] platform
130
+ # the platform to use for when generating this Info.plist file.
131
+ #
132
+ # @param [Symbol] bundle_package_type
133
+ # the CFBundlePackageType of the target this Info.plist file is for.
134
+ #
135
+ # @param [Hash] additional_entries
136
+ # additional entries for the generated Info.plist
137
+ #
138
+ # @return [void]
139
+ #
140
+ def create_info_plist_file(path, native_target, version, platform, bundle_package_type = :fmwk, additional_entries: {})
141
+ create_info_plist_file_with_sandbox(@sandbox, path, native_target, version, platform, bundle_package_type,
142
+ :additional_entries => additional_entries)
143
+ add_file_to_support_group(path)
144
+ end
145
+
146
+ # Creates the module map file which ensures that the umbrella header is
147
+ # recognized with a customized path
148
+ #
149
+ # @param [PBXNativeTarget] native_target
150
+ # the native target to link the module map file into.
151
+ #
152
+ # @return [void]
153
+ #
154
+ def create_module_map(native_target)
155
+ path = target.module_map_path_to_write
156
+ UI.message "- Generating module map file at #{UI.path(path)}" do
157
+ generator = Generator::ModuleMap.new(target)
158
+ yield generator if block_given?
159
+ update_changed_file(generator, path)
160
+ add_file_to_support_group(path)
161
+
162
+ linked_path = target.module_map_path
163
+ if path != linked_path
164
+ linked_path.dirname.mkpath
165
+ source = path.relative_path_from(linked_path.dirname)
166
+ FileUtils.ln_sf(source, linked_path)
167
+ end
168
+
169
+ relative_path_string = target.module_map_path.relative_path_from(sandbox.root).to_s
170
+ native_target.build_configurations.each do |c|
171
+ c.build_settings['MODULEMAP_FILE'] = relative_path_string
172
+ end
173
+ end
174
+ end
175
+
176
+ # Generates a header which ensures that all header files are exported
177
+ # in the module map
178
+ #
179
+ # @param [PBXNativeTarget] native_target
180
+ # the native target to link the umbrella header file into.
181
+ #
182
+ # @yield_param [Generator::UmbrellaHeader]
183
+ # yielded once to configure the imports
184
+ #
185
+ # @return [void]
186
+ #
187
+ def create_umbrella_header(native_target)
188
+ path = target.umbrella_header_path_to_write
189
+ UI.message "- Generating umbrella header at #{UI.path(path)}" do
190
+ generator = Generator::UmbrellaHeader.new(target)
191
+ yield generator if block_given?
192
+ update_changed_file(generator, path)
193
+
194
+ # Add the file to the support group and the native target,
195
+ # so it will been added to the header build phase
196
+ file_ref = add_file_to_support_group(path)
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
+ source = path.relative_path_from(linked_path.dirname)
203
+ FileUtils.ln_sf(source, linked_path)
204
+ end
205
+
206
+ acl = target.build_as_framework? ? 'Public' : 'Project'
207
+ build_file.settings ||= {}
208
+ build_file.settings['ATTRIBUTES'] = [acl]
209
+ end
210
+ end
211
+
212
+ # Generates a dummy source file for each target so libraries that contain
213
+ # only categories build.
214
+ #
215
+ # @param [PBXNativeTarget] native_target
216
+ # the native target to link the dummy source file into.
217
+ #
218
+ # @return [void]
219
+ #
220
+ def create_dummy_source(native_target)
221
+ path = target.dummy_source_path
222
+ UI.message "- Generating dummy source at #{UI.path(path)}" do
223
+ generator = Generator::DummySource.new(target.label)
224
+ update_changed_file(generator, path)
225
+ file_reference = add_file_to_support_group(path)
226
+ native_target.source_build_phase.add_file_reference(file_reference)
227
+ end
228
+ end
229
+
230
+ private
231
+
232
+ #-----------------------------------------------------------------------#
233
+
234
+ # @!group Private helpers.
235
+
236
+ # @return [PBXGroup] the group where the file references to the support
237
+ # files should be stored.
238
+ #
239
+ attr_reader :support_files_group
240
+
241
+ # Adds a reference to the given file in the support group of this target.
242
+ #
243
+ # @param [Pathname] path
244
+ # The path of the file to which the reference should be added.
245
+ #
246
+ # @return [PBXFileReference] the file reference of the added file.
247
+ #
248
+ def add_file_to_support_group(path)
249
+ support_files_group.new_file(path)
250
+ end
251
+
252
+ #-----------------------------------------------------------------------#
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,110 @@
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 [String] 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
+ # @param [String] build_setting_value
52
+ # an optional value to set for the `INFOPLIST_FILE` build setting on the
53
+ # native target. If none is specified then the value is calculated from the
54
+ # Info.plist path relative to the sandbox root.
55
+ #
56
+ # @return [void]
57
+ #
58
+ def create_info_plist_file_with_sandbox(sandbox, path, native_target, version, platform,
59
+ bundle_package_type = :fmwk, additional_entries: {},
60
+ build_setting_value: nil)
61
+ UI.message "- Generating Info.plist file at #{UI.path(path)}" do
62
+ generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type, additional_entries)
63
+ update_changed_file(generator, path)
64
+
65
+ build_setting_value ||= path.relative_path_from(sandbox.root).to_s
66
+ native_target.build_configurations.each do |c|
67
+ c.build_settings['INFOPLIST_FILE'] = build_setting_value
68
+ end
69
+ end
70
+ end
71
+
72
+ # Creates a prefix header file which imports `UIKit` or `Cocoa` according
73
+ # to the platform of the target. This file also include any prefix header
74
+ # content reported by the specification of the pods.
75
+ #
76
+ # @param [Pathname] path
77
+ # the path to generate the prefix header for.
78
+ #
79
+ # @param [Array<Sandbox::FileAccessor>] file_accessors
80
+ # the file accessors to use for this prefix header that point to a path of a prefix header.
81
+ #
82
+ # @param [Platform] platform
83
+ # the platform to use for this prefix header.
84
+ #
85
+ # @param [PBXNativeTarget] native_target
86
+ # the native target on which the prefix header should be configured for.
87
+ #
88
+ # @param [Pathname] project_directory
89
+ # the directory containing the project of the target
90
+ #
91
+ # @return [void]
92
+ #
93
+ def create_prefix_header(path, file_accessors, platform, native_target, project_directory)
94
+ generator = Generator::PrefixHeader.new(file_accessors, platform)
95
+ update_changed_file(generator, path)
96
+
97
+ relative_path = path.relative_path_from(project_directory).to_s
98
+ native_target.build_configurations.each do |c|
99
+ c.build_settings['GCC_PREFIX_HEADER'] = relative_path
100
+ end
101
+ end
102
+
103
+ module_function :update_changed_file
104
+ module_function :create_info_plist_file_with_sandbox
105
+ module_function :create_prefix_header
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,291 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ # The {PodsProjectGenerator} handles generation of CocoaPods Xcode projects.
5
+ #
6
+ class PodsProjectGenerator
7
+ require 'cocoapods/installer/xcode/pods_project_generator/target_installer_helper'
8
+ require 'cocoapods/installer/xcode/pods_project_generator/pod_target_integrator'
9
+ require 'cocoapods/installer/xcode/pods_project_generator/target_installer'
10
+ require 'cocoapods/installer/xcode/pods_project_generator/target_installation_result'
11
+ require 'cocoapods/installer/xcode/pods_project_generator/pod_target_installer'
12
+ require 'cocoapods/installer/xcode/pods_project_generator/file_references_installer'
13
+ require 'cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer'
14
+ require 'cocoapods/installer/xcode/pods_project_generator/project_generator'
15
+ require 'cocoapods/installer/xcode/pods_project_generator_result'
16
+ require 'cocoapods/installer/xcode/pods_project_generator/aggregate_target_dependency_installer'
17
+ require 'cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer'
18
+ require 'cocoapods/native_target_extension.rb'
19
+
20
+ # @return [Sandbox] The sandbox where the Pods should be installed.
21
+ #
22
+ attr_reader :sandbox
23
+
24
+ # @return [Array<AggregateTarget>] The model representations of an
25
+ # aggregation of pod targets generated for a target definition
26
+ # in the Podfile.
27
+ #
28
+ attr_reader :aggregate_targets
29
+
30
+ # @return [Array<PodTarget>] The model representations of pod targets.
31
+ #
32
+ attr_reader :pod_targets
33
+
34
+ # @return [Hash{String => Symbol}] The build configurations that need to be installed.
35
+ #
36
+ attr_reader :build_configurations
37
+
38
+ # @return [InstallationOptions] the installation options from the Podfile.
39
+ #
40
+ attr_reader :installation_options
41
+
42
+ # @return [Config] the global CocoaPods configuration.
43
+ #
44
+ attr_reader :config
45
+
46
+ # @return [Integer] the object version for the projects we will generate.
47
+ #
48
+ attr_reader :project_object_version
49
+
50
+ # @return [ProjectMetadataCache] the metadata cache used to reconstruct target dependencies.
51
+ #
52
+ attr_reader :metadata_cache
53
+
54
+ # Initialize a new instance
55
+ #
56
+ # @param [Sandbox] sandbox @see #sandbox
57
+ # @param [Array<AggregateTarget>] aggregate_targets @see #aggregate_targets
58
+ # @param [Array<PodTarget>] pod_targets @see #pod_targets
59
+ # @param [Hash{String => Symbol}] build_configurations @see #build_configurations
60
+ # @param [InstallationOptions] installation_options @see #installation_options
61
+ # @param [Config] config @see #config
62
+ # @param [Integer] project_object_version @see #project_object_version
63
+ # @param [ProjectMetadataCache] metadata_cache @see #metadata_cache
64
+ #
65
+ def initialize(sandbox, aggregate_targets, pod_targets, build_configurations, installation_options, config,
66
+ project_object_version, metadata_cache = nil)
67
+ @sandbox = sandbox
68
+ @aggregate_targets = aggregate_targets
69
+ @pod_targets = pod_targets
70
+ @build_configurations = build_configurations
71
+ @installation_options = installation_options
72
+ @config = config
73
+ @project_object_version = project_object_version
74
+ @metadata_cache = metadata_cache
75
+ end
76
+
77
+ # Configure schemes for the specified project and pod targets. Schemes for development pods will be shared
78
+ # if requested by the integration.
79
+ #
80
+ # @param [PBXProject] project The project to configure schemes for.
81
+ # @param [Array<PodTarget>] pod_targets The pod targets within that project to configure their schemes.
82
+ # @param [PodsProjectGeneratorResult] generator_result the result of the project generation
83
+ #
84
+ # @return [void]
85
+ #
86
+ def configure_schemes(project, pod_targets, generator_result)
87
+ pod_targets.each do |pod_target|
88
+ share_scheme = pod_target.should_build? && share_scheme_for_development_pod?(pod_target.pod_name) && sandbox.local?(pod_target.pod_name)
89
+ configure_schemes_for_pod_target(project, pod_target, share_scheme, generator_result)
90
+ end
91
+ end
92
+
93
+ # @!attribute [Hash{String => TargetInstallationResult}] pod_target_installation_results
94
+ # @!attribute [Hash{String => TargetInstallationResult}] aggregate_target_installation_results
95
+ InstallationResults = Struct.new(:pod_target_installation_results, :aggregate_target_installation_results)
96
+
97
+ private
98
+
99
+ def install_file_references(project, pod_targets)
100
+ UI.message "- Installing files into #{project.project_name} project" do
101
+ installer = FileReferencesInstaller.new(sandbox, pod_targets, project, installation_options.preserve_pod_file_structure)
102
+ installer.install!
103
+ end
104
+ end
105
+
106
+ def install_pod_targets(project, pod_targets)
107
+ umbrella_headers_by_dir = pod_targets.map do |pod_target|
108
+ next unless pod_target.should_build? && pod_target.defines_module?
109
+ pod_target.umbrella_header_path
110
+ end.compact.group_by(&:dirname)
111
+
112
+ pod_target_installation_results = Hash[pod_targets.sort_by(&:name).map do |pod_target|
113
+ umbrella_headers_in_header_dir = umbrella_headers_by_dir[pod_target.module_map_path.dirname]
114
+ target_installer = PodTargetInstaller.new(sandbox, project, pod_target, umbrella_headers_in_header_dir)
115
+ [pod_target.name, target_installer.install!]
116
+ end]
117
+
118
+ # Hook up system framework dependencies for the pod targets that were just installed.
119
+ pod_target_installation_result_values = pod_target_installation_results.values.compact
120
+ unless pod_target_installation_result_values.empty?
121
+ add_system_framework_dependencies(pod_target_installation_result_values)
122
+ end
123
+
124
+ pod_target_installation_results
125
+ end
126
+
127
+ def install_aggregate_targets(project, aggregate_targets)
128
+ UI.message '- Installing Aggregate Targets' do
129
+ aggregate_target_installation_results = Hash[aggregate_targets.sort_by(&:name).map do |target|
130
+ target_installer = AggregateTargetInstaller.new(sandbox, project, target)
131
+ [target.name, target_installer.install!]
132
+ end]
133
+
134
+ aggregate_target_installation_results
135
+ end
136
+ end
137
+
138
+ # @param [Hash{String => InstallationResult}] pod_target_installation_results
139
+ # the installations to integrate
140
+ #
141
+ # @return [void]
142
+ #
143
+ def integrate_targets(pod_target_installation_results)
144
+ pod_installations_to_integrate = pod_target_installation_results.values.select do |pod_target_installation_result|
145
+ pod_target = pod_target_installation_result.target
146
+ !pod_target_installation_result.test_native_targets.empty? ||
147
+ !pod_target_installation_result.app_native_targets.empty? ||
148
+ pod_target.contains_script_phases? ||
149
+ pod_target.framework_paths.values.flatten.any? { |paths| !paths.dsym_path.nil? } ||
150
+ pod_target.xcframeworks.values.any? { |xcframeworks| !xcframeworks.empty? }
151
+ end
152
+ return if pod_installations_to_integrate.empty?
153
+
154
+ UI.message '- Integrating targets' do
155
+ use_input_output_paths = !installation_options.disable_input_output_paths
156
+ pod_installations_to_integrate.each do |pod_target_installation_result|
157
+ PodTargetIntegrator.new(pod_target_installation_result, :use_input_output_paths => use_input_output_paths).integrate!
158
+ end
159
+ end
160
+ end
161
+
162
+ def add_system_framework_dependencies(pod_target_installation_results)
163
+ sorted_installation_results = pod_target_installation_results.sort_by do |pod_target_installation_result|
164
+ pod_target_installation_result.target.name
165
+ end
166
+ sorted_installation_results.each do |target_installation_result|
167
+ pod_target = target_installation_result.target
168
+ next unless pod_target.should_build?
169
+ next if pod_target.build_as_static?
170
+ pod_target.file_accessors.each do |file_accessor|
171
+ native_target = target_installation_result.native_target_for_spec(file_accessor.spec)
172
+ add_system_frameworks_to_native_target(native_target, file_accessor)
173
+ end
174
+ end
175
+ end
176
+
177
+ # Adds a target dependency for each pod spec to each aggregate target and
178
+ # links the pod targets among each other.
179
+ #
180
+ # @param [Array[Hash{String=>TargetInstallationResult}]] target_installation_results
181
+ # the installation results that were produced when all targets were installed. This includes
182
+ # pod target installation results and aggregate target installation results.
183
+ #
184
+ # @return [void]
185
+ #
186
+ def wire_target_dependencies(target_installation_results)
187
+ pod_target_installation_results_hash = target_installation_results.pod_target_installation_results
188
+ aggregate_target_installation_results_hash = target_installation_results.aggregate_target_installation_results
189
+
190
+ AggregateTargetDependencyInstaller.new(sandbox, aggregate_target_installation_results_hash,
191
+ pod_target_installation_results_hash, metadata_cache).install!
192
+
193
+ PodTargetDependencyInstaller.new(sandbox, pod_target_installation_results_hash, metadata_cache).install!
194
+ end
195
+
196
+ # @param [String] pod The root name of the development pod.
197
+ #
198
+ # @return [Bool] whether the scheme for the given development pod should be
199
+ # shared.
200
+ #
201
+ def share_scheme_for_development_pod?(pod)
202
+ case dev_pods_to_share = installation_options.share_schemes_for_development_pods
203
+ when TrueClass, FalseClass, NilClass
204
+ dev_pods_to_share
205
+ when Array
206
+ dev_pods_to_share.any? { |dev_pod| dev_pod === pod } # rubocop:disable Style/CaseEquality
207
+ else
208
+ raise Informative, 'Unable to handle share_schemes_for_development_pods ' \
209
+ "being set to #{dev_pods_to_share.inspect} -- please set it to true, " \
210
+ 'false, or an array of pods to share schemes for.'
211
+ end
212
+ end
213
+
214
+ #------------------------------------------------------------------------#
215
+
216
+ # @! group Private Helpers
217
+
218
+ def add_system_frameworks_to_native_target(native_target, file_accessor)
219
+ file_accessor.spec_consumer.frameworks.each do |framework|
220
+ native_target.add_system_framework(framework)
221
+ end
222
+ end
223
+
224
+ # @param [Project] project
225
+ # the project of the pod target
226
+ #
227
+ # @param [Pod::PodTarget] pod_target
228
+ # the pod target for which to configure schemes
229
+ #
230
+ # @param [Boolean] share_scheme
231
+ # whether the created schemes should be shared
232
+ #
233
+ # @param [PodsProjectGeneratorResult] generator_result
234
+ # the project generation result
235
+ #
236
+ def configure_schemes_for_pod_target(project, pod_target, share_scheme, generator_result)
237
+ # Ignore subspecs because they do not provide a scheme configuration due to the fact that they are always
238
+ # merged with the root spec scheme.
239
+ specs = [pod_target.root_spec] + pod_target.test_specs + pod_target.app_specs
240
+ hosted_test_specs_by_host = Hash.new do |hash, key|
241
+ hash[key] = []
242
+ end
243
+ pod_target.test_app_hosts_by_spec.each do |spec, (host_spec, host_target)|
244
+ if host_target == pod_target
245
+ hosted_test_specs_by_host[host_spec] << spec
246
+ end
247
+ end
248
+ is_custom_host = !hosted_test_specs_by_host.empty?
249
+ specs.each do |spec|
250
+ scheme_name = pod_target.spec_label(spec)
251
+ scheme_configuration = pod_target.scheme_for_spec(spec)
252
+ if !scheme_configuration.empty? || is_custom_host
253
+ scheme_path = Xcodeproj::XCScheme.user_data_dir(project.path) + "#{scheme_name}.xcscheme"
254
+ scheme = Xcodeproj::XCScheme.new(scheme_path)
255
+ command_line_arguments = scheme.launch_action.command_line_arguments
256
+ scheme_configuration.fetch(:launch_arguments, []).each do |launch_arg|
257
+ command_line_arguments.assign_argument(:argument => launch_arg, :enabled => true)
258
+ end
259
+ scheme.launch_action.command_line_arguments = command_line_arguments
260
+ environment_variables = scheme.launch_action.environment_variables
261
+ scheme_configuration.fetch(:environment_variables, {}).each do |k, v|
262
+ environment_variables.assign_variable(:key => k, :value => v)
263
+ end
264
+ scheme.launch_action.environment_variables = environment_variables
265
+ if scheme_configuration.key?(:code_coverage)
266
+ scheme.test_action.code_coverage_enabled = scheme_configuration[:code_coverage]
267
+ end
268
+
269
+ hosted_test_specs_by_host[spec].each do |hosted_spec|
270
+ # We are an app spec which hosts this test spec.
271
+ # Include the test specs's test bundle within our scheme's test action
272
+ native_target = generator_result.native_target_for_spec(hosted_spec)
273
+ testable = Xcodeproj::XCScheme::TestAction::TestableReference.new(native_target)
274
+ scheme.test_action.add_testable(testable)
275
+ end
276
+
277
+ if spec.test_specification?
278
+ # Default to using the test bundle to expand variables
279
+ native_target_for_expansion = generator_result.native_target_for_spec(spec)
280
+ macro_expansion = Xcodeproj::XCScheme::MacroExpansion.new(native_target_for_expansion)
281
+ scheme.launch_action.add_macro_expansion(macro_expansion)
282
+ end
283
+ scheme.save!
284
+ end
285
+ Xcodeproj::XCScheme.share_scheme(project.path, scheme_name) if share_scheme
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
291
+ end