Skip to content

Commit 3ada49c

Browse files
committed
Adjust error messages
Add test cases Control verbosity of uninstall operation on macOS and other platforms
1 parent df026d6 commit 3ada49c

File tree

10 files changed

+62
-16
lines changed

10 files changed

+62
-16
lines changed

Sources/LinuxPlatform/Linux.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public struct Linux: Platform {
376376
try self.runProgram(tmpDir.appendingPathComponent("swiftly").path, "init")
377377
}
378378

379-
public func uninstall(_ toolchain: ToolchainVersion) throws {
379+
public func uninstall(_ toolchain: ToolchainVersion, verbose _: Bool) throws {
380380
let toolchainDir = self.swiftlyToolchainsDir.appendingPathComponent(toolchain.name)
381381
try FileManager.default.removeItem(at: toolchainDir)
382382
}

Sources/MacOSPlatform/MacOS.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public struct MacOS: Platform {
120120
try self.runProgram(homeDir.appendingPathComponent("usr/local/bin/swiftly").path, "init")
121121
}
122122

123-
public func uninstall(_ toolchain: ToolchainVersion) throws {
123+
public func uninstall(_ toolchain: ToolchainVersion, verbose: Bool) throws {
124124
SwiftlyCore.print("Uninstalling package in user home directory...")
125125

126126
let toolchainDir = self.swiftlyToolchainsDir.appendingPathComponent("\(toolchain.identifier).xctoolchain", isDirectory: true)
@@ -138,7 +138,7 @@ public struct MacOS: Platform {
138138
try FileManager.default.removeItem(at: toolchainDir)
139139

140140
let homedir = ProcessInfo.processInfo.environment["HOME"]!
141-
try? runProgram("pkgutil", "--volume", homedir, "--forget", pkgInfo.CFBundleIdentifier)
141+
try? runProgram("pkgutil", "--volume", homedir, "--forget", pkgInfo.CFBundleIdentifier, quiet: !verbose)
142142
}
143143

144144
public func getExecutableName() -> String {

Sources/Swiftly/Proxy.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public enum Proxy {
5353
}
5454

5555
guard let toolchain = toolchain else {
56-
throw SwiftlyError(message: "No swift toolchain could be selected from either from a .swift-version file, or the default. You can try using `swiftly install <toolchain version>` to install one.")
56+
throw SwiftlyError(message: "No installed swift toolchain is selected from either from a .swift-version file, or the default. You can try using one that's already installed with `swiftly use <toolchain version>` or install a new toolchain to use with `swiftly install --use <toolchain version>`.")
5757
}
5858

5959
// Prevent circularities with a memento environment variable

Sources/Swiftly/Run.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ internal struct Run: SwiftlyCommand {
8686
}
8787

8888
guard let toolchain = toolchain else {
89-
throw SwiftlyError(message: "No swift toolchain could be selected from either from a .swift-version file, or the default. You can try using `swiftly install <toolchain version>` to install one.")
89+
throw SwiftlyError(message: "No installed swift toolchain is selected from either from a .swift-version file, or the default. You can try using one that's already installed with `swiftly use <toolchain version>` or install a new toolchain to use with `swiftly install --use <toolchain version>`.")
9090
}
9191

9292
do {

Sources/Swiftly/Uninstall.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,14 @@ struct Uninstall: SwiftlyCommand {
113113
}
114114
}
115115

116-
try await Self.execute(toolchain, &config)
116+
try await Self.execute(toolchain, &config, verbose: self.root.verbose)
117117
}
118118

119119
SwiftlyCore.print()
120120
SwiftlyCore.print("\(toolchains.count) toolchain(s) successfully uninstalled")
121121
}
122122

123-
static func execute(_ toolchain: ToolchainVersion, _ config: inout Config) async throws {
123+
static func execute(_ toolchain: ToolchainVersion, _ config: inout Config, verbose: Bool) async throws {
124124
SwiftlyCore.print("Uninstalling \(toolchain)...", terminator: "")
125125
config.installedToolchains.remove(toolchain)
126126
// This is here to prevent the inUse from referencing a toolchain that is not installed
@@ -129,7 +129,7 @@ struct Uninstall: SwiftlyCommand {
129129
}
130130
try config.save()
131131

132-
try Swiftly.currentPlatform.uninstall(toolchain)
132+
try Swiftly.currentPlatform.uninstall(toolchain, verbose: verbose)
133133
SwiftlyCore.print("done")
134134
}
135135
}

Sources/Swiftly/Update.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct Update: SwiftlyCommand {
117117
assumeYes: self.root.assumeYes
118118
)
119119

120-
try await Uninstall.execute(parameters.oldToolchain, &config)
120+
try await Uninstall.execute(parameters.oldToolchain, &config, verbose: self.root.verbose)
121121
SwiftlyCore.print("Successfully updated \(parameters.oldToolchain)\(newToolchain)")
122122

123123
if let postInstallScript = postInstallScript {

Sources/SwiftlyCore/Platform.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public protocol Platform {
7272

7373
/// Uninstalls a toolchain associated with the given version.
7474
/// If this version is in use, the next latest version will be used afterwards.
75-
func uninstall(_ version: ToolchainVersion) throws
75+
func uninstall(_ version: ToolchainVersion, verbose: Bool) throws
7676

7777
/// Get the name of the swiftly release binary.
7878
func getExecutableName() -> String

Tests/SwiftlyTests/PlatformTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,21 @@ final class PlatformTests: SwiftlyTests {
5353
(mockedToolchainFile, version) = try await self.mockToolchainDownload(version: "5.6.3")
5454
try Swiftly.currentPlatform.install(from: mockedToolchainFile, version: version, verbose: true)
5555
// WHEN: one of the toolchains is uninstalled
56-
try Swiftly.currentPlatform.uninstall(version)
56+
try Swiftly.currentPlatform.uninstall(version, verbose: true)
5757
// THEN: there is only one remaining toolchain installed
5858
var toolchains = try FileManager.default.contentsOfDirectory(at: Swiftly.currentPlatform.swiftlyToolchainsDir, includingPropertiesForKeys: nil)
5959
XCTAssertEqual(1, toolchains.count)
6060

6161
// GIVEN; there is only one toolchain installed
6262
// WHEN: a non-existent toolchain is uninstalled
63-
try? Swiftly.currentPlatform.uninstall(ToolchainVersion(parsing: "5.9.1"))
63+
try? Swiftly.currentPlatform.uninstall(ToolchainVersion(parsing: "5.9.1"), verbose: true)
6464
// THEN: there is the one remaining toolchain that is still installed
6565
toolchains = try FileManager.default.contentsOfDirectory(at: Swiftly.currentPlatform.swiftlyToolchainsDir, includingPropertiesForKeys: nil)
6666
XCTAssertEqual(1, toolchains.count)
6767

6868
// GIVEN: there is only one toolchain installed
6969
// WHEN: the last toolchain is uninstalled
70-
try Swiftly.currentPlatform.uninstall(ToolchainVersion(parsing: "5.8.0"))
70+
try Swiftly.currentPlatform.uninstall(ToolchainVersion(parsing: "5.8.0"), verbose: true)
7171
// THEN: there are no toolchains installed
7272
toolchains = try FileManager.default.contentsOfDirectory(at: Swiftly.currentPlatform.swiftlyToolchainsDir, includingPropertiesForKeys: nil)
7373
XCTAssertEqual(0, toolchains.count)

Tests/SwiftlyTests/UninstallTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,22 @@ final class UninstallTests: SwiftlyTests {
296296
)
297297
}
298298
}
299+
300+
/// Tests that uninstalling a toolchain that is the global default, but is not in the list of installed toolchains.
301+
func testUninstallNotInstalled() async throws {
302+
let toolchains = Set([Self.oldStable, Self.newStable, Self.newMainSnapshot, Self.oldReleaseSnapshot])
303+
try await self.withMockedHome(homeName: Self.homeName, toolchains: toolchains, inUse: Self.newMainSnapshot) {
304+
var config = try await Config.load()
305+
config.inUse = Self.newMainSnapshot
306+
config.installedToolchains.remove(Self.newMainSnapshot)
307+
try await config.save()
308+
309+
var uninstall = try self.parseCommand(Uninstall.self, ["uninstall", "-y", Self.newMainSnapshot.name])
310+
_ = try await uninstall.run()
311+
try await self.validateInstalledToolchains(
312+
[Self.oldStable, Self.newStable, Self.oldReleaseSnapshot],
313+
description: "uninstall did not uninstall all toolchains"
314+
)
315+
}
316+
}
299317
}

Tests/SwiftlyTests/UpdateTests.swift

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ final class UpdateTests: SwiftlyTests {
109109
}
110110
}
111111

112-
/// Verifies that updating the currently in-use toolchain can be updated, and that after update the new toolchain
113-
/// will be in-use instead.
114-
func testUpdateInUse() async throws {
112+
/// Verifies that updating the currently global default toolchain can be updated, and that after update the new toolchain
113+
/// will be the global default instead.
114+
func testUpdateGlobalDefault() async throws {
115115
try await self.withTestHome {
116116
try await self.withMockedToolchain {
117117
try await self.installMockedToolchain(selector: "6.0.0")
@@ -136,6 +136,34 @@ final class UpdateTests: SwiftlyTests {
136136
}
137137
}
138138

139+
/// Verifies that updating the currently in-use toolchain can be updated, and that after update the new toolchain
140+
/// will be in-use with the swift version file updated.
141+
func testUpdateInUse() async throws {
142+
try await self.withTestHome {
143+
try await self.withMockedToolchain {
144+
try await self.installMockedToolchain(selector: "6.0.0")
145+
146+
let versionFile = URL(fileURLWithPath: FileManager.default.currentDirectoryPath).appendingPathComponent(".swift-version")
147+
try "6.0.0".write(to: versionFile, atomically: true, encoding: .utf8)
148+
149+
var update = try self.parseCommand(Update.self, ["update", "-y", "--no-verify", "--post-install-file=\(Swiftly.currentPlatform.getTempFilePath().path)"])
150+
try await update.run()
151+
152+
let versionFileContents = try String(contentsOf: versionFile, encoding: .utf8)
153+
let inUse = try ToolchainVersion(parsing: versionFileContents)
154+
XCTAssertGreaterThan(inUse, .init(major: 6, minor: 0, patch: 0))
155+
156+
// Since the global default was set to 6.0.0, and that toolchain is no longer installed
157+
// the update should have unset it to prevent the config from going into a bad state.
158+
let config = try Config.load()
159+
XCTAssertTrue(config.inUse == nil)
160+
161+
// The new toolchain should be installed
162+
XCTAssertTrue(config.installedToolchains.contains(inUse))
163+
}
164+
}
165+
}
166+
139167
/// Verifies that snapshots, both from the main branch and from development branches, can be updated.
140168
func testUpdateSnapshot() async throws {
141169
let snapshotsAvailable = try await self.snapshotsAvailable()

0 commit comments

Comments
 (0)