mirror of https://github.com/buresdv/Cork
Merge pull request #459 from Grublady/installation-stage
Fixes in adjusted installation process
This commit is contained in:
commit
e2cfc6e81b
|
|
@ -1,52 +0,0 @@
|
||||||
//
|
|
||||||
// Package Installation Status.swift
|
|
||||||
// Cork
|
|
||||||
//
|
|
||||||
// Created by David Bureš on 22.02.2023.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
enum PackageInstallationStage: CustomStringConvertible
|
|
||||||
{
|
|
||||||
case ready, loadingDependencies, fetchingDependencies, installingDependencies, installingPackage, finished // For Formulae
|
|
||||||
|
|
||||||
case downloadingCask, installingCask, movingCask, linkingCaskBinary // For Casks
|
|
||||||
|
|
||||||
case requiresSudoPassword, wrongArchitecture, binaryAlreadyExists, terminatedUnexpectedly // For Both
|
|
||||||
|
|
||||||
var description: String
|
|
||||||
{
|
|
||||||
switch self
|
|
||||||
{
|
|
||||||
case .ready:
|
|
||||||
return "Ready"
|
|
||||||
case .loadingDependencies:
|
|
||||||
return "Loading Dependencies"
|
|
||||||
case .fetchingDependencies:
|
|
||||||
return "Fetching Dependencies"
|
|
||||||
case .installingDependencies:
|
|
||||||
return "Installing Dependencies"
|
|
||||||
case .installingPackage:
|
|
||||||
return "Installing Package"
|
|
||||||
case .finished:
|
|
||||||
return "Installation Finished"
|
|
||||||
case .downloadingCask:
|
|
||||||
return "Downloaing Cask"
|
|
||||||
case .installingCask:
|
|
||||||
return "Installing Cask"
|
|
||||||
case .movingCask:
|
|
||||||
return "Moving Cask"
|
|
||||||
case .linkingCaskBinary:
|
|
||||||
return "Linking Cask Binary"
|
|
||||||
case .requiresSudoPassword:
|
|
||||||
return "Sudo Password Required"
|
|
||||||
case .wrongArchitecture:
|
|
||||||
return "Wrong Package Architecture"
|
|
||||||
case .binaryAlreadyExists:
|
|
||||||
return "Binary Already Exists"
|
|
||||||
case .terminatedUnexpectedly:
|
|
||||||
return "Terminated Unexpectedly"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7410,6 +7410,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"add-package.install.calculating-dependencies" : {
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Calculating Dependencies..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"add-package.install.downloading-cask-%@" : {
|
"add-package.install.downloading-cask-%@" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"cs" : {
|
"cs" : {
|
||||||
|
|
@ -8139,6 +8149,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"add-package.install.loading-dependencies" : {
|
"add-package.install.loading-dependencies" : {
|
||||||
|
"extractionState" : "stale",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
"cs" : {
|
"cs" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import Foundation
|
||||||
|
|
||||||
class InstallationProgressTracker: ObservableObject
|
class InstallationProgressTracker: ObservableObject
|
||||||
{
|
{
|
||||||
@Published var packageBeingInstalled: PackageInProgressOfBeingInstalled = .init(package: .init(name: "", type: .formula, installedOn: nil, versions: [], sizeInBytes: 0), installationStage: .downloadingCask, packageInstallationProgress: 0)
|
@Published var packageBeingInstalled: PackageInProgressOfBeingInstalled = .init(package: .init(name: "", type: .formula, installedOn: nil, versions: [], sizeInBytes: 0), installationStage: .ready, packageInstallationProgress: 0)
|
||||||
|
|
||||||
@Published var numberOfPackageDependencies: Int = 0
|
@Published var numberOfPackageDependencies: Int = 0
|
||||||
@Published var numberInLineOfPackageCurrentlyBeingFetched: Int = 0
|
@Published var numberInLineOfPackageCurrentlyBeingFetched: Int = 0
|
||||||
|
|
@ -76,97 +76,99 @@ class InstallationProgressTracker: ObservableObject
|
||||||
{
|
{
|
||||||
switch output
|
switch output
|
||||||
{
|
{
|
||||||
case .standardOutput(let outputLine):
|
case .standardOutput(let outputLines):
|
||||||
AppConstants.shared.logger.debug("Package install line out: \(outputLine, privacy: .public)")
|
for outputLine in outputLines.split(separator: "\n")
|
||||||
|
|
||||||
if showRealTimeTerminalOutputs
|
|
||||||
{
|
{
|
||||||
packageBeingInstalled.realTimeTerminalOutput.append(RealTimeTerminalLine(line: outputLine))
|
let outputLine: String = String(outputLine)
|
||||||
}
|
AppConstants.shared.logger.debug("Package install line out: \(outputLine, privacy: .public)")
|
||||||
|
|
||||||
if let stage = BrewInstallationStage.matchingFormula(
|
if showRealTimeTerminalOutputs
|
||||||
outputLine,
|
|
||||||
packageName: package.name,
|
|
||||||
packageDependencies: packageDependencies,
|
|
||||||
hasAlreadyMatchedPackage: hasAlreadyMatchedPackage
|
|
||||||
)
|
|
||||||
{
|
|
||||||
switch stage
|
|
||||||
{
|
{
|
||||||
case .calculatingDependencies:
|
packageBeingInstalled.realTimeTerminalOutput.append(RealTimeTerminalLine(line: outputLine))
|
||||||
AppConstants.shared.logger.warning("Output line: \(outputLine)")
|
|
||||||
|
|
||||||
if var matchedDependencies = try? outputLine.regexMatch("(?<=\(package.name): ).*?(.*)")
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.info("Matched a line describing the dependencies that will be downloaded")
|
|
||||||
matchedDependencies = matchedDependencies.replacingOccurrences(of: " and", with: ",")
|
|
||||||
packageDependencies = matchedDependencies.components(separatedBy: ", ")
|
|
||||||
|
|
||||||
AppConstants.shared.logger.debug("Will fetch \(packageDependencies.count) dependencies!")
|
|
||||||
numberOfPackageDependencies = packageDependencies.count
|
|
||||||
}
|
|
||||||
packageBeingInstalled.packageInstallationProgress = 1
|
|
||||||
|
|
||||||
case .fetchingDependencies(let packageDependencies):
|
|
||||||
AppConstants.shared.logger.info("Will fetch dependencies!")
|
|
||||||
packageBeingInstalled.installationStage = .fetchingDependencies
|
|
||||||
|
|
||||||
numberInLineOfPackageCurrentlyBeingFetched = numberInLineOfPackageCurrentlyBeingFetched + 1
|
|
||||||
|
|
||||||
AppConstants.shared.logger.info("Fetching dependency \(self.numberInLineOfPackageCurrentlyBeingFetched) of \(packageDependencies.count)")
|
|
||||||
|
|
||||||
packageBeingInstalled.packageInstallationProgress = packageBeingInstalled.packageInstallationProgress + Double(Double(10) / (Double(3) * (Double(numberOfPackageDependencies) * Double(5))))
|
|
||||||
|
|
||||||
case .installingDependencies(let packageName):
|
|
||||||
AppConstants.shared.logger.info("Will install dependencies!")
|
|
||||||
packageBeingInstalled.installationStage = .installingDependencies
|
|
||||||
numberInLineOfPackageCurrentlyBeingInstalled += 1
|
|
||||||
packageBeingInstalled.packageInstallationProgress += Double(10) / (3 * Double(numberOfPackageDependencies))
|
|
||||||
|
|
||||||
case .installingPackage(let packageName, let isFirstMatch):
|
|
||||||
if hasAlreadyMatchedPackage
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.info("Will install the package itself!")
|
|
||||||
packageBeingInstalled.installationStage = .installingPackage
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AppConstants.shared.logger.info("Matched the dud line about the package itself being installed!")
|
|
||||||
hasAlreadyMatchedPackage = true
|
|
||||||
}
|
|
||||||
packageBeingInstalled.packageInstallationProgress += (10 - packageBeingInstalled.packageInstallationProgress) / 2
|
|
||||||
|
|
||||||
case .requiresSudoPassword:
|
|
||||||
packageBeingInstalled.installationStage = .requiresSudoPassword
|
|
||||||
|
|
||||||
case .finished:
|
|
||||||
packageBeingInstalled.packageInstallationProgress = 10
|
|
||||||
packageBeingInstalled.installationStage = .finished
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let stage = BrewInstallationStage.matchingFormula(
|
||||||
|
outputLine,
|
||||||
|
packageName: package.name,
|
||||||
|
packageDependencies: packageDependencies,
|
||||||
|
hasAlreadyMatchedPackage: hasAlreadyMatchedPackage
|
||||||
|
)
|
||||||
|
{
|
||||||
|
packageBeingInstalled.installationStage = stage
|
||||||
|
switch stage
|
||||||
|
{
|
||||||
|
case .calculatingDependencies:
|
||||||
|
AppConstants.shared.logger.warning("Output line: \(outputLine)")
|
||||||
|
|
||||||
|
if var matchedDependencies = try? outputLine.regexMatch("(?<=\(package.name): ).*?(.*)")
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.info("Matched a line describing the dependencies that will be downloaded")
|
||||||
|
matchedDependencies = matchedDependencies.replacingOccurrences(of: " and", with: ",")
|
||||||
|
packageDependencies = matchedDependencies.components(separatedBy: ", ")
|
||||||
|
|
||||||
|
AppConstants.shared.logger.debug("Will fetch \(packageDependencies.count) dependencies!")
|
||||||
|
numberOfPackageDependencies = packageDependencies.count
|
||||||
|
}
|
||||||
|
packageBeingInstalled.packageInstallationProgress = 1
|
||||||
|
|
||||||
|
case .fetchingDependencies(let packageDependencies):
|
||||||
|
AppConstants.shared.logger.info("Will fetch dependencies!")
|
||||||
|
|
||||||
|
numberInLineOfPackageCurrentlyBeingFetched = numberInLineOfPackageCurrentlyBeingFetched + 1
|
||||||
|
|
||||||
|
AppConstants.shared.logger.info("Fetching dependency \(self.numberInLineOfPackageCurrentlyBeingFetched) of \(packageDependencies.count)")
|
||||||
|
|
||||||
|
packageBeingInstalled.packageInstallationProgress = packageBeingInstalled.packageInstallationProgress + Double(Double(10) / (Double(3) * (Double(numberOfPackageDependencies) * Double(5))))
|
||||||
|
|
||||||
|
case .installingDependencies:
|
||||||
|
AppConstants.shared.logger.info("Will install dependencies!")
|
||||||
|
numberInLineOfPackageCurrentlyBeingInstalled += 1
|
||||||
|
packageBeingInstalled.packageInstallationProgress += Double(10) / (3 * Double(numberOfPackageDependencies))
|
||||||
|
|
||||||
|
case .installingPackage:
|
||||||
|
if hasAlreadyMatchedPackage
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.info("Will install the package itself!")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppConstants.shared.logger.info("Matched the dud line about the package itself being installed!")
|
||||||
|
hasAlreadyMatchedPackage = true
|
||||||
|
}
|
||||||
|
packageBeingInstalled.packageInstallationProgress += (10 - packageBeingInstalled.packageInstallationProgress) / 2
|
||||||
|
|
||||||
|
case .requiresSudoPassword:
|
||||||
|
packageBeingInstalled.installationStage = .requiresSudoPassword
|
||||||
|
|
||||||
|
case .finished:
|
||||||
|
packageBeingInstalled.packageInstallationProgress = 10
|
||||||
|
packageBeingInstalled.installationStage = .finished
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
installOutput.append(outputLine)
|
||||||
|
AppConstants.shared.logger.debug("Current installation stage: \(self.packageBeingInstalled.installationStage.description, privacy: .public)")
|
||||||
}
|
}
|
||||||
|
|
||||||
installOutput.append(outputLine)
|
case .standardError(let errorLines):
|
||||||
AppConstants.shared.logger.debug("Current installation stage: \(self.packageBeingInstalled.installationStage.description, privacy: .public)")
|
AppConstants.shared.logger.error("Errored out: \(errorLines, privacy: .public)")
|
||||||
|
|
||||||
case .standardError(let errorLine):
|
|
||||||
AppConstants.shared.logger.error("Errored out: \(errorLine, privacy: .public)")
|
|
||||||
|
|
||||||
if showRealTimeTerminalOutputs
|
if showRealTimeTerminalOutputs
|
||||||
{
|
{
|
||||||
packageBeingInstalled.realTimeTerminalOutput.append(RealTimeTerminalLine(line: errorLine))
|
packageBeingInstalled.realTimeTerminalOutput.append(RealTimeTerminalLine(line: errorLines))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let stage = BrewInstallationStage.matchingFormula(
|
if let stage = BrewInstallationStage.matchingFormula(
|
||||||
errorLine,
|
errorLines,
|
||||||
packageName: package.name,
|
packageName: package.name,
|
||||||
packageDependencies: packageDependencies,
|
packageDependencies: packageDependencies,
|
||||||
hasAlreadyMatchedPackage: hasAlreadyMatchedPackage
|
hasAlreadyMatchedPackage: hasAlreadyMatchedPackage
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
packageBeingInstalled.installationStage = .requiresSudoPassword
|
packageBeingInstalled.installationStage = stage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -198,31 +200,27 @@ class InstallationProgressTracker: ObservableObject
|
||||||
|
|
||||||
if let stage = BrewInstallationStage.matchingCask(outputLine)
|
if let stage = BrewInstallationStage.matchingCask(outputLine)
|
||||||
{
|
{
|
||||||
|
packageBeingInstalled.installationStage = stage
|
||||||
switch stage
|
switch stage
|
||||||
{
|
{
|
||||||
case .downloadingCask:
|
case .downloadingCask:
|
||||||
AppConstants.shared.logger.info("Will download Cask")
|
AppConstants.shared.logger.info("Will download Cask")
|
||||||
packageBeingInstalled.installationStage = .downloadingCask
|
|
||||||
packageBeingInstalled.packageInstallationProgress += 2
|
packageBeingInstalled.packageInstallationProgress += 2
|
||||||
|
|
||||||
case .installingCask:
|
case .installingCask:
|
||||||
AppConstants.shared.logger.info("Will install Cask")
|
AppConstants.shared.logger.info("Will install Cask")
|
||||||
packageBeingInstalled.installationStage = .installingCask
|
|
||||||
packageBeingInstalled.packageInstallationProgress += 2
|
packageBeingInstalled.packageInstallationProgress += 2
|
||||||
|
|
||||||
case .movingCask:
|
case .movingCask:
|
||||||
AppConstants.shared.logger.info("Moving App")
|
AppConstants.shared.logger.info("Moving App")
|
||||||
packageBeingInstalled.installationStage = .movingCask
|
|
||||||
packageBeingInstalled.packageInstallationProgress += 2
|
packageBeingInstalled.packageInstallationProgress += 2
|
||||||
|
|
||||||
case .linkingCaskBinary:
|
case .linkingCaskBinary:
|
||||||
AppConstants.shared.logger.info("Linking Binary")
|
AppConstants.shared.logger.info("Linking Binary")
|
||||||
packageBeingInstalled.installationStage = .linkingCaskBinary
|
|
||||||
packageBeingInstalled.packageInstallationProgress += 2
|
packageBeingInstalled.packageInstallationProgress += 2
|
||||||
|
|
||||||
case .finished:
|
case .finished:
|
||||||
AppConstants.shared.logger.info("Finished installing app")
|
AppConstants.shared.logger.info("Finished installing app")
|
||||||
packageBeingInstalled.installationStage = .finished
|
|
||||||
packageBeingInstalled.packageInstallationProgress = 10
|
packageBeingInstalled.packageInstallationProgress = 10
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -240,7 +238,7 @@ class InstallationProgressTracker: ObservableObject
|
||||||
|
|
||||||
if let stage = BrewInstallationStage.matchingCask(errorLine)
|
if let stage = BrewInstallationStage.matchingCask(errorLine)
|
||||||
{
|
{
|
||||||
packageBeingInstalled.installationStage = .terminatedUnexpectedly
|
packageBeingInstalled.installationStage = stage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +260,7 @@ private protocol InstallationStage
|
||||||
|
|
||||||
// MARK: - Installation Stage Enum
|
// MARK: - Installation Stage Enum
|
||||||
|
|
||||||
enum BrewInstallationStage: InstallationStage
|
enum BrewInstallationStage: InstallationStage, Equatable
|
||||||
{
|
{
|
||||||
// Formula-specific stages
|
// Formula-specific stages
|
||||||
case calculatingDependencies
|
case calculatingDependencies
|
||||||
|
|
@ -277,10 +275,12 @@ enum BrewInstallationStage: InstallationStage
|
||||||
case linkingCaskBinary
|
case linkingCaskBinary
|
||||||
|
|
||||||
// Common stages
|
// Common stages
|
||||||
|
case ready
|
||||||
case requiresSudoPassword
|
case requiresSudoPassword
|
||||||
case finished
|
case finished
|
||||||
case binaryAlreadyExists
|
case binaryAlreadyExists
|
||||||
case wrongArchitecture
|
case wrongArchitecture
|
||||||
|
case terminatedUnexpectedly
|
||||||
|
|
||||||
fileprivate var matchConditions: [MatchCondition]
|
fileprivate var matchConditions: [MatchCondition]
|
||||||
{
|
{
|
||||||
|
|
@ -308,7 +308,7 @@ enum BrewInstallationStage: InstallationStage
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
case .installingPackage(let packageName, let isFirstMatch):
|
case .installingPackage(let packageName, _):
|
||||||
return [
|
return [
|
||||||
.simple("Fetching \(packageName)"),
|
.simple("Fetching \(packageName)"),
|
||||||
.simple("Installing \(packageName)")
|
.simple("Installing \(packageName)")
|
||||||
|
|
@ -334,6 +334,9 @@ enum BrewInstallationStage: InstallationStage
|
||||||
return [
|
return [
|
||||||
.simple("==> Linking binary")
|
.simple("==> Linking binary")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
case .ready:
|
||||||
|
return []
|
||||||
|
|
||||||
case .requiresSudoPassword:
|
case .requiresSudoPassword:
|
||||||
return [
|
return [
|
||||||
|
|
@ -358,6 +361,9 @@ enum BrewInstallationStage: InstallationStage
|
||||||
line.contains("but you are running")
|
line.contains("but you are running")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
case .terminatedUnexpectedly:
|
||||||
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,6 +387,8 @@ enum BrewInstallationStage: InstallationStage
|
||||||
return "Moving Cask"
|
return "Moving Cask"
|
||||||
case .linkingCaskBinary:
|
case .linkingCaskBinary:
|
||||||
return "Linking Binary"
|
return "Linking Binary"
|
||||||
|
case .ready:
|
||||||
|
return "Ready"
|
||||||
case .requiresSudoPassword:
|
case .requiresSudoPassword:
|
||||||
return "Requires Sudo Password"
|
return "Requires Sudo Password"
|
||||||
case .finished:
|
case .finished:
|
||||||
|
|
@ -389,6 +397,8 @@ enum BrewInstallationStage: InstallationStage
|
||||||
return "Binary Already Exists"
|
return "Binary Already Exists"
|
||||||
case .wrongArchitecture:
|
case .wrongArchitecture:
|
||||||
return "Wrong Architecture"
|
return "Wrong Architecture"
|
||||||
|
case .terminatedUnexpectedly:
|
||||||
|
return "Terminated Unexpectedly"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ struct PackageInProgressOfBeingInstalled: Identifiable
|
||||||
let id: UUID = .init()
|
let id: UUID = .init()
|
||||||
|
|
||||||
let package: BrewPackage
|
let package: BrewPackage
|
||||||
var installationStage: PackageInstallationStage
|
var installationStage: BrewInstallationStage
|
||||||
var packageInstallationProgress: Double
|
var packageInstallationProgress: Double
|
||||||
|
|
||||||
var realTimeTerminalOutput: [RealTimeTerminalLine] = .init()
|
var realTimeTerminalOutput: [RealTimeTerminalLine] = .init()
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,9 @@ struct InstallingPackageView: View
|
||||||
Text("add-package.install.ready")
|
Text("add-package.install.ready")
|
||||||
|
|
||||||
// FORMULAE
|
// FORMULAE
|
||||||
case .loadingDependencies:
|
case .calculatingDependencies:
|
||||||
Text("add-package.install.loading-dependencies")
|
Text("add-package.install.calculating-dependencies")
|
||||||
|
|
||||||
case .fetchingDependencies:
|
case .fetchingDependencies:
|
||||||
Text("add-package.install.fetching-dependencies")
|
Text("add-package.install.fetching-dependencies")
|
||||||
|
|
||||||
|
|
@ -125,12 +125,13 @@ struct InstallingPackageView: View
|
||||||
AppConstants.shared.logger.debug("Installation result:\nStandard output: \(installationResult.standardOutput, privacy: .public)\nStandard error: \(installationResult.standardError, privacy: .public)")
|
AppConstants.shared.logger.debug("Installation result:\nStandard output: \(installationResult.standardOutput, privacy: .public)\nStandard error: \(installationResult.standardError, privacy: .public)")
|
||||||
|
|
||||||
/// Check if the package installation stag at the end of the install process was something unexpected. Normal package installations go through multiple steps, and the three listed below are not supposed to be the end state. This means that something went wrong during the installation
|
/// Check if the package installation stag at the end of the install process was something unexpected. Normal package installations go through multiple steps, and the three listed below are not supposed to be the end state. This means that something went wrong during the installation
|
||||||
let installationStage: PackageInstallationStage = installationProgressTracker.packageBeingInstalled.installationStage
|
switch installationProgressTracker.packageBeingInstalled.installationStage {
|
||||||
if [.installingCask, .installingPackage, .ready].contains(installationStage)
|
case .installingCask, .installingPackage, .ready:
|
||||||
{
|
|
||||||
AppConstants.shared.logger.warning("The installation process quit before it was supposed to")
|
AppConstants.shared.logger.warning("The installation process quit before it was supposed to")
|
||||||
|
|
||||||
installationProgressTracker.packageBeingInstalled.installationStage = .terminatedUnexpectedly
|
installationProgressTracker.packageBeingInstalled.installationStage = .terminatedUnexpectedly
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch let fatalInstallationError
|
catch let fatalInstallationError
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue