Skip to content

Commit f500186

Browse files
committed
Normalize discovered inputs to copy tasks via source symlink
1 parent 6731317 commit f500186

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

Sources/SWBTaskExecution/TaskActions/FileCopyTaskAction.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public final class FileCopyTaskAction: TaskAction
8080
if !symlinkDestinationPath.isAbsolute {
8181
symlinkDestinationPath = inputPath.dirname.join(symlinkDestinationPath)
8282
}
83+
symlinkDestinationPath = symlinkDestinationPath.normalize()
8384
dynamicExecutionDelegate.discoveredDependencyDirectoryTree(symlinkDestinationPath)
8485
}
8586
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Testing
14+
15+
import SWBBuildSystem
16+
import SWBCore
17+
import SWBUtil
18+
import SWBTestSupport
19+
import SwiftBuildTestSupport
20+
21+
@Suite
22+
fileprivate struct CopyTests: CoreBasedTests {
23+
@Test(.requireSDKs(.host), .skipHostOS(.windows))
24+
func copySymlinkedDirectoryTree() async throws {
25+
try await withTemporaryDirectory { tmpDirPath async throws -> Void in
26+
let testWorkspace = TestWorkspace(
27+
"Test",
28+
sourceRoot: tmpDirPath.join("Test"),
29+
projects: [
30+
TestProject(
31+
"aProject",
32+
groupTree: TestGroup("Sources", children: [
33+
TestFile("MyDirectory"),
34+
]),
35+
buildConfigurations: [TestBuildConfiguration(
36+
"Debug",
37+
buildSettings: ["PRODUCT_NAME": "$(TARGET_NAME)"])],
38+
targets: [
39+
TestAggregateTarget(
40+
"Empty",
41+
buildConfigurations: [TestBuildConfiguration("Debug")],
42+
buildPhases: [
43+
TestCopyFilesBuildPhase([TestBuildFile("MyDirectory")], destinationSubfolder: .absolute, destinationSubpath: tmpDirPath.join("out").str, onlyForDeployment: false),
44+
TestShellScriptBuildPhase(name: "", originalObjectID: "", inputs: [tmpDirPath.join("out").join("MyDirectory").str], outputs: [tmpDirPath.join("out2").str])
45+
])])])
46+
let tester = try await BuildOperationTester(getCore(), testWorkspace, simulated: false)
47+
let SRCROOT = testWorkspace.sourceRoot.join("aProject")
48+
49+
try tester.fs.createDirectory(SRCROOT, recursive: true)
50+
try tester.fs.createDirectory(SRCROOT.join("MyOtherDirectory"))
51+
try tester.fs.write(SRCROOT.join("MyOtherDirectory").join("file.txt"), contents: "Foo")
52+
try tester.fs.symlink(SRCROOT.join("MyDirectory"), target: Path("MyDirectory").join("file.txt").join("..").join("..").join("MyOtherDirectory"))
53+
54+
try await tester.checkBuild(parameters: BuildParameters(configuration: "Debug"), runDestination: .host) { results in
55+
results.checkNoDiagnostics()
56+
try #expect(tester.fs.listdir(tmpDirPath.join("out").join("MyDirectory")) == ["file.txt"])
57+
}
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)