mirror of
https://github.com/ninxsoft/Mist.git
synced 2025-05-13 06:34:44 -04:00
SwiftFormat blankLinesAtStartOfScope
This commit is contained in:
parent
f4e7be977e
commit
6ac54e9a3d
67 changed files with 0 additions and 157 deletions
|
@ -51,7 +51,6 @@ struct AppCommands: Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func help() {
|
private func help() {
|
||||||
|
|
||||||
guard let url: URL = URL(string: .repositoryURL) else {
|
guard let url: URL = URL(string: .repositoryURL) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import AppKit
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
// swiftlint:disable:next weak_delegate
|
// swiftlint:disable:next weak_delegate
|
||||||
private let userNotificationCenterDelegate: UserNotificationCenterDelegate = UserNotificationCenterDelegate()
|
private let userNotificationCenterDelegate: UserNotificationCenterDelegate = UserNotificationCenterDelegate()
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendUpdateNotification(title: String, body: String, success: Bool, url: URL?) {
|
func sendUpdateNotification(title: String, body: String, success: Bool, url: URL?) {
|
||||||
|
|
||||||
let notificationCenter: UNUserNotificationCenter = .current()
|
let notificationCenter: UNUserNotificationCenter = .current()
|
||||||
notificationCenter.getNotificationSettings { settings in
|
notificationCenter.getNotificationSettings { settings in
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
extension Array where Element == UInt8 {
|
extension Array where Element == UInt8 {
|
||||||
|
|
||||||
func uInt8(at offset: Int) -> UInt8 {
|
func uInt8(at offset: Int) -> UInt8 {
|
||||||
self[offset]
|
self[offset]
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Authorized
|
import Authorized
|
||||||
|
|
||||||
extension AuthorizationError: Equatable {
|
extension AuthorizationError: Equatable {
|
||||||
|
|
||||||
public static func == (lhs: AuthorizationError, rhs: AuthorizationError) -> Bool {
|
public static func == (lhs: AuthorizationError, rhs: AuthorizationError) -> Bool {
|
||||||
lhs.localizedDescription == rhs.localizedDescription
|
lhs.localizedDescription == rhs.localizedDescription
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
extension ButtonStyle where Self == MistActionButtonStyle {
|
extension ButtonStyle where Self == MistActionButtonStyle {
|
||||||
|
|
||||||
static var mistAction: Self {
|
static var mistAction: Self {
|
||||||
.init()
|
.init()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
extension Dictionary where Key == String {
|
extension Dictionary where Key == String {
|
||||||
|
|
||||||
func firmwareCSVString() -> String {
|
func firmwareCSVString() -> String {
|
||||||
|
|
||||||
guard let signed: Bool = self["signed"] as? Bool,
|
guard let signed: Bool = self["signed"] as? Bool,
|
||||||
let name: String = self["name"] as? String,
|
let name: String = self["name"] as? String,
|
||||||
let version: String = self["version"] as? String,
|
let version: String = self["version"] as? String,
|
||||||
|
@ -24,7 +22,6 @@ extension Dictionary where Key == String {
|
||||||
}
|
}
|
||||||
|
|
||||||
func installerCSVString() -> String {
|
func installerCSVString() -> String {
|
||||||
|
|
||||||
guard let identifier: String = self["identifier"] as? String,
|
guard let identifier: String = self["identifier"] as? String,
|
||||||
let name: String = self["name"] as? String,
|
let name: String = self["name"] as? String,
|
||||||
let version: String = self["version"] as? String,
|
let version: String = self["version"] as? String,
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension Double {
|
extension Double {
|
||||||
|
|
||||||
/// kilobytes constant
|
/// kilobytes constant
|
||||||
static let kilobyte: Double = 1_000
|
static let kilobyte: Double = 1_000
|
||||||
/// megabytes constant
|
/// megabytes constant
|
||||||
|
@ -17,7 +16,6 @@ extension Double {
|
||||||
static let gigabyte: Double = .megabyte * 1_000
|
static let gigabyte: Double = .megabyte * 1_000
|
||||||
|
|
||||||
func bytesString() -> String {
|
func bytesString() -> String {
|
||||||
|
|
||||||
if self < .kilobyte {
|
if self < .kilobyte {
|
||||||
return "\(Int(self)) bytes"
|
return "\(Int(self)) bytes"
|
||||||
} else if self < .megabyte {
|
} else if self < .megabyte {
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension FileManager {
|
extension FileManager {
|
||||||
|
|
||||||
func sizeOfDirectory(at url: URL) throws -> UInt64 {
|
func sizeOfDirectory(at url: URL) throws -> UInt64 {
|
||||||
|
|
||||||
var enumeratorError: Error?
|
var enumeratorError: Error?
|
||||||
|
|
||||||
let urlResourceKeys: Set<URLResourceKey> = [
|
let urlResourceKeys: Set<URLResourceKey> = [
|
||||||
|
@ -29,7 +27,6 @@ extension FileManager {
|
||||||
var size: UInt64 = 0
|
var size: UInt64 = 0
|
||||||
|
|
||||||
for item in enumerator {
|
for item in enumerator {
|
||||||
|
|
||||||
if enumeratorError != nil {
|
if enumeratorError != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
extension Scene {
|
extension Scene {
|
||||||
|
|
||||||
func fixedWindow() -> some Scene {
|
func fixedWindow() -> some Scene {
|
||||||
if #available(macOS 13.0, *) {
|
if #available(macOS 13.0, *) {
|
||||||
return self.windowResizability(.contentSize)
|
return self.windowResizability(.contentSize)
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
import Yams
|
import Yams
|
||||||
|
|
||||||
extension Sequence where Iterator.Element == [String: Any] {
|
extension Sequence where Iterator.Element == [String: Any] {
|
||||||
|
|
||||||
func firmwaresCSVString() -> String {
|
func firmwaresCSVString() -> String {
|
||||||
"Signed,Name,Version,Build,Size,Date,Compatible\n" + self.map { $0.firmwareCSVString() }.joined()
|
"Signed,Name,Version,Build,Size,Date,Compatible\n" + self.map { $0.firmwareCSVString() }.joined()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
|
|
||||||
static let appName: String = "mist"
|
static let appName: String = "mist"
|
||||||
static let appIdentifier: String = "com.ninxsoft.\(appName)"
|
static let appIdentifier: String = "com.ninxsoft.\(appName)"
|
||||||
static let helperIdentifier: String = "\(appIdentifier).helper"
|
static let helperIdentifier: String = "\(appIdentifier).helper"
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension UInt32 {
|
extension UInt32 {
|
||||||
|
|
||||||
func hexString() -> String {
|
func hexString() -> String {
|
||||||
String(format: "0x%08X", self)
|
String(format: "0x%08X", self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension UInt64 {
|
extension UInt64 {
|
||||||
|
|
||||||
/// kilobytes constant
|
/// kilobytes constant
|
||||||
static let kilobyte: UInt64 = 1_000
|
static let kilobyte: UInt64 = 1_000
|
||||||
/// megabytes constant
|
/// megabytes constant
|
||||||
|
@ -17,7 +16,6 @@ extension UInt64 {
|
||||||
static let gigabyte: UInt64 = .megabyte * 1_000
|
static let gigabyte: UInt64 = .megabyte * 1_000
|
||||||
|
|
||||||
func bytesString() -> String {
|
func bytesString() -> String {
|
||||||
|
|
||||||
if self < .kilobyte {
|
if self < .kilobyte {
|
||||||
return "\(self) bytes"
|
return "\(self) bytes"
|
||||||
} else if self < .megabyte {
|
} else if self < .megabyte {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension UInt8 {
|
extension UInt8 {
|
||||||
|
|
||||||
func hexString() -> String {
|
func hexString() -> String {
|
||||||
String(format: "0x%02X", self)
|
String(format: "0x%02X", self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
extension UNNotificationAction {
|
extension UNNotificationAction {
|
||||||
|
|
||||||
struct Identifier {
|
struct Identifier {
|
||||||
/// Show Identifier
|
/// Show Identifier
|
||||||
static let show: String = "Show"
|
static let show: String = "Show"
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
extension UNNotificationCategory {
|
extension UNNotificationCategory {
|
||||||
|
|
||||||
struct Identifier {
|
struct Identifier {
|
||||||
/// Success Identifier
|
/// Success Identifier
|
||||||
static let success: String = "Success"
|
static let success: String = "Success"
|
||||||
|
|
|
@ -9,9 +9,7 @@ import CryptoKit
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension URL {
|
extension URL {
|
||||||
|
|
||||||
func fileSize() throws -> UInt64 {
|
func fileSize() throws -> UInt64 {
|
||||||
|
|
||||||
let urlResourceKeys: Set<URLResourceKey> = [
|
let urlResourceKeys: Set<URLResourceKey> = [
|
||||||
.isRegularFileKey,
|
.isRegularFileKey,
|
||||||
.fileAllocatedSizeKey,
|
.fileAllocatedSizeKey,
|
||||||
|
@ -29,7 +27,6 @@ extension URL {
|
||||||
}
|
}
|
||||||
|
|
||||||
func shasum() -> String? {
|
func shasum() -> String? {
|
||||||
|
|
||||||
let length: Int = 1_024 * 1_024 * 50 // 50 MB
|
let length: Int = 1_024 * 1_024 * 50 // 50 MB
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to codesign a file (ie. Disk Image).
|
/// Helper struct to codesign a file (ie. Disk Image).
|
||||||
struct Codesigner {
|
struct Codesigner {
|
||||||
|
|
||||||
/// Sign a file with the provided signing identity.
|
/// Sign a file with the provided signing identity.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to create directories.
|
/// Helper struct to create directories.
|
||||||
struct DirectoryCreator {
|
struct DirectoryCreator {
|
||||||
|
|
||||||
/// Create a directory at the provided URL.
|
/// Create a directory at the provided URL.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -10,7 +10,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper struct to remove directories
|
/// Helper struct to remove directories
|
||||||
struct DirectoryRemover {
|
struct DirectoryRemover {
|
||||||
|
|
||||||
/// Remove directory at the provided URL.
|
/// Remove directory at the provided URL.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -18,7 +17,6 @@ struct DirectoryRemover {
|
||||||
///
|
///
|
||||||
/// - Throws: An `Error` if the command failed to execute.
|
/// - Throws: An `Error` if the command failed to execute.
|
||||||
static func remove(_ url: URL) async throws {
|
static func remove(_ url: URL) async throws {
|
||||||
|
|
||||||
guard FileManager.default.fileExists(atPath: url.path) else {
|
guard FileManager.default.fileExists(atPath: url.path) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to create disk images.
|
/// Helper struct to create disk images.
|
||||||
struct DiskImageCreator {
|
struct DiskImageCreator {
|
||||||
|
|
||||||
/// Create an empty Disk Image of fixed size.
|
/// Create an empty Disk Image of fixed size.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -18,7 +17,6 @@ struct DiskImageCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: An `MistError` if the command failed to execute.
|
/// - Throws: An `MistError` if the command failed to execute.
|
||||||
static func create(_ url: URL, size: Double) async throws {
|
static func create(_ url: URL, size: Double) async throws {
|
||||||
|
|
||||||
let arguments: [String] = [
|
let arguments: [String] = [
|
||||||
"hdiutil", "create",
|
"hdiutil", "create",
|
||||||
"-fs", "JHFS+",
|
"-fs", "JHFS+",
|
||||||
|
@ -38,7 +36,6 @@ struct DiskImageCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: An `MistError` if the command failed to execute.
|
/// - Throws: An `MistError` if the command failed to execute.
|
||||||
static func create(_ url: URL, from source: URL) async throws {
|
static func create(_ url: URL, from source: URL) async throws {
|
||||||
|
|
||||||
let arguments: [String] = [
|
let arguments: [String] = [
|
||||||
"hdiutil", "create",
|
"hdiutil", "create",
|
||||||
"-fs", "HFS+",
|
"-fs", "HFS+",
|
||||||
|
@ -57,7 +54,6 @@ struct DiskImageCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: An `MistError` if the command failed to execute.
|
/// - Throws: An `MistError` if the command failed to execute.
|
||||||
private static func create(_ url: URL, with arguments: [String]) async throws {
|
private static func create(_ url: URL, with arguments: [String]) async throws {
|
||||||
|
|
||||||
try await DirectoryRemover.remove(url)
|
try await DirectoryRemover.remove(url)
|
||||||
let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments)
|
let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to mount Disk Images.
|
/// Helper struct to mount Disk Images.
|
||||||
struct DiskImageMounter {
|
struct DiskImageMounter {
|
||||||
|
|
||||||
/// Mount a Disk Image at the provided mount point.
|
/// Mount a Disk Image at the provided mount point.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -18,7 +17,6 @@ struct DiskImageMounter {
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the command failed to execute.
|
/// - Throws: A `MistError` if the command failed to execute.
|
||||||
static func mount(_ url: URL, mountPoint: URL) async throws {
|
static func mount(_ url: URL, mountPoint: URL) async throws {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await DiskImageUnmounter.unmount(mountPoint)
|
try await DiskImageUnmounter.unmount(mountPoint)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to unmount Disk Images.
|
/// Helper struct to unmount Disk Images.
|
||||||
struct DiskImageUnmounter {
|
struct DiskImageUnmounter {
|
||||||
|
|
||||||
/// Unmount a Disk Image at the provided mount point.
|
/// Unmount a Disk Image at the provided mount point.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class DownloadManager: NSObject, ObservableObject {
|
class DownloadManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
static let shared: DownloadManager = DownloadManager()
|
static let shared: DownloadManager = DownloadManager()
|
||||||
private var task: URLSessionDownloadTask?
|
private var task: URLSessionDownloadTask?
|
||||||
private var progress: Progress = Progress()
|
private var progress: Progress = Progress()
|
||||||
|
@ -18,7 +17,6 @@ class DownloadManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
// swiftlint:disable:next cyclomatic_complexity function_body_length
|
// swiftlint:disable:next cyclomatic_complexity function_body_length
|
||||||
func download(_ url: URL, to destination: URL, retries retriesMaximum: Int, delay retryDelay: Int) async throws {
|
func download(_ url: URL, to destination: URL, retries retriesMaximum: Int, delay retryDelay: Int) async throws {
|
||||||
|
|
||||||
guard !FileManager.default.fileExists(atPath: destination.path) else {
|
guard !FileManager.default.fileExists(atPath: destination.path) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -32,7 +30,6 @@ class DownloadManager: NSObject, ObservableObject {
|
||||||
let completionHandler: (URL?, URLResponse?, Error?) -> Void = { url, _, error in
|
let completionHandler: (URL?, URLResponse?, Error?) -> Void = { url, _, error in
|
||||||
|
|
||||||
if let error: URLError = error as? URLError {
|
if let error: URLError = error as? URLError {
|
||||||
|
|
||||||
guard error.code != .cancelled else {
|
guard error.code != .cancelled else {
|
||||||
mistError = .userCancelled
|
mistError = .userCancelled
|
||||||
completed = true
|
completed = true
|
||||||
|
@ -74,13 +71,11 @@ class DownloadManager: NSObject, ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
while !completed {
|
while !completed {
|
||||||
|
|
||||||
guard retries < retriesMaximum else {
|
guard retries < retriesMaximum else {
|
||||||
throw MistError.maximumRetriesReached
|
throw MistError.maximumRetriesReached
|
||||||
}
|
}
|
||||||
|
|
||||||
if let error: URLError = urlError {
|
if let error: URLError = urlError {
|
||||||
|
|
||||||
guard let data: Data = error.downloadTaskResumeData else {
|
guard let data: Data = error.downloadTaskResumeData else {
|
||||||
throw MistError.invalidDownloadResumeData
|
throw MistError.invalidDownloadResumeData
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper struct to update file / directory attributes
|
/// Helper struct to update file / directory attributes
|
||||||
struct FileAttributesUpdater {
|
struct FileAttributesUpdater {
|
||||||
|
|
||||||
/// Update file / directory attributes at the provided URL.
|
/// Update file / directory attributes at the provided URL.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -19,7 +18,6 @@ struct FileAttributesUpdater {
|
||||||
///
|
///
|
||||||
/// - Throws: An `Error` if the command failed to execute.
|
/// - Throws: An `Error` if the command failed to execute.
|
||||||
static func update(url: URL, ownerAccountName: String) async throws {
|
static func update(url: URL, ownerAccountName: String) async throws {
|
||||||
|
|
||||||
guard FileManager.default.fileExists(atPath: url.path) else {
|
guard FileManager.default.fileExists(atPath: url.path) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to copy files.
|
/// Helper struct to copy files.
|
||||||
struct FileCopier {
|
struct FileCopier {
|
||||||
|
|
||||||
/// Copy a file from one location to another.
|
/// Copy a file from one location to another.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to move files.
|
/// Helper struct to move files.
|
||||||
struct FileMover {
|
struct FileMover {
|
||||||
|
|
||||||
/// Move a file from one location to another.
|
/// Move a file from one location to another.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to convert Disk Images to ISOs.
|
/// Helper struct to convert Disk Images to ISOs.
|
||||||
struct ISOConverter {
|
struct ISOConverter {
|
||||||
|
|
||||||
/// Convert a Disk Image to an ISO.
|
/// Convert a Disk Image to an ISO.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -10,7 +10,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper struct to execute the `createinstallmedia` command found in macOS Install app bundles.
|
/// Helper struct to execute the `createinstallmedia` command found in macOS Install app bundles.
|
||||||
struct InstallMediaCreator {
|
struct InstallMediaCreator {
|
||||||
|
|
||||||
/// Create the macOS Install Media at the specified mount point.
|
/// Create the macOS Install Media at the specified mount point.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
|
|
@ -10,7 +10,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper Struct used to create macOS Installers.
|
/// Helper Struct used to create macOS Installers.
|
||||||
struct InstallerCreator {
|
struct InstallerCreator {
|
||||||
|
|
||||||
/// Creates a recently downloaded macOS Installer.
|
/// Creates a recently downloaded macOS Installer.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -20,11 +19,9 @@ struct InstallerCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the downloaded macOS Installer fails to generate.
|
/// - Throws: A `MistError` if the downloaded macOS Installer fails to generate.
|
||||||
static func create(_ installer: Installer, mountPoint: URL, cacheDirectory: String) async throws {
|
static func create(_ installer: Installer, mountPoint: URL, cacheDirectory: String) async throws {
|
||||||
|
|
||||||
let packageURL: URL
|
let packageURL: URL
|
||||||
|
|
||||||
if installer.sierraOrOlder {
|
if installer.sierraOrOlder {
|
||||||
|
|
||||||
guard let package: Package = installer.packages.first else {
|
guard let package: Package = installer.packages.first else {
|
||||||
throw MistError.invalidData
|
throw MistError.invalidData
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to create macOS Installer Packages.
|
/// Helper struct to create macOS Installer Packages.
|
||||||
struct PackageCreator {
|
struct PackageCreator {
|
||||||
|
|
||||||
/// Create a macOS Installer Package based off the passed in `Installer` struct.
|
/// Create a macOS Installer Package based off the passed in `Installer` struct.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -20,7 +19,6 @@ struct PackageCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: An `Error` if the command failed to execute.
|
/// - Throws: An `Error` if the command failed to execute.
|
||||||
static func create(_ url: URL, from installer: Installer, identifier: String, identity: String? = nil) async throws {
|
static func create(_ url: URL, from installer: Installer, identifier: String, identity: String? = nil) async throws {
|
||||||
|
|
||||||
var arguments: [String] = [
|
var arguments: [String] = [
|
||||||
"pkgbuild",
|
"pkgbuild",
|
||||||
"--identifier", identifier,
|
"--identifier", identifier,
|
||||||
|
@ -45,7 +43,6 @@ struct PackageCreator {
|
||||||
///
|
///
|
||||||
/// - Throws: An `MistError` if the command failed to execute.
|
/// - Throws: An `MistError` if the command failed to execute.
|
||||||
private static func create(_ url: URL, with arguments: [String]) async throws {
|
private static func create(_ url: URL, with arguments: [String]) async throws {
|
||||||
|
|
||||||
try await DirectoryRemover.remove(url)
|
try await DirectoryRemover.remove(url)
|
||||||
let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments)
|
let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to perform lookups on the Privilged Helper Tool executable.
|
/// Helper struct to perform lookups on the Privilged Helper Tool executable.
|
||||||
struct PrivilegedHelperTool {
|
struct PrivilegedHelperTool {
|
||||||
|
|
||||||
/// The URL of the Privileged Helper Tool within the Mist app bundle.
|
/// The URL of the Privileged Helper Tool within the Mist app bundle.
|
||||||
static let availableURL: URL = URL(fileURLWithPath: "\(Bundle.main.bundlePath)/Contents/Library/LaunchServices/\(String.helperIdentifier)")
|
static let availableURL: URL = URL(fileURLWithPath: "\(Bundle.main.bundlePath)/Contents/Library/LaunchServices/\(String.helperIdentifier)")
|
||||||
/// The URL of the Privileged Helper Tool within /Library/PrivilegedHelperTools.
|
/// The URL of the Privileged Helper Tool within /Library/PrivilegedHelperTools.
|
||||||
|
@ -19,7 +18,6 @@ struct PrivilegedHelperTool {
|
||||||
///
|
///
|
||||||
/// - Returns: `true` if the Privileged Helper Tool is installed, otherwise `false`.
|
/// - Returns: `true` if the Privileged Helper Tool is installed, otherwise `false`.
|
||||||
static func isInstalled() -> Bool {
|
static func isInstalled() -> Bool {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// launchctl service is loaded
|
// launchctl service is loaded
|
||||||
let arguments: [String] = ["launchctl", "print", "system/\(String.helperIdentifier)"]
|
let arguments: [String] = ["launchctl", "print", "system/\(String.helperIdentifier)"]
|
||||||
|
|
|
@ -9,7 +9,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper struct to kill the child process of the Privileted Helper Tool.
|
/// Helper struct to kill the child process of the Privileted Helper Tool.
|
||||||
struct ProcessKiller {
|
struct ProcessKiller {
|
||||||
|
|
||||||
/// Attempts to kill the child process of the Privileged Helper Tool.
|
/// Attempts to kill the child process of the Privileged Helper Tool.
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the process fails to be killed.
|
/// - Throws: A `MistError` if the process fails to be killed.
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct to update a Property List key-pair value.
|
/// Helper struct to update a Property List key-pair value.
|
||||||
struct PropertyListUpdater {
|
struct PropertyListUpdater {
|
||||||
|
|
||||||
/// Update a key-pair value in a Property List.
|
/// Update a key-pair value in a Property List.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -19,7 +18,6 @@ struct PropertyListUpdater {
|
||||||
///
|
///
|
||||||
/// - Throws: An `Error` if the command failed to execute.
|
/// - Throws: An `Error` if the command failed to execute.
|
||||||
static func update(_ url: URL, key: String, value: AnyHashable) throws {
|
static func update(_ url: URL, key: String, value: AnyHashable) throws {
|
||||||
|
|
||||||
let input: String = try String(contentsOf: url, encoding: .utf8)
|
let input: String = try String(contentsOf: url, encoding: .utf8)
|
||||||
|
|
||||||
guard var data: Data = input.data(using: .utf8) else {
|
guard var data: Data = input.data(using: .utf8) else {
|
||||||
|
|
|
@ -11,13 +11,11 @@ import System
|
||||||
// swiftlint:disable file_length
|
// swiftlint:disable file_length
|
||||||
// swiftlint:disable:next type_body_length
|
// swiftlint:disable:next type_body_length
|
||||||
class TaskManager: ObservableObject {
|
class TaskManager: ObservableObject {
|
||||||
|
|
||||||
static let shared: TaskManager = TaskManager()
|
static let shared: TaskManager = TaskManager()
|
||||||
@Published var taskGroups: [(section: MistTaskSection, tasks: [MistTask])]
|
@Published var taskGroups: [(section: MistTaskSection, tasks: [MistTask])]
|
||||||
var task: Task<Any, Error> = Task { }
|
var task: Task<Any, Error> = Task { }
|
||||||
|
|
||||||
var currentState: MistTaskState {
|
var currentState: MistTaskState {
|
||||||
|
|
||||||
let states: Set<MistTaskState> = Set(taskGroups.flatMap { $0.tasks }.map { $0.state })
|
let states: Set<MistTaskState> = Set(taskGroups.flatMap { $0.tasks }.map { $0.state })
|
||||||
|
|
||||||
if states.contains(.inProgress) {
|
if states.contains(.inProgress) {
|
||||||
|
@ -40,7 +38,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
static func taskGroups(for firmware: Firmware, destination destinationURL: URL?, retries: Int, delay retryDelay: Int) throws -> [(section: MistTaskSection, tasks: [MistTask])] {
|
static func taskGroups(for firmware: Firmware, destination destinationURL: URL?, retries: Int, delay retryDelay: Int) throws -> [(section: MistTaskSection, tasks: [MistTask])] {
|
||||||
|
|
||||||
let temporaryDirectoryURL: URL = URL(fileURLWithPath: .temporaryDirectory)
|
let temporaryDirectoryURL: URL = URL(fileURLWithPath: .temporaryDirectory)
|
||||||
|
|
||||||
guard let destinationURL: URL = destinationURL else {
|
guard let destinationURL: URL = destinationURL else {
|
||||||
|
@ -265,7 +262,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func downloadTasks(for installer: Installer, cacheDirectory cacheDirectoryURL: URL, retries: Int, delay retryDelay: Int) throws -> [MistTask] {
|
private static func downloadTasks(for installer: Installer, cacheDirectory cacheDirectoryURL: URL, retries: Int, delay retryDelay: Int) throws -> [MistTask] {
|
||||||
|
|
||||||
var tasks: [MistTask] = []
|
var tasks: [MistTask] = []
|
||||||
|
|
||||||
if !FileManager.default.fileExists(atPath: cacheDirectoryURL.path) {
|
if !FileManager.default.fileExists(atPath: cacheDirectoryURL.path) {
|
||||||
|
@ -295,7 +291,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
for package in installer.allDownloads {
|
for package in installer.allDownloads {
|
||||||
|
|
||||||
guard let packageURL: URL = URL(string: package.url) else {
|
guard let packageURL: URL = URL(string: package.url) else {
|
||||||
throw MistError.invalidURL(package.url)
|
throw MistError.invalidURL(package.url)
|
||||||
}
|
}
|
||||||
|
@ -316,7 +311,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func installTasks(for installer: Installer, temporaryDirectory temporaryDirectoryURL: URL, mountPoint mountPointURL: URL, cacheDirectory: String) -> [MistTask] {
|
private static func installTasks(for installer: Installer, temporaryDirectory temporaryDirectoryURL: URL, mountPoint mountPointURL: URL, cacheDirectory: String) -> [MistTask] {
|
||||||
|
|
||||||
let imageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id) Temp.dmg")
|
let imageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id) Temp.dmg")
|
||||||
var tasks: [MistTask] = [
|
var tasks: [MistTask] = [
|
||||||
MistTask(type: .configure, description: "temporary directory") {
|
MistTask(type: .configure, description: "temporary directory") {
|
||||||
|
@ -371,7 +365,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func applicationTasks(for installer: Installer, filename: String, destination destinationURL: URL) -> [MistTask] {
|
private static func applicationTasks(for installer: Installer, filename: String, destination destinationURL: URL) -> [MistTask] {
|
||||||
|
|
||||||
let applicationURL: URL = destinationURL.appendingPathComponent(filename.stringWithSubstitutions(name: installer.name, version: installer.version, build: installer.build))
|
let applicationURL: URL = destinationURL.appendingPathComponent(filename.stringWithSubstitutions(name: installer.name, version: installer.version, build: installer.build))
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -390,7 +383,6 @@ class TaskManager: ObservableObject {
|
||||||
destination destinationURL: URL,
|
destination destinationURL: URL,
|
||||||
temporaryDirectory temporaryDirectoryURL: URL
|
temporaryDirectory temporaryDirectoryURL: URL
|
||||||
) -> [MistTask] {
|
) -> [MistTask] {
|
||||||
|
|
||||||
let imageDirectoryURL: URL = temporaryDirectoryURL.appendingPathComponent(installer.id)
|
let imageDirectoryURL: URL = temporaryDirectoryURL.appendingPathComponent(installer.id)
|
||||||
let applicationURL: URL = imageDirectoryURL.appendingPathComponent(installer.temporaryInstallerURL.lastPathComponent)
|
let applicationURL: URL = imageDirectoryURL.appendingPathComponent(installer.temporaryInstallerURL.lastPathComponent)
|
||||||
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
||||||
|
@ -427,7 +419,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func isoTasks(for installer: Installer, filename: String, destination destinationURL: URL, temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
private static func isoTasks(for installer: Installer, filename: String, destination destinationURL: URL, temporaryDirectory temporaryDirectoryURL: URL) -> [MistTask] {
|
||||||
|
|
||||||
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
let temporaryImageURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).dmg")
|
||||||
let createInstallMediaURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Resources/createinstallmedia")
|
let createInstallMediaURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Resources/createinstallmedia")
|
||||||
let temporaryCDRURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).cdr")
|
let temporaryCDRURL: URL = temporaryDirectoryURL.appendingPathComponent("\(installer.id).cdr")
|
||||||
|
@ -442,7 +433,6 @@ class TaskManager: ObservableObject {
|
||||||
try await DiskImageMounter.mount(temporaryImageURL, mountPoint: installer.temporaryISOMountPointURL)
|
try await DiskImageMounter.mount(temporaryImageURL, mountPoint: installer.temporaryISOMountPointURL)
|
||||||
},
|
},
|
||||||
MistTask(type: .create, description: "macOS Installer in temporary Disk Image") {
|
MistTask(type: .create, description: "macOS Installer in temporary Disk Image") {
|
||||||
|
|
||||||
// Workaround to make macOS Sierra 10.12 createinstallmedia work
|
// Workaround to make macOS Sierra 10.12 createinstallmedia work
|
||||||
if installer.version.hasPrefix("10.12") {
|
if installer.version.hasPrefix("10.12") {
|
||||||
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
|
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
|
||||||
|
@ -497,7 +487,6 @@ class TaskManager: ObservableObject {
|
||||||
temporaryDirectory temporaryDirectoryURL: URL,
|
temporaryDirectory temporaryDirectoryURL: URL,
|
||||||
cacheDirectory cacheDirectoryURL: URL
|
cacheDirectory cacheDirectoryURL: URL
|
||||||
) -> [MistTask] {
|
) -> [MistTask] {
|
||||||
|
|
||||||
let packageURL: URL = destinationURL.appendingPathComponent(filename.stringWithSubstitutions(name: installer.name, version: installer.version, build: installer.build))
|
let packageURL: URL = destinationURL.appendingPathComponent(filename.stringWithSubstitutions(name: installer.name, version: installer.version, build: installer.build))
|
||||||
var tasks: [MistTask] = []
|
var tasks: [MistTask] = []
|
||||||
|
|
||||||
|
@ -532,7 +521,6 @@ class TaskManager: ObservableObject {
|
||||||
let mountPointURL: URL = URL(fileURLWithPath: volume.path)
|
let mountPointURL: URL = URL(fileURLWithPath: volume.path)
|
||||||
let tasks: [MistTask] = [
|
let tasks: [MistTask] = [
|
||||||
MistTask(type: .create, description: "Bootable Installer") {
|
MistTask(type: .create, description: "Bootable Installer") {
|
||||||
|
|
||||||
// Workaround to make macOS Sierra 10.12 createinstallmedia work
|
// Workaround to make macOS Sierra 10.12 createinstallmedia work
|
||||||
if installer.version.hasPrefix("10.12") {
|
if installer.version.hasPrefix("10.12") {
|
||||||
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
|
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
|
||||||
|
@ -547,7 +535,6 @@ class TaskManager: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func cleanupTasks(mountPoint mountPointURL: URL, temporaryDirectory temporaryDirectoryURL: URL, cacheDownloads: Bool, cacheDirectory cacheDirectoryURL: URL) -> [MistTask] {
|
private static func cleanupTasks(mountPoint mountPointURL: URL, temporaryDirectory temporaryDirectoryURL: URL, cacheDownloads: Bool, cacheDirectory cacheDirectoryURL: URL) -> [MistTask] {
|
||||||
|
|
||||||
var tasks: [MistTask] = [
|
var tasks: [MistTask] = [
|
||||||
MistTask(type: .unmount, description: "Disk Image") {
|
MistTask(type: .unmount, description: "Disk Image") {
|
||||||
try await DiskImageUnmounter.unmount(mountPointURL)
|
try await DiskImageUnmounter.unmount(mountPointURL)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper struct used to validate Firmware and Installer checksums.
|
/// Helper struct used to validate Firmware and Installer checksums.
|
||||||
struct Validator {
|
struct Validator {
|
||||||
|
|
||||||
/// Validates a Firmware's checksum.
|
/// Validates a Firmware's checksum.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -19,7 +18,6 @@ struct Validator {
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the validation fails.
|
/// - Throws: A `MistError` if the validation fails.
|
||||||
static func validate(_ firmware: Firmware, at destination: URL) async throws {
|
static func validate(_ firmware: Firmware, at destination: URL) async throws {
|
||||||
|
|
||||||
guard let shasum: String = destination.shasum() else {
|
guard let shasum: String = destination.shasum() else {
|
||||||
throw MistError.invalidData
|
throw MistError.invalidData
|
||||||
}
|
}
|
||||||
|
@ -37,7 +35,6 @@ struct Validator {
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the validation fails.
|
/// - Throws: A `MistError` if the validation fails.
|
||||||
static func validate(_ package: Package, at destination: URL) async throws {
|
static func validate(_ package: Package, at destination: URL) async throws {
|
||||||
|
|
||||||
guard !package.url.hasSuffix("English.dist") else {
|
guard !package.url.hasSuffix("English.dist") else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ struct MistApp: App {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideZoomButton() {
|
func hideZoomButton() {
|
||||||
|
|
||||||
for window in NSApplication.shared.windows {
|
for window in NSApplication.shared.windows {
|
||||||
|
|
||||||
guard let button: NSButton = window.standardWindowButton(NSWindow.ButtonType.zoomButton) else {
|
guard let button: NSButton = window.standardWindowButton(NSWindow.ButtonType.zoomButton) else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct Catalog: Identifiable, Decodable, Equatable {
|
struct Catalog: Identifiable, Decodable, Equatable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
// swiftlint:disable:next redundant_string_enum_value
|
// swiftlint:disable:next redundant_string_enum_value
|
||||||
case type = "type"
|
case type = "type"
|
||||||
|
|
|
@ -38,7 +38,6 @@ enum CatalogType: String, CaseIterable, Comparable, Decodable {
|
||||||
|
|
||||||
// swiftlint:disable:next cyclomatic_complexity
|
// swiftlint:disable:next cyclomatic_complexity
|
||||||
func url(for seedType: CatalogSeedType) -> String {
|
func url(for seedType: CatalogSeedType) -> String {
|
||||||
|
|
||||||
switch self {
|
switch self {
|
||||||
case .sonoma:
|
case .sonoma:
|
||||||
switch seedType {
|
switch seedType {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Struct used to store all elements of the Chunklist.
|
/// Struct used to store all elements of the Chunklist.
|
||||||
struct Chunklist {
|
struct Chunklist {
|
||||||
|
|
||||||
/// Chunklist Magic Header constant
|
/// Chunklist Magic Header constant
|
||||||
static let magicHeader: UInt32 = 0x4C4B4E43
|
static let magicHeader: UInt32 = 0x4C4B4E43
|
||||||
/// Chunklist Header Size constant
|
/// Chunklist Header Size constant
|
||||||
|
@ -56,7 +55,6 @@ struct Chunklist {
|
||||||
///
|
///
|
||||||
/// - Throws: A `MistError` if the Chunklist validation fails
|
/// - Throws: A `MistError` if the Chunklist validation fails
|
||||||
init(from url: URL, size: Int) throws {
|
init(from url: URL, size: Int) throws {
|
||||||
|
|
||||||
let data: Data = try Data(contentsOf: url)
|
let data: Data = try Data(contentsOf: url)
|
||||||
|
|
||||||
guard data.count == size else {
|
guard data.count == size else {
|
||||||
|
@ -121,7 +119,6 @@ struct Chunklist {
|
||||||
///
|
///
|
||||||
/// - Returns: An array of Chunk structs.
|
/// - Returns: An array of Chunk structs.
|
||||||
private static func chunks(_ array: [UInt8], totalChunks: Int) -> [Chunk] {
|
private static func chunks(_ array: [UInt8], totalChunks: Int) -> [Chunk] {
|
||||||
|
|
||||||
var chunks: [Chunk] = []
|
var chunks: [Chunk] = []
|
||||||
|
|
||||||
for offset in 0..<totalChunks {
|
for offset in 0..<totalChunks {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct Firmware: Decodable, Hashable, Identifiable {
|
struct Firmware: Decodable, Hashable, Identifiable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case version = "version"
|
case version = "version"
|
||||||
case build = "buildid"
|
case build = "buildid"
|
||||||
|
@ -49,7 +48,6 @@ struct Firmware: Decodable, Hashable, Identifiable {
|
||||||
"\(String.appIdentifier).\(version)-\(build)"
|
"\(String.appIdentifier).\(version)-\(build)"
|
||||||
}
|
}
|
||||||
var name: String {
|
var name: String {
|
||||||
|
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
|
|
||||||
if version.range(of: "^14", options: .regularExpression) != nil {
|
if version.range(of: "^14", options: .regularExpression) != nil {
|
||||||
|
@ -113,7 +111,6 @@ struct Firmware: Decodable, Hashable, Identifiable {
|
||||||
///
|
///
|
||||||
/// - Returns: An array of Firmware build strings.
|
/// - Returns: An array of Firmware build strings.
|
||||||
static func supportedBuilds() throws -> [String] {
|
static func supportedBuilds() throws -> [String] {
|
||||||
|
|
||||||
guard let architecture: Architecture = Hardware.architecture,
|
guard let architecture: Architecture = Hardware.architecture,
|
||||||
architecture == .appleSilicon,
|
architecture == .appleSilicon,
|
||||||
let modelIdentifier: String = Hardware.modelIdentifier,
|
let modelIdentifier: String = Hardware.modelIdentifier,
|
||||||
|
@ -134,7 +131,6 @@ struct Firmware: Decodable, Hashable, Identifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Firmware: Equatable {
|
extension Firmware: Equatable {
|
||||||
|
|
||||||
static func == (lhs: Firmware, rhs: Firmware) -> Bool {
|
static func == (lhs: Firmware, rhs: Firmware) -> Bool {
|
||||||
lhs.version == rhs.version && lhs.build == rhs.build
|
lhs.version == rhs.version && lhs.build == rhs.build
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Hardware Struct used to retrieve Hardware information.
|
/// Hardware Struct used to retrieve Hardware information.
|
||||||
struct Hardware {
|
struct Hardware {
|
||||||
|
|
||||||
/// Hardware Architecture (Apple Silicon or Intel).
|
/// Hardware Architecture (Apple Silicon or Intel).
|
||||||
static var architecture: Architecture? {
|
static var architecture: Architecture? {
|
||||||
#if arch(arm64)
|
#if arch(arm64)
|
||||||
|
@ -27,7 +26,6 @@ struct Hardware {
|
||||||
}
|
}
|
||||||
/// Hardware Device ID (Apple Silicon or Intel T2).
|
/// Hardware Device ID (Apple Silicon or Intel T2).
|
||||||
static var deviceID: String? {
|
static var deviceID: String? {
|
||||||
|
|
||||||
switch architecture {
|
switch architecture {
|
||||||
case .appleSilicon:
|
case .appleSilicon:
|
||||||
return registryProperty(for: "compatible")?.components(separatedBy: "\0").first?.uppercased()
|
return registryProperty(for: "compatible")?.components(separatedBy: "\0").first?.uppercased()
|
||||||
|
@ -49,7 +47,6 @@ struct Hardware {
|
||||||
///
|
///
|
||||||
/// - Returns: The entity property for the provided key.
|
/// - Returns: The entity property for the provided key.
|
||||||
private static func registryProperty(for key: String) -> String? {
|
private static func registryProperty(for key: String) -> String? {
|
||||||
|
|
||||||
let entry: io_service_t = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
|
let entry: io_service_t = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import Foundation
|
||||||
// swiftlint:disable file_length
|
// swiftlint:disable file_length
|
||||||
// swiftlint:disable:next type_body_length
|
// swiftlint:disable:next type_body_length
|
||||||
struct Installer: Decodable, Hashable, Identifiable {
|
struct Installer: Decodable, Hashable, Identifiable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case id = "Identifier"
|
case id = "Identifier"
|
||||||
case version = "Version"
|
case version = "Version"
|
||||||
|
@ -654,7 +653,6 @@ struct Installer: Decodable, Hashable, Identifiable {
|
||||||
let deviceIDs: [String]
|
let deviceIDs: [String]
|
||||||
let unsupportedModelIdentifiers: [String]
|
let unsupportedModelIdentifiers: [String]
|
||||||
var name: String {
|
var name: String {
|
||||||
|
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
|
|
||||||
if version.range(of: "^14", options: .regularExpression) != nil {
|
if version.range(of: "^14", options: .regularExpression) != nil {
|
||||||
|
@ -710,7 +708,6 @@ struct Installer: Decodable, Hashable, Identifiable {
|
||||||
// Model Identifier (Apple Silicon or Intel)
|
// Model Identifier (Apple Silicon or Intel)
|
||||||
// macOS Catalina 10.15 or older
|
// macOS Catalina 10.15 or older
|
||||||
if version.range(of: "^10\\.", options: .regularExpression) != nil {
|
if version.range(of: "^10\\.", options: .regularExpression) != nil {
|
||||||
|
|
||||||
if let architecture: Architecture = Hardware.architecture,
|
if let architecture: Architecture = Hardware.architecture,
|
||||||
architecture == .appleSilicon {
|
architecture == .appleSilicon {
|
||||||
return false
|
return false
|
||||||
|
@ -790,7 +787,6 @@ struct Installer: Decodable, Hashable, Identifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Installer: Equatable {
|
extension Installer: Equatable {
|
||||||
|
|
||||||
static func == (lhs: Installer, rhs: Installer) -> Bool {
|
static func == (lhs: Installer, rhs: Installer) -> Bool {
|
||||||
lhs.version == rhs.version && lhs.build == rhs.build
|
lhs.version == rhs.version && lhs.build == rhs.build
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ struct MistTask: Identifiable {
|
||||||
let operation: @Sendable () async throws -> Void
|
let operation: @Sendable () async throws -> Void
|
||||||
|
|
||||||
var currentDescription: String {
|
var currentDescription: String {
|
||||||
|
|
||||||
var prefix: String = type.rawValue
|
var prefix: String = type.rawValue
|
||||||
var suffix: String = description
|
var suffix: String = description
|
||||||
|
|
||||||
|
@ -46,14 +45,12 @@ struct MistTask: Identifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MistTask: Equatable {
|
extension MistTask: Equatable {
|
||||||
|
|
||||||
static func == (lhs: MistTask, rhs: MistTask) -> Bool {
|
static func == (lhs: MistTask, rhs: MistTask) -> Bool {
|
||||||
lhs.id == rhs.id
|
lhs.id == rhs.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MistTask: Hashable {
|
extension MistTask: Hashable {
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
func hash(into hasher: inout Hasher) {
|
||||||
hasher.combine(id)
|
hasher.combine(id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ import AppKit
|
||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
class UserNotificationCenterDelegate: NSObject, UNUserNotificationCenterDelegate {
|
class UserNotificationCenterDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||||
|
|
||||||
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
|
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
|
||||||
|
|
||||||
guard response.actionIdentifier == UNNotificationAction.Identifier.show,
|
guard response.actionIdentifier == UNNotificationAction.Identifier.show,
|
||||||
let string: String = response.notification.request.content.userInfo["URL"] as? String else {
|
let string: String = response.notification.request.content.userInfo["URL"] as? String else {
|
||||||
return
|
return
|
||||||
|
|
|
@ -126,7 +126,6 @@ struct ActivityView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performTasks() async {
|
private func performTasks() async {
|
||||||
|
|
||||||
for taskGroupIndex in taskManager.taskGroups.indices {
|
for taskGroupIndex in taskManager.taskGroups.indices {
|
||||||
for taskIndex in taskManager.taskGroups[taskGroupIndex].tasks.indices {
|
for taskIndex in taskManager.taskGroups[taskGroupIndex].tasks.indices {
|
||||||
currentTaskId = "\(taskManager.taskGroups[taskGroupIndex].section.id).\(taskIndex)"
|
currentTaskId = "\(taskManager.taskGroups[taskGroupIndex].section.id).\(taskIndex)"
|
||||||
|
@ -165,7 +164,6 @@ struct ActivityView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if showInFinder {
|
if showInFinder {
|
||||||
|
|
||||||
guard let url: URL = destinationURL else {
|
guard let url: URL = destinationURL else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -175,7 +173,6 @@ struct ActivityView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkForUserCancellation(_ failure: Error) -> Bool {
|
private func checkForUserCancellation(_ failure: Error) -> Bool {
|
||||||
|
|
||||||
if failure as? CancellationError != nil {
|
if failure as? CancellationError != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -214,7 +211,6 @@ struct ActivityView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func stop() {
|
private func stop() {
|
||||||
|
|
||||||
switch taskManager.currentState {
|
switch taskManager.currentState {
|
||||||
case .pending, .inProgress:
|
case .pending, .inProgress:
|
||||||
alertType = .cancel
|
alertType = .cancel
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PathControl: NSViewRepresentable {
|
struct PathControl: NSViewRepresentable {
|
||||||
|
|
||||||
@Binding var path: String
|
@Binding var path: String
|
||||||
|
|
||||||
func makeNSView(context: Context) -> NSPathControl {
|
func makeNSView(context: Context) -> NSPathControl {
|
||||||
|
|
|
@ -33,14 +33,12 @@ struct TextFieldStepperView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func increment() {
|
private func increment() {
|
||||||
|
|
||||||
if value < maximum {
|
if value < maximum {
|
||||||
value += 1
|
value += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func decrement() {
|
private func decrement() {
|
||||||
|
|
||||||
if value > minimum {
|
if value > minimum {
|
||||||
value -= 1
|
value -= 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,14 +124,12 @@ struct ContentView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func releaseNames(for type: DownloadType) -> [String] {
|
private func releaseNames(for type: DownloadType) -> [String] {
|
||||||
|
|
||||||
var releaseNames: [String] = []
|
var releaseNames: [String] = []
|
||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
case .firmware:
|
case .firmware:
|
||||||
|
|
||||||
for firmware in filteredFirmwares {
|
for firmware in filteredFirmwares {
|
||||||
|
|
||||||
let releaseName: String = firmware.name.replacingOccurrences(of: " beta", with: "")
|
let releaseName: String = firmware.name.replacingOccurrences(of: " beta", with: "")
|
||||||
|
|
||||||
if !releaseNames.contains(releaseName) {
|
if !releaseNames.contains(releaseName) {
|
||||||
|
@ -141,7 +139,6 @@ struct ContentView: View {
|
||||||
case .installer:
|
case .installer:
|
||||||
|
|
||||||
for installer in filteredInstallers {
|
for installer in filteredInstallers {
|
||||||
|
|
||||||
let releaseName: String = installer.name.replacingOccurrences(of: " beta", with: "")
|
let releaseName: String = installer.name.replacingOccurrences(of: " beta", with: "")
|
||||||
|
|
||||||
if !releaseNames.contains(releaseName) {
|
if !releaseNames.contains(releaseName) {
|
||||||
|
|
|
@ -33,7 +33,6 @@ struct FooterView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func export() {
|
private func export() {
|
||||||
|
|
||||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||||
let date: String = dateFormatter.string(from: Date())
|
let date: String = dateFormatter.string(from: Date())
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ struct InstallerExportView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateExports() {
|
private func updateExports() {
|
||||||
|
|
||||||
var exports: [InstallerExportType] = []
|
var exports: [InstallerExportType] = []
|
||||||
|
|
||||||
if !isoCompatible && exportISO {
|
if !isoCompatible && exportISO {
|
||||||
|
|
|
@ -62,7 +62,6 @@ struct InstallerVolumeSelectionView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getAvailableVolumes() -> [InstallerVolume] {
|
private func getAvailableVolumes() -> [InstallerVolume] {
|
||||||
|
|
||||||
var volumes: [InstallerVolume] = []
|
var volumes: [InstallerVolume] = []
|
||||||
let keys: [URLResourceKey] = [.volumeNameKey, .volumeLocalizedFormatDescriptionKey, .volumeIsReadOnlyKey, .volumeTotalCapacityKey]
|
let keys: [URLResourceKey] = [.volumeNameKey, .volumeLocalizedFormatDescriptionKey, .volumeIsReadOnlyKey, .volumeTotalCapacityKey]
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ struct ListRowFirmware: View {
|
||||||
private let spacing: CGFloat = 5
|
private let spacing: CGFloat = 5
|
||||||
private let padding: CGFloat = 3
|
private let padding: CGFloat = 3
|
||||||
private var compatibilityMessage: String {
|
private var compatibilityMessage: String {
|
||||||
|
|
||||||
guard let architecture: Architecture = Hardware.architecture else {
|
guard let architecture: Architecture = Hardware.architecture else {
|
||||||
return "Invalid architecture!"
|
return "Invalid architecture!"
|
||||||
}
|
}
|
||||||
|
@ -36,7 +35,6 @@ struct ListRowFirmware: View {
|
||||||
return "This macOS Firmware download cannot be used to restore macOS on this \(architecture.description) Mac.\n\nAre you sure you want to continue?"
|
return "This macOS Firmware download cannot be used to restore macOS on this \(architecture.description) Mac.\n\nAre you sure you want to continue?"
|
||||||
}
|
}
|
||||||
private var errorMessage: String {
|
private var errorMessage: String {
|
||||||
|
|
||||||
if let error: BlessError = error as? BlessError {
|
if let error: BlessError = error as? BlessError {
|
||||||
return error.description
|
return error.description
|
||||||
}
|
}
|
||||||
|
@ -136,7 +134,6 @@ struct ListRowFirmware: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func validate() {
|
private func validate() {
|
||||||
|
|
||||||
guard PrivilegedHelperTool.isInstalled() else {
|
guard PrivilegedHelperTool.isInstalled() else {
|
||||||
alertType = .helperTool
|
alertType = .helperTool
|
||||||
showAlert = true
|
showAlert = true
|
||||||
|
@ -158,7 +155,6 @@ struct ListRowFirmware: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ListRowFirmware_Previews: PreviewProvider {
|
struct ListRowFirmware_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ListRowFirmware(firmware: .example, savePanel: .constant(NSSavePanel()), tasksInProgress: .constant(false), taskManager: .shared)
|
ListRowFirmware(firmware: .example, savePanel: .constant(NSSavePanel()), tasksInProgress: .constant(false), taskManager: .shared)
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ struct ListRowInstaller: View {
|
||||||
private let spacing: CGFloat = 5
|
private let spacing: CGFloat = 5
|
||||||
private let padding: CGFloat = 3
|
private let padding: CGFloat = 3
|
||||||
private var compatibilityMessage: String {
|
private var compatibilityMessage: String {
|
||||||
|
|
||||||
guard let architecture: Architecture = Hardware.architecture else {
|
guard let architecture: Architecture = Hardware.architecture else {
|
||||||
return "Invalid architecture!"
|
return "Invalid architecture!"
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,6 @@ struct ListRowInstaller: View {
|
||||||
"The cache directory has incorrect ownership and/or permissions, which will cause issues caching macOS Installers.\n\nRepair the cache directory ownership and/or permissions and try again."
|
"The cache directory has incorrect ownership and/or permissions, which will cause issues caching macOS Installers.\n\nRepair the cache directory ownership and/or permissions and try again."
|
||||||
}
|
}
|
||||||
private var errorMessage: String {
|
private var errorMessage: String {
|
||||||
|
|
||||||
if let error: BlessError = error as? BlessError {
|
if let error: BlessError = error as? BlessError {
|
||||||
return error.description
|
return error.description
|
||||||
}
|
}
|
||||||
|
@ -203,7 +201,6 @@ struct ListRowInstaller: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createBootableInstaller() {
|
private func createBootableInstaller() {
|
||||||
|
|
||||||
guard let volume: InstallerVolume = volume else {
|
guard let volume: InstallerVolume = volume else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -230,7 +227,6 @@ struct ListRowInstaller: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func validate() {
|
private func validate() {
|
||||||
|
|
||||||
guard PrivilegedHelperTool.isInstalled() else {
|
guard PrivilegedHelperTool.isInstalled() else {
|
||||||
alertType = .helperTool
|
alertType = .helperTool
|
||||||
showAlert = true
|
showAlert = true
|
||||||
|
@ -244,7 +240,6 @@ struct ListRowInstaller: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacheDownloads {
|
if cacheDownloads {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
var isDirectory: ObjCBool = false
|
var isDirectory: ObjCBool = false
|
||||||
|
|
||||||
|
@ -299,7 +294,6 @@ struct ListRowInstaller: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openFullDiskAccessPreferences() {
|
private func openFullDiskAccessPreferences() {
|
||||||
|
|
||||||
guard let url: URL = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles") else {
|
guard let url: URL = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles") else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func retrieveFirmwares() throws -> [Firmware] {
|
private func retrieveFirmwares() throws -> [Firmware] {
|
||||||
|
|
||||||
var firmwares: [Firmware] = []
|
var firmwares: [Firmware] = []
|
||||||
|
|
||||||
guard let firmwaresURL: URL = URL(string: Firmware.firmwaresURL) else {
|
guard let firmwaresURL: URL = URL(string: Firmware.firmwaresURL) else {
|
||||||
|
@ -119,7 +118,6 @@ struct RefreshView: View {
|
||||||
let supportedBuilds: [String] = try Firmware.supportedBuilds()
|
let supportedBuilds: [String] = try Firmware.supportedBuilds()
|
||||||
|
|
||||||
for (identifier, device) in devices {
|
for (identifier, device) in devices {
|
||||||
|
|
||||||
guard identifier.contains("Mac"),
|
guard identifier.contains("Mac"),
|
||||||
let device: [String: Any] = device as? [String: Any],
|
let device: [String: Any] = device as? [String: Any],
|
||||||
let firmwaresArray: [[String: Any]] = device["firmwares"] as? [[String: Any]] else {
|
let firmwaresArray: [[String: Any]] = device["firmwares"] as? [[String: Any]] else {
|
||||||
|
@ -127,7 +125,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
for var firmwareDictionary in firmwaresArray {
|
for var firmwareDictionary in firmwaresArray {
|
||||||
|
|
||||||
if let url: String = firmwareDictionary["url"] as? String,
|
if let url: String = firmwareDictionary["url"] as? String,
|
||||||
url.contains("http://updates-http.cdn-apple.com") {
|
url.contains("http://updates-http.cdn-apple.com") {
|
||||||
firmwareDictionary["url"] = url.replacingOccurrences(of: "http://updates-http.cdn-apple.com", with: "https://updates.cdn-apple.com")
|
firmwareDictionary["url"] = url.replacingOccurrences(of: "http://updates-http.cdn-apple.com", with: "https://updates.cdn-apple.com")
|
||||||
|
@ -156,7 +153,6 @@ struct RefreshView: View {
|
||||||
let catalogURLs: [String] = getCatalogURLs()
|
let catalogURLs: [String] = getCatalogURLs()
|
||||||
|
|
||||||
for catalogURL in catalogURLs {
|
for catalogURL in catalogURLs {
|
||||||
|
|
||||||
guard let url: URL = URL(string: catalogURL) else {
|
guard let url: URL = URL(string: catalogURL) else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -196,7 +192,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getCatalogURLs() -> [String] {
|
private func getCatalogURLs() -> [String] {
|
||||||
|
|
||||||
var catalogURLs: [String] = []
|
var catalogURLs: [String] = []
|
||||||
var catalogs: [Catalog] = []
|
var catalogs: [Catalog] = []
|
||||||
let defaultCatalogs: [Catalog] = CatalogType.allCases.map { Catalog(type: $0, standard: true, customerSeed: false, developerSeed: false, publicSeed: false) }
|
let defaultCatalogs: [Catalog] = CatalogType.allCases.map { Catalog(type: $0, standard: true, customerSeed: false, developerSeed: false, publicSeed: false) }
|
||||||
|
@ -239,13 +234,11 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getInstallers(from dictionary: [String: Any]) -> [Installer] {
|
private func getInstallers(from dictionary: [String: Any]) -> [Installer] {
|
||||||
|
|
||||||
var installers: [Installer] = []
|
var installers: [Installer] = []
|
||||||
let dateFormatter: DateFormatter = DateFormatter()
|
let dateFormatter: DateFormatter = DateFormatter()
|
||||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||||
|
|
||||||
for (key, value) in dictionary {
|
for (key, value) in dictionary {
|
||||||
|
|
||||||
guard var value: [String: Any] = value as? [String: Any],
|
guard var value: [String: Any] = value as? [String: Any],
|
||||||
let date: Date = value["PostDate"] as? Date,
|
let date: Date = value["PostDate"] as? Date,
|
||||||
let extendedMetaInfo: [String: Any] = value["ExtendedMetaInfo"] as? [String: Any],
|
let extendedMetaInfo: [String: Any] = value["ExtendedMetaInfo"] as? [String: Any],
|
||||||
|
@ -296,7 +289,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func nameFromDistribution(_ string: String) -> String? {
|
private func nameFromDistribution(_ string: String) -> String? {
|
||||||
|
|
||||||
guard string.contains("suDisabledGroupID") else {
|
guard string.contains("suDisabledGroupID") else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -307,7 +299,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func versionFromDistribution(_ string: String) -> String? {
|
private func versionFromDistribution(_ string: String) -> String? {
|
||||||
|
|
||||||
guard string.contains("<key>VERSION</key>") else {
|
guard string.contains("<key>VERSION</key>") else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -317,7 +308,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func buildFromDistribution(_ string: String) -> String? {
|
private func buildFromDistribution(_ string: String) -> String? {
|
||||||
|
|
||||||
guard string.contains("<key>BUILD</key>") else {
|
guard string.contains("<key>BUILD</key>") else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -327,7 +317,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func boardIDsFromDistribution(_ string: String) -> [String] {
|
private func boardIDsFromDistribution(_ string: String) -> [String] {
|
||||||
|
|
||||||
guard string.contains("supportedBoardIDs") || string.contains("boardIds") else {
|
guard string.contains("supportedBoardIDs") || string.contains("boardIds") else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
@ -341,7 +330,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deviceIDsFromDistribution(_ string: String) -> [String] {
|
private func deviceIDsFromDistribution(_ string: String) -> [String] {
|
||||||
|
|
||||||
guard string.contains("supportedDeviceIDs") else {
|
guard string.contains("supportedDeviceIDs") else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
@ -356,7 +344,6 @@ struct RefreshView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsupportedModelIdentifiersFromDistribution(_ string: String) -> [String] {
|
private func unsupportedModelIdentifiersFromDistribution(_ string: String) -> [String] {
|
||||||
|
|
||||||
guard string.contains("nonSupportedModels") else {
|
guard string.contains("nonSupportedModels") else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ struct SettingsAboutView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func visitHomepage() {
|
private func visitHomepage() {
|
||||||
|
|
||||||
guard let url: URL = URL(string: .repositoryURL) else {
|
guard let url: URL = URL(string: .repositoryURL) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ struct SettingsDiskImagesView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateCodesigningIdentities() {
|
private func updateCodesigningIdentities() {
|
||||||
|
|
||||||
var codesigningIdentities: [String] = []
|
var codesigningIdentities: [String] = []
|
||||||
|
|
||||||
let query: [String: Any] = [
|
let query: [String: Any] = [
|
||||||
|
|
|
@ -19,7 +19,6 @@ struct SettingsGeneralHelperView: View {
|
||||||
@State private var error: Error?
|
@State private var error: Error?
|
||||||
private let length: CGFloat = 16
|
private let length: CGFloat = 16
|
||||||
private var status: String {
|
private var status: String {
|
||||||
|
|
||||||
guard installed,
|
guard installed,
|
||||||
let installed: HelperToolInfoPropertyList = installedInfoPropertyList else {
|
let installed: HelperToolInfoPropertyList = installedInfoPropertyList else {
|
||||||
return "Not Installed"
|
return "Not Installed"
|
||||||
|
@ -29,7 +28,6 @@ struct SettingsGeneralHelperView: View {
|
||||||
return "Installed (\(version.major).\(version.minor).\(version.patch))"
|
return "Installed (\(version.major).\(version.minor).\(version.patch))"
|
||||||
}
|
}
|
||||||
private var errorMessage: String {
|
private var errorMessage: String {
|
||||||
|
|
||||||
if let error: BlessError = error as? BlessError {
|
if let error: BlessError = error as? BlessError {
|
||||||
return error.description
|
return error.description
|
||||||
}
|
}
|
||||||
|
@ -70,7 +68,6 @@ struct SettingsGeneralHelperView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func install() {
|
private func install() {
|
||||||
|
|
||||||
processing = true
|
processing = true
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -44,7 +44,6 @@ struct SettingsGeneralNotificationsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func validateNotifications() {
|
private func validateNotifications() {
|
||||||
|
|
||||||
let notificationCenter: UNUserNotificationCenter = .current()
|
let notificationCenter: UNUserNotificationCenter = .current()
|
||||||
notificationCenter.getNotificationSettings { settings in
|
notificationCenter.getNotificationSettings { settings in
|
||||||
|
|
||||||
|
@ -56,7 +55,6 @@ struct SettingsGeneralNotificationsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func request() {
|
private func request() {
|
||||||
|
|
||||||
let userNotificationCenter: UNUserNotificationCenter = UNUserNotificationCenter.current()
|
let userNotificationCenter: UNUserNotificationCenter = UNUserNotificationCenter.current()
|
||||||
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
|
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
|
||||||
|
|
||||||
|
@ -71,7 +69,6 @@ struct SettingsGeneralNotificationsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openNotifications() {
|
private func openNotifications() {
|
||||||
|
|
||||||
guard let url: URL = URL(string: "x-apple.systempreferences:com.apple.preference.notifications?Notifications") else {
|
guard let url: URL = URL(string: "x-apple.systempreferences:com.apple.preference.notifications?Notifications") else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func retrieveCache() {
|
private func retrieveCache() {
|
||||||
|
|
||||||
let url: URL = URL(fileURLWithPath: cacheDirectory)
|
let url: URL = URL(fileURLWithPath: cacheDirectory)
|
||||||
var isDirectory: ObjCBool = false
|
var isDirectory: ObjCBool = false
|
||||||
|
|
||||||
|
@ -143,7 +142,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func installer(for url: URL) -> Installer? {
|
private func installer(for url: URL) -> Installer? {
|
||||||
|
|
||||||
let id: String = url.lastPathComponent
|
let id: String = url.lastPathComponent
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -194,7 +192,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func versionFromDistribution(_ string: String) -> String? {
|
private func versionFromDistribution(_ string: String) -> String? {
|
||||||
|
|
||||||
guard string.contains("<key>VERSION</key>") else {
|
guard string.contains("<key>VERSION</key>") else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -204,7 +201,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func buildFromDistribution(_ string: String) -> String? {
|
private func buildFromDistribution(_ string: String) -> String? {
|
||||||
|
|
||||||
guard string.contains("<key>BUILD</key>") else {
|
guard string.contains("<key>BUILD</key>") else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -214,7 +210,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showInFinder() {
|
private func showInFinder() {
|
||||||
|
|
||||||
guard let id: String = selectedInstallerId else {
|
guard let id: String = selectedInstallerId else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -224,7 +219,6 @@ struct SettingsInstallersCacheView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func emptyCache(for id: String?) async {
|
private func emptyCache(for id: String?) async {
|
||||||
|
|
||||||
guard let id: String = id else {
|
guard let id: String = id else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ struct SettingsInstallersView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getCatalogs() -> [Catalog] {
|
private func getCatalogs() -> [Catalog] {
|
||||||
|
|
||||||
guard let array: [[String: Any]] = UserDefaults.standard.array(forKey: "catalogs") as? [[String: Any]] else {
|
guard let array: [[String: Any]] = UserDefaults.standard.array(forKey: "catalogs") as? [[String: Any]] else {
|
||||||
return defaultCatalogs
|
return defaultCatalogs
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ struct SettingsPackagesView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateCodesigningIdentities() {
|
private func updateCodesigningIdentities() {
|
||||||
|
|
||||||
var codesigningIdentities: [String] = []
|
var codesigningIdentities: [String] = []
|
||||||
|
|
||||||
let query: [String: Any] = [
|
let query: [String: Any] = [
|
||||||
|
|
|
@ -10,7 +10,6 @@ import SecureXPC
|
||||||
|
|
||||||
/// Helper Tool struct to run a command sent from the main application.
|
/// Helper Tool struct to run a command sent from the main application.
|
||||||
struct HelperToolCommandRunner {
|
struct HelperToolCommandRunner {
|
||||||
|
|
||||||
/// Run the requested command and return the status and output.
|
/// Run the requested command and return the status and output.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
@ -20,7 +19,6 @@ struct HelperToolCommandRunner {
|
||||||
///
|
///
|
||||||
/// - Returns: A `HelperToolCommandResponse` struct containing the termination status, standard output and standard error.
|
/// - Returns: A `HelperToolCommandResponse` struct containing the termination status, standard output and standard error.
|
||||||
static func run(_ request: HelperToolCommandRequest) throws -> HelperToolCommandResponse {
|
static func run(_ request: HelperToolCommandRequest) throws -> HelperToolCommandResponse {
|
||||||
|
|
||||||
switch request.type {
|
switch request.type {
|
||||||
case .remove:
|
case .remove:
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
final class MistTests: XCTestCase {
|
final class MistTests: XCTestCase {
|
||||||
|
|
||||||
func test() throws {
|
func test() throws {
|
||||||
XCTAssertTrue(true)
|
XCTAssertTrue(true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import EmbeddedPropertyList
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct HelperToolInfoPropertyList: Decodable, Equatable {
|
struct HelperToolInfoPropertyList: Decodable, Equatable {
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case buildHash = "BuildHash"
|
case buildHash = "BuildHash"
|
||||||
case bundleIdentifier = "CFBundleIdentifier"
|
case bundleIdentifier = "CFBundleIdentifier"
|
||||||
|
|
|
@ -9,7 +9,6 @@ import EmbeddedPropertyList
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct HelperToolLaunchdPropertyList: Decodable, Equatable {
|
struct HelperToolLaunchdPropertyList: Decodable, Equatable {
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case machServices = "MachServices"
|
case machServices = "MachServices"
|
||||||
case label = "Label"
|
case label = "Label"
|
||||||
|
|
|
@ -9,7 +9,6 @@ import Foundation
|
||||||
|
|
||||||
/// Helper class used to execute shell commands.
|
/// Helper class used to execute shell commands.
|
||||||
class ShellExecutor: NSObject {
|
class ShellExecutor: NSObject {
|
||||||
|
|
||||||
static var shared: ShellExecutor = ShellExecutor()
|
static var shared: ShellExecutor = ShellExecutor()
|
||||||
private var process: Process = Process()
|
private var process: Process = Process()
|
||||||
|
|
||||||
|
@ -60,7 +59,6 @@ class ShellExecutor: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func terminate() {
|
func terminate() {
|
||||||
|
|
||||||
guard process.isRunning else {
|
guard process.isRunning else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue