From bda5022b3a54507680350dfe23c5afa76142db12 Mon Sep 17 00:00:00 2001 From: Maxim Kholyavkin Date: Thu, 10 Oct 2024 12:56:04 +0300 Subject: [PATCH 1/3] IOSC-12423 do sort projectReferences as Xcode 16 do --- .../Objects/Project/PBXProjEncoder.swift | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index 7321fb1d0..cacc3e051 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -54,6 +54,7 @@ final class PBXProjEncoder { sort(buildPhases: proj.objects.resourcesBuildPhases, outputSettings: outputSettings) sort(buildPhases: proj.objects.sourcesBuildPhases, outputSettings: outputSettings) sort(navigatorGroups: proj.objects.groups, outputSettings: outputSettings) + sortProjectReferences(for: proj.projects, outputSettings: outputSettings) var output = [String]() var stateHolder = StateHolder() @@ -468,4 +469,44 @@ final class PBXProjEncoder { navigatorGroups.values.forEach { $0.children = $0.children.sorted(by: sort) } } } + + private func sortProjectReferences(for projects: [PBXProject], outputSettings: PBXOutputSettings) { + guard outputSettings.projReferenceFormat == .xcode else { + return + } + + for project in projects { + do { + project.projectReferences = try project.projectReferences.sorted(by: { lhs, rhs in + guard let lProjectRef = lhs["ProjectRef"] else { + throw Errors.unexpectedPbxProj() + } + guard let lFile: PBXFileElement = lProjectRef.getObject() else { + throw Errors.unexpectedPbxProj() + } + guard let rProjectRef = rhs["ProjectRef"] else { + throw Errors.unexpectedPbxProj() + } + guard let rFile: PBXFileElement = rProjectRef.getObject() else { + throw Errors.unexpectedPbxProj() + } + guard let lName = lFile.name else { + throw Errors.unexpectedPbxProj() + } + guard let rName = rFile.name else { + throw Errors.unexpectedPbxProj() + } + + return lName.compare(rName, options: .caseInsensitive) == .orderedAscending + }) + } catch { + print("Unable to sort as Xcode 16 do: \(error)") + fatalError("\(error)") + } + } + } +} + +private enum Errors: Error { + case unexpectedPbxProj(_ id: Int = #line) } From 43f5fc47892a5857559102a14cf9ad4a8b0a2d19 Mon Sep 17 00:00:00 2001 From: Maxim Kholyavkin Date: Thu, 10 Oct 2024 12:58:13 +0300 Subject: [PATCH 2/3] IOSC-12423 comment fatalError to publish code to co --- Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index cacc3e051..cabce4a28 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -501,7 +501,9 @@ final class PBXProjEncoder { }) } catch { print("Unable to sort as Xcode 16 do: \(error)") - fatalError("\(error)") + // actually we could do even fatalError here + // but it could be too brave for common repository + // fatalError("\(error)") } } } From 61391f4db0dab86013ff255acae8612088a94d02 Mon Sep 17 00:00:00 2001 From: Pedro Date: Tue, 3 Dec 2024 17:15:48 +0100 Subject: [PATCH 3/3] Make the sorting stricter --- .../Objects/Project/PBXProjEncoder.swift | 43 +++++-------------- .../Objects/Project/PBXProjEncoderTests.swift | 2 + 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift index cabce4a28..6e38c4747 100644 --- a/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift +++ b/Sources/XcodeProj/Objects/Project/PBXProjEncoder.swift @@ -476,39 +476,16 @@ final class PBXProjEncoder { } for project in projects { - do { - project.projectReferences = try project.projectReferences.sorted(by: { lhs, rhs in - guard let lProjectRef = lhs["ProjectRef"] else { - throw Errors.unexpectedPbxProj() - } - guard let lFile: PBXFileElement = lProjectRef.getObject() else { - throw Errors.unexpectedPbxProj() - } - guard let rProjectRef = rhs["ProjectRef"] else { - throw Errors.unexpectedPbxProj() - } - guard let rFile: PBXFileElement = rProjectRef.getObject() else { - throw Errors.unexpectedPbxProj() - } - guard let lName = lFile.name else { - throw Errors.unexpectedPbxProj() - } - guard let rName = rFile.name else { - throw Errors.unexpectedPbxProj() - } - - return lName.compare(rName, options: .caseInsensitive) == .orderedAscending - }) - } catch { - print("Unable to sort as Xcode 16 do: \(error)") - // actually we could do even fatalError here - // but it could be too brave for common repository - // fatalError("\(error)") - } + /// The project references are sorted alphabetically based on the name of the project it's being referenced. + project.projectReferences = project.projectReferences.sorted(by: { lhs, rhs in + let lProjectRef = lhs["ProjectRef"]! + let lFile: PBXFileElement = lProjectRef.getObject()! + let rProjectRef = rhs["ProjectRef"]! + let rFile: PBXFileElement = rProjectRef.getObject()! + let lName = lFile.name! + let rName = rFile.name! + return lName.compare(rName, options: .caseInsensitive) == .orderedAscending + }) } } } - -private enum Errors: Error { - case unexpectedPbxProj(_ id: Int = #line) -} diff --git a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift index 482bf8cce..fe3b9e54b 100644 --- a/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift +++ b/Tests/XcodeProjTests/Objects/Project/PBXProjEncoderTests.swift @@ -328,6 +328,8 @@ class PBXProjEncoderTests: XCTestCase { line = lines.validate(line: "/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */", after: line) } + // MARK: - Projects + // MARK: - Build phases func test_build_phase_sources_unsorted_when_iOSProject() throws {