Skip to content

Commit e00c1f5

Browse files
authored
Swiftly-Use: JSON: Handle no selected toolchain (#546)
Uninstalling all of the tools in Swiftly and printing the current toolchain with `swiftly use --format=json` results in swiftly printing nothing. This is invalid JSON, so tools like the VSCode extension would emit an error. Without the fix, the empty JSON passed to the Foundation JSON decoder emits the following error: ``` Caught error: Error Domain=NSCocoaErrorDomain Code=3840 "Unable to parse empty data." UserInfo={NSDebugDescription=Unable to parse empty data.} ``` Fixes: #545
1 parent d166ae1 commit e00c1f5

3 files changed

Lines changed: 19 additions & 0 deletions

File tree

Sources/Swiftly/OutputSchema.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import Foundation
22
import SwiftlyCore
33

4+
struct EmptyObject: OutputData {
5+
var description: String { "" }
6+
}
7+
48
struct LocationInfo: OutputData {
59
let path: String
610

Sources/Swiftly/Use.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct Use: SwiftlyCommand {
8989

9090
guard let selectedVersion else {
9191
// Return with nothing if there's no toolchain that is selected
92+
try await ctx.output(EmptyObject())
9293
return
9394
}
9495

Tests/SwiftlyTests/UseTests.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,20 @@ import Testing
351351
}
352352
}
353353

354+
/// Tests that `swiftly use --format=json` emits a valid empty JSON object when no toolchain is selected.
355+
@Test(.mockedSwiftlyVersion(), .mockHomeToolchains(toolchains: []))
356+
func printInUseJsonFormatNoSelection() async throws {
357+
let output = try await SwiftlyTests.runWithMockedIO(
358+
Use.self, ["use", "--format", "json"], format: .json
359+
)
360+
361+
let joined = output.joined(separator: "\n")
362+
let data = try #require(joined.data(using: .utf8))
363+
let json = try JSONSerialization.jsonObject(with: data)
364+
let object = try #require(json as? [String: Any])
365+
#expect(object.isEmpty)
366+
}
367+
354368
/// Tests that running a use command without an argument prints the currently in-use toolchain.
355369
@Test(.mockedSwiftlyVersion()) func printInUseJsonFormat() async throws {
356370
let toolchains = [

0 commit comments

Comments
 (0)