mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-04-25 14:47:38 +00:00
Merge identical builds into the release version instead of filtering
This commit is contained in:
parent
bc45daeb74
commit
dcd4001548
3 changed files with 26 additions and 36 deletions
|
|
@ -425,7 +425,7 @@ class AppState: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateAllXcodes(availableXcodes: [AvailableXcode], installedXcodes: [InstalledXcode], selectedXcodePath: String?) {
|
func updateAllXcodes(availableXcodes: [AvailableXcode], installedXcodes: [InstalledXcode], selectedXcodePath: String?) {
|
||||||
var adjustedAvailableXcodes = filterPrereleasesThatMatchReleaseBuildMetadataIdentifiers(availableXcodes)
|
var adjustedAvailableXcodes = availableXcodes
|
||||||
|
|
||||||
// First, adjust all of the available Xcodes so that available and installed versions line up and the second part of this function works properly.
|
// First, adjust all of the available Xcodes so that available and installed versions line up and the second part of this function works properly.
|
||||||
if dataSource == .apple {
|
if dataSource == .apple {
|
||||||
|
|
@ -449,10 +449,28 @@ class AppState: ObservableObject {
|
||||||
|
|
||||||
// Map all of the available versions into Xcode values that join available and installed Xcode data for display.
|
// Map all of the available versions into Xcode values that join available and installed Xcode data for display.
|
||||||
var newAllXcodes = adjustedAvailableXcodes
|
var newAllXcodes = adjustedAvailableXcodes
|
||||||
|
.filter { availableXcode in
|
||||||
|
let availableXcodesWithIdenticalBuildIdentifiers = availableXcodes
|
||||||
|
.filter({ $0.version.buildMetadataIdentifiers == availableXcode.version.buildMetadataIdentifiers })
|
||||||
|
|
||||||
|
// Include this version if there's only one with this build identifier
|
||||||
|
return availableXcodesWithIdenticalBuildIdentifiers.count == 1 ||
|
||||||
|
// Or if there's more than one with this build identifier and this is the release version
|
||||||
|
availableXcodesWithIdenticalBuildIdentifiers.count > 1 && availableXcode.version.prereleaseIdentifiers.isEmpty
|
||||||
|
}
|
||||||
.map { availableXcode -> Xcode in
|
.map { availableXcode -> Xcode in
|
||||||
let installedXcode = installedXcodes.first(where: { installedXcode in
|
let installedXcode = installedXcodes.first(where: { installedXcode in
|
||||||
availableXcode.version.isEquivalent(to: installedXcode.version)
|
availableXcode.version.isEquivalent(to: installedXcode.version)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let identicalBuilds: [Version]
|
||||||
|
let availableXcodesWithIdenticalBuildIdentifiers = availableXcodes
|
||||||
|
.filter({ $0.version.buildMetadataIdentifiers == availableXcode.version.buildMetadataIdentifiers })
|
||||||
|
if availableXcodesWithIdenticalBuildIdentifiers.count > 1, availableXcode.version.prereleaseIdentifiers.isEmpty {
|
||||||
|
identicalBuilds = availableXcodesWithIdenticalBuildIdentifiers.map(\.version)
|
||||||
|
} else {
|
||||||
|
identicalBuilds = []
|
||||||
|
}
|
||||||
|
|
||||||
// If the existing install state is "installing", keep it
|
// If the existing install state is "installing", keep it
|
||||||
let existingXcodeInstallState = allXcodes.first { $0.version == availableXcode.version && $0.installState.installing }?.installState
|
let existingXcodeInstallState = allXcodes.first { $0.version == availableXcode.version && $0.installState.installing }?.installState
|
||||||
|
|
@ -461,7 +479,7 @@ class AppState: ObservableObject {
|
||||||
|
|
||||||
return Xcode(
|
return Xcode(
|
||||||
version: availableXcode.version,
|
version: availableXcode.version,
|
||||||
identicalBuilds: [],
|
identicalBuilds: identicalBuilds,
|
||||||
installState: existingXcodeInstallState ?? defaultXcodeInstallState,
|
installState: existingXcodeInstallState ?? defaultXcodeInstallState,
|
||||||
selected: installedXcode != nil && selectedXcodePath?.hasPrefix(installedXcode!.path.string) == true,
|
selected: installedXcode != nil && selectedXcodePath?.hasPrefix(installedXcode!.path.string) == true,
|
||||||
icon: (installedXcode?.path.string).map(NSWorkspace.shared.icon(forFile:)),
|
icon: (installedXcode?.path.string).map(NSWorkspace.shared.icon(forFile:)),
|
||||||
|
|
@ -492,30 +510,6 @@ class AppState: ObservableObject {
|
||||||
self.allXcodes = newAllXcodes.sorted { $0.version > $1.version }
|
self.allXcodes = newAllXcodes.sorted { $0.version > $1.version }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Xcode Releases may have multiple releases with the same build metadata when a build doesn't change between candidate and final releases.
|
|
||||||
/// For example, 12.3 RC and 12.3 are both build 12C33
|
|
||||||
/// We don't care about that difference, so only keep the final release (GM or Release, in XCModel terms).
|
|
||||||
/// The downside of this is that a user could technically have both releases installed, and so they won't both be shown in the list, but I think most users wouldn't do this.
|
|
||||||
func filterPrereleasesThatMatchReleaseBuildMetadataIdentifiers(_ availableXcodes: [AvailableXcode]) -> [AvailableXcode] {
|
|
||||||
var filteredAvailableXcodes: [AvailableXcode] = []
|
|
||||||
for availableXcode in availableXcodes {
|
|
||||||
if availableXcode.version.buildMetadataIdentifiers.isEmpty {
|
|
||||||
filteredAvailableXcodes.append(availableXcode)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
let availableXcodesWithSameBuildMetadataIdentifiers = availableXcodes
|
|
||||||
.filter({ $0.version.buildMetadataIdentifiers == availableXcode.version.buildMetadataIdentifiers })
|
|
||||||
if availableXcodesWithSameBuildMetadataIdentifiers.count > 1,
|
|
||||||
availableXcode.version.prereleaseIdentifiers.isEmpty || availableXcode.version.prereleaseIdentifiers == ["GM"] {
|
|
||||||
filteredAvailableXcodes.append(availableXcode)
|
|
||||||
} else if availableXcodesWithSameBuildMetadataIdentifiers.count == 1 {
|
|
||||||
filteredAvailableXcodes.append(availableXcode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filteredAvailableXcodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func uninstallXcode(path: Path) -> AnyPublisher<Void, Error> {
|
private func uninstallXcode(path: Path) -> AnyPublisher<Void, Error> {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import struct XCModel.Compilers
|
||||||
|
|
||||||
struct Xcode: Identifiable, CustomStringConvertible {
|
struct Xcode: Identifiable, CustomStringConvertible {
|
||||||
let version: Version
|
let version: Version
|
||||||
|
/// Other Xcode versions that have the same build identifier
|
||||||
|
let identicalBuilds: [Version]
|
||||||
var installState: XcodeInstallState
|
var installState: XcodeInstallState
|
||||||
let selected: Bool
|
let selected: Bool
|
||||||
let icon: NSImage?
|
let icon: NSImage?
|
||||||
|
|
@ -17,6 +19,7 @@ struct Xcode: Identifiable, CustomStringConvertible {
|
||||||
|
|
||||||
init(
|
init(
|
||||||
version: Version,
|
version: Version,
|
||||||
|
identicalBuilds: [Version] = [],
|
||||||
installState: XcodeInstallState,
|
installState: XcodeInstallState,
|
||||||
selected: Bool,
|
selected: Bool,
|
||||||
icon: NSImage?,
|
icon: NSImage?,
|
||||||
|
|
@ -27,6 +30,7 @@ struct Xcode: Identifiable, CustomStringConvertible {
|
||||||
downloadFileSize: Int64? = nil
|
downloadFileSize: Int64? = nil
|
||||||
) {
|
) {
|
||||||
self.version = version
|
self.version = version
|
||||||
|
self.identicalBuilds = identicalBuilds
|
||||||
self.installState = installState
|
self.installState = installState
|
||||||
self.selected = selected
|
self.selected = selected
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,7 @@ class AppStateUpdateTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
XCTAssertEqual(subject.allXcodes.map(\.version), [Version("12.4.0+12D4e")!])
|
XCTAssertEqual(subject.allXcodes.map(\.version), [Version("12.4.0+12D4e")!])
|
||||||
|
XCTAssertEqual(subject.allXcodes.map(\.identicalBuilds), [[Version("12.4.0+12D4e")!, Version("12.4.0-RC+12D4e")!]])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIdenticalBuilds_KeepsReleaseVersion_WithPrereleaseInstalled() {
|
func testIdenticalBuilds_KeepsReleaseVersion_WithPrereleaseInstalled() {
|
||||||
|
|
@ -203,15 +204,6 @@ class AppStateUpdateTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
XCTAssertEqual(subject.allXcodes.map(\.version), [Version("12.4.0+12D4e")!])
|
XCTAssertEqual(subject.allXcodes.map(\.version), [Version("12.4.0+12D4e")!])
|
||||||
}
|
XCTAssertEqual(subject.allXcodes.map(\.identicalBuilds), [[Version("12.4.0+12D4e")!, Version("12.4.0-RC+12D4e")!]])
|
||||||
|
|
||||||
func testFilterReleasesThatMatchPrereleases() {
|
|
||||||
let result = subject.filterPrereleasesThatMatchReleaseBuildMetadataIdentifiers(
|
|
||||||
[
|
|
||||||
AvailableXcode(version: Version("12.3.0+12C33")!, url: URL(string: "https://apple.com")!, filename: "Xcode_12.3.xip", releaseDate: nil),
|
|
||||||
AvailableXcode(version: Version("12.3.0-RC+12C33")!, url: URL(string: "https://apple.com")!, filename: "Xcode_12.3_RC_1.xip", releaseDate: nil),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
XCTAssertEqual(result.map(\.version), [Version("12.3.0+12C33")])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue