xcocoapods 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
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