Don't replace existing install state when updating

This commit is contained in:
Brandon Evans 2021-01-07 19:58:42 -07:00
parent 4a33d010a8
commit fecb40893f
No known key found for this signature in database
GPG key ID: D58A4B8DB64F8E93
3 changed files with 52 additions and 8 deletions

View file

@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
63EAA4EB259944450046AB8F /* ProgressButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63EAA4EA259944450046AB8F /* ProgressButton.swift */; };
CA11E7BA2598476C00D2EE1C /* XcodeCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA11E7B92598476C00D2EE1C /* XcodeCommands.swift */; };
CA2518EC25A7FF2B00F08414 /* AppStateUpdateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA2518EB25A7FF2B00F08414 /* AppStateUpdateTests.swift */; };
CA378F992466567600A58CE0 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA378F982466567600A58CE0 /* AppState.swift */; };
CA39711924495F0E00AFFB77 /* AppStoreButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA39711824495F0E00AFFB77 /* AppStoreButtonStyle.swift */; };
CA44901F2463AD34003D8213 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA44901E2463AD34003D8213 /* Tag.swift */; };
@ -132,6 +133,7 @@
/* Begin PBXFileReference section */
63EAA4EA259944450046AB8F /* ProgressButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressButton.swift; sourceTree = "<group>"; };
CA11E7B92598476C00D2EE1C /* XcodeCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeCommands.swift; sourceTree = "<group>"; };
CA2518EB25A7FF2B00F08414 /* AppStateUpdateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStateUpdateTests.swift; sourceTree = "<group>"; };
CA378F982466567600A58CE0 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
CA39711824495F0E00AFFB77 /* AppStoreButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreButtonStyle.swift; sourceTree = "<group>"; };
CA44901E2463AD34003D8213 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = "<group>"; };
@ -485,6 +487,7 @@
CAC281E1259FA44600B8AB0B /* Bundle+XcodesTests.swift */,
CAC281E6259FA45A00B8AB0B /* Environment+Mock.swift */,
CAD2E7B72449575100113D76 /* AppStateTests.swift */,
CA2518EB25A7FF2B00F08414 /* AppStateUpdateTests.swift */,
CAD2E7B92449575100113D76 /* Info.plist */,
);
path = XcodesTests;
@ -743,6 +746,7 @@
files = (
CAC281E7259FA45A00B8AB0B /* Environment+Mock.swift in Sources */,
CAC281E2259FA44600B8AB0B /* Bundle+XcodesTests.swift in Sources */,
CA2518EC25A7FF2B00F08414 /* AppStateUpdateTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -15,13 +15,21 @@ class AppState: ObservableObject {
@Published var authenticationState: AuthenticationState = .unauthenticated
@Published var availableXcodes: [AvailableXcode] = [] {
willSet {
updateAllXcodes(availableXcodes: newValue, selectedXcodePath: selectedXcodePath)
updateAllXcodes(
availableXcodes: newValue,
installedXcodes: Current.files.installedXcodes(Path.root/"Applications"),
selectedXcodePath: selectedXcodePath
)
}
}
@Published var allXcodes: [Xcode] = []
@Published var selectedXcodePath: String? {
willSet {
updateAllXcodes(availableXcodes: availableXcodes, selectedXcodePath: newValue)
updateAllXcodes(
availableXcodes: availableXcodes,
installedXcodes: Current.files.installedXcodes(Path.root/"Applications"),
selectedXcodePath: newValue
)
}
}
@Published var updatePublisher: AnyCancellable?
@ -336,10 +344,7 @@ class AppState: ObservableObject {
NSPasteboard.general.setString(installedXcode.path.string, forType: .string)
}
// MARK: - Private
private func updateAllXcodes(availableXcodes: [AvailableXcode], selectedXcodePath: String?) {
let installedXcodes = Current.files.installedXcodes(Path.root/"Applications")
func updateAllXcodes(availableXcodes: [AvailableXcode], installedXcodes: [InstalledXcode], selectedXcodePath: String?) {
var allXcodeVersions = availableXcodes.map { $0.version }
for installedXcode in installedXcodes {
// If an installed version isn't listed online, add the installed version
@ -362,9 +367,13 @@ class AppState: ObservableObject {
.map { xcodeVersion in
let installedXcode = installedXcodes.first(where: { xcodeVersion.isEquivalentForDeterminingIfInstalled(toInstalled: $0.version) })
let availableXcode = availableXcodes.first { $0.version == xcodeVersion }
let existingXcode = allXcodes.first { $0.version == xcodeVersion }
let defaultInstallState: XcodeInstallState = installedXcode != nil ? .installed : .notInstalled
return Xcode(
version: xcodeVersion,
installState: installedXcode != nil ? .installed : .notInstalled,
installState: existingXcode?.installState ?? defaultInstallState,
selected: installedXcode != nil && selectedXcodePath?.hasPrefix(installedXcode!.path.string) == true,
path: installedXcode?.path.string,
icon: (installedXcode?.path.string).map(NSWorkspace.shared.icon(forFile:)),
@ -376,6 +385,7 @@ class AppState: ObservableObject {
}
}
// MARK: - Private
private func uninstallXcode(path: Path) -> AnyPublisher<Void, Error> {
return Deferred {

View file

@ -0,0 +1,30 @@
import Path
import Version
@testable import Xcodes
import XCTest
class AppStateUpdateTests: XCTestCase {
var subject: AppState!
override func setUpWithError() throws {
Current = .mock
subject = AppState()
}
func testDoesNotReplaceInstallState() throws {
subject.allXcodes = [
Xcode(version: Version("0.0.0")!, installState: .installing(.unarchiving), selected: false, path: nil, icon: nil)
]
subject.updateAllXcodes(
availableXcodes: [
AvailableXcode(version: Version("0.0.0")!, url: URL(string: "https://apple.com/xcode.xip")!, filename: "mock.xip", releaseDate: nil)
],
installedXcodes: [
],
selectedXcodePath: nil
)
XCTAssertEqual(subject.allXcodes[0].installState, .installing(.unarchiving))
}
}