Class: Pod::Project

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

Overview

The Pods project.

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

Constant Summary

LEGACY_BUILD_ROOT =

-------------------------------------------------------------------------#

'${SRCROOT}/../build'
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',
}

Private helpers collapse

Instance Attribute Summary collapse

Legacy Xcode build root collapse

Pod Groups collapse

File references collapse

Private helpers collapse

Instance Method Summary collapse

Constructor Details

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

Initialize a new instance

Parameters:

  • path (Pathname, String)

    @see path

  • skip_initialization (Bool) (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.



19
20
21
22
23
24
25
26
27
28
# File 'lib/cocoapods/project.rb', line 19

def initialize(path, skip_initialization = false,
    object_version = Xcodeproj::Constants::DEFAULT_OBJECT_VERSION)
  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')
  self.symroot = LEGACY_BUILD_ROOT
end

Instance Attribute Details

#development_podsPBXGroup (readonly)

Returns The group for Development Pods.

Returns:

  • (PBXGroup)

    The group for Development Pods.



41
42
43
# File 'lib/cocoapods/project.rb', line 41

def development_pods
  @development_pods
end

#podsPBXGroup (readonly)

Returns The group for the Pods.

Returns:

  • (PBXGroup)

    The group for the Pods.



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

def pods
  @pods
end

#refs_by_absolute_pathHash{String => PBXFileReference} (readonly, private)

Returns The file references grouped by absolute path.

Returns:

  • (Hash{String => PBXFileReference})

    The file references grouped by absolute path.



313
314
315
# File 'lib/cocoapods/project.rb', line 313

def refs_by_absolute_path
  @refs_by_absolute_path
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.



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

def support_files_group
  @support_files_group
end

#variant_groups_by_path_and_nameHash{[Pathname, String] => PBXVariantGroup} (readonly, private)

Returns The variant groups grouped by absolute path of parent dir and name.

Returns:

  • (Hash{[Pathname, String] => PBXVariantGroup})

    The variant groups grouped by absolute path of parent dir and name.



318
319
320
# File 'lib/cocoapods/project.rb', line 318

def variant_groups_by_path_and_name
  @variant_groups_by_path_and_name
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.



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/cocoapods/project.rb', line 275

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_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 (Bool) (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.



204
205
206
207
208
209
210
211
212
213
# File 'lib/cocoapods/project.rb', line 204

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 (Bool) (defaults to: false)

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

  • absolute (Bool) (defaults to: false)

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

Returns:

  • (PBXGroup)

    The new group.



101
102
103
104
105
106
107
108
109
# File 'lib/cocoapods/project.rb', line 101

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

  parent_group = development ? development_pods : pods
  source_tree = absolute ? :absolute : :group

  group = parent_group.new_group(pod_name, path, source_tree)
  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.



239
240
241
242
243
# File 'lib/cocoapods/project.rb', line 239

def add_podfile(podfile_path)
  new_file(podfile_path, :project).tap do |podfile_ref|
    mark_ruby_file_ref(podfile_ref)
  end
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.



301
302
303
# File 'lib/cocoapods/project.rb', line 301

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)


53
54
55
56
57
58
# File 'lib/cocoapods/project.rb', line 53

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

#group_for_path_in_group(absolute_pathname, group, reflect_file_system_structure, base_path = nil) ⇒ PBXGroup (private)

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.

Parameters:

  • absolute_pathname (Pathname)

    The pathname of the file to get the group for.

  • group (PBXGroup)

    The parent group used as the base of the relative path.

  • reflect_file_system_structure (Bool)

    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 the newly created group. If nil, the provided group's real_path is used.

Returns:

  • (PBXGroup)

    The appropriate group for the filepath. Can be PBXVariantGroup, if the file is localized.



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/cocoapods/project.rb', line 345

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

#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.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/cocoapods/project.rb', line 144

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



251
252
253
254
255
# File 'lib/cocoapods/project.rb', line 251

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'
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.



124
125
126
# File 'lib/cocoapods/project.rb', line 124

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.



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

def pod_groups
  pods.children.objects + development_pods.children.objects
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.



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

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.



223
224
225
226
227
228
229
230
# File 'lib/cocoapods/project.rb', line 223

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.



73
74
75
76
77
# File 'lib/cocoapods/project.rb', line 73

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

#variant_group_name(path) ⇒ String (private)

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).

Parameters:

  • The (Pathname)

    localized path to get a variant group name for.

Returns:

  • (String)

    The variant group name.



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/cocoapods/project.rb', line 388

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