From f71ac440accc4868978642c9afbc5fe24728ea90 Mon Sep 17 00:00:00 2001 From: Ruslan Silimir Date: Sun, 1 Feb 2026 19:46:09 -0800 Subject: [PATCH 1/2] Fix missing productRefGroup in generated projects --- Sources/XcodeGenKit/PBXProjGenerator.swift | 1 + .../Project.xcodeproj/project.pbxproj | 1 + .../SPM/SPM.xcodeproj/project.pbxproj | 1 + .../AnotherProject.xcodeproj/project.pbxproj | 1 + .../Project.xcodeproj/project.pbxproj | 1 + .../TestProject.xcodeproj/project.pbxproj | 1 + .../PBXProjGeneratorTests.swift | 51 +++++++++++++++++++ 7 files changed, 57 insertions(+) diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 8dcad5afb..256ac5e12 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -190,6 +190,7 @@ public class PBXProjGenerator { ) ) derivedGroups.append(productGroup) + pbxProject.productsGroup = productGroup let sortedProjectReferences = project.projectReferences.sorted { $0.name < $1.name } let subprojectFileReferences: [PBXFileReference] = sortedProjectReferences.map { projectReference in diff --git a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj index 5b62b8139..85329cbd9 100644 --- a/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/CarthageProject/Project.xcodeproj/project.pbxproj @@ -334,6 +334,7 @@ mainGroup = 293D0FF827366B513839236A; minimizedProjectReferenceProxies = 1; preferredProjectObjectVersion = 77; + productRefGroup = AC523591AC7BE9275003D2DB /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj index eef5a9d73..107d5ccb4 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/project.pbxproj @@ -262,6 +262,7 @@ C6539B364583AE96C18CE377 /* XCLocalSwiftPackageReference "../../.." */, ); preferredProjectObjectVersion = 77; + productRefGroup = 5D68FDDE55EE935627A1B376 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( diff --git a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj index 00cc84622..d589aabbb 100644 --- a/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/AnotherProject/AnotherProject.xcodeproj/project.pbxproj @@ -131,6 +131,7 @@ mainGroup = 4E8CFA4275C972686621210C; minimizedProjectReferenceProxies = 1; preferredProjectObjectVersion = 77; + productRefGroup = 6BB7980FAF18A93459B051A1 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index 6aa8bed91..6fd1e9ed9 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -2460,6 +2460,7 @@ 4EDA79334592CBBA0E507AD2 /* XCRemoteSwiftPackageReference "Swinject" */, ); preferredProjectObjectVersion = 77; + productRefGroup = AC523591AC7BE9275003D2DB /* Products */; projectDirPath = ""; projectReferences = ( { diff --git a/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj b/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj index baed78ca9..85e0a4479 100644 --- a/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/scheme_test/TestProject.xcodeproj/project.pbxproj @@ -84,6 +84,7 @@ mainGroup = 2D08B11F4EE060D112B7BCA1; minimizedProjectReferenceProxies = 1; preferredProjectObjectVersion = 77; + productRefGroup = 5B8D13EAC88739DF2D92F8AE /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( diff --git a/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift b/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift index 31873cdcf..5e3ea0071 100644 --- a/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/PBXProjGeneratorTests.swift @@ -391,6 +391,57 @@ class PBXProjGeneratorTests: XCTestCase { } } + func testProductsGroupIsSet() throws { + let target = Target(name: "TestApp", type: .application, platform: .iOS) + let project = Project(name: "Test", targets: [target]) + let projGenerator = PBXProjGenerator(project: project) + + let pbxProj = try projGenerator.generate() + + let pbxProject = try XCTUnwrap(pbxProj.projects.first) + let productsGroup = try XCTUnwrap(pbxProject.productsGroup) + + XCTAssertEqual(productsGroup.name, "Products") + XCTAssertEqual(productsGroup.children.count, 1) + + let productReference = try XCTUnwrap(productsGroup.children.first as? PBXFileReference) + XCTAssertEqual(productReference.path, "TestApp.app") + } + + func testProductsGroupIsSetWithMultipleTargets() throws { + let appTarget = Target(name: "TestApp", type: .application, platform: .iOS) + let frameworkTarget = Target(name: "TestFramework", type: .framework, platform: .iOS) + let project = Project(name: "Test", targets: [appTarget, frameworkTarget]) + let projGenerator = PBXProjGenerator(project: project) + + let pbxProj = try projGenerator.generate() + + let pbxProject = try XCTUnwrap(pbxProj.projects.first) + let productsGroup = try XCTUnwrap(pbxProject.productsGroup) + + XCTAssertEqual(productsGroup.name, "Products") + XCTAssertEqual(productsGroup.children.count, 2) + + let productNames = productsGroup.children + .compactMap { $0 as? PBXFileReference } + .compactMap { $0.path } + .sorted() + XCTAssertEqual(productNames, ["TestApp.app", "TestFramework.framework"]) + } + + func testProductsGroupIsSetWithNoTargets() throws { + let project = Project(name: "Test") + let projGenerator = PBXProjGenerator(project: project) + + let pbxProj = try projGenerator.generate() + + let pbxProject = try XCTUnwrap(pbxProj.projects.first) + let productsGroup = try XCTUnwrap(pbxProject.productsGroup) + + XCTAssertEqual(productsGroup.name, "Products") + XCTAssertEqual(productsGroup.children.count, 0) + } + func testPlatformDependencies() { describe { let directoryPath = Path("TestDirectory") From 33382748078d227117743e124ead2388c30ef140 Mon Sep 17 00:00:00 2001 From: Ruslan Silimir Date: Sun, 1 Feb 2026 19:51:57 -0800 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc18bf44d..339d4301c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next Version +### Fixed +- Fix missing productRefGroup in generated projects #1591 @ruslic19 + ## 2.44.1 ### Fixed