diff --git a/Sources/XcodeProj/Utils/ReferenceGenerator.swift b/Sources/XcodeProj/Utils/ReferenceGenerator.swift index a098c829..01f0267e 100644 --- a/Sources/XcodeProj/Utils/ReferenceGenerator.swift +++ b/Sources/XcodeProj/Utils/ReferenceGenerator.swift @@ -139,6 +139,8 @@ final class ReferenceGenerator: ReferenceGenerating { guard let childFileElement: PBXFileElement = child.getObject() else { return } if let childGroup = childFileElement as? PBXGroup { try generateGroupReferences(childGroup, identifiers: identifiers) + } else if let childSynchronizedRootGroup = childFileElement as? PBXFileSystemSynchronizedRootGroup { + try generateSynchronizedRootGroupReferences(childSynchronizedRootGroup, identifiers: identifiers) } else if let childFileReference = childFileElement as? PBXFileReference { try generateFileReference(childFileReference, identifiers: identifiers) } else if let childReferenceProxy = childFileElement as? PBXReferenceProxy { @@ -161,6 +163,21 @@ final class ReferenceGenerator: ReferenceGenerating { fixReference(for: fileReference, identifiers: identifiers) } + /// Generates the reference for a synchronized root group object. + /// + /// - Parameters: + /// - synchronizedRootGroup: synchronized root group instance. + /// - identifiers: list of identifiers. + private func generateSynchronizedRootGroupReferences(_ synchronizedRootGroup: PBXFileSystemSynchronizedRootGroup, + identifiers: [String]) throws { + var identifiers = identifiers + if let groupName = synchronizedRootGroup.fileName() { + identifiers.append(groupName) + } + + fixReference(for: synchronizedRootGroup, identifiers: identifiers) + } + /// Generates the reference for a configuration list object. /// /// - Parameters: diff --git a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift index 6df8959c..af3a2f1b 100644 --- a/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift +++ b/Tests/XcodeProjTests/Utils/ReferenceGeneratorTests.swift @@ -83,6 +83,21 @@ class ReferenceGeneratorTests: XCTestCase { XCTAssertNotEqual(firstProductsGroupUUID, secondProductsGroupUUID) } + + func test_projectWithFilesystemSynchronizedRootGroup_convertsReferencesToPermanent() throws { + let project = PBXProj(rootObject: nil, objectVersion: 0, archiveVersion: 0, classes: [:], objects: []) + let pbxProject = project.makeProject() + + let syncedGroup = project.makeSynchronizedRootGroup() + let target = project.makeTarget() + target.fileSystemSynchronizedGroups = [syncedGroup] + pbxProject.targets.append(target) + + let referenceGenerator = ReferenceGenerator(outputSettings: PBXOutputSettings()) + try referenceGenerator.generateReferences(proj: project) + + XCTAssert(!syncedGroup.reference.temporary) + } } private extension PBXProj { @@ -168,4 +183,23 @@ private extension PBXProj { return (target, buildFile) } + + func makeTarget() -> PBXTarget { + let target = PBXNativeTarget(name: "MyApp", + productName: "MyApp.app", + productType: .application) + add(object: target) + return target + } + + func makeSynchronizedRootGroup() -> PBXFileSystemSynchronizedRootGroup { + let syncedGroup = PBXFileSystemSynchronizedRootGroup( + sourceTree: .group, + path: "SyncedPath", + name: "SyncedGroup" + ) + add(object: syncedGroup) + rootObject!.mainGroup.children.append(syncedGroup) + return syncedGroup + } }