Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
7 changes: 6 additions & 1 deletion lib/xcodeproj/project/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,12 @@ def nested_object_for_hash(object, method)
end

def ascii_plist_annotation
" #{display_name} "
name = display_name

if name && name.is_a?(String) && (name.encoding == Encoding::UTF_8 || name.encoding == Encoding::US_ASCII)
name = name.unicode_normalize(:nfd)
end
" #{name} "
end

def to_ascii_plist
Expand Down
14 changes: 14 additions & 0 deletions lib/xcodeproj/project/object/build_phase.rb
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,20 @@ def pretty_print
},
}
end

def to_hash_as(method = :to_hash)
hash_as = super
included_keys_for_serialization_when_empty.each do |key|
if hash_as[key].nil?
hash_as[key] = []
end
end
hash_as
end

def included_keys_for_serialization_when_empty
%w(inputPaths outputPaths)
end
end

#-----------------------------------------------------------------------#
Expand Down
5 changes: 5 additions & 0 deletions lib/xcodeproj/project/object/file_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ class PBXFileReference < AbstractObject
# needed.
#
def display_name
# For folder references with SOURCE_ROOT, use full path like Xcode
if last_known_file_type&.start_with?('folder') && source_tree == 'SOURCE_ROOT'
return path if path
end

if name
name
elsif (class << GroupableHelper; self; end)::SOURCE_TREES_BY_KEY[:built_products] == source_tree
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class PBXFileSystemSynchronizedBuildFileExceptionSet < AbstractObject
attribute :platform_filters_by_relative_path, Hash

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

Expand All @@ -49,12 +49,16 @@ class PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet < AbstractO
#
attribute :membership_exceptions, Array

# @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 \"#{build_phase.name}\" build phase"
'PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet'
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ def display_name
return path if path
super
end

def to_hash_as(method = :to_hash)
hash_as = super
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

# @return [Array<String>] array of keys to exclude from serialization when the value is empty
def excluded_keys_for_serialization_when_empty
%w(exceptions)
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class XCLocalSwiftPackageReference < AbstractObject
#--------------------------------------#

def ascii_plist_annotation
" #{isa} \"#{File.basename(display_name)}\" "
" #{isa} \"#{display_name}\" "
end

# @return [String] the path of the local Swift package reference.
Expand Down
33 changes: 32 additions & 1 deletion lib/xcodeproj/project/object/swift_package_remote_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class XCRemoteSwiftPackageReference < AbstractObject
#--------------------------------------#

def ascii_plist_annotation
" #{isa} \"#{File.basename(display_name, '.git')}\" "
name = extract_package_name(display_name)
" #{isa} \"#{name}\" "
end

# @return [String] the name of the remote Swift package reference.
Expand All @@ -27,6 +28,36 @@ def display_name
return repositoryURL if repositoryURL
super
end

private

# Extracts package name from repository URL
# Handles different URL formats:
# - https://github.com/owner/repo.git -> repo
# - https://github.com/owner/socket.io-client-swift -> socket
# - [email protected]:owner/repo.git -> repo
# - github.com/owner/repo -> repo
# - domain.xyz (custom registry) -> xyz
def extract_package_name(url)
return url unless url

# Remove .git extension first
name = url.sub(/\.git$/, '')

# Check if it's a URL with path (contains /)
if name.include?('/')
# Extract last path component (handle both / and :)
name = name.split(/[\/:]/).last
# If name contains a dot, use only the part before the first dot
# e.g., socket.io-client-swift -> socket
name = name.split('.').first if name.include?('.')
elsif name.include?('.')
# For other URLs (e.g., custom registry like domain.xyz), split by . and use last component
name = name.split('.').last
end

name
end
end
end
end
Expand Down
26 changes: 26 additions & 0 deletions spec/project/object/file_reference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,32 @@ module ProjectSpecs
@target.build_phases[0].files.should.be.empty
end

describe 'concerning folder references' do
it 'returns full path for display_name when lastKnownFileType is folder with SOURCE_ROOT' do
folder = @project.new(PBXFileReference)
folder.last_known_file_type = 'folder'
folder.path = 'NaverMap_v5Tests/NaviSearch/Fixtures'
folder.source_tree = 'SOURCE_ROOT'
folder.display_name.should == 'NaverMap_v5Tests/NaviSearch/Fixtures'
end

it 'returns basename for display_name for folder with <group> source tree' do
folder = @project.new(PBXFileReference)
folder.last_known_file_type = 'folder'
folder.path = 'Path/To/Folder'
folder.source_tree = '<group>'
folder.display_name.should == 'Folder'
end

it 'returns basename for display_name for folder.assetcatalog with <group>' do
folder = @project.new(PBXFileReference)
folder.last_known_file_type = 'folder.assetcatalog'
folder.path = 'Resources/Assets.xcassets'
folder.source_tree = '<group>'
folder.display_name.should == 'Assets.xcassets'
end
end

describe 'concerning proxies' do
it 'returns that it is not a proxy' do
@file.should.not.be.a.proxy
Expand Down
10 changes: 10 additions & 0 deletions spec/project/object/swift_package_remote_reference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,15 @@ module ProjectSpecs
@proxy.repositoryURL = 'github.com/swift/package.git'
@proxy.ascii_plist_annotation.should == ' XCRemoteSwiftPackageReference "package" '
end

it 'returns the ascii plist annotation with the part before the first dot for URLs with dotted names' do
@proxy.repositoryURL = 'https://github.com/socketio/socket.io-client-swift'
@proxy.ascii_plist_annotation.should == ' XCRemoteSwiftPackageReference "socket" '
end

it 'returns the ascii plist annotation with the part before the first dot for git@ URLs with dotted names' do
@proxy.repositoryURL = '[email protected]:socketio/socket.io-client-swift.git'
@proxy.ascii_plist_annotation.should == ' XCRemoteSwiftPackageReference "socket" '
end
end
end