Skip to content

Commit 7f1fefa

Browse files
committed
Fix configFiles creating duplicate group inside synced folder
When configFiles reference paths inside a synced folder source, getContainedFileReference() created a separate PBXGroup hierarchy that duplicated the PBXFileSystemSynchronizedRootGroup already managing those files. Skip group creation in getContainedFileReference when the file path falls inside an existing synced folder root. Fixes the same class of issue as #1602, but for configFiles rather than target sources.
1 parent acd366f commit 7f1fefa

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

Sources/XcodeGenKit/SourceGenerator.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ class SourceGenerator {
201201

202202
let parentPath = path.parent()
203203
let fileReference = getFileReference(path: path, inPath: parentPath)
204+
205+
guard !isInsideSyncedFolder(path: path) else {
206+
return fileReference
207+
}
208+
204209
let parentGroup = getGroup(
205210
path: parentPath,
206211
mergingChildren: [fileReference],
@@ -277,6 +282,19 @@ class SourceGenerator {
277282
}
278283
}
279284

285+
/// Whether the given path falls inside a target source configured as a synced folder.
286+
/// Checks the project spec directly because configFiles are resolved before target sources
287+
/// populate `syncedGroupsByPath`.
288+
private func isInsideSyncedFolder(path: Path) -> Bool {
289+
let relativePath = (try? path.relativePath(from: project.basePath)) ?? path
290+
return project.targets.contains { target in
291+
target.sources.contains { source in
292+
let resolvedType = source.type ?? (project.options.defaultSourceDirectoryType ?? .group)
293+
return resolvedType == .syncedFolder && relativePath.string.hasPrefix(source.path + "/")
294+
}
295+
}
296+
}
297+
280298
/// returns a default build phase for a given path. This is based off the filename
281299
private func getDefaultBuildPhase(for path: Path, targetType: PBXProductType) -> BuildPhaseSpec? {
282300
if let buildPhase = getFileType(path: path)?.buildPhase {

Tests/XcodeGenKitTests/SourceGeneratorTests.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,34 @@ class SourceGeneratorTests: XCTestCase {
491491
try expect(appGroup === testsGroup) == true
492492
}
493493

494+
$0.it("does not create duplicate group for configFiles inside synced folder") {
495+
let directories = """
496+
Sources:
497+
- a.swift
498+
- Config:
499+
- config.xcconfig
500+
"""
501+
try createDirectories(directories)
502+
503+
let source = TargetSource(path: "Sources", type: .syncedFolder)
504+
let target = Target(name: "Target1", type: .application, platform: .iOS, sources: [source])
505+
let project = Project(
506+
basePath: directoryPath,
507+
name: "Test",
508+
targets: [target],
509+
configFiles: ["Debug": "Sources/Config/config.xcconfig"]
510+
)
511+
512+
let pbxProj = try project.generatePbxProj()
513+
let mainGroup = try pbxProj.getMainGroup()
514+
515+
let sourcesChildren = mainGroup.children.filter { $0.path == "Sources" || $0.name == "Sources" }
516+
try expect(sourcesChildren.count) == 1
517+
518+
let syncedFolders = mainGroup.children.compactMap { $0 as? PBXFileSystemSynchronizedRootGroup }
519+
try expect(syncedFolders.count) == 1
520+
}
521+
494522
$0.it("supports frameworks in sources") {
495523
let directories = """
496524
Sources:

0 commit comments

Comments
 (0)