Class: Pod::Project

Inherits:
Xcodeproj::Project
  • Object
show all
Defined in:
lib/cocoapods/project.rb,
lib/cocoapods/native_target_extension.rb

Overview

The Pods project.

Model class which provides helpers for working with the Pods project through the installation process.

Legacy Xcode build root collapse

LEGACY_BUILD_ROOT =

————————————————————————-#

'${SRCROOT}/../build'

Pod Groups collapse

SPEC_SUBGROUPS =

Returns The names of the specification subgroups by key.

Returns:

  • (Hash)

    The names of the specification subgroups by key.

{
  :resources  => 'Resources',
  :frameworks => 'Frameworks',
  :developer  => 'Pod',
}

Instance Attribute Summary collapse

Legacy Xcode build root collapse

Pod Groups collapse

File references collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, skip_initialization = false, object_version = Xcodeproj::Constants::DEFAULT_OBJECT_VERSION, pod_target_subproject: false) ⇒ Project

Initialize a new instance

Parameters:

  • path (Pathname, String)

    @see Xcodeproj::Project#path

  • skip_initialization (Boolean) (defaults to: false)

    Whether the project should be initialized from scratch.

  • object_version (Int) (defaults to: Xcodeproj::Constants::DEFAULT_OBJECT_VERSION)

    Object version to use for serialization, defaults to Xcode 3.2 compatible.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cocoapods/project.rb', line 45

def initialize(path, skip_initialization = false,
                object_version = Xcodeproj::Constants::DEFAULT_OBJECT_VERSION, pod_target_subproject: false)
  @uuid_prefix = Digest('SHA256').hexdigest(File.basename(path)).upcase
  super(path, skip_initialization, object_version)
  @support_files_group = new_group('Targets Support Files')
  @refs_by_absolute_path = {}
  @variant_groups_by_path_and_name = {}
  @pods = new_group('Pods')
  @development_pods = new_group('Development Pods')
  @dependencies_group = new_group('Dependencies')
  @pod_target_subproject = pod_target_subproject
  @project_name = Pathname(path).basename('.*').to_s
  self.symroot = LEGACY_BUILD_ROOT
end

Instance Attribute Details

#dependencies_groupPBXGroup (readonly)

Used by #generate_multiple_pod_projects installation option.

Returns:

  • (PBXGroup)

    The group for dependencies.



27
28
29
# File 'lib/cocoapods/project.rb', line 27

def dependencies_group
  @dependencies_group
end

#development_podsPBXGroup (readonly)

Returns The group for Development Pods.

Returns:

  • (PBXGroup)

    The group for Development Pods.



22
23
24
# File 'lib/cocoapods/project.rb', line 22

def development_pods
  @development_pods
end

#pod_target_subprojectBoolean (readonly) Also known as: pod_target_subproject?

Used by ‘generate_multiple_pod_projects` installation option.

Returns:

  • (Boolean)

    Bool indicating if this project is a pod target subproject.



32
33
34
# File 'lib/cocoapods/project.rb', line 32

def pod_target_subproject
  @pod_target_subproject
end

#podsPBXGroup (readonly)

Returns The group for the Pods.

Returns:

  • (PBXGroup)

    The group for the Pods.



18
19
20
# File 'lib/cocoapods/project.rb', line 18

def pods
  @pods
end

#project_nameString (readonly)

Returns The basename of the project path without .xcodeproj extension.

Returns:

  • (String)

    The basename of the project path without .xcodeproj extension.



37
38
39
# File 'lib/cocoapods/project.rb', line 37

def project_name
  @project_name
end

#support_files_groupPBXGroup (readonly)

Returns The group for the support files of the aggregate targets.

Returns:

  • (PBXGroup)

    The group for the support files of the aggregate targets.



14
15
16
# File 'lib/cocoapods/project.rb', line 14

def support_files_group
  @support_files_group
end

Class Method Details

.add_cached_dependency(sandbox, target, metadata) ⇒ void

This method returns an undefined value.

Adds a dependency on the given metadata cache.

Parameters:

  • sandbox (Sandbox)

    The sandbox used for this installation.

  • target (AbstractTarget)

    The parent target used to add a cached dependency.

  • metadata (MetadataCache)

    The metadata holding all the required metadata to construct a target as a dependency.

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/cocoapods/native_target_extension.rb', line 16

def self.add_cached_dependency(sandbox, target, )
  return if dependency_for_cached_target?(sandbox, target, )
  container_proxy = target.project.new(Xcodeproj::Project::PBXContainerItemProxy)

  subproject_reference = target.project.reference_for_path(sandbox.root + .container_project_path)
  raise ArgumentError, "add_dependency received target (#{target}) that belongs to a project that is not this project (#{self}) and is not a subproject of this project" unless subproject_reference
  container_proxy.container_portal = subproject_reference.uuid

  container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
  container_proxy.remote_global_id_string = .native_target_uuid
  container_proxy.remote_info = .target_label

  dependency = target.project.new(Xcodeproj::Project::PBXTargetDependency)
  dependency.name = .target_label
  dependency.target_proxy = container_proxy

  target.dependencies << dependency
end

.dependency_for_cached_target?(sandbox, target, cached_target) ⇒ Boolean

Checks whether this target has a dependency on the given target.

Parameters:

  • sandbox (Sandbox)

    The sandbox used for this installation.

  • target (AbstractTarget)

    The parent target used to add a cached dependency.

  • cached_target (TargetMetadata)

    the target to search for.

Returns:

  • (Boolean)


48
49
50
51
52
53
54
55
56
57
58
# File 'lib/cocoapods/native_target_extension.rb', line 48

def self.dependency_for_cached_target?(sandbox, target, cached_target)
  target.dependencies.find do |dep|
    if dep.target_proxy.remote?
      subproject_reference = target.project.reference_for_path(sandbox.root + cached_target.container_project_path)
      uuid = subproject_reference.uuid if subproject_reference
      dep.target_proxy.remote_global_id_string == cached_target.native_target_uuid && dep.target_proxy.container_portal == uuid
    else
      dep.target.uuid == cached_target.native_target_uuid
    end
  end
end

Instance Method Details

#add_build_configuration(name, type) ⇒ XCBuildConfiguration

Note:

This method extends the original Xcodeproj implementation to include a preprocessor definition named after the build setting. This is done to support the TargetEnvironmentHeader specification of Pods available only on certain build configurations.

Adds a new build configuration to the project and populates it with default settings according to the provided type.

Parameters:

  • name (String)

    The name of the build configuration.

  • type (Symbol)

    The type of the build configuration used to populate the build settings, must be :debug or :release.

Returns:

  • (XCBuildConfiguration)

    The new build configuration.



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/cocoapods/project.rb', line 374

def add_build_configuration(name, type)
  build_configuration = super
  settings = build_configuration.build_settings
  definitions = settings['GCC_PREPROCESSOR_DEFINITIONS'] || ['$(inherited)']
  defines = [defininition_for_build_configuration(name)]
  defines << 'DEBUG' if type == :debug
  defines.each do |define|
    value = "#{define}=1"
    unless definitions.include?(value)
      definitions.unshift(value)
    end
  end
  settings['GCC_PREPROCESSOR_DEFINITIONS'] = definitions

  if type == :debug
    settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] = 'DEBUG'
  end

  build_configuration
end

#add_cached_pod_subproject(sandbox, metadata, development = false) ⇒ PBXFileReference

Creates a new subproject reference for the given cached metadata and configures its group location.

Parameters:

  • sandbox (Sandbox)

    The sandbox used for installation.

  • metadata (TargetMetadata)

    The project metadata to be added.

  • development (Boolean) (defaults to: false)

    Whether the project should be added to the Development Pods group. For projects where ‘pod_target_subproject` is enabled, all subprojects are added into the Dependencies group.

Returns:

  • (PBXFileReference)

    The new file reference.



165
166
167
168
# File 'lib/cocoapods/project.rb', line 165

def add_cached_pod_subproject(sandbox, , development = false)
  parent_group = group_for_subproject_reference(development)
  add_cached_subproject_reference(sandbox, , parent_group)
end

#add_cached_subproject_reference(sandbox, metadata, group) ⇒ PBXFileReference

Adds a file reference for a cached project as a child of the given group.

Parameters:

  • sandbox (Sandbox)

    The sandbox used for installation.

  • metadata (MetadataCache)

    The metadata holding the required properties to create a subproject reference.

  • group (PBXGroup)

    The group for the new subproject reference.

Returns:

  • (PBXFileReference)

    The new file reference.



308
309
310
# File 'lib/cocoapods/project.rb', line 308

def add_cached_subproject_reference(sandbox, , group)
  new_subproject_file_reference(sandbox.root + .container_project_path, group)
end

#add_file_reference(absolute_path, group, reflect_file_system_structure = false, base_path = nil) ⇒ PBXFileReference

Adds a file reference to given path as a child of the given group.

Parameters:

  • absolute_path (Array<Pathname,String>)

    The path of the file.

  • group (PBXGroup)

    The group for the new file reference.

  • reflect_file_system_structure (Boolean) (defaults to: false)

    Whether group structure should reflect the file system structure. If yes, where needed, intermediate groups are created, similar to how mkdir -p operates.

  • base_path (Pathname) (defaults to: nil)

    The base path for newly created groups when reflect_file_system_structure is true. If nil, the provided group’s real_path is used.

Returns:

  • (PBXFileReference)

    The new file reference.



267
268
269
270
271
272
273
274
275
276
# File 'lib/cocoapods/project.rb', line 267

def add_file_reference(absolute_path, group, reflect_file_system_structure = false, base_path = nil)
  file_path_name = absolute_path.is_a?(Pathname) ? absolute_path : Pathname(absolute_path)
  if ref = reference_for_path(file_path_name)
    return ref
  end

  group = group_for_path_in_group(file_path_name, group, reflect_file_system_structure, base_path)
  ref = group.new_file(file_path_name.realpath)
  @refs_by_absolute_path[file_path_name.to_s] = ref
end

#add_pod_group(pod_name, path, development = false, absolute = false) ⇒ PBXGroup

Creates a new group for the Pod with the given name and configures its path.

Parameters:

  • pod_name (String)

    The name of the Pod.

  • path (#to_s)

    The path to the root of the Pod.

  • development (Boolean) (defaults to: false)

    Whether the group should be added to the Development Pods group.

  • absolute (Boolean) (defaults to: false)

    Whether the path of the group should be set as absolute.

Returns:

  • (PBXGroup)

    The new group.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/cocoapods/project.rb', line 118

def add_pod_group(pod_name, path, development = false, absolute = false)
  raise '[BUG]' if pod_group(pod_name)

  parent_group =
    if pod_target_subproject
      main_group
    else
      development ? development_pods : pods
    end
  source_tree = absolute ? :absolute : :group

  group = parent_group.new_group(pod_name, path, source_tree)
  group
end

#add_pod_subproject(project, development = false) ⇒ PBXFileReference

Creates a new subproject reference for the given project and configures its group location.

Parameters:

  • project (Project)

    The subproject to be added.

  • development (Boolean) (defaults to: false)

    Whether the project should be added to the Development Pods group. For projects where ‘pod_target_subproject` is enabled, all subprojects are added into the Dependencies group.

Returns:

  • (PBXFileReference)

    The new file reference.



145
146
147
148
# File 'lib/cocoapods/project.rb', line 145

def add_pod_subproject(project, development = false)
  parent_group = group_for_subproject_reference(development)
  add_subproject_reference(project, parent_group)
end

#add_podfile(podfile_path) ⇒ PBXFileReference

Adds a file reference to the Podfile.

Parameters:

  • podfile_path (#to_s)

    The path of the Podfile.

Returns:

  • (PBXFileReference)

    The new file reference.



336
337
338
339
340
# File 'lib/cocoapods/project.rb', line 336

def add_podfile(podfile_path)
  new_file(podfile_path, :project).tap do |podfile_ref|
    mark_ruby_file_ref(podfile_ref)
  end
end

#add_subproject_reference(project, group) ⇒ PBXFileReference

Adds a file reference for a project as a child of the given group.

Parameters:

  • project (Project)

    The project to add as a subproject reference.

  • group (PBXGroup)

    The group for the new subproject reference.

Returns:

  • (PBXFileReference)

    The new file reference.



291
292
293
# File 'lib/cocoapods/project.rb', line 291

def add_subproject_reference(project, group)
  new_subproject_file_reference(project.path, group)
end

#defininition_for_build_configuration(name) ⇒ String

Returns The preprocessor definition to set for the configuration.

Parameters:

  • name (String)

    The name of the build configuration.

Returns:

  • (String)

    The preprocessor definition to set for the configuration.



400
401
402
# File 'lib/cocoapods/project.rb', line 400

def defininition_for_build_configuration(name)
  "POD_CONFIGURATION_#{name.underscore}".gsub(/[^a-zA-Z0-9_]/, '_').upcase
end

#generate_available_uuid_list(count = 100) ⇒ Void

Note:

Overridden to generate UUIDs in a much faster way, since we don’t need to check for collisions (as the Pods project is regenerated each time, and thus all UUIDs will have come from this method)

Generates a list of new UUIDs that created objects can be assigned.

Parameters:

  • count (Integer) (defaults to: 100)

    The number of UUIDs to generate

Returns:

  • (Void)


70
71
72
73
74
75
# File 'lib/cocoapods/project.rb', line 70

def generate_available_uuid_list(count = 100)
  start = @generated_uuids.size
  uniques = Array.new(count) { |i| format('%.6s%07X0', @uuid_prefix, start + i) }
  @generated_uuids += uniques
  @available_uuids += uniques
end

#group_for_spec(spec_name, subgroup_key = nil) ⇒ PBXGroup

Returns the group for the specification with the give name creating it if needed.

Parameters:

  • spec_name (String)

    The full name of the specification.

Returns:

  • (PBXGroup)

    The group.



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/cocoapods/project.rb', line 207

def group_for_spec(spec_name, subgroup_key = nil)
  pod_name = Specification.root_name(spec_name)
  group = pod_group(pod_name)
  raise "[Bug] Unable to locate group for Pod named `#{pod_name}`" unless group
  if spec_name != pod_name
    subspecs_names = spec_name.gsub(pod_name + '/', '').split('/')
    subspecs_names.each do |name|
      group = group[name] || group.new_group(name)
    end
  end

  if subgroup_key
    subgroup_name = SPEC_SUBGROUPS[subgroup_key]
    raise ArgumentError, "Unrecognized subgroup key `#{subgroup_key}`" unless subgroup_name
    group = group[subgroup_name] || group.new_group(subgroup_name)
  end

  group
end

#mark_ruby_file_ref(file_ref) ⇒ Object

Sets the syntax of the provided file reference to be Ruby, in the case that the file does not already have a “.rb” file extension (ex. the Podfile)

Parameters:

  • file_ref (PBXFileReference)

    The file reference to change



348
349
350
351
352
353
354
# File 'lib/cocoapods/project.rb', line 348

def mark_ruby_file_ref(file_ref)
  file_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
  file_ref.explicit_file_type = 'text.script.ruby'
  file_ref.last_known_file_type = 'text'
  file_ref.tab_width = '2'
  file_ref.indent_width = '2'
end

#pod_group(pod_name) ⇒ PBXGroup

Returns the group for the Pod with the given name.

Parameters:

  • pod_name (String)

    The name of the Pod.

Returns:

  • (PBXGroup)

    The group.



187
188
189
# File 'lib/cocoapods/project.rb', line 187

def pod_group(pod_name)
  pod_groups.find { |group| group.name == pod_name }
end

#pod_groupsArray<PBXGroup>

Returns all the group of the Pods.

Returns:

  • (Array<PBXGroup>)

    Returns all the group of the Pods.



172
173
174
175
176
177
178
# File 'lib/cocoapods/project.rb', line 172

def pod_groups
  if pod_target_subproject
    main_group.children.objects
  else
    pods.children.objects + development_pods.children.objects
  end
end

#pod_support_files_group(pod_name, dir) ⇒ PBXGroup

Returns the support files group for the Pod with the given name.

Parameters:

  • pod_name (String)

    The name of the Pod.

Returns:

  • (PBXGroup)

    The group.



234
235
236
237
238
239
240
241
# File 'lib/cocoapods/project.rb', line 234

def pod_support_files_group(pod_name, dir)
  group = pod_group(pod_name)
  support_files_group = group['Support Files']
  unless support_files_group
    support_files_group = group.new_group('Support Files', dir)
  end
  support_files_group
end

#reference_for_path(absolute_path) ⇒ PBXFileReference, Nil

Returns the file reference for the given absolute path.

Parameters:

  • absolute_path (#to_s)

    The absolute path of the file whose reference is needed.

Returns:

  • (PBXFileReference)

    The file reference.

  • (Nil)

    If no file reference could be found.



320
321
322
323
324
325
326
327
# File 'lib/cocoapods/project.rb', line 320

def reference_for_path(absolute_path)
  absolute_path = absolute_path.is_a?(Pathname) ? absolute_path : Pathname(absolute_path)
  unless absolute_path.absolute?
    raise ArgumentError, "Paths must be absolute #{absolute_path}"
  end

  refs_by_absolute_path[absolute_path.to_s] ||= refs_by_absolute_path[absolute_path.realpath.to_s]
end

#symroot=(symroot) ⇒ void

This method returns an undefined value.

Parameters:

  • symroot (String)

    The build root that is used when Xcode is configured to not use the workspace’s build root. Defaults to ‘$SRCROOT/../build`.



90
91
92
93
94
# File 'lib/cocoapods/project.rb', line 90

def symroot=(symroot)
  root_object.build_configuration_list.build_configurations.each do |config|
    config.build_settings['SYMROOT'] = symroot
  end
end