Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Xcode 16 and synchronized groups #985

Merged
merged 14 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/xcodeproj/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module Constants

# @return [String] The last known object version to Xcodeproj.
#
LAST_KNOWN_OBJECT_VERSION = 63
LAST_KNOWN_OBJECT_VERSION = 70

# @return [String] The last known Xcode version to Xcodeproj.
#
Expand Down Expand Up @@ -132,6 +132,7 @@ module Constants
# @return [Hash] The compatibility version string for different object versions.
#
COMPATIBILITY_VERSION_BY_OBJECT_VERSION = {
70 => 'Xcode 16.0',
63 => 'Xcode 15.3',
60 => 'Xcode 15.0',
56 => 'Xcode 14.0',
Expand Down
2 changes: 2 additions & 0 deletions lib/xcodeproj/project/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,5 @@ def inspect
require 'xcodeproj/project/object/root_object'
require 'xcodeproj/project/object/target_dependency'
require 'xcodeproj/project/object/reference_proxy'
require 'xcodeproj/project/object/file_system_synchronized_root_group'
require 'xcodeproj/project/object/file_system_synchronized_exception_set'
16 changes: 16 additions & 0 deletions lib/xcodeproj/project/object/build_configuration.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'xcodeproj/project/object/file_system_synchronized_root_group'

module Xcodeproj
class Project
module Object
Expand Down Expand Up @@ -25,6 +27,20 @@ class XCBuildConfiguration < AbstractObject
#
has_one :base_configuration_reference, PBXFileReference

# @return [PBXFileSystemSynchronizedRootGroup] an optional reference to a group
# synchronized with the file system that contains a configuration file (`.xcconfig`).
#
# @note the configuration file relative path must be provided in `base_configuration_reference_relative_path`
#
has_one :base_configuration_reference_anchor, PBXFileSystemSynchronizedRootGroup

# @return [String] the relative path of a configuration file (`.xcconfig`)
# inside a group synchronized with the file system.
#
# @note the configuration file group must be provided in `base_configuration_reference_anchor`
#
attribute :base_configuration_reference_relative_path, String

public

# @!group AbstractObject Hooks
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require 'xcodeproj/project/object_attributes'
require 'xcodeproj/project/object/helpers/groupable_helper'

module Xcodeproj
class Project
module Object
# This class represents a file system synchronized build file exception set.
class PBXFileSystemSynchronizedBuildFileExceptionSet < AbstractObject
# @return [AbstractTarget] The target to which this exception set applies.
#
has_one :target, AbstractTarget

# @return [Array<String>] The list of files in the group that are excluded from the target.
#
attribute :membership_exceptions, Array

# @return [Array<String>] The list of public headers.
#
attribute :public_headers, Array

# @return [Array<String>] The list of private headers.
#
attribute :private_headers, Array

# @return [Hash] The files with specific compiler flags.
#
attribute :additional_compiler_flags_by_relative_path, Hash

# @return [Hash] The files with specific attributes.
#
attribute :attributes_by_relative_path, Hash

# @return [Hash] The files with a platform filter.
#
attribute :platform_filters_by_relative_path, Hash

def display_name
"Exceptions for \"#{GroupableHelper.parent(self).display_name}\" folder in \"#{target.name}\" target"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason you have this explicit string here vs what Xcode itself generates here: PBXFileSystemSynchronizedBuildFileExceptionSet

Xcode replaces this string with that when editing the project file, so we're seeing a back-and-forth diff of this comment being edited by both parties.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked in Xcode 16.2RC and this string format is what is used on my projects still.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1000

oh I'm on 16.1, let me try 16.2 real quick to verify

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm Xcode 16.2 RC still reverts this comment:

  1. we're calling fastlane increment_version_number_in_xcodeproj, which just does project = Xcodeproj::Project.open, edits a build setting, then does project.save
  2. this custom comment then gets added
  3. move a package/group/file in Xcode that is tracked in the project file
  4. the comment now becomes PBXFileSystemSynchronizedBuildFileExceptionSet

end
end

# This class represents a file system synchronized group build phase membership exception set.
class PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet < AbstractObject
# @return [PBXSourcesBuildPhase] The build phase to which this exception set applies.
#
has_one :build_phase, PBXSourcesBuildPhase

# @return [Array<String>] The list of files in the group that are excluded from the build phase.
#
attribute :membership_exceptions, Array

# @return [Hash] The files with a platform filter.
#
attribute :platform_filters_by_relative_path, Hash

def display_name
"Exceptions for \"#{GroupableHelper.parent(self).display_name}\" folder in \"#{build_phase.name}\" build phase"
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require 'xcodeproj/project/object/file_system_synchronized_exception_set'

module Xcodeproj
class Project
module Object
# This class represents a file system synchronized root group.
class PBXFileSystemSynchronizedRootGroup < AbstractObject
# @return [String] the directory to which the path is relative.
#
# @note The accepted values are:
# - `<absolute>` for absolute paths
# - `<group>` for paths relative to the group
# - `SOURCE_ROOT` for paths relative to the project
# - `DEVELOPER_DIR` for paths relative to the developer
# directory.
# - `BUILT_PRODUCTS_DIR` for paths relative to the build
# products directory.
# - `SDKROOT` for paths relative to the SDK directory.
#
attribute :source_tree, String, '<group>'

# @return [String] the path to a folder in the file system.
#
attribute :path, String

# @return [String] Whether Xcode should use tabs for text alignment.
#
# @example
# `1`
#
attribute :uses_tabs, String

# @return [String] The width of the indent.
#
# @example
# `2`
#
attribute :indent_width, String

# @return [String] The width of the tabs.
#
# @example
# `2`
#
attribute :tab_width, String

# @return [String] Whether Xcode should wrap lines.
#
# @example
# `1`
#
attribute :wraps_lines, String

# @return [Array<PBXFileSystemSynchronizedBuildFileExceptionSet, PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet>]
# The list of exceptions applying to this group.
#
has_many :exceptions, [PBXFileSystemSynchronizedBuildFileExceptionSet, PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet]

# @return [Hash] The files in the group that have a file type defined explicitly.
#
attribute :explicit_file_types, Hash

# @return [Array] The folders in the group that are defined explicitly.
#
attribute :explicit_folders, Array

def display_name
return path if path
super
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/xcodeproj/project/object/group.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'xcodeproj/project/object/helpers/groupable_helper'
require 'xcodeproj/project/object/helpers/file_references_factory'
require 'xcodeproj/project/object/file_system_synchronized_root_group'

module Xcodeproj
class Project
Expand All @@ -13,7 +14,7 @@ class PBXGroup < AbstractObject
# @return [ObjectList<PBXGroup, PBXFileReference>]
# the objects contained by the group.
#
has_many :children, [PBXGroup, PBXFileReference, PBXReferenceProxy]
has_many :children, [PBXGroup, PBXFileReference, PBXReferenceProxy, PBXFileSystemSynchronizedRootGroup]

# @return [String] the directory to which the path is relative.
#
Expand Down
22 changes: 18 additions & 4 deletions lib/xcodeproj/project/object/native_target.rb
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,11 @@ class PBXNativeTarget < AbstractTarget
#
has_many :build_phases, AbstractBuildPhase

# @return [ObjectList<PBXFileSystemSynchronizedRootGroup>] the file system synchronized
# groups containing files to include to build this target.
#
has_many :file_system_synchronized_groups, PBXFileSystemSynchronizedRootGroup

public

# @!group Helpers
Expand Down Expand Up @@ -684,19 +689,28 @@ def sort(_options = nil)

def to_hash_as(method = :to_hash)
hash_as = super
if !hash_as['packageProductDependencies'].nil? && hash_as['packageProductDependencies'].empty?
hash_as.delete('packageProductDependencies')
excluded_keys_for_serialization_when_empty.each do |key|
if !hash_as[key].nil? && hash_as[key].empty?
hash_as.delete(key)
end
end
hash_as
end

def to_ascii_plist
plist = super
if !plist.value['packageProductDependencies'].nil? && plist.value['packageProductDependencies'].empty?
plist.value.delete('packageProductDependencies')
excluded_keys_for_serialization_when_empty.each do |key|
if !plist.value[key].nil? && plist.value[key].empty?
plist.value.delete(key)
end
end
plist
end

# @return [Array<String>] array of keys to exclude from serialization when the value is empty
def excluded_keys_for_serialization_when_empty
%w(packageProductDependencies fileSystemSynchronizedGroups)
end
end

#-----------------------------------------------------------------------#
Expand Down
4 changes: 4 additions & 0 deletions lib/xcodeproj/project/object/root_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ class PBXProject < AbstractObject
#
attribute :minimized_project_reference_proxies, String, '0'

# @return [String] preferred project object version
#
attribute :preferred_project_object_version, String, '70'

# @return [PBXGroup] the group containing the references to products of
# the project.
#
Expand Down
4 changes: 4 additions & 0 deletions spec/project/object/root_object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ module ProjectSpecs
@root_object.minimized_project_reference_proxies.should == '0'
end

it 'returns the preferred project object version' do
@root_object.preferred_project_object_version.should == '70'
end

it 'returns the products group' do
@root_object.product_ref_group.class.should == PBXGroup
end
Expand Down
Loading