Skip to content

Commit d265d90

Browse files
committed
SwiftPM outputs raw diagnostics from SwiftDriver without trailing newlines
SwiftPM uses the Swift Driver's `-parseable-output` flag to get a sequence of length-prefixed JSON-encoded messages that it can read. Unfortunately the Swift Driver doesn't JSON-encode its own diagnostics, leading to things like #5968. I filed #5968 on the Swift Driver to get it to encode its JSON messages, but meanwhile, it turns out that we can fairly easily fix the fallback logic that SwiftPM uses when it emits raw output. It was simply missing a newline. It's safe to always add a newline to the raw driver output, since the logic that parses JSON splits by newlines, so we won't find any terminating newlines that shouldn't be on the string. Note that we do not add newlines to the output coming from messages from the compiler frontend, since that output already has trailing newlines. So in essence this change makes the `.unparsableOutput()` case the same as the cases of regular output, from a newline perspective. rdar://103608636
1 parent 6b477d9 commit d265d90

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

Diff for: Sources/Build/SwiftCompilerOutputParser.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ extension SwiftCompilerOutputParser: JSONMessageStreamingParserDelegate {
162162
return
163163
}
164164

165-
let message = SwiftCompilerMessage(name: "unknown", kind: .unparsableOutput(text))
165+
let message = SwiftCompilerMessage(name: "unknown", kind: .unparsableOutput(text + "\n"))
166166
delegate?.swiftCompilerOutputParser(self, didParse: message)
167167
}
168168

Diff for: Tests/BuildTests/SwiftCompilerOutputParserTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ class SwiftCompilerOutputParserTests: XCTestCase {
156156
157157
""".utf8)
158158
delegate.assert(messages: [
159-
SwiftCompilerMessage(name: "unknown", kind: .unparsableOutput("2A"))
159+
SwiftCompilerMessage(name: "unknown", kind: .unparsableOutput("2A\n"))
160160
], errorDescription: nil)
161161

162162
parser.parse(bytes: """

Diff for: Tests/CommandsTests/BuildToolTests.swift

+12
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,16 @@ final class BuildToolTests: CommandsTestCase {
390390
XCTAssertMatch(output, .prefix("digraph Jobs {"))
391391
}
392392
}
393+
394+
func testSwiftDriverRawOutputGetsNewlines() throws {
395+
try fixture(name: "DependencyResolution/Internal/Simple") { fixturePath in
396+
// Building with `-wmo` should result in a `remark: Incremental compilation has been disabled: it is not compatible with whole module optimization` message, which should have a trailing newline. Since that message won't be there at all when the legacy compiler driver is used, we gate this check on whether the remark is there in the first place.
397+
let result = try execute(["-c", "release", "-Xswiftc", "-wmo"], packagePath: fixturePath)
398+
if result.stdout.contains("remark: Incremental compilation has been disabled: it is not compatible with whole module optimization") {
399+
XCTAssertMatch(result.stdout, .contains("optimization\n"))
400+
XCTAssertNoMatch(result.stdout, .contains("optimization["))
401+
XCTAssertNoMatch(result.stdout, .contains("optimizationremark"))
402+
}
403+
}
404+
}
393405
}

0 commit comments

Comments
 (0)