Handle helper installation errors

This commit is contained in:
Brandon Evans 2021-01-22 22:18:59 -07:00
parent d834f3ed74
commit e21e4d9cdf
No known key found for this signature in database
GPG key ID: D58A4B8DB64F8E93
5 changed files with 44 additions and 26 deletions

View file

@ -303,11 +303,10 @@ extension AppState {
}
func enableDeveloperMode() -> AnyPublisher<Void, Error> {
if helperInstallState == .notInstalled {
installHelper()
}
return Current.helper.devToolsSecurityEnable()
installHelperIfNecessary()
.flatMap {
Current.helper.devToolsSecurityEnable()
}
.flatMap {
Current.helper.addStaffToDevelopersGroup()
}
@ -315,20 +314,18 @@ extension AppState {
}
func approveLicense(for xcode: InstalledXcode) -> AnyPublisher<Void, Error> {
if helperInstallState == .notInstalled {
installHelper()
}
return Current.helper.acceptXcodeLicense(xcode.path.string)
installHelperIfNecessary()
.flatMap {
Current.helper.acceptXcodeLicense(xcode.path.string)
}
.eraseToAnyPublisher()
}
func installComponents(for xcode: InstalledXcode) -> AnyPublisher<Void, Swift.Error> {
if helperInstallState == .notInstalled {
installHelper()
}
return Current.helper.runFirstLaunch(xcode.path.string)
installHelperIfNecessary()
.flatMap {
Current.helper.runFirstLaunch(xcode.path.string)
}
.flatMap {
Current.shell.getUserCacheDir().map { $0.out }
.combineLatest(

View file

@ -203,9 +203,29 @@ class AppState: ObservableObject {
// MARK: - Helper
func installHelper() {
Current.helper.install()
checkIfHelperIsInstalled()
func installHelperIfNecessary() {
installHelperIfNecessary()
.sink(
receiveCompletion: { [unowned self] completion in
if case let .failure(error) = completion {
self.error = error
}
},
receiveValue: {}
)
.store(in: &cancellables)
}
func installHelperIfNecessary() -> AnyPublisher<Void, Error> {
Result {
if helperInstallState == .notInstalled {
try Current.helper.install()
checkIfHelperIsInstalled()
}
}
.publisher
.subscribe(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
private func checkIfHelperIsInstalled() {
@ -320,16 +340,15 @@ class AppState: ObservableObject {
}
func select(id: Xcode.ID) {
if helperInstallState == .notInstalled {
installHelper()
}
guard
let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }),
selectPublisher == nil
else { return }
selectPublisher = HelperClient().switchXcodePath(installedXcode.path.string)
selectPublisher = installHelperIfNecessary()
.flatMap {
Current.helper.switchXcodePath(installedXcode.path.string)
}
.flatMap { [unowned self] _ in
self.updateSelectedXcodePath()
}

View file

@ -237,7 +237,7 @@ public struct Defaults {
private let helperClient = HelperClient()
public struct Helper {
var install: () -> Void = helperClient.install
var install: () throws -> Void = helperClient.install
var checkIfLatestHelperIsInstalled: () -> AnyPublisher<Bool, Never> = helperClient.checkIfLatestHelperIsInstalled
var getVersion: () -> AnyPublisher<String, Error> = helperClient.getVersion
var switchXcodePath: (_ absolutePath: String) -> AnyPublisher<Void, Error> = helperClient.switchXcodePath

View file

@ -307,7 +307,7 @@ final class HelperClient {
// MARK: - Install
// From https://github.com/securing/SimpleXPCApp/
func install() {
func install() throws {
Logger.helperClient.info(#function)
var authItem = kSMRightBlessPrivilegedHelper.withCString { name in
@ -329,6 +329,8 @@ final class HelperClient {
Logger.helperClient.info("\(#function): Finished installation")
} catch {
Logger.helperClient.error("\(#function): \(error.localizedDescription)")
throw error
}
}

View file

@ -55,7 +55,7 @@ struct AdvancedPreferencePane: View {
HStack {
Text("Helper is not installed")
Button("Install helper") {
appState.installHelper()
appState.installHelperIfNecessary()
}
}
}