xcocoapods 1.5.3

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/CHANGELOG.md +6303 -0
  3. data/LICENSE +28 -0
  4. data/README.md +80 -0
  5. data/bin/pod +56 -0
  6. data/bin/sandbox-pod +168 -0
  7. data/lib/cocoapods.rb +73 -0
  8. data/lib/cocoapods/command.rb +175 -0
  9. data/lib/cocoapods/command/cache.rb +28 -0
  10. data/lib/cocoapods/command/cache/clean.rb +90 -0
  11. data/lib/cocoapods/command/cache/list.rb +69 -0
  12. data/lib/cocoapods/command/env.rb +66 -0
  13. data/lib/cocoapods/command/init.rb +128 -0
  14. data/lib/cocoapods/command/install.rb +45 -0
  15. data/lib/cocoapods/command/ipc.rb +19 -0
  16. data/lib/cocoapods/command/ipc/list.rb +40 -0
  17. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  18. data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
  19. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  20. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  21. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  22. data/lib/cocoapods/command/lib.rb +11 -0
  23. data/lib/cocoapods/command/lib/create.rb +105 -0
  24. data/lib/cocoapods/command/lib/lint.rb +121 -0
  25. data/lib/cocoapods/command/list.rb +39 -0
  26. data/lib/cocoapods/command/options/project_directory.rb +36 -0
  27. data/lib/cocoapods/command/options/repo_update.rb +34 -0
  28. data/lib/cocoapods/command/outdated.rb +140 -0
  29. data/lib/cocoapods/command/repo.rb +29 -0
  30. data/lib/cocoapods/command/repo/add.rb +103 -0
  31. data/lib/cocoapods/command/repo/lint.rb +82 -0
  32. data/lib/cocoapods/command/repo/list.rb +93 -0
  33. data/lib/cocoapods/command/repo/push.rb +281 -0
  34. data/lib/cocoapods/command/repo/remove.rb +36 -0
  35. data/lib/cocoapods/command/repo/update.rb +28 -0
  36. data/lib/cocoapods/command/setup.rb +103 -0
  37. data/lib/cocoapods/command/spec.rb +112 -0
  38. data/lib/cocoapods/command/spec/cat.rb +51 -0
  39. data/lib/cocoapods/command/spec/create.rb +283 -0
  40. data/lib/cocoapods/command/spec/edit.rb +87 -0
  41. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  42. data/lib/cocoapods/command/spec/lint.rb +137 -0
  43. data/lib/cocoapods/command/spec/which.rb +43 -0
  44. data/lib/cocoapods/command/update.rb +101 -0
  45. data/lib/cocoapods/config.rb +347 -0
  46. data/lib/cocoapods/core_overrides.rb +1 -0
  47. data/lib/cocoapods/downloader.rb +190 -0
  48. data/lib/cocoapods/downloader/cache.rb +233 -0
  49. data/lib/cocoapods/downloader/request.rb +86 -0
  50. data/lib/cocoapods/downloader/response.rb +16 -0
  51. data/lib/cocoapods/executable.rb +222 -0
  52. data/lib/cocoapods/external_sources.rb +57 -0
  53. data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
  54. data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
  55. data/lib/cocoapods/external_sources/path_source.rb +55 -0
  56. data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
  57. data/lib/cocoapods/gem_version.rb +5 -0
  58. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  59. data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
  60. data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
  61. data/lib/cocoapods/generator/app_target_helper.rb +244 -0
  62. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  63. data/lib/cocoapods/generator/constant.rb +19 -0
  64. data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
  65. data/lib/cocoapods/generator/dummy_source.rb +31 -0
  66. data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
  67. data/lib/cocoapods/generator/header.rb +103 -0
  68. data/lib/cocoapods/generator/info_plist_file.rb +116 -0
  69. data/lib/cocoapods/generator/module_map.rb +99 -0
  70. data/lib/cocoapods/generator/prefix_header.rb +60 -0
  71. data/lib/cocoapods/generator/umbrella_header.rb +46 -0
  72. data/lib/cocoapods/hooks_manager.rb +132 -0
  73. data/lib/cocoapods/installer.rb +703 -0
  74. data/lib/cocoapods/installer/analyzer.rb +972 -0
  75. data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
  76. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
  77. data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
  78. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
  79. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  80. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
  81. data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
  82. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
  83. data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
  84. data/lib/cocoapods/installer/installation_options.rb +158 -0
  85. data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
  86. data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
  87. data/lib/cocoapods/installer/podfile_validator.rb +139 -0
  88. data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
  89. data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
  90. data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
  91. data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
  92. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
  93. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
  94. data/lib/cocoapods/installer/xcode.rb +8 -0
  95. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
  96. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
  97. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
  98. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
  99. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
  100. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
  101. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
  102. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
  103. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
  104. data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
  105. data/lib/cocoapods/open-uri.rb +33 -0
  106. data/lib/cocoapods/project.rb +414 -0
  107. data/lib/cocoapods/resolver.rb +585 -0
  108. data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
  109. data/lib/cocoapods/sandbox.rb +404 -0
  110. data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
  111. data/lib/cocoapods/sandbox/headers_store.rb +146 -0
  112. data/lib/cocoapods/sandbox/path_list.rb +220 -0
  113. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
  114. data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
  115. data/lib/cocoapods/sources_manager.rb +157 -0
  116. data/lib/cocoapods/target.rb +261 -0
  117. data/lib/cocoapods/target/aggregate_target.rb +338 -0
  118. data/lib/cocoapods/target/build_settings.rb +1075 -0
  119. data/lib/cocoapods/target/pod_target.rb +559 -0
  120. data/lib/cocoapods/user_interface.rb +459 -0
  121. data/lib/cocoapods/user_interface/error_report.rb +187 -0
  122. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  123. data/lib/cocoapods/validator.rb +981 -0
  124. metadata +533 -0
@@ -0,0 +1,444 @@
1
+ autoload :MachO, 'macho'
2
+
3
+ module Pod
4
+ class Sandbox
5
+ # Resolves the file patterns of a specification against its root directory,
6
+ # taking into account any exclude pattern and the default extensions to use
7
+ # for directories.
8
+ #
9
+ # @note The FileAccessor always returns absolute paths.
10
+ #
11
+ class FileAccessor
12
+ HEADER_EXTENSIONS = Xcodeproj::Constants::HEADER_FILES_EXTENSIONS
13
+ SOURCE_FILE_EXTENSIONS = (%w(.m .mm .i .c .cc .cxx .cpp .c++ .swift) + HEADER_EXTENSIONS).uniq.freeze
14
+
15
+ GLOB_PATTERNS = {
16
+ :readme => 'readme{*,.*}'.freeze,
17
+ :license => 'licen{c,s}e{*,.*}'.freeze,
18
+ :source_files => "*{#{SOURCE_FILE_EXTENSIONS.join(',')}}".freeze,
19
+ :public_header_files => "*{#{HEADER_EXTENSIONS.join(',')}}".freeze,
20
+ :podspecs => '*.{podspec,podspec.json}'.freeze,
21
+ :docs => 'doc{s}{*,.*}/**/*'.freeze,
22
+ }.freeze
23
+
24
+ # @return [Sandbox::PathList] the directory where the source of the Pod
25
+ # is located.
26
+ #
27
+ attr_reader :path_list
28
+
29
+ # @return [Specification::Consumer] the consumer of the specification for
30
+ # which the file patterns should be resolved.
31
+ #
32
+ attr_reader :spec_consumer
33
+
34
+ # Initialize a new instance
35
+ #
36
+ # @param [Sandbox::PathList, Pathname] path_list @see #path_list
37
+ # @param [Specification::Consumer] spec_consumer @see #spec_consumer
38
+ #
39
+ def initialize(path_list, spec_consumer)
40
+ if path_list.is_a?(PathList)
41
+ @path_list = path_list
42
+ else
43
+ @path_list = PathList.new(path_list)
44
+ end
45
+ @spec_consumer = spec_consumer
46
+
47
+ unless @spec_consumer
48
+ raise Informative, 'Attempt to initialize File Accessor without a specification consumer.'
49
+ end
50
+ end
51
+
52
+ # @return [Pathname] the directory which contains the files of the Pod.
53
+ #
54
+ def root
55
+ path_list.root if path_list
56
+ end
57
+
58
+ # @return [Specification] the specification.
59
+ #
60
+ def spec
61
+ spec_consumer.spec
62
+ end
63
+
64
+ # @return [Specification] the platform used to consume the specification.
65
+ #
66
+ def platform_name
67
+ spec_consumer.platform_name
68
+ end
69
+
70
+ # @return [String] A string suitable for debugging.
71
+ #
72
+ def inspect
73
+ "<#{self.class} spec=#{spec.name} platform=#{platform_name} root=#{root}>"
74
+ end
75
+
76
+ #-----------------------------------------------------------------------#
77
+
78
+ public
79
+
80
+ # @!group Paths
81
+
82
+ # @return [Array<Pathname>] the source files of the specification.
83
+ #
84
+ def source_files
85
+ paths_for_attribute(:source_files)
86
+ end
87
+
88
+ # @return [Array<Pathname>] the source files of the specification that
89
+ # use ARC.
90
+ #
91
+ def arc_source_files
92
+ case spec_consumer.requires_arc
93
+ when TrueClass
94
+ source_files
95
+ when FalseClass
96
+ []
97
+ else
98
+ paths_for_attribute(:requires_arc) & source_files
99
+ end
100
+ end
101
+
102
+ # @return [Array<Pathname>] the source files of the specification that
103
+ # do not use ARC.
104
+ #
105
+ def non_arc_source_files
106
+ source_files - arc_source_files
107
+ end
108
+
109
+ # @return [Array<Pathname] the source files that do not match any of the
110
+ # recognized file extensions
111
+ def other_source_files
112
+ extensions = SOURCE_FILE_EXTENSIONS
113
+ source_files.reject { |f| extensions.include?(f.extname) }
114
+ end
115
+
116
+ # @return [Array<Pathname>] the headers of the specification.
117
+ #
118
+ def headers
119
+ extensions = HEADER_EXTENSIONS
120
+ source_files.select { |f| extensions.include?(f.extname) }
121
+ end
122
+
123
+ # @param [Boolean] include_frameworks
124
+ # Whether or not to include the headers of the vendored frameworks.
125
+ # Defaults to not include them.
126
+ #
127
+ # @return [Array<Pathname>] the public headers of the specification.
128
+ #
129
+ def public_headers(include_frameworks = false)
130
+ public_headers = public_header_files
131
+ private_headers = private_header_files
132
+ if public_headers.nil? || public_headers.empty?
133
+ header_files = headers
134
+ else
135
+ header_files = public_headers
136
+ end
137
+ header_files += vendored_frameworks_headers if include_frameworks
138
+ header_files - private_headers
139
+ end
140
+
141
+ # @return [Array<Pathname>] The private headers of the specification.
142
+ #
143
+ def private_headers
144
+ private_header_files
145
+ end
146
+
147
+ # @return [Array<Pathname>] the resources of the specification.
148
+ #
149
+ def resources
150
+ paths_for_attribute(:resources, true)
151
+ end
152
+
153
+ # @return [Array<Pathname>] the files of the specification to preserve.
154
+ #
155
+ def preserve_paths
156
+ paths_for_attribute(:preserve_paths, true)
157
+ end
158
+
159
+ # @return [Array<Pathname>] The paths of the framework bundles that come
160
+ # shipped with the Pod.
161
+ #
162
+ def vendored_frameworks
163
+ paths_for_attribute(:vendored_frameworks, true)
164
+ end
165
+
166
+ # @return [Array<Pathname>] The paths of the dynamic framework bundles
167
+ # that come shipped with the Pod.
168
+ #
169
+ def vendored_dynamic_frameworks
170
+ vendored_frameworks.select do |framework|
171
+ dynamic_binary?(framework + framework.basename('.*'))
172
+ end
173
+ end
174
+
175
+ # @return [Array<Pathname>] The paths of the static (fake) framework
176
+ # bundles that come shipped with the Pod.
177
+ #
178
+ def vendored_static_frameworks
179
+ vendored_frameworks - vendored_dynamic_frameworks
180
+ end
181
+
182
+ # @param [Pathname] framework
183
+ # The vendored framework to search into.
184
+ # @return [Pathname] The path of the header directory of the
185
+ # vendored framework.
186
+ #
187
+ def self.vendored_frameworks_headers_dir(framework)
188
+ dir = framework + 'Headers'
189
+ dir.directory? ? dir.realpath : dir
190
+ end
191
+
192
+ # @param [Pathname] framework
193
+ # The vendored framework to search into.
194
+ # @return [Array<Pathname>] The paths of the headers included in the
195
+ # vendored framework.
196
+ #
197
+ def self.vendored_frameworks_headers(framework)
198
+ headers_dir = vendored_frameworks_headers_dir(framework)
199
+ Pathname.glob(headers_dir + '**/' + GLOB_PATTERNS[:public_header_files])
200
+ end
201
+
202
+ # @return [Array<Pathname>] The paths of the framework headers that come
203
+ # shipped with the Pod.
204
+ #
205
+ def vendored_frameworks_headers
206
+ vendored_frameworks.flat_map do |framework|
207
+ self.class.vendored_frameworks_headers(framework)
208
+ end.uniq
209
+ end
210
+
211
+ # @return [Array<Pathname>] The paths of the library bundles that come
212
+ # shipped with the Pod.
213
+ #
214
+ def vendored_libraries
215
+ paths_for_attribute(:vendored_libraries)
216
+ end
217
+
218
+ # @return [Array<Pathname>] The paths of the dynamic libraries
219
+ # that come shipped with the Pod.
220
+ #
221
+ def vendored_dynamic_libraries
222
+ vendored_libraries.select do |library|
223
+ dynamic_binary?(library)
224
+ end
225
+ end
226
+
227
+ # @return [Array<Pathname>] The paths of the static libraries
228
+ # that come shipped with the Pod.
229
+ #
230
+ def vendored_static_libraries
231
+ vendored_libraries - vendored_dynamic_libraries
232
+ end
233
+
234
+ # @return [Array<Pathname>] The paths of the dynamic binary artifacts
235
+ # that come shipped with the Pod.
236
+ #
237
+ def vendored_dynamic_artifacts
238
+ vendored_dynamic_libraries + vendored_dynamic_frameworks
239
+ end
240
+
241
+ # @return [Array<Pathname>] The paths of the static binary artifacts
242
+ # that come shipped with the Pod.
243
+ #
244
+ def vendored_static_artifacts
245
+ vendored_static_libraries + vendored_static_frameworks
246
+ end
247
+
248
+ # @return [Hash{String => Array<Pathname>}] A hash that describes the
249
+ # resource bundles of the Pod. The keys represent the name of
250
+ # the bundle while the values the path of the resources.
251
+ #
252
+ def resource_bundles
253
+ result = {}
254
+ spec_consumer.resource_bundles.each do |name, file_patterns|
255
+ paths = expanded_paths(file_patterns,
256
+ :exclude_patterns => spec_consumer.exclude_files,
257
+ :include_dirs => true)
258
+ result[name] = paths
259
+ end
260
+ result
261
+ end
262
+
263
+ # @return [Array<Pathname>] The paths of the files which should be
264
+ # included in resources bundles by the Pod.
265
+ #
266
+ def resource_bundle_files
267
+ resource_bundles.values.flatten
268
+ end
269
+
270
+ # @return [Pathname] The of the prefix header file of the specification.
271
+ #
272
+ def prefix_header
273
+ if file = spec_consumer.prefix_header_file
274
+ path_list.root + file
275
+ end
276
+ end
277
+
278
+ # @return [Pathname] The path of the auto-detected README file.
279
+ #
280
+ def readme
281
+ path_list.glob([GLOB_PATTERNS[:readme]]).first
282
+ end
283
+
284
+ # @return [Pathname] The path of the license file as indicated in the
285
+ # specification or auto-detected.
286
+ #
287
+ def license
288
+ spec_license || path_list.glob([GLOB_PATTERNS[:license]]).first
289
+ end
290
+
291
+ # @return [Pathname, Nil] The path of the custom module map file of the
292
+ # specification, if specified.
293
+ def module_map
294
+ if module_map = spec_consumer.module_map
295
+ path_list.root + module_map
296
+ end
297
+ end
298
+
299
+ # @return [Array<Pathname>] The paths of auto-detected podspecs
300
+ #
301
+ def specs
302
+ path_list.glob([GLOB_PATTERNS[:podspecs]])
303
+ end
304
+
305
+ # @return [Array<Pathname>] The paths of auto-detected docs
306
+ #
307
+ def docs
308
+ path_list.glob([GLOB_PATTERNS[:docs]])
309
+ end
310
+
311
+ # @return [Pathname] The path of the license file specified in the
312
+ # specification, if it exists
313
+ #
314
+ def spec_license
315
+ if file = spec_consumer.license[:file]
316
+ absolute_path = root + file
317
+ absolute_path if File.exist?(absolute_path)
318
+ end
319
+ end
320
+
321
+ # @return [Array<Pathname>] Paths to include for local pods to assist in development
322
+ #
323
+ def developer_files
324
+ podspecs = specs
325
+ result = [module_map, prefix_header]
326
+
327
+ if license_path = spec_consumer.license[:file]
328
+ license_path = root + license_path
329
+ unless File.exist?(license_path)
330
+ UI.warn "A license was specified in podspec `#{spec.name}` but the file does not exist - #{license_path}"
331
+ end
332
+ end
333
+
334
+ if podspecs.size <= 1
335
+ result += [license, readme, podspecs, docs]
336
+ else
337
+ # Manually add non-globbing files since there are multiple podspecs in the same folder
338
+ result << podspec_file
339
+ if license_file = spec_license
340
+ absolute_path = root + license_file
341
+ result << absolute_path if File.exist?(absolute_path)
342
+ end
343
+ end
344
+ result.compact.flatten.sort
345
+ end
346
+
347
+ #-----------------------------------------------------------------------#
348
+
349
+ private
350
+
351
+ # @!group Private paths
352
+
353
+ # @return [Array<Pathname>] The paths of the user-specified public header
354
+ # files.
355
+ #
356
+ def public_header_files
357
+ paths_for_attribute(:public_header_files)
358
+ end
359
+
360
+ # @return [Array<Pathname>] The paths of the user-specified public header
361
+ # files.
362
+ #
363
+ def private_header_files
364
+ paths_for_attribute(:private_header_files)
365
+ end
366
+
367
+ # @return [Pathname] The path of the podspec matching @spec
368
+ #
369
+ def podspec_file
370
+ specs.lazy.select { |p| File.basename(p.to_s, '.*') == spec.name }.first
371
+ end
372
+
373
+ #-----------------------------------------------------------------------#
374
+
375
+ private
376
+
377
+ # @!group Private helpers
378
+
379
+ # Returns the list of the paths founds in the file system for the
380
+ # attribute with given name. It takes into account any dir pattern and
381
+ # any file excluded in the specification.
382
+ #
383
+ # @param [Symbol] attribute
384
+ # the name of the attribute.
385
+ #
386
+ # @return [Array<Pathname>] the paths.
387
+ #
388
+ def paths_for_attribute(attribute, include_dirs = false)
389
+ file_patterns = spec_consumer.send(attribute)
390
+ options = {
391
+ :exclude_patterns => spec_consumer.exclude_files,
392
+ :dir_pattern => GLOB_PATTERNS[attribute],
393
+ :include_dirs => include_dirs,
394
+ }
395
+ expanded_paths(file_patterns, options)
396
+ end
397
+
398
+ # Matches the given patterns to the file present in the root of the path
399
+ # list.
400
+ #
401
+ # @param [Array<String>] patterns
402
+ # The patterns to expand.
403
+ #
404
+ # @param [Hash] options
405
+ # The options to use to expand the patterns to file paths.
406
+ #
407
+ # @option options [String] :dir_pattern
408
+ # The pattern to add to directories.
409
+ #
410
+ # @option options [Array<String>] :exclude_patterns
411
+ # The exclude patterns to pass to the PathList.
412
+ #
413
+ # @option options [Bool] :include_dirs
414
+ # Whether directories should be also included or just plain
415
+ # files.
416
+ #
417
+ # @raise [Informative] If the pod does not exists.
418
+ #
419
+ # @return [Array<Pathname>] A list of the paths.
420
+ #
421
+ def expanded_paths(patterns, options = {})
422
+ return [] if patterns.empty?
423
+ path_list.glob(patterns, options).flatten.compact.uniq
424
+ end
425
+
426
+ # @param [Pathname] binary
427
+ # The file to be checked for being a dynamic Mach-O binary.
428
+ #
429
+ # @return [Boolean] Whether `binary` can be dynamically linked.
430
+ #
431
+ def dynamic_binary?(binary)
432
+ @cached_dynamic_binary_results ||= {}
433
+ return @cached_dynamic_binary_results[binary] unless @cached_dynamic_binary_results[binary].nil?
434
+ return false unless binary.file?
435
+
436
+ @cached_dynamic_binary_results[binary] = MachO.open(binary).dylib?
437
+ rescue MachO::MachOError
438
+ @cached_dynamic_binary_results[binary] = false
439
+ end
440
+
441
+ #-----------------------------------------------------------------------#
442
+ end
443
+ end
444
+ end
@@ -0,0 +1,146 @@
1
+ module Pod
2
+ class Sandbox
3
+ # Provides support for managing a header directory. It also keeps track of
4
+ # the header search paths.
5
+ #
6
+ class HeadersStore
7
+ SEARCH_PATHS_KEY = Struct.new(:platform_name, :target_name, :use_modular_headers)
8
+
9
+ # @return [Pathname] the absolute path of this header directory.
10
+ #
11
+ def root
12
+ sandbox.headers_root + @relative_path
13
+ end
14
+
15
+ # @return [Sandbox] the sandbox where this header directory is stored.
16
+ #
17
+ attr_reader :sandbox
18
+
19
+ # @param [Sandbox] @see #sandbox
20
+ #
21
+ # @param [String] relative_path
22
+ # the relative path to the sandbox root and hence to the Pods
23
+ # project.
24
+ #
25
+ # @param [Symbol] visibility_scope
26
+ # the header visibility scope to use in this store. Can be `:private` or `:public`.
27
+ #
28
+ def initialize(sandbox, relative_path, visibility_scope)
29
+ @sandbox = sandbox
30
+ @relative_path = relative_path
31
+ @search_paths = []
32
+ @search_paths_cache = {}
33
+ @visibility_scope = visibility_scope
34
+ end
35
+
36
+ # @param [Platform] platform
37
+ # the platform for which the header search paths should be
38
+ # returned.
39
+ #
40
+ # @param [String] target_name
41
+ # the target for which the header search paths should be
42
+ # returned. Can be `nil` in which case all headers that match the platform
43
+ # will be returned.
44
+ #
45
+ # @param [Boolean] use_modular_headers
46
+ # whether the search paths generated should use modular (stricter) style.
47
+ #
48
+ # @return [Array<String>] All the search paths of the header directory in
49
+ # xcconfig format. The paths are specified relative to the pods
50
+ # root with the `${PODS_ROOT}` variable.
51
+ #
52
+ def search_paths(platform, target_name = nil, use_modular_headers = false)
53
+ key = SEARCH_PATHS_KEY.new(platform.name, target_name, use_modular_headers)
54
+ return @search_paths_cache[key] if @search_paths_cache.key?(key)
55
+ search_paths = @search_paths.select do |entry|
56
+ matches_platform = entry[:platform] == platform.name
57
+ matches_target = target_name.nil? || (File.basename(entry[:path]) == target_name)
58
+ matches_platform && matches_target
59
+ end
60
+ headers_dir = root.relative_path_from(sandbox.root).dirname
61
+ @search_paths_cache[key] = search_paths.flat_map do |entry|
62
+ paths = []
63
+ paths << "${PODS_ROOT}/#{headers_dir}/#{@relative_path}" if !use_modular_headers || @visibility_scope == :public
64
+ paths << "${PODS_ROOT}/#{headers_dir}/#{entry[:path]}" if !use_modular_headers || @visibility_scope == :private
65
+ paths
66
+ end.tap(&:uniq!).freeze
67
+ end
68
+
69
+ # Removes the directory as it is regenerated from scratch during each
70
+ # installation.
71
+ #
72
+ # @return [void]
73
+ #
74
+ def implode!
75
+ root.rmtree if root.exist?
76
+ end
77
+
78
+ #-----------------------------------------------------------------------#
79
+
80
+ public
81
+
82
+ # @!group Adding headers
83
+
84
+ # Adds headers to the directory.
85
+ #
86
+ # @param [Pathname] namespace
87
+ # the path where the header file should be stored relative to the
88
+ # headers directory.
89
+ #
90
+ # @param [Array<Pathname>] relative_header_paths
91
+ # the path of the header file relative to the Pods project
92
+ # (`PODS_ROOT` variable of the xcconfigs).
93
+ #
94
+ # @note This method does _not_ add the files to the search paths.
95
+ #
96
+ # @return [Array<Pathname>]
97
+ #
98
+ def add_files(namespace, relative_header_paths)
99
+ root.join(namespace).mkpath unless relative_header_paths.empty?
100
+ relative_header_paths.map do |relative_header_path|
101
+ add_file(namespace, relative_header_path, :mkdir => false)
102
+ end
103
+ end
104
+
105
+ # Adds a header to the directory.
106
+ #
107
+ # @param [Pathname] namespace
108
+ # the path where the header file should be stored relative to the
109
+ # headers directory.
110
+ #
111
+ # @param [Pathname] relative_header_path
112
+ # the path of the header file relative to the Pods project
113
+ # (`PODS_ROOT` variable of the xcconfigs).
114
+ #
115
+ # @note This method does _not_ add the file to the search paths.
116
+ #
117
+ # @return [Pathname]
118
+ #
119
+ def add_file(namespace, relative_header_path, mkdir: true)
120
+ namespaced_path = root + namespace
121
+ namespaced_path.mkpath if mkdir
122
+
123
+ absolute_source = (sandbox.root + relative_header_path)
124
+ source = absolute_source.relative_path_from(namespaced_path)
125
+ FileUtils.ln_sf(source, namespaced_path)
126
+ namespaced_path + relative_header_path.basename
127
+ end
128
+
129
+ # Adds an header search path to the sandbox.
130
+ #
131
+ # @param [Pathname] path
132
+ # the path to add.
133
+ #
134
+ # @param [String] platform
135
+ # the platform the search path applies to
136
+ #
137
+ # @return [void]
138
+ #
139
+ def add_search_path(path, platform)
140
+ @search_paths << { :platform => platform.name, :path => File.join(@relative_path, path) }
141
+ end
142
+
143
+ #-----------------------------------------------------------------------#
144
+ end
145
+ end
146
+ end