Skip to content

Commit b501e10

Browse files
committed
Use a different path extension for swift-testing builds.
Currently, SwiftPM is using the same path to build swift-testing and XCTest content. This works about 90% of the time because we only need one or the other at any given moment, but it causes some workflows to fail on Linux because the build system sees the existing build product and assumes the build has already completed, which is incorrect. Darwin doesn't seem to be affected (because the XCTest build product is a bundle rather than an executable.) This PR selects a different path extension, ".swift-testing", for swift-testing's build product.
1 parent a4eda63 commit b501e10

File tree

6 files changed

+36
-20
lines changed

6 files changed

+36
-20
lines changed

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,8 @@ public struct BuildDescription: Codable {
393393
return try BuiltTestProduct(
394394
productName: desc.product.name,
395395
binaryPath: desc.binaryPath,
396-
packagePath: desc.package.path
396+
packagePath: desc.package.path,
397+
library: desc.buildParameters.testingParameters.library
397398
)
398399
}
399400
self.pluginDescriptions = pluginDescriptions

Sources/SPMBuildCore/BuildParameters/BuildParameters.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,16 @@ public struct BuildParameters: Encodable {
286286
guard !targetTriple.isWASI() else {
287287
return try RelativePath(validating: "\(product.name).wasm")
288288
}
289-
290-
let base = "\(product.name).xctest"
291-
if targetTriple.isDarwin() {
292-
return try RelativePath(validating: "\(base)/Contents/MacOS/\(product.name)")
293-
} else {
294-
return try RelativePath(validating: base)
289+
switch testingParameters.library {
290+
case .xctest:
291+
let base = "\(product.name).xctest"
292+
if targetTriple.isDarwin() {
293+
return try RelativePath(validating: "\(base)/Contents/MacOS/\(product.name)")
294+
} else {
295+
return try RelativePath(validating: base)
296+
}
297+
case .swiftTesting:
298+
return try RelativePath(validating: "\(product.name).swift-testing")
295299
}
296300
case .macro:
297301
#if BUILD_MACROS_AS_DYLIBS

Sources/SPMBuildCore/BuiltTestProduct.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,39 @@ public struct BuiltTestProduct: Codable {
2424
public let packagePath: AbsolutePath
2525

2626
/// The path of the test bundle.
27+
///
28+
/// When the test product is not bundled (for instance, when using XCTest on
29+
/// non-Darwin targets), this path is equal to ``binaryPath``.
2730
public var bundlePath: AbsolutePath {
28-
// Go up the folder hierarchy until we find the .xctest bundle.
31+
// Go up the folder hierarchy until we find the .xctest or
32+
// .swift-testing bundle.
33+
let pathExtension: String
34+
switch library {
35+
case .xctest:
36+
pathExtension = ".xctest"
37+
case .swiftTesting:
38+
pathExtension = ".swift-testing"
39+
}
2940
let hierarchySequence = sequence(first: binaryPath, next: { $0.isRoot ? nil : $0.parentDirectory })
30-
guard let bundlePath = hierarchySequence.first(where: { $0.basename.hasSuffix(".xctest") }) else {
41+
guard let bundlePath = hierarchySequence.first(where: { $0.basename.hasSuffix(pathExtension) }) else {
3142
fatalError("could not find test bundle path from '\(binaryPath)'")
3243
}
3344

3445
return bundlePath
3546
}
3647

48+
/// The library used to build this test product.
49+
public var library: BuildParameters.Testing.Library
50+
3751
/// Creates a new instance.
3852
/// - Parameters:
3953
/// - productName: The test product name.
4054
/// - binaryPath: The path of the test binary.
4155
/// - packagePath: The path to the package this product was declared in.
42-
public init(productName: String, binaryPath: AbsolutePath, packagePath: AbsolutePath) {
56+
public init(productName: String, binaryPath: AbsolutePath, packagePath: AbsolutePath, library: BuildParameters.Testing.Library) {
4357
self.productName = productName
4458
self.binaryPath = binaryPath
4559
self.packagePath = packagePath
60+
self.library = library
4661
}
4762
}

Sources/SPMTestSupport/SwiftPMProduct.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,7 @@ extension SwiftPM {
4444
}
4545
}
4646

47-
/// Path to currently built binary.
48-
public var path: AbsolutePath {
49-
return Self.testBinaryPath(for: self.executableName)
50-
}
51-
52-
public static func testBinaryPath(for executableName: RelativePath) -> AbsolutePath {
47+
public static func xctestBinaryPath(for executableName: RelativePath) -> AbsolutePath {
5348
#if canImport(Darwin)
5449
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
5550
return try! AbsolutePath(AbsolutePath(validating: bundle.bundlePath).parentDirectory, executableName)
@@ -114,15 +109,15 @@ extension SwiftPM {
114109
#endif
115110
// FIXME: We use this private environment variable hack to be able to
116111
// create special conditions in swift-build for swiftpm tests.
117-
environment["SWIFTPM_TESTS_MODULECACHE"] = self.path.parentDirectory.pathString
112+
environment["SWIFTPM_TESTS_MODULECACHE"] = Self.xctestBinaryPath(for: executableName).parentDirectory.pathString
118113
#if !os(Windows)
119114
environment["SDKROOT"] = nil
120115
#endif
121116

122117
// Unset the internal env variable that allows skipping certain tests.
123118
environment["_SWIFTPM_SKIP_TESTS_LIST"] = nil
124119

125-
var completeArgs = [self.path.pathString]
120+
var completeArgs = [Self.xctestBinaryPath(for: executableName).pathString]
126121
if let packagePath = packagePath {
127122
completeArgs += ["--package-path", packagePath.pathString]
128123
}

Sources/XCBuildSupport/XcodeBuildSystem.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem {
5656
BuiltTestProduct(
5757
productName: product.name,
5858
binaryPath: binaryPath,
59-
packagePath: package.path
59+
packagePath: package.path,
60+
library: buildParameters.testingParameters.library
6061
)
6162
)
6263
}

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ final class BuildToolTests: CommandsTestCase {
506506
return buildArenaPath.appending(component: filename)
507507
}
508508

509-
let dummySwiftcPath = SwiftPM.testBinaryPath(for: "dummy-swiftc")
509+
let dummySwiftcPath = SwiftPM.xctestBinaryPath(for: "dummy-swiftc")
510510
let swiftCompilerPath = try UserToolchain.default.swiftCompilerPath
511511

512512
var environment = [

0 commit comments

Comments
 (0)