class Pod::Project
The Pods project.
Model class which provides helpers for working with the Pods project through the installation process.
Constants
- LEGACY_BUILD_ROOT
@!group Legacy
Xcode
build root- SPEC_SUBGROUPS
@return [Hash] The names of the specification subgroups by key.
Attributes
@return [PBXGroup] The group for dependencies. Used by generate_multiple_pod_projects installation option.
@return [PBXGroup] The group for Development Pods.
@return [Boolean] Bool indicating if this project is a pod target subproject. Used by ‘generate_multiple_pod_projects` installation option.
@return [Boolean] Bool indicating if this project is a pod target subproject. Used by ‘generate_multiple_pod_projects` installation option.
@return [PBXGroup] The group for the Pods.
@return [String] The basename of the project path without .xcodeproj extension.
@return [Hash{String => PBXFileReference}] The file references grouped
by absolute path.
@return [PBXGroup] The group for the support files of the aggregate
targets.
@return [Hash{[Pathname, String] => PBXVariantGroup}] The variant groups
grouped by absolute path of parent dir and name.
Public Class Methods
Adds a dependency on the given metadata cache.
@param [Sandbox] sandbox
The sandbox used for this installation.
@param [AbstractTarget] target
The parent target used to add a cached dependency.
@param [MetadataCache] metadata
The metadata holding all the required metadata to construct a target as a dependency.
@return [void]
# File lib/cocoapods/native_target_extension.rb, line 16 def self.add_cached_dependency(sandbox, target, metadata) return if dependency_for_cached_target?(sandbox, target, metadata) container_proxy = target.project.new(Xcodeproj::Project::PBXContainerItemProxy) subproject_reference = target.project.reference_for_path(sandbox.root + metadata.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 = metadata.native_target_uuid container_proxy.remote_info = metadata.target_label dependency = target.project.new(Xcodeproj::Project::PBXTargetDependency) dependency.name = metadata.target_label dependency.target_proxy = container_proxy target.dependencies << dependency end
Checks whether this target has a dependency on the given target.
@param [Sandbox] sandbox
The sandbox used for this installation.
@param [AbstractTarget] target
The parent target used to add a cached dependency.
@param [TargetMetadata] cached_target
the target to search for.
@return [Boolean]
# 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
Initialize a new instance
@param [Pathname, String] path @see Xcodeproj::Project#path @param [Boolean] skip_initialization Whether the project should be initialized from scratch. @param [Int] object_version Object
version to use for serialization, defaults to Xcode
3.2 compatible.
# 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
Public Instance Methods
Adds a new build configuration to the project and populates it with default settings according to the provided type.
@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.
@param [String] name
The name of the build configuration.
@param [Symbol] type
The type of the build configuration used to populate the build settings, must be :debug or :release.
@return [XCBuildConfiguration] The new build configuration.
# 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
Creates a new subproject reference for the given cached metadata and configures its group location.
@param [Sandbox] sandbox
The sandbox used for installation.
@param [TargetMetadata] metadata
The project metadata to be added.
@param [Boolean] development
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.
@return [PBXFileReference] The new file reference.
# File lib/cocoapods/project.rb, line 165 def add_cached_pod_subproject(sandbox, metadata, development = false) parent_group = group_for_subproject_reference(development) add_cached_subproject_reference(sandbox, metadata, parent_group) end
Adds a file reference for a cached project as a child of the given group.
@param [Sandbox] sandbox
The sandbox used for installation.
@param [MetadataCache] metadata
The metadata holding the required properties to create a subproject reference.
@param [PBXGroup] group
The group for the new subproject reference.
@return [PBXFileReference] The new file reference.
# File lib/cocoapods/project.rb, line 308 def add_cached_subproject_reference(sandbox, metadata, group) new_subproject_file_reference(sandbox.root + metadata.container_project_path, group) end
Adds a file reference to given path as a child of the given group.
@param [Array<Pathname,String>] absolute_path
The path of the file.
@param [PBXGroup] group
The group for the new file reference.
@param [Boolean] reflect_file_system_structure
Whether group structure should reflect the file system structure. If yes, where needed, intermediate groups are created, similar to how mkdir -p operates.
@param [Pathname] base_path
The base path for newly created groups when reflect_file_system_structure is true. If nil, the provided group's real_path is used.
@return [PBXFileReference] The new file reference.
# 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
Creates a new group for the Pod
with the given name and configures its path.
@param [String] pod_name
The name of the Pod.
@param [#to_s] path
The path to the root of the Pod.
@param [Boolean] development
Whether the group should be added to the Development Pods group.
@param [Boolean] absolute
Whether the path of the group should be set as absolute.
@return [PBXGroup] The new group.
# 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
Creates a new subproject reference for the given project and configures its group location.
@param [Project] project
The subproject to be added.
@param [Boolean] development
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.
@return [PBXFileReference] The new file reference.
# 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
Adds a file reference to the Podfile
.
@param [#to_s] podfile_path
The path of the Podfile.
@return [PBXFileReference] The new file reference.
# 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
Adds a file reference for a project as a child of the given group.
@param [Project] project
The project to add as a subproject reference.
@param [PBXGroup] group
The group for the new subproject reference.
@return [PBXFileReference] The new file reference.
# File lib/cocoapods/project.rb, line 291 def add_subproject_reference(project, group) new_subproject_file_reference(project.path, group) end
@param [String] name
The name of the build configuration.
@return [String] The preprocessor definition to set for the configuration.
# File lib/cocoapods/project.rb, line 400 def defininition_for_build_configuration(name) "POD_CONFIGURATION_#{name.underscore}".gsub(/[^a-zA-Z0-9_]/, '_').upcase end
Generates a list of new UUIDs that created objects can be assigned.
@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)
@param [Integer] count
The number of UUIDs to generate
@return [Void]
# 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
Returns the group for the specification with the give name creating it if needed.
@param [String] spec_name
The full name of the specification.
@return [PBXGroup] The group.
# 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
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
)
@param [PBXFileReference] file_ref
The file reference to change
# 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
Returns the group for the Pod
with the given name.
@param [String] pod_name
The name of the Pod.
@return [PBXGroup] The group.
# File lib/cocoapods/project.rb, line 187 def pod_group(pod_name) pod_groups.find { |group| group.name == pod_name } end
@return [Array<PBXGroup>] Returns all the group of the Pods.
# 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
Returns the support files group for the Pod
with the given name.
@param [String] pod_name
The name of the Pod.
@return [PBXGroup] The group.
# 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
Returns the file reference for the given absolute path.
@param [#to_s] absolute_path
The absolute path of the file whose reference is needed.
@return [PBXFileReference] The file reference. @return [Nil] If no file reference could be found.
# 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
@param [String] symroot
The build root that is used when Xcode is configured to not use the workspace’s build root. Defaults to `${SRCROOT}/../build`.
@return [void]
# 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
Private Instance Methods
Returns the group for an absolute file path in another group. Creates subgroups to reflect the file system structure if reflect_file_system_structure is set to true. Makes a variant group if the path points to a localized file inside a *.lproj directory. To support Apple Base Internationalization, the same variant group is returned for interface files and strings files with the same name.
@param [Pathname] absolute_pathname
The pathname of the file to get the group for.
@param [PBXGroup] group
The parent group used as the base of the relative path.
@param [Boolean] reflect_file_system_structure
Whether group structure should reflect the file system structure. If yes, where needed, intermediate groups are created, similar to how mkdir -p operates.
@param [Pathname] base_path
The base path for the newly created group. If nil, the provided group's real_path is used.
@return [PBXGroup] The appropriate group for the filepath.
Can be PBXVariantGroup, if the file is localized.
# File lib/cocoapods/project.rb, line 444 def group_for_path_in_group(absolute_pathname, group, reflect_file_system_structure, base_path = nil) unless absolute_pathname.absolute? raise ArgumentError, "Paths must be absolute #{absolute_pathname}" end unless base_path.nil? || base_path.absolute? raise ArgumentError, "Paths must be absolute #{base_path}" end relative_base = base_path.nil? ? group.real_path : base_path.realdirpath relative_pathname = absolute_pathname.relative_path_from(relative_base) relative_dir = relative_pathname.dirname # Add subgroups for directories, but treat .lproj as a file if reflect_file_system_structure path = relative_base relative_dir.each_filename do |name| break if name.to_s.downcase.include? '.lproj' next if name == '.' # Make sure groups have the correct absolute path set, as intermittent # directories may not be included in the group structure path += name group = group.children.find { |c| c.display_name == name } || group.new_group(name, path) end end # Turn files inside .lproj directories into a variant group if relative_dir.basename.to_s.downcase.include? '.lproj' group_name = variant_group_name(absolute_pathname) lproj_parent_dir = absolute_pathname.dirname.dirname group = @variant_groups_by_path_and_name[[lproj_parent_dir, group_name]] ||= group.new_variant_group(group_name, lproj_parent_dir) end group end
Returns the parent group a new subproject reference should belong to.
# File lib/cocoapods/project.rb, line 534 def group_for_subproject_reference(development) if pod_target_subproject dependencies_group else development ? development_pods : pods end end
# File lib/cocoapods/project.rb, line 511 def new_subproject_file_reference(project_path, group) if ref = reference_for_path(project_path) return ref end # We call into the private function `FileReferencesFactory.new_file_reference` instead of `FileReferencesFactory.new_reference` # because it delegates into `FileReferencesFactory.new_subproject` which has the extra behavior of opening the Project which # is an expensive operation for large projects. # ref = Xcodeproj::Project::FileReferencesFactory.send(:new_file_reference, group, project_path, :group) ref.name = Pathname(project_path).basename('.*').to_s ref.include_in_index = nil attribute = PBXProject.references_by_keys_attributes.find { |attrb| attrb.name == :project_references } project_reference = ObjectDictionary.new(attribute, group.project.root_object) project_reference[:project_ref] = ref root_object.project_references << project_reference refs_by_absolute_path[project_path.to_s] = ref ref end
Returns the name to be used for a the variant group for a file at a given path. The path must be localized (within an *.lproj directory).
@param [Pathname] path The localized path to get a variant group name for.
@return [String] The variant group name.
# File lib/cocoapods/project.rb, line 487 def variant_group_name(path) unless path.to_s.downcase.include?('.lproj/') raise ArgumentError, 'Only localized resources can be added to variant groups.' end # When using Base Internationalization for XIBs and Storyboards a strings # file is generated with the same name as the XIB/Storyboard in each .lproj # directory: # Base.lproj/MyViewController.xib # fr.lproj/MyViewController.strings # # In this scenario we want the variant group to be the same as the XIB or Storyboard. # # Base Internationalization: https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/InternationalizingYourUserInterface/InternationalizingYourUserInterface.html if path.extname.downcase == '.strings' %w(.xib .storyboard).each do |extension| possible_interface_file = path.dirname.dirname + 'Base.lproj' + path.basename.sub_ext(extension) return possible_interface_file.basename.to_s if possible_interface_file.exist? end end path.basename.to_s end