-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make updates better and more resilient #245
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,7 +56,12 @@ struct Uninstall: SwiftlyCommand { | |
} | ||
} else { | ||
let selector = try ToolchainSelector(parsing: self.toolchain) | ||
toolchains = startingConfig.listInstalledToolchains(selector: selector) | ||
var installedToolchains = startingConfig.listInstalledToolchains(selector: selector) | ||
// This is in the unusual case that the inUse toolchain is not listed in the installed toolchains | ||
if let inUse = startingConfig.inUse, selector.matches(toolchain: inUse) && !startingConfig.installedToolchains.contains(inUse) { | ||
installedToolchains.append(inUse) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are we going to allow swiftly then to be able to uninstall toolchains it didn't have a hand in installing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the toolchain is in the |
||
} | ||
toolchains = installedToolchains | ||
} | ||
|
||
guard !toolchains.isEmpty else { | ||
|
@@ -108,18 +113,23 @@ struct Uninstall: SwiftlyCommand { | |
} | ||
} | ||
|
||
try await Self.execute(toolchain, &config) | ||
try await Self.execute(toolchain, &config, verbose: self.root.verbose) | ||
} | ||
|
||
SwiftlyCore.print() | ||
SwiftlyCore.print("\(toolchains.count) toolchain(s) successfully uninstalled") | ||
} | ||
|
||
static func execute(_ toolchain: ToolchainVersion, _ config: inout Config) async throws { | ||
static func execute(_ toolchain: ToolchainVersion, _ config: inout Config, verbose: Bool) async throws { | ||
SwiftlyCore.print("Uninstalling \(toolchain)...", terminator: "") | ||
try Swiftly.currentPlatform.uninstall(toolchain) | ||
config.installedToolchains.remove(toolchain) | ||
// This is here to prevent the inUse from referencing a toolchain that is not installed | ||
if config.inUse == toolchain { | ||
config.inUse = nil | ||
} | ||
try config.save() | ||
|
||
try Swiftly.currentPlatform.uninstall(toolchain, verbose: verbose) | ||
SwiftlyCore.print("done") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,7 +133,7 @@ internal struct Use: SwiftlyCommand { | |
} else { | ||
config.inUse = toolchain | ||
try config.save() | ||
message = "The global default toolchain has set to `\(toolchain)`" | ||
message = "The global default toolchain has been set to `\(toolchain)`" | ||
} | ||
|
||
if let selectedVersion = selectedVersion { | ||
|
@@ -177,7 +177,8 @@ public enum ToolchainSelectionResult { | |
/// Selection of a toolchain can be accomplished in a number of ways. There is the | ||
/// the configuration's global default 'inUse' setting. This is the fallback selector | ||
/// if there are no other selections. The returned tuple will contain the default toolchain | ||
/// version and the result will be .default. | ||
/// version and the result will be .globalDefault. This will always be the result if | ||
/// the globalDefault parameter is true. | ||
/// | ||
/// A toolchain can also be selected from a `.swift-version` file in the current | ||
/// working directory, or an ancestor directory. If it successfully selects a toolchain | ||
|
@@ -233,5 +234,11 @@ public func selectToolchain(config: inout Config, globalDefault: Bool = false) a | |
} | ||
} | ||
|
||
return (config.inUse, .globalDefault) | ||
// Check to ensure that the global default in use toolchain matches one of the installed toolchains, and return | ||
// no selected toolchain if it doesn't. | ||
guard let defaultInUse = config.inUse, config.installedToolchains.contains(defaultInUse) else { | ||
return (nil, .globalDefault) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to confirm: You shouldn't be able to select a toolchain that wasn't installed by swiftly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a rare case, caused by things like improper handling of the update operation that this PR should solve. Another potential case is race conditions. This is pure hardening of the code, and also giving the user a way back to a nominal state by |
||
} | ||
|
||
return (defaultInUse, .globalDefault) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we only want to do this when the user passes
--use
to install? In other words if--use
was omitted does this still make sense?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it will be good to try and set a default global toolchain whenever we can to help users avoid cases where there's no default toolchain to fallback. It's an extra annoyance that most people probably don't care to have.
"Give me some kind of a swift toolchain please. I know that I have at least one installed in there."