Merge pull request #156 from RobotsAndPencils/matt/OpenIdenticalBuilds

Better handling of duplicate builds and buttons not working
This commit is contained in:
Matt Kiazyk 2021-10-08 16:27:32 -05:00 committed by GitHub
commit 04c79c36ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 28 deletions

View file

@ -378,13 +378,13 @@ class AppState: ObservableObject {
}
// MARK: - Uninstall
func uninstall(id: Xcode.ID) {
func uninstall(xcode: Xcode) {
guard
let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }),
let installedXcodePath = xcode.installedPath,
uninstallPublisher == nil
else { return }
uninstallPublisher = uninstallXcode(path: installedXcode.path)
uninstallPublisher = uninstallXcode(path: installedXcodePath)
.flatMap { [unowned self] _ in
self.updateSelectedXcodePath()
}
@ -400,10 +400,10 @@ class AppState: ObservableObject {
)
}
func reveal(id: Xcode.ID) {
func reveal(xcode: Xcode) {
// TODO: show error if not
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
NSWorkspace.shared.activateFileViewerSelecting([installedXcode.path.url])
guard let installedXcodePath = xcode.installedPath else { return }
NSWorkspace.shared.activateFileViewerSelecting([installedXcodePath.url])
}
func reveal(path: String) {
@ -421,26 +421,26 @@ class AppState: ObservableObject {
/// If they consent to installing the helper then this method will be invoked again with `shouldPrepareUserForHelperInstallation` set to false.
/// This will install the helper and make the Xcode active.
///
/// - Parameter id: The identifier of the Xcode to make active.
/// - Parameter xcode: The Xcode to make active.
/// - Parameter shouldPrepareUserForHelperInstallation: Whether the user should be presented with an alert preparing them for helper installation before making the Xcode version active.
func select(id: Xcode.ID, shouldPrepareUserForHelperInstallation: Bool = true) {
func select(xcode: Xcode, shouldPrepareUserForHelperInstallation: Bool = true) {
guard helperInstallState == .installed || shouldPrepareUserForHelperInstallation == false else {
isPreparingUserForActionRequiringHelper = { [unowned self] userConsented in
guard userConsented else { return }
self.select(id: id, shouldPrepareUserForHelperInstallation: false)
self.select(xcode: xcode, shouldPrepareUserForHelperInstallation: false)
}
presentedAlert = .privilegedHelper
return
}
guard
let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }),
guard
let installedXcodePath = xcode.installedPath,
selectPublisher == nil
else { return }
selectPublisher = installHelperIfNecessary()
.flatMap {
Current.helper.switchXcodePath(installedXcode.path.string)
Current.helper.switchXcodePath(installedXcodePath.string)
}
.flatMap { [unowned self] _ in
self.updateSelectedXcodePath()
@ -457,16 +457,22 @@ class AppState: ObservableObject {
)
}
func open(id: Xcode.ID) {
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
NSWorkspace.shared.openApplication(at: installedXcode.path.url, configuration: .init())
func open(xcode: Xcode) {
switch xcode.installState {
case let .installed(path):
NSWorkspace.shared.openApplication(at: path.url, configuration: .init())
default:
Logger.appState.error("\(xcode.id) is not installed")
return
}
}
func copyPath(id: Xcode.ID) {
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
func copyPath(xcode: Xcode) {
guard let installedXcodePath = xcode.installedPath else { return }
NSPasteboard.general.declareTypes([.URL, .string], owner: nil)
NSPasteboard.general.writeObjects([installedXcode.path.url as NSURL])
NSPasteboard.general.setString(installedXcode.path.string, forType: .string)
NSPasteboard.general.writeObjects([installedXcodePath.url as NSURL])
NSPasteboard.general.setString(installedXcodePath.string, forType: .string)
}
func updateAllXcodes(availableXcodes: [AvailableXcode], installedXcodes: [InstalledXcode], selectedXcodePath: String?) {

View file

@ -3,6 +3,7 @@ import Foundation
import Version
import struct XCModel.SDKs
import struct XCModel.Compilers
import Path
struct Xcode: Identifiable, CustomStringConvertible {
let version: Version
@ -57,4 +58,13 @@ struct Xcode: Identifiable, CustomStringConvertible {
return nil
}
}
var installedPath: Path? {
switch installState {
case .installed(let path):
return path
default:
return nil
}
}
}

View file

@ -83,7 +83,7 @@ struct SelectButton: View {
private func select() {
guard let xcode = xcode else { return }
appState.select(id: xcode.id)
appState.select(xcode: xcode)
}
}
@ -100,7 +100,7 @@ struct OpenButton: View {
private func open() {
guard let xcode = xcode else { return }
appState.open(id: xcode.id)
appState.open(xcode: xcode)
}
}
@ -132,7 +132,7 @@ struct RevealButton: View {
private func reveal() {
guard let xcode = xcode else { return }
appState.reveal(id: xcode.id)
appState.reveal(xcode: xcode)
}
}
@ -149,7 +149,7 @@ struct CopyPathButton: View {
private func copyPath() {
guard let xcode = xcode else { return }
appState.copyPath(id: xcode.id)
appState.copyPath(xcode: xcode)
}
}

View file

@ -31,7 +31,7 @@ struct InfoPane: View {
case let .installed(path):
HStack {
Text(path.string)
Button(action: { appState.reveal(id: xcode.id) }) {
Button(action: { appState.reveal(xcode: xcode) }) {
Image(systemName: "arrow.right.circle.fill")
}
.buttonStyle(PlainButtonStyle())

View file

@ -22,7 +22,7 @@ struct MainWindow: View {
.alert(item: $appState.xcodeBeingConfirmedForUninstallation) { xcode in
Alert(title: Text("Uninstall Xcode \(xcode.description)?"),
message: Text("It will be moved to the Trash, but won't be emptied."),
primaryButton: .destructive(Text("Uninstall"), action: { self.appState.uninstall(id: xcode.id) }),
primaryButton: .destructive(Text("Uninstall"), action: { self.appState.uninstall(xcode: xcode) }),
secondaryButton: .cancel(Text("Cancel")))
}

View file

@ -85,7 +85,7 @@ struct XcodeListViewRow: View {
.foregroundColor(.green)
.help("This is the active version")
} else {
Button(action: { appState.select(id: xcode.id) }) {
Button(action: { appState.select(xcode: xcode) }) {
Image(systemName: "checkmark.circle")
.foregroundColor(.secondary)
}
@ -101,7 +101,7 @@ struct XcodeListViewRow: View {
private func installControl(for xcode: Xcode) -> some View {
switch xcode.installState {
case .installed:
Button("OPEN") { appState.open(id: xcode.id) }
Button("OPEN") { appState.open(xcode: xcode) }
.buttonStyle(AppStoreButtonStyle(primary: true, highlighted: selected))
.help("Open this version")
case .notInstalled: