cocoapods 0.16.4 → 0.17.0.rc1

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +108 -0
  3. data/README.md +3 -3
  4. data/bin/pod +1 -1
  5. data/lib/cocoapods.rb +31 -31
  6. data/lib/cocoapods/command.rb +62 -107
  7. data/lib/cocoapods/command/inter_process_communication.rb +103 -0
  8. data/lib/cocoapods/command/list.rb +45 -44
  9. data/lib/cocoapods/command/outdated.rb +28 -25
  10. data/lib/cocoapods/command/project.rb +90 -0
  11. data/lib/cocoapods/command/push.rb +50 -32
  12. data/lib/cocoapods/command/repo.rb +125 -155
  13. data/lib/cocoapods/command/search.rb +23 -12
  14. data/lib/cocoapods/command/setup.rb +103 -64
  15. data/lib/cocoapods/command/spec.rb +329 -90
  16. data/lib/cocoapods/config.rb +197 -44
  17. data/lib/cocoapods/downloader.rb +47 -34
  18. data/lib/cocoapods/executable.rb +98 -41
  19. data/lib/cocoapods/external_sources.rb +325 -0
  20. data/lib/cocoapods/file_list.rb +8 -1
  21. data/lib/cocoapods/gem_version.rb +7 -0
  22. data/lib/cocoapods/generator/acknowledgements.rb +71 -7
  23. data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
  24. data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
  25. data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
  26. data/lib/cocoapods/generator/documentation.rb +153 -37
  27. data/lib/cocoapods/generator/prefix_header.rb +82 -0
  28. data/lib/cocoapods/generator/target_header.rb +58 -0
  29. data/lib/cocoapods/generator/xcconfig.rb +130 -0
  30. data/lib/cocoapods/hooks/installer_representation.rb +123 -0
  31. data/lib/cocoapods/hooks/library_representation.rb +79 -0
  32. data/lib/cocoapods/hooks/pod_representation.rb +74 -0
  33. data/lib/cocoapods/installer.rb +398 -147
  34. data/lib/cocoapods/installer/analyzer.rb +556 -0
  35. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
  36. data/lib/cocoapods/installer/file_references_installer.rb +179 -0
  37. data/lib/cocoapods/installer/pod_source_installer.rb +289 -0
  38. data/lib/cocoapods/installer/target_installer.rb +307 -112
  39. data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
  40. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
  41. data/lib/cocoapods/library.rb +195 -0
  42. data/lib/cocoapods/open_uri.rb +16 -14
  43. data/lib/cocoapods/project.rb +175 -52
  44. data/lib/cocoapods/resolver.rb +151 -164
  45. data/lib/cocoapods/sandbox.rb +276 -54
  46. data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
  47. data/lib/cocoapods/sandbox/headers_store.rb +96 -0
  48. data/lib/cocoapods/sandbox/path_list.rb +178 -0
  49. data/lib/cocoapods/sources_manager.rb +218 -0
  50. data/lib/cocoapods/user_interface.rb +82 -18
  51. data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
  52. data/lib/cocoapods/validator.rb +379 -0
  53. metadata +74 -55
  54. data/lib/cocoapods/command/install.rb +0 -55
  55. data/lib/cocoapods/command/linter.rb +0 -317
  56. data/lib/cocoapods/command/update.rb +0 -25
  57. data/lib/cocoapods/dependency.rb +0 -285
  58. data/lib/cocoapods/downloader/git.rb +0 -276
  59. data/lib/cocoapods/downloader/http.rb +0 -99
  60. data/lib/cocoapods/downloader/mercurial.rb +0 -26
  61. data/lib/cocoapods/downloader/subversion.rb +0 -42
  62. data/lib/cocoapods/local_pod.rb +0 -620
  63. data/lib/cocoapods/lockfile.rb +0 -274
  64. data/lib/cocoapods/platform.rb +0 -127
  65. data/lib/cocoapods/podfile.rb +0 -551
  66. data/lib/cocoapods/source.rb +0 -223
  67. data/lib/cocoapods/specification.rb +0 -579
  68. data/lib/cocoapods/specification/set.rb +0 -175
  69. data/lib/cocoapods/specification/statistics.rb +0 -112
  70. data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
  71. data/lib/cocoapods/version.rb +0 -26
@@ -1,99 +0,0 @@
1
- require 'open-uri'
2
- require 'tempfile'
3
- require 'zlib'
4
- require 'yaml'
5
-
6
- module Pod
7
- class Downloader
8
- class Http < Downloader
9
- class UnsupportedFileTypeError < StandardError; end
10
-
11
- executable :curl
12
- executable :unzip
13
- executable :tar
14
-
15
- attr_accessor :filename, :download_path
16
- def download
17
- @filename = filename_with_type type
18
- @download_path = target_path + @filename
19
- UI.section(' > Downloading from HTTP', '', 3) do
20
- download_file @download_path
21
- extract_with_type @download_path, type
22
- end
23
- end
24
-
25
- def type
26
- options[:type] || type_with_url(url)
27
- end
28
-
29
- def should_flatten?
30
- if options.has_key? :flatten
31
- options[:flatten] # spec file can always override
32
- elsif [:tgz, :tar, :tbz].include? type
33
- true # those archives flatten by default
34
- else
35
- false # all others (actually only .zip) default not to flatten
36
- end
37
- end
38
-
39
- private
40
- def type_with_url(url)
41
- if url =~ /.zip$/
42
- :zip
43
- elsif url =~ /.(tgz|tar\.gz)$/
44
- :tgz
45
- elsif url =~ /.tar$/
46
- :tar
47
- elsif url =~ /.(tbz|tar\.bz2)$/
48
- :tbz
49
- else
50
- nil
51
- end
52
- end
53
-
54
- def filename_with_type(type=:zip)
55
- case type
56
- when :zip
57
- "file.zip"
58
- when :tgz
59
- "file.tgz"
60
- when :tar
61
- "file.tar"
62
- when :tbz
63
- "file.tbz"
64
- else
65
- raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
66
- end
67
- end
68
-
69
- def download_file(full_filename)
70
- curl! "-L -o '#{full_filename}' '#{url}'"
71
- end
72
-
73
- def extract_with_type(full_filename, type=:zip)
74
- case type
75
- when :zip
76
- unzip! "'#{full_filename}' -d '#{target_path}'"
77
- when :tgz
78
- tar! "xfz '#{full_filename}' -C '#{target_path}'"
79
- when :tar
80
- tar! "xf '#{full_filename}' -C '#{target_path}'"
81
- when :tbz
82
- tar! "xfj '#{full_filename}' -C '#{target_path}'"
83
- else
84
- raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
85
- end
86
-
87
- if should_flatten?
88
- contents = target_path.children
89
- contents.delete(full_filename)
90
- entry = contents.first
91
- if contents.count == 1 && entry.directory?
92
- FileUtils.move(entry.children, target_path)
93
- end
94
- end
95
- end
96
-
97
- end
98
- end
99
- end
@@ -1,26 +0,0 @@
1
- module Pod
2
- class Downloader
3
- class Mercurial < Downloader
4
- executable :hg
5
-
6
- def download
7
- UI.section(' > Cloning mercurial repo', '', 3) do
8
- if options[:revision]
9
- download_revision
10
- else
11
- download_head
12
- end
13
- end
14
- end
15
-
16
- def download_head
17
- hg! "clone \"#{url}\" \"#{target_path}\""
18
- end
19
-
20
- def download_revision
21
- hg! "clone \"#{url}\" --rev '#{options[:revision]}' \"#{target_path}\""
22
- end
23
- end
24
- end
25
- end
26
-
@@ -1,42 +0,0 @@
1
- module Pod
2
- class Downloader
3
- class Subversion < Downloader
4
- executable :svn
5
-
6
- def initialize(target_path, url, options)
7
- @target_path, @url, @options = target_path, url, options
8
- end
9
-
10
- def download
11
- UI.section(' > Exporting subversion repo', '', 3) do
12
- svn! %|#{export_subcommand} "#{reference_url}" "#{target_path}"|
13
- end
14
- end
15
-
16
- def download_head
17
- UI.section(' > Exporting subversion repo', '', 3) do
18
- svn! %|#{export_subcommand} "#{trunk_url}" "#{target_path}"|
19
- end
20
- end
21
-
22
- def export_subcommand
23
- result = 'export --non-interactive --trust-server-cert'
24
- end
25
-
26
- def reference_url
27
- result = url.dup
28
- result << '/' << options[:folder] if options[:folder]
29
- result << '/tags/' << options[:tag] if options[:tag]
30
- result << '" -r "' << options[:revision] if options[:revision]
31
- result
32
- end
33
-
34
- def trunk_url
35
- result = url.dup
36
- result << '/' << options[:folder] if options[:folder]
37
- result << '/trunk'
38
- result
39
- end
40
- end
41
- end
42
- end
@@ -1,620 +0,0 @@
1
- module Pod
2
-
3
- # A {LocalPod} interfaces one or more specifications belonging to one pod
4
- # (a library) and their concrete instance in the file system.
5
- #
6
- # The {LocalPod} is responsible for orchestrating the activated
7
- # specifications of a single pod. Specifically, it keeps track of the
8
- # activated specifications and handles issues related to duplicates
9
- # files.
10
- # Inheritance logic belongs to the {Specification} class.
11
- #
12
- # The activated specifications are used to compute the paths that can be
13
- # safely cleaned by the pod.
14
- #
15
- # @example
16
- # pod = LocalPod.new 'RestKit/Networking'
17
- # pod.add_specification 'RestKit/UI'
18
- #
19
- # @note
20
- # Unless otherwise specified in the name of the method the {LocalPod}
21
- # returns absolute paths.
22
- #
23
- class LocalPod
24
-
25
- # @return [Specification] The specification that describes the pod.
26
- #
27
- attr_reader :top_specification
28
-
29
- # @return [Specification] The activated specifications of the pod.
30
- #
31
- attr_reader :specifications
32
-
33
- # @return [Sandbox] The sandbox where the pod is installed.
34
- #
35
- attr_reader :sandbox
36
-
37
- # @return [Platform] The platform that will be used to build the pod.
38
- #
39
- attr_reader :platform
40
-
41
- # @return [Boolean] Wether or not the pod has been downloaded in the
42
- # current install process and still needs its docs
43
- # generated and be cleaned.
44
- #
45
- attr_accessor :downloaded
46
- alias_method :downloaded?, :downloaded
47
-
48
- # @param [Specification] specification The first activated specification
49
- # of the pod.
50
- #
51
- # @param [Sandbox] sandbox The sandbox where the files of the
52
- # pod will be located.
53
- #
54
- # @param [Platform] platform The platform that will be used to
55
- # build the pod.
56
- #
57
- # @todo The local pod should be initialized with all the activated
58
- # specifications passed as an array, in order to be able to cache the
59
- # computed values. In other words, it should be immutable.
60
- #
61
- def initialize(specification, sandbox, platform)
62
- @top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform
63
- @top_specification.activate_platform(platform)
64
- @specifications = [] << specification
65
- end
66
-
67
- # Initializes a local pod from the top specification of a podspec file.
68
- #
69
- # @return [LocalPod] A new local pod.
70
- #
71
- def self.from_podspec(podspec, sandbox, platform)
72
- new(Specification.from_file(podspec), sandbox, platform)
73
- end
74
-
75
- # Activates a specification or subspecs for the pod.
76
- # Adding specifications is idempotent.
77
- #
78
- # @param {Specification} spec The specification to add to the pod.
79
- #
80
- # @raise {Informative} If the specification is not part of the same pod.
81
- #
82
- def add_specification(spec)
83
- unless spec.top_level_parent == top_specification
84
- raise Informative,
85
- "[Local Pod] Attempt to add a specification from another pod"
86
- end
87
- spec.activate_platform(platform)
88
- @specifications << spec unless @specifications.include?(spec)
89
- end
90
-
91
- # @return [Pathname] The root directory of the pod
92
- #
93
- def root
94
- @sandbox.root + top_specification.name
95
- end
96
-
97
- # @return [String] A string representation of the pod which indicates if
98
- # the pods comes from a local source or has a preferred
99
- # dependency.
100
- #
101
- def to_s
102
- s = top_specification.to_s
103
- s << " defaulting to #{top_specification.preferred_dependency} subspec" if top_specification.preferred_dependency
104
- s
105
- end
106
-
107
- # @return [String] The name of the Pod.
108
- #
109
- def name
110
- top_specification.name
111
- end
112
-
113
- # @!group Installation
114
-
115
- # Creates the root path of the pod.
116
- #
117
- # @return [void]
118
- #
119
- def create
120
- root.mkpath unless exists?
121
- end
122
-
123
- # Whether the root path of the pod exists.
124
- #
125
- def exists?
126
- root.exist?
127
- end
128
-
129
- # Executes a block in the root directory of the Pod.
130
- #
131
- # @return [void]
132
- #
133
- def chdir(&block)
134
- create
135
- Dir.chdir(root, &block)
136
- end
137
-
138
- # Deletes the pod from the file system.
139
- #
140
- # @return [void]
141
- #
142
- def implode
143
- root.rmtree if exists?
144
- end
145
-
146
- def local?
147
- false
148
- end
149
-
150
- # @!group Cleaning
151
-
152
- # Deletes any path that is not used by the pod.
153
- #
154
- # @return [void]
155
- #
156
- def clean!
157
- clean_paths.each { |path| FileUtils.rm_rf(path) }
158
- @cleaned = true
159
- end
160
-
161
- # Finds the absolute paths, including hidden ones, of the files
162
- # that are not used by the pod and thus can be safely deleted.
163
- #
164
- # @return [Array<Strings>] The paths that can be deleted.
165
- #
166
- # @note Implementation detail: Don't use Dir#glob as there is an
167
- # unexplained issue (#568, #572 and #602).
168
- #
169
- def clean_paths
170
- cached_used = used_files
171
- files = Pathname.glob(root + "**/*", File::FNM_DOTMATCH | File::FNM_CASEFOLD).map(&:to_s)
172
-
173
- files.reject! do |candidate|
174
- candidate.end_with?('.', '..') || cached_used.any? do |path|
175
- path.include?(candidate) || candidate.include?(path)
176
- end
177
- end
178
- files
179
- end
180
-
181
- # @return [Array<String>] The absolute path of the files used by the pod.
182
- #
183
- def used_files
184
- files = [ source_files, resource_files, preserve_files, readme_file, license_file, prefix_header_file ]
185
- files.compact!
186
- files.flatten!
187
- files.map!{ |path| path.to_s }
188
- files
189
- end
190
-
191
- # @!group Files
192
-
193
- # @return [Pathname] Returns the relative path from the sandbox.
194
- #
195
- # @note If the two abosule paths don't share the same root directory an
196
- # extra `../` is added to the result of {Pathname#relative_path_from}
197
- #
198
- # path = Pathname.new('/Users/dir')
199
- # @sandbox
200
- # #=> Pathname('/tmp/CocoaPods/Lint/Pods')
201
- #
202
- # p.relative_path_from(@sandbox
203
- # #=> '../../../../Users/dir'
204
- #
205
- # relativize_from_sandbox(path)
206
- # #=> '../../../../../Users/dir'
207
- #
208
- def relativize_from_sandbox(path)
209
- result = path.relative_path_from(@sandbox.root)
210
- result = Pathname.new('../') + result unless @sandbox.root.to_s.split('/')[1] == path.to_s.split('/')[1]
211
- result
212
- end
213
-
214
- # @return [Array<Pathname>] The paths of the source files.
215
- #
216
- def source_files
217
- source_files_by_spec.values.flatten
218
- end
219
-
220
- # @return [Array<Pathname>] The *relative* paths of the source files.
221
- #
222
- def relative_source_files
223
- source_files.map{ |p| relativize_from_sandbox(p) }
224
- end
225
-
226
- def relative_source_files_by_spec
227
- result = {}
228
- source_files_by_spec.each do |spec, paths|
229
- result[spec] = paths.map{ |p| relativize_from_sandbox(p) }
230
- end
231
- result
232
- end
233
-
234
-
235
- # Finds the source files that every activated {Specification} requires.
236
- #
237
- # @note If the same file is required by two specifications the one at the
238
- # higher level in the inheritance chain wins.
239
- #
240
- # @return [Hash{Specification => Array<Pathname>}] The files grouped by
241
- # {Specification}.
242
- #
243
- def source_files_by_spec
244
- options = {:glob => '*.{h,hpp,hh,m,mm,c,cpp}'}
245
- paths_by_spec(:source_files, options)
246
- end
247
-
248
- # @return [Array<Pathname>] The paths of the header files.
249
- #
250
- def header_files
251
- header_files_by_spec.values.flatten
252
- end
253
-
254
- # @return [Array<Pathname>] The *relative* paths of the source files.
255
- #
256
- def relative_header_files
257
- header_files.map{ |p| relativize_from_sandbox(p) }
258
- end
259
-
260
- # @return [Hash{Specification => Array<Pathname>}] The paths of the header
261
- # files grouped by {Specification}.
262
- #
263
- def header_files_by_spec
264
- result = {}
265
- source_files_by_spec.each do |spec, paths|
266
- headers = paths.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
267
- result[spec] = headers unless headers.empty?
268
- end
269
- result
270
- end
271
-
272
- # @return [Hash{Specification => Array<Pathname>}] The paths of the header
273
- # files grouped by {Specification} that should be copied in the public
274
- # folder.
275
- #
276
- # If a spec does not match any public header it means that all the
277
- # header files (i.e. the build ones) are intended to be public.
278
- #
279
- def public_header_files_by_spec
280
- public_headers = paths_by_spec(:public_header_files, :glob => '*.{h,hpp,hh}')
281
- build_headers = header_files_by_spec
282
-
283
- result = {}
284
- specifications.each do |spec|
285
- if (public_h = public_headers[spec]) && !public_h.empty?
286
- result[spec] = public_h
287
- elsif (build_h = build_headers[spec]) && !build_h.empty?
288
- result[spec] = build_h
289
- end
290
- end
291
- result
292
- end
293
-
294
- # @return [Array<Pathname>] The paths of the resources.
295
- #
296
- def resource_files
297
- paths_by_spec(:resources).values.flatten
298
- end
299
-
300
- # @return [Array<Pathname>] The *relative* paths of the resources.
301
- #
302
- def relative_resource_files
303
- resource_files.map{ |p| relativize_from_sandbox(p) }
304
- end
305
-
306
- # @return [Pathname] The absolute path of the prefix header file
307
- #
308
- def prefix_header_file
309
- root + top_specification.prefix_header_file if top_specification.prefix_header_file
310
- end
311
-
312
- # @return [Array<Pathname>] The absolute paths of the files of the pod
313
- # that should be preserved.
314
- #
315
- def preserve_files
316
- paths = paths_by_spec(:preserve_paths).values
317
- paths += expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
318
- paths.compact!
319
- paths.uniq!
320
- paths
321
- end
322
-
323
- # @return [Pathname] The automatically detected absolute path of the README
324
- # file.
325
- #
326
- def readme_file
327
- expanded_paths(%w[ readme{*,.*} ]).first
328
- end
329
-
330
- # @return [Pathname] The absolute path of the license file from the
331
- # specification or automatically detected.
332
- #
333
- def license_file
334
- if top_specification.license && top_specification.license[:file]
335
- root + top_specification.license[:file]
336
- else
337
- expanded_paths(%w[ licen{c,s}e{*,.*} ]).first
338
- end
339
- end
340
-
341
- # @return [String] The text of the license of the pod from the
342
- # specification or from the license file.
343
- #
344
- def license_text
345
- if (license_hash = top_specification.license)
346
- if (result = license_hash[:text])
347
- result
348
- elsif license_file
349
- result = IO.read(license_file)
350
- end
351
- end
352
- end
353
-
354
- def xcconfig
355
- specifications.map { |s| s.xcconfig }.reduce(:merge)
356
- end
357
-
358
- # Computes the paths of all the public headers of the pod including every
359
- # subspec (activated or not).
360
- # For this reason the pod must not be cleaned when calling this command.
361
- #
362
- # This method is used by {Generator::Documentation}.
363
- #
364
- # @raise [Informative] If the pod was cleaned.
365
- #
366
- # @return [Array<Pathname>] The path of all the public headers of the pod.
367
- #
368
- def documentation_headers
369
- if @cleaned
370
- raise Informative, "The pod is cleaned and cannot compute the " \
371
- "header files, as some might have been deleted."
372
- end
373
-
374
- specs = [top_specification] + top_specification.recursive_subspecs
375
- source_files = paths_by_spec(:source_files, { :glob => '*.{h}'}, specs)
376
- public_headers = paths_by_spec(:public_header_files,{ :glob => '*.{h}'}, specs)
377
-
378
- result = []
379
- specs.each do |spec|
380
- if (public_h = public_headers[spec]) && !public_h.empty?
381
- result += public_h
382
- elsif (source_f = source_files[spec]) && !source_f.empty?
383
- build_h = source_f.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
384
- result += build_h unless build_h.empty?
385
- end
386
- end
387
- result
388
- end
389
-
390
- # @!group Xcodeproj integration
391
-
392
- # Adds the file references, to the given `Pods.xcodeproj` project, for the
393
- # source files of the pod. The file references are grouped by specification
394
- # and stored in {#file_references_by_spec}.
395
- #
396
- # @note If the pod is locally sourced the file references are stored in the
397
- # `Local Pods` group otherwise they are stored in the `Pods` group.
398
- #
399
- # @return [void]
400
- #
401
- def add_file_references_to_project(project)
402
- @file_references_by_spec = {}
403
- parent_group = local? ? project.local_pods : project.pods
404
-
405
- relative_source_files_by_spec.each do |spec, paths|
406
- group = project.add_spec_group(spec.name, parent_group)
407
- file_references = []
408
- paths.each do |path|
409
- file_references << group.new_file(path)
410
- end
411
- @file_references_by_spec[spec] = file_references
412
- end
413
- end
414
-
415
- # @return [Hash{Specification => Array<PBXFileReference>}] The file
416
- # references of the pod in the `Pods.xcodeproj` project.
417
- #
418
- attr_reader :file_references_by_spec
419
-
420
- # Adds a build file for each file reference to a given target taking into
421
- # account the compiler flags of the corresponding specification.
422
- #
423
- # @raise If the {#add_file_references_to_project} was not called before of
424
- # calling this method.
425
- #
426
- # @return [void]
427
- #
428
- def add_build_files_to_target(target)
429
- unless file_references_by_spec
430
- raise Informative, "Local Pod needs to add the file references to the " \
431
- "project before adding the build files to the target."
432
- end
433
- file_references_by_spec.each do |spec, file_reference|
434
- target.add_file_references(file_reference, spec.compiler_flags.strip)
435
- end
436
- end
437
-
438
- # @return [void] Copies the pods headers to the sandbox.
439
- #
440
- def link_headers
441
- @sandbox.build_headers.add_search_path(headers_sandbox)
442
- @sandbox.public_headers.add_search_path(headers_sandbox)
443
-
444
- header_mappings(header_files_by_spec).each do |namespaced_path, files|
445
- @sandbox.build_headers.add_files(namespaced_path, files)
446
- end
447
-
448
- header_mappings(public_header_files_by_spec).each do |namespaced_path, files|
449
- @sandbox.public_headers.add_files(namespaced_path, files)
450
- end
451
- end
452
-
453
- # @return Whether the pod requires ARC.
454
- #
455
- # TODO: this should be not used anymore.
456
- #
457
- def requires_arc?
458
- top_specification.requires_arc
459
- end
460
-
461
- private
462
-
463
- # @return [Array<Pathname>] The implementation files
464
- # (the files the need to compiled) of the pod.
465
- #
466
- def implementation_files
467
- relative_source_files.reject { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
468
- end
469
-
470
- # @return [Pathname] The path of the pod relative from the sandbox.
471
- #
472
- def relative_root
473
- root.relative_path_from(@sandbox.root)
474
- end
475
-
476
- # @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers
477
- # folders as the keys and the the absolute paths of the header files
478
- # as the values.
479
- #
480
- # @todo this is being overridden in the RestKit 0.9.4 spec, need to do
481
- # something with that, and this method also still exists in Specification.
482
- #
483
- # @todo This is not overridden anymore in specification refactor and the
484
- # code Pod::Specification#copy_header_mapping can be moved here.
485
- def header_mappings(files_by_spec)
486
- mappings = {}
487
- files_by_spec.each do |spec, paths|
488
- paths = paths - headers_excluded_from_search_paths
489
- dir = spec.header_dir ? (headers_sandbox + spec.header_dir) : headers_sandbox
490
- paths.each do |from|
491
- from_relative = from.relative_path_from(root)
492
- to = dir + spec.copy_header_mapping(from_relative)
493
- (mappings[to.dirname] ||= []) << from
494
- end
495
- end
496
- mappings
497
- end
498
-
499
- # @return <Pathname> The name of the folder where the headers of this pod
500
- # will be namespaced.
501
- #
502
- def headers_sandbox
503
- @headers_sandbox ||= Pathname.new(top_specification.name)
504
- end
505
-
506
- # @return [<Pathname>] The relative path of the headers that should not be
507
- # included in the linker search paths.
508
- #
509
- def headers_excluded_from_search_paths
510
- options = { :glob => '*.{h,hpp,hh}' }
511
- paths = paths_by_spec(:exclude_header_search_paths, options)
512
- paths.values.compact.uniq
513
- end
514
-
515
- # @!group Paths Patterns
516
-
517
- # The paths obtained by resolving the patterns of an attribute
518
- # groupped by spec.
519
- #
520
- # @param [Symbol] accessor The accessor to use to obtain the paths patterns.
521
- # @param [Hash] options (see #expanded_paths)
522
- #
523
- def paths_by_spec(accessor, options = {}, specs = nil)
524
- specs ||= specifications
525
- paths_by_spec = {}
526
- processed_paths = []
527
-
528
- specs = specs.sort_by { |s| s.name.length }
529
- specs.each do |spec|
530
- paths = expanded_paths(spec.send(accessor), options)
531
- unless paths.empty?
532
- paths_by_spec[spec] = paths - processed_paths
533
- processed_paths += paths
534
- end
535
- end
536
- paths_by_spec
537
- end
538
-
539
- # Converts patterns of paths to the {Pathname} of the files present in the
540
- # pod.
541
- #
542
- # @param [String, FileList, Array<String, Pathname>] patterns
543
- # The patterns to expand.
544
- # @param [Hash] options
545
- # The options to used for expanding the paths patterns.
546
- # @option options [String] :glob
547
- # The pattern to use for globing directories.
548
- #
549
- # @raise [Informative] If the pod does not exists.
550
- #
551
- # @todo implement case insensitive search
552
- #
553
- # @return [Array<Pathname>] A list of the paths.
554
- #
555
- def expanded_paths(patterns, options = {})
556
- unless exists?
557
- raise Informative, "[Local Pod] Attempt to resolve paths for nonexistent pod.\n" \
558
- "\tSpecifications: #{@specifications.inspect}\n" \
559
- "\t Patterns: #{patterns.inspect}\n" \
560
- "\t Options: #{options.inspect}"
561
- end
562
-
563
- return [] if patterns.empty?
564
- patterns = [ patterns ] if patterns.is_a?(String)
565
- file_lists = patterns.select { |p| p.is_a?(FileList) }
566
- glob_patterns = patterns - file_lists
567
-
568
- result = []
569
-
570
- result << file_lists.map do |file_list|
571
- file_list.prepend_patterns(root)
572
- file_list.glob
573
- end
574
-
575
- result << glob_patterns.map do |pattern|
576
- pattern = root + pattern
577
- if pattern.directory? && options[:glob]
578
- pattern += options[:glob]
579
- end
580
- Pathname.glob(pattern, File::FNM_CASEFOLD)
581
- end.flatten
582
-
583
- result.flatten.compact.uniq
584
- end
585
-
586
- # A {LocalSourcedPod} is a {LocalPod} that interacts with the files of
587
- # a folder controlled by the users. As such this class does not alter
588
- # in any way the contents of the folder.
589
- #
590
- class LocalSourcedPod < LocalPod
591
- def downloaded?
592
- true
593
- end
594
-
595
- def create
596
- # No ops
597
- end
598
-
599
- def root
600
- @root ||= Pathname.new(@top_specification.source[:local]).expand_path
601
- end
602
-
603
- def implode
604
- # No ops
605
- end
606
-
607
- def clean!
608
- # No ops
609
- end
610
-
611
- def to_s
612
- super + " [LOCAL]"
613
- end
614
-
615
- def local?
616
- true
617
- end
618
- end
619
- end
620
- end