-
Notifications
You must be signed in to change notification settings - Fork 3
/
Update.swift
92 lines (83 loc) · 3.86 KB
/
Update.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import Foundation
import Releases
import ShellOut
enum UpdateError: Error, Equatable {
case resolvedVersionNotFound(String, Version, Version)
case updatedVersionNotFound(String, Version, Version)
}
enum Update: Equatable {
case withoutChangingRequirements(Version)
case withChangingRequirements(Version)
case skipped
static func getUpdate(name: String, currentVersion: Version?, swiftPackageUpdate: SwiftPackageUpdate?, latestRelease: Version?) throws -> Update? {
guard let currentVersion = currentVersion else {
return .skipped
}
if let latestRelease = latestRelease, currentVersion != latestRelease {
if currentVersion < latestRelease {
if let update = swiftPackageUpdate {
if update.newVersion < latestRelease {
return .withChangingRequirements(latestRelease)
} else if update.newVersion > latestRelease {
throw UpdateError.updatedVersionNotFound(name, update.newVersion, latestRelease)
} else {
return .withoutChangingRequirements(update.newVersion)
}
} else {
return .withChangingRequirements(latestRelease)
}
} else {
throw UpdateError.resolvedVersionNotFound(name, currentVersion, latestRelease)
}
} else if let update = swiftPackageUpdate {
return .withoutChangingRequirements(update.newVersion)
} else {
return nil
}
}
func execute(for dependency: Dependency, in folder: URL) throws {
switch self {
case let .withChangingRequirements(version):
print("Updating \(dependency.name): \(dependency.resolvedVersion.versionNumberOrRevision) -> \(version)".bold)
let swiftPackage = SwiftPackage(in: folder)
let packageUpdate = try swiftPackage.performUpdate(self, of: dependency)
print("Updated Package.swift".green)
if packageUpdate {
try shellOut(to: "swift", arguments: ["package", "update", dependency.name, "--package-path", "\"\(folder.path)\"" ])
print("Resolved to new version".green)
} else {
try shellOut(to: "swift", arguments: ["package", "update", "resolve", "--package-path", "\"\(folder.path)\"" ])
print("Resolved Version".green)
}
case let .withoutChangingRequirements(version):
print("Updating \(dependency.name): \(dependency.resolvedVersion.versionNumberOrRevision) -> \(version)".bold)
try shellOut(to: "swift", arguments: ["package", "update", dependency.name, "--package-path", "\"\(folder.path)\"" ])
print("Resolved to new version".green)
default:
// Do nothing
break
}
}
}
extension Update: CustomStringConvertible {
public var description: String {
switch self {
case let .withoutChangingRequirements(version):
return "\("\(version)".yellow) (Without changing requirements)"
case let .withChangingRequirements(version):
return "\("\(version)".red) (Requires changing requirements)"
case .skipped:
return "Current version is not a release version, skipping".yellow
}
}
}
extension UpdateError: LocalizedError {
public var errorDescription: String? {
switch self {
case let .resolvedVersionNotFound(name, resolved, remote):
return "The resolved version of \(name) is \(resolved), but the newest release on the remote is \(remote)"
case let .updatedVersionNotFound(name, updated, remote):
return "The swift package manager wants to update the version of \(name) to \(updated), but the newest release on the remote is \(remote)"
}
}
}