Skip to content

Commit 6df2edc

Browse files
authored
Fix self update macOS (#440)
* Fix the self update for macOS so that the installer is executed * Add compatible configuration versions to init command for updates * Add test for a migration for the current swiftly version to capture branching problems * Permit self-updates to identical version using the hidden --to-version option.
1 parent 8088e37 commit 6df2edc

File tree

4 files changed

+35
-10
lines changed

4 files changed

+35
-10
lines changed

Sources/MacOSPlatform/MacOS.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ public struct MacOS: Platform {
117117

118118
if ctx.mockedHomeDir == nil {
119119
await ctx.message("Extracting the swiftly package...")
120-
_ = sys.installer(
120+
try await sys.installer(
121121
.pkg(archive),
122122
.target("CurrentUserHomeDirectory")
123-
)
123+
).run(self)
124124
try? await sys.pkgutil(.volume(userHomeDir)).forget(pkg_id: "org.swift.swiftly").run(self)
125125
} else {
126126
let installDir = userHomeDir / ".swiftly"

Sources/Swiftly/Init.swift

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@ import Foundation
33
import SwiftlyCore
44
import SystemPackage
55

6+
public enum SwiftlyVersionMigration {
7+
case exact(SwiftlyVersion)
8+
case minor(SwiftlyVersion)
9+
10+
public func matches(_ version: SwiftlyVersion) -> Bool {
11+
switch self {
12+
case let .exact(v):
13+
return version.major == v.major && version.minor == v.minor && version.patch == v.patch && version.suffix == v.suffix
14+
case let .minor(v):
15+
return version.major == v.major && version.minor == v.minor
16+
}
17+
}
18+
}
19+
20+
public var migrations: [SwiftlyVersionMigration] {
21+
[
22+
.exact(.init(major: 0, minor: 4, patch: 0, suffix: "dev")),
23+
.exact(.init(major: 0, minor: 4, patch: 0)),
24+
.minor(.init(major: 1, minor: 0, patch: 0)),
25+
.minor(.init(major: 1, minor: 1, patch: 0)),
26+
.minor(.init(major: 1, minor: 2, patch: 0)),
27+
]
28+
}
29+
630
struct Init: SwiftlyCommand {
731
public static let configuration = CommandConfiguration(
832
abstract: "Perform swiftly initialization into your user account."
@@ -44,13 +68,7 @@ struct Init: SwiftlyCommand {
4468

4569
var config = try? await Config.load(ctx)
4670

47-
if var config, !overwrite &&
48-
(
49-
config.version == SwiftlyVersion(major: 0, minor: 4, patch: 0, suffix: "dev") ||
50-
config.version == SwiftlyVersion(major: 0, minor: 4, patch: 0) ||
51-
(config.version.major == 1 && config.version.minor == 0)
52-
)
53-
{
71+
if var config, !overwrite && !migrations.filter({ $0.matches(config.version) }).isEmpty {
5472
// This is a simple upgrade from the 0.4.0 pre-releases, or 1.x
5573

5674
// Move our executable over to the correct place

Sources/Swiftly/SelfUpdate.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ struct SelfUpdate: SwiftlyCommand {
6565
fatalError("Unsupported OS")
6666
#endif
6767

68-
guard version > SwiftlyCore.version else {
68+
// Allow newer or identical versions to help self-update testing of a release
69+
guard version >= SwiftlyCore.version else {
6970
await ctx.print("Self-update does not support downgrading to an older version or re-installing the current version. Current version is \(SwiftlyCore.version) and requested version is \(version).")
7071
return SwiftlyCore.version
7172
}

Tests/SwiftlyTests/InitTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import SystemPackage
55
import Testing
66

77
@Suite struct InitTests {
8+
@Test func migrationsHasCurrentSwiftlyVersion() async throws {
9+
// If the current swiftly version isn't in the migration list then it should be added there to
10+
// support future self updates.
11+
#expect(!migrations.filter { $0.matches(SwiftlyCore.version) }.isEmpty)
12+
}
13+
814
@Test(.testHome(), arguments: ["/bin/bash", "/bin/zsh", "/bin/fish"]) func initFresh(_ shell: String) async throws {
915
// GIVEN: a fresh user account without swiftly installed
1016
try? await fs.remove(atPath: Swiftly.currentPlatform.swiftlyConfigFile(SwiftlyTests.ctx))

0 commit comments

Comments
 (0)