Skip to content

Commit 4e6dc94

Browse files
WITExtractor: Fix Swift 6.0 compatibility
1 parent 4ade281 commit 4e6dc94

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

Plugins/WITExtractorPlugin/Plugin.swift

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ struct Plugin: CommandPlugin {
4848
"--package-name", context.package.displayName,
4949
"--wit-output-path", witOutputPath.string,
5050
"--swift-output-path", swiftOutputPath.string,
51-
"-I", buildPath.string
51+
"-I", buildPath.string,
52+
// SwiftPM 6.0 and later emits swiftmodule files into a separate directory
53+
// https://github.com/swiftlang/swift-package-manager/pull/7212
54+
"-I", buildPath.appending(["Modules"]).string,
5255
]
5356
if let sdk {
5457
arguments += ["-sdk", sdk]
@@ -74,12 +77,28 @@ struct Plugin: CommandPlugin {
7477
return nil
7578
}
7679
for line in contents.split(separator: "\n") {
77-
let prefix = " executable: \""
78-
if line.hasPrefix(prefix), line.hasSuffix("/swiftc\"") {
79-
let pathStart = line.index(line.startIndex, offsetBy: prefix.count)
80-
let pathEnd = line.index(before: line.endIndex)
81-
let executablePath = line[pathStart..<pathEnd]
82-
return String(executablePath)
80+
do {
81+
let prefix = " executable: \""
82+
if line.hasPrefix(prefix), line.hasSuffix("/swiftc\"") {
83+
let pathStart = line.index(line.startIndex, offsetBy: prefix.count)
84+
let pathEnd = line.index(before: line.endIndex)
85+
let executablePath = line[pathStart..<pathEnd]
86+
return String(executablePath)
87+
}
88+
}
89+
do {
90+
// Swift 6.0 no longer uses llbuild's built-in swift tool. Instead,
91+
// it uses the generic shell tool with full arguments.
92+
// https://github.com/swiftlang/swift-package-manager/pull/6585
93+
let prefix = " args: "
94+
if line.hasPrefix(prefix) {
95+
let argsString = line[line.index(line.startIndex, offsetBy: prefix.count)...]
96+
guard let args = try? JSONDecoder().decode([String].self, from: Data(argsString.utf8)),
97+
let swiftc = args.first(where: { $0.hasSuffix("/swiftc") }) else {
98+
continue
99+
}
100+
return swiftc
101+
}
83102
}
84103
}
85104
return nil

Sources/WITExtractor/SwiftAPIDigester.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,15 @@ struct SwiftAPIDigester {
138138
throw SwiftAPIDigesterError.unexpectedEmptyOutput
139139
}
140140
process.waitUntilExit()
141+
guard process.terminationStatus == 0 else {
142+
throw SwiftAPIDigesterError.nonZeroExitCode(process.terminationStatus, arguments: args)
143+
}
141144
return try Output.parse(output)
142145
#endif
143146
}
144147
}
145148

146149
enum SwiftAPIDigesterError: Error {
147150
case unexpectedEmptyOutput
151+
case nonZeroExitCode(Int32, arguments: [String])
148152
}

Tests/WITExtractorPluginTests/PluginSmokeTests.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import XCTest
22

33
class PluginSmokeTests: XCTestCase {
44
func testExtractPlugin() throws {
5-
#if compiler(>=6.0)
6-
throw XCTSkip("XFAIL: Swift compiler path inference is broken in Swift 6.0")
7-
#endif
85
guard ProcessInfo.processInfo.environment["__XCODE_BUILT_PRODUCTS_DIR_PATHS"] == nil else {
96
throw XCTSkip(
107
"\"swift package resolve\" somehow fails to clone git repository only when invoking from Xcode test runner"

0 commit comments

Comments
 (0)