Skip to content

Commit

Permalink
Merge pull request #199 from RobotsAndPencils/MinOSVersionCheck
Browse files Browse the repository at this point in the history
Add check for min MacOS version when installing
  • Loading branch information
MattKiazyk authored Apr 14, 2022
2 parents e2f0c9d + 20e7b57 commit b36ef47
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Xcodes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
CAFE4AB425B7D3AF0064FE51 /* AdvancedPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE4AB325B7D3AF0064FE51 /* AdvancedPreferencePane.swift */; };
CAFE4ABC25B7D54B0064FE51 /* UpdatesPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE4ABB25B7D54B0064FE51 /* UpdatesPreferencePane.swift */; };
CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */; };
E81D7EA02805250100A205FC /* Collection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81D7E9F2805250100A205FC /* Collection+.swift */; };
E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; };
E89342FA25EDCC17007CF557 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E89342F925EDCC17007CF557 /* NotificationManager.swift */; };
E8977EA325C11E1500835F80 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8977EA225C11E1500835F80 /* PreferencesView.swift */; };
Expand Down Expand Up @@ -272,6 +273,7 @@
CAFE4ABB25B7D54B0064FE51 /* UpdatesPreferencePane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatesPreferencePane.swift; sourceTree = "<group>"; };
CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListViewRow.swift; sourceTree = "<group>"; };
CAFFFEEE259CEAC400903F81 /* RingProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingProgressViewStyle.swift; sourceTree = "<group>"; };
E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = "<group>"; };
E87DD6EA25D053FA00D86808 /* Progress+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Progress+.swift"; sourceTree = "<group>"; };
E89342F925EDCC17007CF557 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
E8977EA225C11E1500835F80 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -458,6 +460,7 @@
CA25192925A9644800F08414 /* XcodeInstallState.swift */,
CA11E7B92598476C00D2EE1C /* XcodeCommands.swift */,
E87DD6EA25D053FA00D86808 /* Progress+.swift */,
E81D7E9F2805250100A205FC /* Collection+.swift */,
);
path = Backend;
sourceTree = "<group>";
Expand Down Expand Up @@ -815,6 +818,7 @@
CA25192A25A9644800F08414 /* XcodeInstallState.swift in Sources */,
E8DA461125FAF7FB002E85EF /* NotificationsView.swift in Sources */,
CAA1CB35255A5AD5003FD669 /* SignInCredentialsView.swift in Sources */,
E81D7EA02805250100A205FC /* Collection+.swift in Sources */,
CA9FF877259528CC00E47BAF /* Version+XcodeReleases.swift in Sources */,
CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */,
CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */,
Expand Down
5 changes: 3 additions & 2 deletions Xcodes/Backend/AppState+Install.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ extension AppState {
if autoInstallType == .newestBeta {
Logger.appState.info("Auto installing newest Xcode Beta")
// install it, as user doesn't have it installed and it's either latest beta or latest release
install(id: newestXcode.id)
checkMinVersionAndInstall(id: newestXcode.id)
} else if autoInstallType == .newestVersion && newestXcode.version.isNotPrerelease {
Logger.appState.info("Auto installing newest Xcode")
install(id: newestXcode.id)
checkMinVersionAndInstall(id: newestXcode.id)
} else {
Logger.appState.info("No new Xcodes version found to auto install")
}
Expand Down Expand Up @@ -92,6 +92,7 @@ extension AppState {
return Fail(error: InstallationError.versionAlreadyInstalled(installedXcode))
.eraseToAnyPublisher()
}

return downloadXcode(availableXcode: availableXcode, downloader: downloader)
}
}
Expand Down
24 changes: 24 additions & 0 deletions Xcodes/Backend/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,24 @@ class AppState: ObservableObject {

// MARK: - Install

func checkMinVersionAndInstall(id: Xcode.ID) {
guard let availableXcode = availableXcodes.first(where: { $0.version == id }) else { return }

// Check to see if users MacOS is supported
if let requiredMacOSVersion = availableXcode.requiredMacOSVersion {
let split = requiredMacOSVersion.components(separatedBy: ".").compactMap { Int($0) }
let xcodeMinimumMacOSVersion = OperatingSystemVersion(majorVersion: split[safe: 0] ?? 0, minorVersion: split[safe: 1] ?? 0, patchVersion: split[safe: 2] ?? 0)

if !ProcessInfo.processInfo.isOperatingSystemAtLeast(xcodeMinimumMacOSVersion) {
// prompt
self.presentedAlert = .checkMinSupportedVersion(xcode: availableXcode, macOS: ProcessInfo.processInfo.operatingSystemVersion.versionString())
return
}
}

install(id: id)
}

func install(id: Xcode.ID) {
guard let availableXcode = availableXcodes.first(where: { $0.version == id }) else { return }

Expand Down Expand Up @@ -666,3 +684,9 @@ class AppState: ObservableObject {
let sessionData: AppleSessionData
}
}

extension OperatingSystemVersion {
func versionString() -> String {
return String(majorVersion) + "." + String(minorVersion) + "." + String(patchVersion)
}
}
17 changes: 17 additions & 0 deletions Xcodes/Backend/Collection+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Collection+.swift
// Xcodes
//
// Created by Matt Kiazyk on 2022-04-11.
// Copyright © 2022 Robots and Pencils. All rights reserved.
//

import Foundation

public extension Collection {

/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
2 changes: 1 addition & 1 deletion Xcodes/Backend/XcodeCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct InstallButton: View {

private func install() {
guard let xcode = xcode else { return }
appState.install(id: xcode.id)
appState.checkMinVersionAndInstall(id: xcode.id)
}
}

Expand Down
2 changes: 2 additions & 0 deletions Xcodes/Frontend/Common/XcodesAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ enum XcodesAlert: Identifiable {
case cancelInstall(xcode: Xcode)
case privilegedHelper
case generic(title: String, message: String)
case checkMinSupportedVersion(xcode: AvailableXcode, macOS: String)

var id: Int {
switch self {
case .cancelInstall: return 1
case .privilegedHelper: return 2
case .generic: return 3
case .checkMinSupportedVersion: return 4
}
}
}
12 changes: 12 additions & 0 deletions Xcodes/Frontend/MainWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ struct MainWindow: View {
action: { appState.presentedAlert = nil }
)
)
case let .checkMinSupportedVersion(xcode, deviceVersion):
return Alert(
title: Text("Minimum requirements not met"),
message: Text("Xcode \(xcode.version.descriptionWithoutBuildMetadata) requires MacOS \(xcode.requiredMacOSVersion ?? ""), but you are running MacOS \(deviceVersion), do you still want to install it?"),
primaryButton: .default(
Text("Install"),
action: {
self.appState.install(id: xcode.version)
}
),
secondaryButton: .cancel(Text("Cancel"))
)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Xcodes/Frontend/XcodeList/XcodeListViewRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ struct XcodeListViewRow: View {
.buttonStyle(AppStoreButtonStyle(primary: true, highlighted: selected))
.help("Open this version")
case .notInstalled:
Button("INSTALL") { appState.install(id: xcode.id) }
Button("INSTALL") { appState.checkMinVersionAndInstall(id: xcode.id) }
.buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selected))
.help("Install this version")
case let .installing(installationStep):
Expand Down

0 comments on commit b36ef47

Please sign in to comment.