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,60 @@
1
+ module Pod
2
+ class Project
3
+ # Adds a dependency on the given metadata cache.
4
+ #
5
+ # @param [Sandbox] sandbox
6
+ # The sandbox used for this installation.
7
+ #
8
+ # @param [AbstractTarget] target
9
+ # The parent target used to add a cached dependency.
10
+ #
11
+ # @param [MetadataCache] metadata
12
+ # The metadata holding all the required metadata to construct a target as a dependency.
13
+ #
14
+ # @return [void]
15
+ #
16
+ def self.add_cached_dependency(sandbox, target, metadata)
17
+ return if dependency_for_cached_target?(sandbox, target, metadata)
18
+ container_proxy = target.project.new(Xcodeproj::Project::PBXContainerItemProxy)
19
+
20
+ subproject_reference = target.project.reference_for_path(sandbox.root + metadata.container_project_path)
21
+ raise ArgumentError, "add_dependency received target (#{target}) that belongs to a project that is not this project (#{self}) and is not a subproject of this project" unless subproject_reference
22
+ container_proxy.container_portal = subproject_reference.uuid
23
+
24
+ container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
25
+ container_proxy.remote_global_id_string = metadata.native_target_uuid
26
+ container_proxy.remote_info = metadata.target_label
27
+
28
+ dependency = target.project.new(Xcodeproj::Project::PBXTargetDependency)
29
+ dependency.name = metadata.target_label
30
+ dependency.target_proxy = container_proxy
31
+
32
+ target.dependencies << dependency
33
+ end
34
+
35
+ # Checks whether this target has a dependency on the given target.
36
+ #
37
+ # @param [Sandbox] sandbox
38
+ # The sandbox used for this installation.
39
+ #
40
+ # @param [AbstractTarget] target
41
+ # The parent target used to add a cached dependency.
42
+ #
43
+ # @param [TargetMetadata] cached_target
44
+ # the target to search for.
45
+ #
46
+ # @return [Bool]
47
+ #
48
+ def self.dependency_for_cached_target?(sandbox, target, cached_target)
49
+ target.dependencies.find do |dep|
50
+ if dep.target_proxy.remote?
51
+ subproject_reference = target.project.reference_for_path(sandbox.root + cached_target.container_project_path)
52
+ uuid = subproject_reference.uuid if subproject_reference
53
+ dep.target_proxy.remote_global_id_string == cached_target.native_target_uuid && dep.target_proxy.container_portal == uuid
54
+ else
55
+ dep.target.uuid == cached_target.native_target_uuid
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ # rubocop:disable Naming/FileName
2
+
3
+ require 'open-uri'
4
+
5
+ # Allow OpenURI to follow http to https redirects.
6
+ #
7
+ module OpenURI
8
+ # Whether {#open} should follow a redirect.
9
+ #
10
+ # Inspiration from: https://gist.github.com/1271420
11
+ # Relevant issue: https://bugs.ruby-lang.org/issues/3719
12
+ # Source here: https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb
13
+ #
14
+ # This test is intended to forbid a redirection from http://... to
15
+ # file:///etc/passwd, file:///dev/zero, etc. CVE-2011-1521
16
+ # https to http redirect is also forbidden intentionally.
17
+ # It avoids sending secure cookie or referrer by non-secure HTTP protocol.
18
+ # (RFC 2109 4.3.1, RFC 2965 3.3, RFC 2616 15.1.3)
19
+ # However this is ad hoc. It should be extensible/configurable.
20
+ #
21
+ # @param [URI::Generic] uri1
22
+ # the origin uri from where the redirect origins
23
+ #
24
+ # @param [URI::Generic] uri2
25
+ # the target uri where to where the redirect points to
26
+ #
27
+ # @return [Bool]
28
+ #
29
+ def self.redirectable?(uri1, uri2)
30
+ uri1.scheme.downcase == uri2.scheme.downcase ||
31
+ (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:https?|ftp)\z/i =~ uri2.scheme)
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ require 'cocoapods-core/podfile'
2
+
3
+ module Pod
4
+ class Podfile
5
+ autoload :InstallationOptions, 'cocoapods/installer/installation_options'
6
+
7
+ # @return [Pod::Installer::InstallationOptions] the installation options specified in the Podfile
8
+ #
9
+ def installation_options
10
+ @installation_options ||= Pod::Installer::InstallationOptions.from_podfile(self)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,544 @@
1
+ require 'xcodeproj'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module Pod
5
+ # The Pods project.
6
+ #
7
+ # Model class which provides helpers for working with the Pods project
8
+ # through the installation process.
9
+ #
10
+ class Project < Xcodeproj::Project
11
+ # @return [PBXGroup] The group for the support files of the aggregate
12
+ # targets.
13
+ #
14
+ attr_reader :support_files_group
15
+
16
+ # @return [PBXGroup] The group for the Pods.
17
+ #
18
+ attr_reader :pods
19
+
20
+ # @return [PBXGroup] The group for Development Pods.
21
+ #
22
+ attr_reader :development_pods
23
+
24
+ # @return [PBXGroup] The group for dependencies.
25
+ # Used by #generate_multiple_pod_projects installation option.
26
+ #
27
+ attr_reader :dependencies_group
28
+
29
+ # @return [Bool] Bool indicating if this project is a pod target subproject.
30
+ # Used by `generate_multiple_pod_projects` installation option.
31
+ #
32
+ attr_reader :pod_target_subproject
33
+ alias pod_target_subproject? pod_target_subproject
34
+
35
+ # @return [String] The basename of the project path without .xcodeproj extension.
36
+ #
37
+ attr_reader :project_name
38
+
39
+ # Initialize a new instance
40
+ #
41
+ # @param [Pathname, String] path @see Xcodeproj::Project#path
42
+ # @param [Bool] skip_initialization Whether the project should be initialized from scratch.
43
+ # @param [Int] object_version Object version to use for serialization, defaults to Xcode 3.2 compatible.
44
+ #
45
+ def initialize(path, skip_initialization = false,
46
+ object_version = Xcodeproj::Constants::DEFAULT_OBJECT_VERSION, pod_target_subproject: false)
47
+ @uuid_prefix = Digest('SHA256').hexdigest(File.basename(path)).upcase
48
+ super(path, skip_initialization, object_version)
49
+ @support_files_group = new_group('Targets Support Files')
50
+ @refs_by_absolute_path = {}
51
+ @variant_groups_by_path_and_name = {}
52
+ @pods = new_group('Pods')
53
+ @development_pods = new_group('Development Pods')
54
+ @dependencies_group = new_group('Dependencies')
55
+ @pod_target_subproject = pod_target_subproject
56
+ @project_name = Pathname(path).basename('.*').to_s
57
+ self.symroot = LEGACY_BUILD_ROOT
58
+ end
59
+
60
+ # Generates a list of new UUIDs that created objects can be assigned.
61
+ #
62
+ # @note Overridden to generate UUIDs in a much faster way, since we don't need to check for collisions
63
+ # (as the Pods project is regenerated each time, and thus all UUIDs will have come from this method)
64
+ #
65
+ # @param [Integer] count
66
+ # The number of UUIDs to generate
67
+ #
68
+ # @return [Void]
69
+ #
70
+ def generate_available_uuid_list(count = 100)
71
+ start = @generated_uuids.size
72
+ uniques = Array.new(count) { |i| format('%.6s%07X0', @uuid_prefix, start + i) }
73
+ @generated_uuids += uniques
74
+ @available_uuids += uniques
75
+ end
76
+
77
+ public
78
+
79
+ # @!group Legacy Xcode build root
80
+ #-------------------------------------------------------------------------#
81
+
82
+ LEGACY_BUILD_ROOT = '${SRCROOT}/../build'
83
+
84
+ # @param [String] symroot
85
+ # The build root that is used when Xcode is configured to not use the
86
+ # workspace’s build root. Defaults to `${SRCROOT}/../build`.
87
+ #
88
+ # @return [void]
89
+ #
90
+ def symroot=(symroot)
91
+ root_object.build_configuration_list.build_configurations.each do |config|
92
+ config.build_settings['SYMROOT'] = symroot
93
+ end
94
+ end
95
+
96
+ public
97
+
98
+ # @!group Pod Groups
99
+ #-------------------------------------------------------------------------#
100
+
101
+ # Creates a new group for the Pod with the given name and configures its
102
+ # path.
103
+ #
104
+ # @param [String] pod_name
105
+ # The name of the Pod.
106
+ #
107
+ # @param [#to_s] path
108
+ # The path to the root of the Pod.
109
+ #
110
+ # @param [Bool] development
111
+ # Whether the group should be added to the Development Pods group.
112
+ #
113
+ # @param [Bool] absolute
114
+ # Whether the path of the group should be set as absolute.
115
+ #
116
+ # @return [PBXGroup] The new group.
117
+ #
118
+ def add_pod_group(pod_name, path, development = false, absolute = false)
119
+ raise '[BUG]' if pod_group(pod_name)
120
+
121
+ parent_group =
122
+ if pod_target_subproject
123
+ main_group
124
+ else
125
+ development ? development_pods : pods
126
+ end
127
+ source_tree = absolute ? :absolute : :group
128
+
129
+ group = parent_group.new_group(pod_name, path, source_tree)
130
+ group
131
+ end
132
+
133
+ # Creates a new subproject reference for the given project and configures its
134
+ # group location.
135
+ #
136
+ # @param [Project] project
137
+ # The subproject to be added.
138
+ #
139
+ # @param [Bool] development
140
+ # Whether the project should be added to the Development Pods group.
141
+ # For projects where `pod_target_subproject` is enabled, all subprojects are added into the Dependencies group.
142
+ #
143
+ # @return [PBXFileReference] The new file reference.
144
+ #
145
+ def add_pod_subproject(project, development = false)
146
+ parent_group = group_for_subproject_reference(development)
147
+ add_subproject_reference(project, parent_group)
148
+ end
149
+
150
+ # Creates a new subproject reference for the given cached metadata and configures its
151
+ # group location.
152
+ #
153
+ # @param [Sandbox] sandbox
154
+ # The sandbox used for installation.
155
+ #
156
+ # @param [TargetMetadata] metadata
157
+ # The project metadata to be added.
158
+ #
159
+ # @param [Bool] development
160
+ # Whether the project should be added to the Development Pods group.
161
+ # For projects where `pod_target_subproject` is enabled, all subprojects are added into the Dependencies group.
162
+ #
163
+ # @return [PBXFileReference] The new file reference.
164
+ #
165
+ def add_cached_pod_subproject(sandbox, metadata, development = false)
166
+ parent_group = group_for_subproject_reference(development)
167
+ add_cached_subproject_reference(sandbox, metadata, parent_group)
168
+ end
169
+
170
+ # @return [Array<PBXGroup>] Returns all the group of the Pods.
171
+ #
172
+ def pod_groups
173
+ if pod_target_subproject
174
+ main_group.children.objects
175
+ else
176
+ pods.children.objects + development_pods.children.objects
177
+ end
178
+ end
179
+
180
+ # Returns the group for the Pod with the given name.
181
+ #
182
+ # @param [String] pod_name
183
+ # The name of the Pod.
184
+ #
185
+ # @return [PBXGroup] The group.
186
+ #
187
+ def pod_group(pod_name)
188
+ pod_groups.find { |group| group.name == pod_name }
189
+ end
190
+
191
+ # @return [Hash] The names of the specification subgroups by key.
192
+ #
193
+ SPEC_SUBGROUPS = {
194
+ :resources => 'Resources',
195
+ :frameworks => 'Frameworks',
196
+ :developer => 'Pod',
197
+ }
198
+
199
+ # Returns the group for the specification with the give name creating it if
200
+ # needed.
201
+ #
202
+ # @param [String] spec_name
203
+ # The full name of the specification.
204
+ #
205
+ # @return [PBXGroup] The group.
206
+ #
207
+ def group_for_spec(spec_name, subgroup_key = nil)
208
+ pod_name = Specification.root_name(spec_name)
209
+ group = pod_group(pod_name)
210
+ raise "[Bug] Unable to locate group for Pod named `#{pod_name}`" unless group
211
+ if spec_name != pod_name
212
+ subspecs_names = spec_name.gsub(pod_name + '/', '').split('/')
213
+ subspecs_names.each do |name|
214
+ group = group[name] || group.new_group(name)
215
+ end
216
+ end
217
+
218
+ if subgroup_key
219
+ subgroup_name = SPEC_SUBGROUPS[subgroup_key]
220
+ raise ArgumentError, "Unrecognized subgroup key `#{subgroup_key}`" unless subgroup_name
221
+ group = group[subgroup_name] || group.new_group(subgroup_name)
222
+ end
223
+
224
+ group
225
+ end
226
+
227
+ # Returns the support files group for the Pod with the given name.
228
+ #
229
+ # @param [String] pod_name
230
+ # The name of the Pod.
231
+ #
232
+ # @return [PBXGroup] The group.
233
+ #
234
+ def pod_support_files_group(pod_name, dir)
235
+ group = pod_group(pod_name)
236
+ support_files_group = group['Support Files']
237
+ unless support_files_group
238
+ support_files_group = group.new_group('Support Files', dir)
239
+ end
240
+ support_files_group
241
+ end
242
+
243
+ public
244
+
245
+ # @!group File references
246
+ #-------------------------------------------------------------------------#
247
+
248
+ # Adds a file reference to given path as a child of the given group.
249
+ #
250
+ # @param [Array<Pathname,String>] absolute_path
251
+ # The path of the file.
252
+ #
253
+ # @param [PBXGroup] group
254
+ # The group for the new file reference.
255
+ #
256
+ # @param [Bool] reflect_file_system_structure
257
+ # Whether group structure should reflect the file system structure.
258
+ # If yes, where needed, intermediate groups are created, similar to
259
+ # how mkdir -p operates.
260
+ #
261
+ # @param [Pathname] base_path
262
+ # The base path for newly created groups when reflect_file_system_structure is true.
263
+ # If nil, the provided group's real_path is used.
264
+ #
265
+ # @return [PBXFileReference] The new file reference.
266
+ #
267
+ def add_file_reference(absolute_path, group, reflect_file_system_structure = false, base_path = nil)
268
+ file_path_name = absolute_path.is_a?(Pathname) ? absolute_path : Pathname(absolute_path)
269
+ if ref = reference_for_path(file_path_name)
270
+ return ref
271
+ end
272
+
273
+ group = group_for_path_in_group(file_path_name, group, reflect_file_system_structure, base_path)
274
+ ref = group.new_file(file_path_name.realpath)
275
+ @refs_by_absolute_path[file_path_name.to_s] = ref
276
+ end
277
+
278
+ # @!group File references
279
+ #-------------------------------------------------------------------------#
280
+
281
+ # Adds a file reference for a project as a child of the given group.
282
+ #
283
+ # @param [Project] project
284
+ # The project to add as a subproject reference.
285
+ #
286
+ # @param [PBXGroup] group
287
+ # The group for the new subproject reference.
288
+ #
289
+ # @return [PBXFileReference] The new file reference.
290
+ #
291
+ def add_subproject_reference(project, group)
292
+ new_subproject_file_reference(project.path, group)
293
+ end
294
+
295
+ # Adds a file reference for a cached project as a child of the given group.
296
+ #
297
+ # @param [Sandbox] sandbox
298
+ # The sandbox used for installation.
299
+ #
300
+ # @param [MetadataCache] metadata
301
+ # The metadata holding the required properties to create a subproject reference.
302
+ #
303
+ # @param [PBXGroup] group
304
+ # The group for the new subproject reference.
305
+ #
306
+ # @return [PBXFileReference] The new file reference.
307
+ #
308
+ def add_cached_subproject_reference(sandbox, metadata, group)
309
+ new_subproject_file_reference(sandbox.root + metadata.container_project_path, group)
310
+ end
311
+
312
+ # Returns the file reference for the given absolute path.
313
+ #
314
+ # @param [#to_s] absolute_path
315
+ # The absolute path of the file whose reference is needed.
316
+ #
317
+ # @return [PBXFileReference] The file reference.
318
+ # @return [Nil] If no file reference could be found.
319
+ #
320
+ def reference_for_path(absolute_path)
321
+ absolute_path = absolute_path.is_a?(Pathname) ? absolute_path : Pathname(absolute_path)
322
+ unless absolute_path.absolute?
323
+ raise ArgumentError, "Paths must be absolute #{absolute_path}"
324
+ end
325
+
326
+ refs_by_absolute_path[absolute_path.to_s] ||= refs_by_absolute_path[absolute_path.realpath.to_s]
327
+ end
328
+
329
+ # Adds a file reference to the Podfile.
330
+ #
331
+ # @param [#to_s] podfile_path
332
+ # The path of the Podfile.
333
+ #
334
+ # @return [PBXFileReference] The new file reference.
335
+ #
336
+ def add_podfile(podfile_path)
337
+ new_file(podfile_path, :project).tap do |podfile_ref|
338
+ mark_ruby_file_ref(podfile_ref)
339
+ end
340
+ end
341
+
342
+ # Sets the syntax of the provided file reference to be Ruby, in the case that
343
+ # the file does not already have a ".rb" file extension (ex. the Podfile)
344
+ #
345
+ # @param [PBXFileReference] file_ref
346
+ # The file reference to change
347
+ #
348
+ def mark_ruby_file_ref(file_ref)
349
+ file_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
350
+ file_ref.explicit_file_type = 'text.script.ruby'
351
+ file_ref.last_known_file_type = 'text'
352
+ file_ref.tab_width = '2'
353
+ file_ref.indent_width = '2'
354
+ end
355
+
356
+ # Adds a new build configuration to the project and populates it with
357
+ # default settings according to the provided type.
358
+ #
359
+ # @note This method extends the original Xcodeproj implementation to
360
+ # include a preprocessor definition named after the build
361
+ # setting. This is done to support the TargetEnvironmentHeader
362
+ # specification of Pods available only on certain build
363
+ # configurations.
364
+ #
365
+ # @param [String] name
366
+ # The name of the build configuration.
367
+ #
368
+ # @param [Symbol] type
369
+ # The type of the build configuration used to populate the build
370
+ # settings, must be :debug or :release.
371
+ #
372
+ # @return [XCBuildConfiguration] The new build configuration.
373
+ #
374
+ def add_build_configuration(name, type)
375
+ build_configuration = super
376
+ settings = build_configuration.build_settings
377
+ definitions = settings['GCC_PREPROCESSOR_DEFINITIONS'] || ['$(inherited)']
378
+ defines = [defininition_for_build_configuration(name)]
379
+ defines << 'DEBUG' if type == :debug
380
+ defines.each do |define|
381
+ value = "#{define}=1"
382
+ unless definitions.include?(value)
383
+ definitions.unshift(value)
384
+ end
385
+ end
386
+ settings['GCC_PREPROCESSOR_DEFINITIONS'] = definitions
387
+
388
+ if type == :debug
389
+ settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] = 'DEBUG'
390
+ end
391
+
392
+ build_configuration
393
+ end
394
+
395
+ # @param [String] name
396
+ # The name of the build configuration.
397
+ #
398
+ # @return [String] The preprocessor definition to set for the configuration.
399
+ #
400
+ def defininition_for_build_configuration(name)
401
+ "POD_CONFIGURATION_#{name.underscore}".gsub(/[^a-zA-Z0-9_]/, '_').upcase
402
+ end
403
+
404
+ private
405
+
406
+ # @!group Private helpers
407
+ #-------------------------------------------------------------------------#
408
+
409
+ # @return [Hash{String => PBXFileReference}] The file references grouped
410
+ # by absolute path.
411
+ #
412
+ attr_reader :refs_by_absolute_path
413
+
414
+ # @return [Hash{[Pathname, String] => PBXVariantGroup}] The variant groups
415
+ # grouped by absolute path of parent dir and name.
416
+ #
417
+ attr_reader :variant_groups_by_path_and_name
418
+
419
+ # Returns the group for an absolute file path in another group.
420
+ # Creates subgroups to reflect the file system structure if
421
+ # reflect_file_system_structure is set to true.
422
+ # Makes a variant group if the path points to a localized file inside a
423
+ # *.lproj directory. To support Apple Base Internationalization, the same
424
+ # variant group is returned for interface files and strings files with
425
+ # the same name.
426
+ #
427
+ # @param [Pathname] absolute_pathname
428
+ # The pathname of the file to get the group for.
429
+ #
430
+ # @param [PBXGroup] group
431
+ # The parent group used as the base of the relative path.
432
+ #
433
+ # @param [Bool] reflect_file_system_structure
434
+ # Whether group structure should reflect the file system structure.
435
+ # If yes, where needed, intermediate groups are created, similar to
436
+ # how mkdir -p operates.
437
+ #
438
+ # @param [Pathname] base_path
439
+ # The base path for the newly created group. If nil, the provided group's real_path is used.
440
+ #
441
+ # @return [PBXGroup] The appropriate group for the filepath.
442
+ # Can be PBXVariantGroup, if the file is localized.
443
+ #
444
+ def group_for_path_in_group(absolute_pathname, group, reflect_file_system_structure, base_path = nil)
445
+ unless absolute_pathname.absolute?
446
+ raise ArgumentError, "Paths must be absolute #{absolute_pathname}"
447
+ end
448
+ unless base_path.nil? || base_path.absolute?
449
+ raise ArgumentError, "Paths must be absolute #{base_path}"
450
+ end
451
+
452
+ relative_base = base_path.nil? ? group.real_path : base_path.realdirpath
453
+ relative_pathname = absolute_pathname.relative_path_from(relative_base)
454
+ relative_dir = relative_pathname.dirname
455
+
456
+ # Add subgroups for directories, but treat .lproj as a file
457
+ if reflect_file_system_structure
458
+ path = relative_base
459
+ relative_dir.each_filename do |name|
460
+ break if name.to_s.downcase.include? '.lproj'
461
+ next if name == '.'
462
+ # Make sure groups have the correct absolute path set, as intermittent
463
+ # directories may not be included in the group structure
464
+ path += name
465
+ group = group.children.find { |c| c.display_name == name } || group.new_group(name, path)
466
+ end
467
+ end
468
+
469
+ # Turn files inside .lproj directories into a variant group
470
+ if relative_dir.basename.to_s.downcase.include? '.lproj'
471
+ group_name = variant_group_name(absolute_pathname)
472
+ lproj_parent_dir = absolute_pathname.dirname.dirname
473
+ group = @variant_groups_by_path_and_name[[lproj_parent_dir, group_name]] ||=
474
+ group.new_variant_group(group_name, lproj_parent_dir)
475
+ end
476
+
477
+ group
478
+ end
479
+
480
+ # Returns the name to be used for a the variant group for a file at a given path.
481
+ # The path must be localized (within an *.lproj directory).
482
+ #
483
+ # @param [Pathname] path The localized path to get a variant group name for.
484
+ #
485
+ # @return [String] The variant group name.
486
+ #
487
+ def variant_group_name(path)
488
+ unless path.to_s.downcase.include?('.lproj/')
489
+ raise ArgumentError, 'Only localized resources can be added to variant groups.'
490
+ end
491
+
492
+ # When using Base Internationalization for XIBs and Storyboards a strings
493
+ # file is generated with the same name as the XIB/Storyboard in each .lproj
494
+ # directory:
495
+ # Base.lproj/MyViewController.xib
496
+ # fr.lproj/MyViewController.strings
497
+ #
498
+ # In this scenario we want the variant group to be the same as the XIB or Storyboard.
499
+ #
500
+ # Base Internationalization: https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/InternationalizingYourUserInterface/InternationalizingYourUserInterface.html
501
+ if path.extname.downcase == '.strings'
502
+ %w(.xib .storyboard).each do |extension|
503
+ possible_interface_file = path.dirname.dirname + 'Base.lproj' + path.basename.sub_ext(extension)
504
+ return possible_interface_file.basename.to_s if possible_interface_file.exist?
505
+ end
506
+ end
507
+
508
+ path.basename.to_s
509
+ end
510
+
511
+ def new_subproject_file_reference(project_path, group)
512
+ if ref = reference_for_path(project_path)
513
+ return ref
514
+ end
515
+
516
+ # We call into the private function `FileReferencesFactory.new_file_reference` instead of `FileReferencesFactory.new_reference`
517
+ # because it delegates into `FileReferencesFactory.new_subproject` which has the extra behavior of opening the Project which
518
+ # is an expensive operation for large projects.
519
+ #
520
+ ref = Xcodeproj::Project::FileReferencesFactory.send(:new_file_reference, group, project_path, :group)
521
+ ref.name = Pathname(project_path).basename('.*').to_s
522
+ ref.include_in_index = nil
523
+
524
+ attribute = PBXProject.references_by_keys_attributes.find { |attrb| attrb.name == :project_references }
525
+ project_reference = ObjectDictionary.new(attribute, group.project.root_object)
526
+ project_reference[:project_ref] = ref
527
+ root_object.project_references << project_reference
528
+ refs_by_absolute_path[project_path.to_s] = ref
529
+ ref
530
+ end
531
+
532
+ # Returns the parent group a new subproject reference should belong to.
533
+ #
534
+ def group_for_subproject_reference(development)
535
+ if pod_target_subproject
536
+ dependencies_group
537
+ else
538
+ development ? development_pods : pods
539
+ end
540
+ end
541
+
542
+ #-------------------------------------------------------------------------#
543
+ end
544
+ end