Class: Pod::Sandbox

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods/sandbox.rb,
lib/cocoapods/sandbox/path_list.rb,
lib/cocoapods/sandbox/file_accessor.rb,
lib/cocoapods/sandbox/headers_store.rb,
lib/cocoapods/sandbox/podspec_finder.rb,
lib/cocoapods/sandbox/pod_dir_cleaner.rb

Overview

The sandbox provides support for the directory that CocoaPods uses for an installation. In this directory the Pods projects, the support files and the sources of the Pods are stored.

CocoaPods assumes to have control of the sandbox.

Once completed the sandbox will have the following file structure:

Pods
|
+-- Headers
|   +-- Private
|   |   +-- [Pod Name]
|   +-- Public
|       +-- [Pod Name]
|
+-- Local Podspecs
|   +-- External Sources
|   +-- Normal Sources
|
+-- Target Support Files
|   +-- [Target Name]
|       +-- Pods-acknowledgements.markdown
|       +-- Pods-acknowledgements.plist
|       +-- Pods-dummy.m
|       +-- Pods-prefix.pch
|       +-- Pods.xcconfig
|
+-- [Pod Name]
|
+-- Manifest.lock
|
+-- Pods.xcodeproj  (if installation option 'generate_multiple_pod_projects' is enabled)
|
+-- PodTarget1.xcodeproj
|    ...
|
+-- PodTargetN.xcodeproj

Defined Under Namespace

Classes: FileAccessor, HeadersStore, PathList, PodDirCleaner, PodspecFinder

Pods information collapse

Instance Attribute Summary collapse

Paths collapse

Specification store collapse

Pods information collapse

Convenience Methods collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ Sandbox

Initialize a new instance

Parameters:

  • root (String, Pathname)

    @see #root



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cocoapods/sandbox.rb', line 65

def initialize(root)
  FileUtils.mkdir_p(root)
  @root = Pathname.new(root).realpath
  @public_headers = HeadersStore.new(self, 'Public', :public)
  @predownloaded_pods = []
  @downloaded_pods = []
  @checkout_sources = {}
  @development_pods = {}
  @pods_with_absolute_path = []
  @stored_podspecs = {}
end

Instance Attribute Details

#checkout_sourcesHash{String=>Hash} (readonly)

Returns The options necessary to recreate the exact checkout of a given Pod grouped by its name.

Returns:

  • (Hash{String=>Hash})

    The options necessary to recreate the exact checkout of a given Pod grouped by its name.



433
434
435
# File 'lib/cocoapods/sandbox.rb', line 433

def checkout_sources
  @checkout_sources
end

#development_podsHash{String=>Pathname} (readonly)

Returns The path of the Pods’ podspecs with a local source grouped by their root name.

Returns:

  • (Hash{String=>Pathname})

    The path of the Pods’ podspecs with a local source grouped by their root name.



460
461
462
# File 'lib/cocoapods/sandbox.rb', line 460

def development_pods
  @development_pods
end

#downloaded_podsArray<String> (readonly)

Returns The names of the pods that have been downloaded before the installation process begins. These are distinct from the pre-downloaded pods in that these do not necessarily come from external sources, and are only downloaded right before installation if the parallel_pod_downloads option is on.

Returns:

  • (Array<String>)

    The names of the pods that have been downloaded before the installation process begins. These are distinct from the pre-downloaded pods in that these do not necessarily come from external sources, and are only downloaded right before installation if the parallel_pod_downloads option is on.



386
387
388
# File 'lib/cocoapods/sandbox.rb', line 386

def downloaded_pods
  @downloaded_pods
end

#predownloaded_podsArray<String> (readonly)

Returns The names of the pods that have been pre-downloaded from an external source.

Returns:

  • (Array<String>)

    The names of the pods that have been pre-downloaded from an external source.



337
338
339
# File 'lib/cocoapods/sandbox.rb', line 337

def predownloaded_pods
  @predownloaded_pods
end

#public_headersHeadersStore (readonly)

Returns the header directory for the user targets.

Returns:

  • (HeadersStore)

    the header directory for the user targets.



59
60
61
# File 'lib/cocoapods/sandbox.rb', line 59

def public_headers
  @public_headers
end

#rootPathname (readonly)

Returns the root of the sandbox.

Returns:

  • (Pathname)

    the root of the sandbox.



55
56
57
# File 'lib/cocoapods/sandbox.rb', line 55

def root
  @root
end

Class Method Details

.update_changed_file(path, contents) ⇒ void

This method returns an undefined value.

Writes a file if it does not exist or if its contents have changed.

Parameters:

  • path (Pathname)

    The path to read from and write to.

  • contents (String)

    The contents to write if they do not match or the file does not exist.



495
496
497
498
499
500
501
502
# File 'lib/cocoapods/sandbox.rb', line 495

def self.update_changed_file(path, contents)
  if path.exist?
    content_stream = StringIO.new(contents)
    identical = File.open(path, 'rb') { |f| FileUtils.compare_stream(f, content_stream) }
    return if identical
  end
  File.open(path, 'w') { |f| f.write(contents) }
end

Instance Method Details

#clean_pod(name, pod_dir) ⇒ void

This method returns an undefined value.

Removes the files of the Pod with the given name from the sandbox.

Parameters:

  • name (String)

    The name of the pod, which is used to calculate additional paths to clean.

  • pod_dir (String)

    The directory of the pod to clean.



93
94
95
96
97
98
99
# File 'lib/cocoapods/sandbox.rb', line 93

def clean_pod(name, pod_dir)
  pod_dir.rmtree if pod_dir&.exist?
  podspec_path = specification_path(name)
  podspec_path.rmtree if podspec_path&.exist?
  pod_target_project_path = pod_target_project_path(name)
  pod_target_project_path.rmtree if pod_target_project_path&.exist?
end

#downloaded?(name) ⇒ Boolean

Checks if a Pod has been downloaded before the installation process.

Parameters:

  • name (String)

    The name of the Pod.

Returns:

  • (Boolean)

    Whether the Pod has been downloaded.



374
375
376
377
# File 'lib/cocoapods/sandbox.rb', line 374

def downloaded?(name)
  root_name = Specification.root_name(name)
  downloaded_pods.include?(root_name)
end

#headers_rootPathname

Returns The directory where headers are stored.

Returns:

  • (Pathname)

    The directory where headers are stored.



203
204
205
# File 'lib/cocoapods/sandbox.rb', line 203

def headers_root
  root + 'Headers'
end

#inspectString

Returns a string representation suitable for debugging.

Returns:

  • (String)

    a string representation suitable for debugging.



113
114
115
# File 'lib/cocoapods/sandbox.rb', line 113

def inspect
  "#<#{self.class}> with root #{root}"
end

#local?(name) ⇒ Boolean

Checks if a Pod is locally sourced?

Parameters:

  • name (String)

    The name of the Pod.

Returns:

  • (Boolean)

    Whether the Pod is locally sourced.



469
470
471
# File 'lib/cocoapods/sandbox.rb', line 469

def local?(name)
  !local_podspec(name).nil?
end

#local_path_was_absolute?(name) ⇒ Boolean

Returns true if the path as originally specified was absolute.

Parameters:

  • name (String)

Returns:

  • (Boolean)

    true if originally absolute



197
198
199
# File 'lib/cocoapods/sandbox.rb', line 197

def local_path_was_absolute?(name)
  @pods_with_absolute_path.include? name
end

#local_podspec(name) ⇒ Pathname

Returns Path to the local Podspec of the Pod.

Parameters:

  • name (String)

    The name of a locally specified Pod

Returns:

  • (Pathname)

    Path to the local Podspec of the Pod



478
479
480
481
# File 'lib/cocoapods/sandbox.rb', line 478

def local_podspec(name)
  root_name = Specification.root_name(name)
  development_pods[root_name]
end

#manifestLockfile

Returns the manifest which contains the information about the installed pods or nil if one is not present.

Returns:

  • (Lockfile)

    the manifest which contains the information about the installed pods or nil if one is not present.



80
81
82
83
84
# File 'lib/cocoapods/sandbox.rb', line 80

def manifest
  @manifest ||= begin
    Lockfile.from_file(manifest_path) if manifest_path.exist?
  end
end

#manifest_pathPathname

Returns the path of the manifest.

Returns:

  • (Pathname)

    the path of the manifest.



125
126
127
# File 'lib/cocoapods/sandbox.rb', line 125

def manifest_path
  root + 'Manifest.lock'
end

#pod_dir(name) ⇒ Pathname

Returns the path where the Pod with the given name is stored, taking into account whether the Pod is locally sourced.

Parameters:

  • name (String)

    The name of the Pod.

Returns:

  • (Pathname)

    the path of the Pod.



182
183
184
185
186
187
188
189
# File 'lib/cocoapods/sandbox.rb', line 182

def pod_dir(name)
  root_name = Specification.root_name(name)
  if local?(root_name)
    Pathname.new(development_pods[root_name].dirname)
  else
    sources_root + root_name
  end
end

#pod_target_project_path(pod_target_name) ⇒ Pathname

Name of the pod target used to generate the path of its Xcode project.

Parameters:

  • pod_target_name (String)

Returns:

  • (Pathname)

    the path of the project for a pod target.



158
159
160
# File 'lib/cocoapods/sandbox.rb', line 158

def pod_target_project_path(pod_target_name)
  root + "#{pod_target_name}.xcodeproj"
end

#predownloaded?(name) ⇒ Boolean

Checks if a Pod has been pre-downloaded by the resolver in order to fetch the podspec.

Parameters:

  • name (String)

    The name of the Pod.

Returns:

  • (Boolean)

    Whether the Pod has been pre-downloaded.



347
348
349
350
# File 'lib/cocoapods/sandbox.rb', line 347

def predownloaded?(name)
  root_name = Specification.root_name(name)
  predownloaded_pods.include?(root_name)
end

#prepareObject

Prepares the sandbox for a new installation removing any file that will be regenerated and ensuring that the directories exists.



104
105
106
107
108
109
# File 'lib/cocoapods/sandbox.rb', line 104

def prepare
  FileUtils.mkdir_p(headers_root)
  FileUtils.mkdir_p(sources_root)
  FileUtils.mkdir_p(specifications_root)
  FileUtils.mkdir_p(target_support_files_root)
end

#project_installation_cache_pathPathname

Returns the path of the installation cache.

Returns:

  • (Pathname)

    the path of the installation cache.



137
138
139
# File 'lib/cocoapods/sandbox.rb', line 137

def project_installation_cache_path
  root.join('.project_cache', 'installation_cache.yaml')
end

#project_metadata_cache_pathPathname

Returns the path of the metadata cache.

Returns:

  • (Pathname)

    the path of the metadata cache.



143
144
145
# File 'lib/cocoapods/sandbox.rb', line 143

def 
  root.join('.project_cache', 'metadata_cache.yaml')
end

#project_pathPathname

Returns the path of the Pods project.

Returns:

  • (Pathname)

    the path of the Pods project.



131
132
133
# File 'lib/cocoapods/sandbox.rb', line 131

def project_path
  root + 'Pods.xcodeproj'
end

#project_version_cache_pathPathname

Returns the path of the version cache.

Returns:

  • (Pathname)

    the path of the version cache.



149
150
151
# File 'lib/cocoapods/sandbox.rb', line 149

def project_version_cache_path
  root.join('.project_cache', 'version')
end

#remove_checkout_source(name) ⇒ void

This method returns an undefined value.

Removes the checkout source of a Pod.

Parameters:

  • name (String)

    The name of the Pod.



413
414
415
416
# File 'lib/cocoapods/sandbox.rb', line 413

def remove_checkout_source(name)
  root_name = Specification.root_name(name)
  checkout_sources.delete(root_name)
end

#remove_local_podspec(name) ⇒ void

This method returns an undefined value.

Removes local podspec a Pod.

Parameters:

  • name (String)

    The name of the Pod.



425
426
427
428
# File 'lib/cocoapods/sandbox.rb', line 425

def remove_local_podspec(name)
  local_podspec = specification_path(name)
  FileUtils.rm(local_podspec) if local_podspec
end

#sources_rootPathname

Returns The directory where the downloaded sources of the Pods are stored.

Returns:

  • (Pathname)

    The directory where the downloaded sources of the Pods are stored.



210
211
212
# File 'lib/cocoapods/sandbox.rb', line 210

def sources_root
  root
end

#specification(name) ⇒ Specification

Returns the specification for the Pod with the given name.

Parameters:

  • name (String)

    the name of the Pod for which the specification is requested.

Returns:



241
242
243
244
245
246
# File 'lib/cocoapods/sandbox.rb', line 241

def specification(name)
  @stored_podspecs[name] ||= if file = specification_path(name)
                               original_path = development_pods[name]
                               Specification.from_file(original_path || file)
  end
end

#specification_path(name) ⇒ Pathname, Nil

Returns the path of the specification for the Pod with the given name, if one is stored.

Parameters:

  • name (String)

    the name of the Pod for which the podspec file is requested.

Returns:

  • (Pathname)

    the path or nil.

  • (Nil)

    if the podspec is not stored.



257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/cocoapods/sandbox.rb', line 257

def specification_path(name)
  name = Specification.root_name(name)
  path = specifications_root + "#{name}.podspec"
  if path.exist?
    path
  else
    path = specifications_root + "#{name}.podspec.json"
    if path.exist?
      path
    end
  end
end

#specifications_rootPathname

Returns the path for the directory where the specifications are stored.

Returns:

  • (Pathname)

    the path for the directory where the specifications are stored.



217
218
219
# File 'lib/cocoapods/sandbox.rb', line 217

def specifications_root
  root + 'Local Podspecs'
end

#store_checkout_source(name, source) ⇒ void

This method returns an undefined value.

Stores the local path of a Pod.

Parameters:

  • name (String)

    The name of the Pod.

  • source (Hash)

    The hash which contains the options as returned by the downloader.



401
402
403
404
# File 'lib/cocoapods/sandbox.rb', line 401

def store_checkout_source(name, source)
  root_name = Specification.root_name(name)
  checkout_sources[root_name] = source
end

#store_downloaded_pod(name) ⇒ void

This method returns an undefined value.

Marks a Pod as downloaded

Parameters:

  • name (String)

    The name of the Pod.



361
362
363
364
# File 'lib/cocoapods/sandbox.rb', line 361

def store_downloaded_pod(name)
  root_name = Specification.root_name(name)
  downloaded_pods << root_name
end

#store_local_path(name, path, was_absolute = false) ⇒ void

This method returns an undefined value.

Stores the local path of a Pod.

Parameters:

  • name (String)

    The name of the Pod.

  • path (Pathname, String)

    The path to the local Podspec

  • was_absolute (Boolean) (defaults to: false)

    True if the specified local path was absolute.



450
451
452
453
454
455
# File 'lib/cocoapods/sandbox.rb', line 450

def store_local_path(name, path, was_absolute = false)
  root_name = Specification.root_name(name)
  path = Pathname.new(path) unless path.is_a?(Pathname)
  development_pods[root_name] = path
  @pods_with_absolute_path << root_name if was_absolute
end

#store_podspec(name, podspec, _external_source = false, json = false) ⇒ void

This method returns an undefined value.

Stores a specification in the Local Podspecs folder.

Parameters:

  • name (String)

    the name of the pod

  • podspec (String, Pathname, Specification)

    The contents of the specification (String) or the path to a podspec file (Pathname).



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/cocoapods/sandbox.rb', line 282

def store_podspec(name, podspec, _external_source = false, json = false)
  file_name = json ? "#{name}.podspec.json" : "#{name}.podspec"
  output_path = specifications_root + file_name

  spec =
    case podspec
    when String
      Sandbox.update_changed_file(output_path, podspec)
      Specification.from_file(output_path)
    when Pathname
      unless podspec.exist?
        raise Informative, "No podspec found for `#{name}` in #{podspec}"
      end
      FileUtils.copy(podspec, output_path)
      Specification.from_file(podspec)
    when Specification
      raise ArgumentError, 'can only store Specification objects as json' unless json
      Sandbox.update_changed_file(output_path, podspec.to_pretty_json)
      podspec.dup
    else
      raise ArgumentError, "Unknown type for podspec: #{podspec.inspect}"
    end

  # we force the file to be the file in the sandbox, so specs that have been serialized to
  # json maintain a consistent checksum.
  # this is safe to do because `spec` is always a clean instance
  spec.defined_in_file = output_path

  unless spec.name == name
    raise Informative, "The name of the given podspec `#{spec.name}` doesn't match the expected one `#{name}`"
  end
  @stored_podspecs[spec.name] = spec
end

#store_pre_downloaded_pod(name) ⇒ void

This method returns an undefined value.

Marks a Pod as pre-downloaded

Parameters:

  • name (String)

    The name of the Pod.



329
330
331
332
# File 'lib/cocoapods/sandbox.rb', line 329

def store_pre_downloaded_pod(name)
  root_name = Specification.root_name(name)
  predownloaded_pods << root_name
end

#target_support_files_dir(name) ⇒ Pathname

Returns the path for the directory where the support files of a target are stored.

Parameters:

  • name (String)

    The name of the target.

Returns:

  • (Pathname)

    the path of the support files.



170
171
172
# File 'lib/cocoapods/sandbox.rb', line 170

def target_support_files_dir(name)
  target_support_files_root + name
end

#target_support_files_rootPathname

Returns The directory where the files generated by CocoaPods to support the umbrella targets are stored.

Returns:

  • (Pathname)

    The directory where the files generated by CocoaPods to support the umbrella targets are stored.



224
225
226
# File 'lib/cocoapods/sandbox.rb', line 224

def target_support_files_root
  root + 'Target Support Files'
end