mirror of
https://github.com/ninxsoft/Mist.git
synced 2025-05-28 14:04:49 -04:00
Add support for custom cache directories
This commit is contained in:
parent
24d0591822
commit
d58bf5137a
7 changed files with 94 additions and 22 deletions
|
@ -28,6 +28,7 @@
|
|||
390451E1285740E800E0B563 /* Sequence+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E0285740E800E0B563 /* Sequence+Extension.swift */; };
|
||||
390451E528574F0000E0B563 /* Catalog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E428574F0000E0B563 /* Catalog.swift */; };
|
||||
390451E72857510C00E0B563 /* TextTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390451E62857510B00E0B563 /* TextTag.swift */; };
|
||||
39148CFC28DD55B300011FF5 /* PathControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39148CFB28DD55B300011FF5 /* PathControl.swift */; };
|
||||
39252A77285A849F00956C74 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39252A76285A849F00956C74 /* AppDelegate.swift */; };
|
||||
39252A79285A85AF00956C74 /* SettingsInstallersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39252A78285A85AF00956C74 /* SettingsInstallersView.swift */; };
|
||||
39252A7B285AC50400956C74 /* SettingsDiskImagesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39252A7A285AC50400956C74 /* SettingsDiskImagesView.swift */; };
|
||||
|
@ -175,6 +176,7 @@
|
|||
390451E0285740E800E0B563 /* Sequence+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Extension.swift"; sourceTree = "<group>"; };
|
||||
390451E428574F0000E0B563 /* Catalog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Catalog.swift; sourceTree = "<group>"; };
|
||||
390451E62857510B00E0B563 /* TextTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextTag.swift; sourceTree = "<group>"; };
|
||||
39148CFB28DD55B300011FF5 /* PathControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PathControl.swift; sourceTree = "<group>"; };
|
||||
39252A76285A849F00956C74 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
39252A78285A85AF00956C74 /* SettingsInstallersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInstallersView.swift; sourceTree = "<group>"; };
|
||||
39252A7A285AC50400956C74 /* SettingsDiskImagesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDiskImagesView.swift; sourceTree = "<group>"; };
|
||||
|
@ -484,6 +486,7 @@
|
|||
39252AA4285C463A00956C74 /* DynamicTextView.swift */,
|
||||
39252A86285ACE9C00956C74 /* FooterText.swift */,
|
||||
39252AA0285C2A1600956C74 /* PaddedDivider.swift */,
|
||||
39148CFB28DD55B300011FF5 /* PathControl.swift */,
|
||||
39252A84285ACDC800956C74 /* ResetToDefaultButton.swift */,
|
||||
390451C92856F1D300E0B563 /* ScaledImage.swift */,
|
||||
390451CB2856F23100E0B563 /* ScaledSystemImage.swift */,
|
||||
|
@ -756,6 +759,7 @@
|
|||
390451CA2856F1D300E0B563 /* ScaledImage.swift in Sources */,
|
||||
39252A95285BF83D00956C74 /* MistTask.swift in Sources */,
|
||||
39CF56272861E10F006FB5D2 /* Codesigner.swift in Sources */,
|
||||
39148CFC28DD55B300011FF5 /* PathControl.swift in Sources */,
|
||||
3935F4892866C68000760AB0 /* DownloadSectionHeaderView.swift in Sources */,
|
||||
39252AB5285C706000956C74 /* URL+Extension.swift in Sources */,
|
||||
39CF56352862D4BF006FB5D2 /* FileCompressor.swift in Sources */,
|
||||
|
|
|
@ -14,11 +14,12 @@ struct InstallerCreator {
|
|||
/// Creates a recently downloaded macOS Installer.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - installer: The selected macOS Installer that was downloaded.
|
||||
/// - mountPoint: The URL of the directory mount point.
|
||||
/// - installer: The selected macOS Installer that was downloaded.
|
||||
/// - mountPoint: The URL of the directory mount point.
|
||||
/// - cacheDirectory: The cache directory storing all macOS Installer components.
|
||||
///
|
||||
/// - Throws: A `MistError` if the downloaded macOS Installer fails to generate.
|
||||
static func create(_ installer: Installer, mountPoint: URL) async throws {
|
||||
static func create(_ installer: Installer, mountPoint: URL, cacheDirectory: String) async throws {
|
||||
|
||||
guard let url: URL = URL(string: installer.distributionURL) else {
|
||||
throw MistError.invalidURL(installer.distributionURL)
|
||||
|
@ -26,7 +27,7 @@ struct InstallerCreator {
|
|||
|
||||
try await DirectoryRemover.remove(installer.temporaryInstallerURL)
|
||||
|
||||
let cacheDirectoryURL: URL = URL(fileURLWithPath: .cacheDirectory)
|
||||
let cacheDirectoryURL: URL = URL(fileURLWithPath: cacheDirectory)
|
||||
let distributionURL: URL = cacheDirectoryURL.appendingPathComponent(installer.id).appendingPathComponent(url.lastPathComponent)
|
||||
var argumentsArrays: [[String]] = [
|
||||
["installer", "-pkg", distributionURL.path, "-target", mountPoint.path]
|
||||
|
|
|
@ -137,6 +137,7 @@ class TaskManager: ObservableObject {
|
|||
destination destinationURL: URL?,
|
||||
exports: [InstallerExportType],
|
||||
cacheDownloads: Bool,
|
||||
cacheDirectory: String,
|
||||
retries: Int,
|
||||
delay retryDelay: Int,
|
||||
applicationFilename: String,
|
||||
|
@ -150,7 +151,7 @@ class TaskManager: ObservableObject {
|
|||
packageSigningIdentity: String
|
||||
) throws -> [(section: MistTaskSection, tasks: [MistTask])] {
|
||||
var taskGroups: [(section: MistTaskSection, tasks: [MistTask])] = []
|
||||
let cacheDirectoryURL: URL = URL(fileURLWithPath: .cacheDirectory).appendingPathComponent(installer.id)
|
||||
let cacheDirectoryURL: URL = URL(fileURLWithPath: cacheDirectory).appendingPathComponent(installer.id)
|
||||
let temporaryDirectoryURL: URL = URL(fileURLWithPath: .temporaryDirectory)
|
||||
let mountPointURL: URL = URL(fileURLWithPath: "/Volumes/\(installer.id) Temp")
|
||||
|
||||
|
@ -165,7 +166,7 @@ class TaskManager: ObservableObject {
|
|||
),
|
||||
(
|
||||
section: .setup,
|
||||
tasks: installTasks(for: installer, temporaryDirectory: temporaryDirectoryURL, mountPoint: mountPointURL)
|
||||
tasks: installTasks(for: installer, temporaryDirectory: temporaryDirectoryURL, mountPoint: mountPointURL, cacheDirectory: cacheDirectory)
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -252,7 +253,7 @@ class TaskManager: ObservableObject {
|
|||
return tasks
|
||||
}
|
||||
|
||||
private static func installTasks(for installer: Installer, temporaryDirectory temporaryDirectoryURL: URL, mountPoint mountPointURL: URL) -> [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 mountPointURL: URL = URL(fileURLWithPath: "/Volumes/\(installer.id) Temp")
|
||||
|
@ -268,7 +269,7 @@ class TaskManager: ObservableObject {
|
|||
try await DiskImageMounter.mount(imageURL, mountPoint: mountPointURL)
|
||||
},
|
||||
MistTask(type: .create, description: "macOS Installer in Disk Image") {
|
||||
try await InstallerCreator.create(installer, mountPoint: mountPointURL)
|
||||
try await InstallerCreator.create(installer, mountPoint: mountPointURL, cacheDirectory: cacheDirectory)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
27
Mist/Views/Components/PathControl.swift
Normal file
27
Mist/Views/Components/PathControl.swift
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// PathControl.swift
|
||||
// Mist
|
||||
//
|
||||
// Created by Nindi Gill on 23/9/2022.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct PathControl: NSViewRepresentable {
|
||||
|
||||
@Binding var path: String
|
||||
|
||||
func makeNSView(context: Context) -> NSPathControl {
|
||||
NSPathControl()
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSPathControl, context: Context) {
|
||||
nsView.url = URL(fileURLWithPath: path)
|
||||
}
|
||||
}
|
||||
|
||||
struct PathControl_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
PathControl(path: .constant(.cacheDirectory))
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import SwiftUI
|
|||
|
||||
struct InstallerListRow: View {
|
||||
@AppStorage("cacheDownloads") private var cacheDownloads: Bool = false
|
||||
@AppStorage("cacheDirectory") private var cacheDirectory: String = .cacheDirectory
|
||||
@AppStorage("applicationFilename") private var applicationFilename: String = .applicationFilenameTemplate
|
||||
@AppStorage("diskImageFilename") private var diskImageFilename: String = .diskImageFilenameTemplate
|
||||
@AppStorage("diskImageSign") private var diskImageSign: Bool = false
|
||||
|
@ -83,6 +84,7 @@ struct InstallerListRow: View {
|
|||
destination: openPanel.url,
|
||||
exports: exports,
|
||||
cacheDownloads: cacheDownloads,
|
||||
cacheDirectory: cacheDirectory,
|
||||
retries: retries,
|
||||
delay: retryDelay,
|
||||
applicationFilename: applicationFilename,
|
||||
|
|
|
@ -8,29 +8,44 @@
|
|||
import SwiftUI
|
||||
|
||||
struct SettingsInstallersCacheView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var cacheDownloads: Bool
|
||||
@Binding var cacheDirectory: String
|
||||
@State private var cacheSize: String = ""
|
||||
@State private var buttonClicked: Bool = false
|
||||
@State private var openPanel: NSOpenPanel = NSOpenPanel()
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(isOn: $enabled) {
|
||||
Text("Cache downloads")
|
||||
VStack(alignment: .leading) {
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(isOn: $cacheDownloads) {
|
||||
Text("Cache downloads")
|
||||
}
|
||||
FooterText("Speed up future operations by caching a local copy of macOS Installer files.")
|
||||
}
|
||||
FooterText("Speed up future operations by caching a local copy of macOS Installer files.")
|
||||
Spacer()
|
||||
Button("Select...") {
|
||||
selectCacheDirectory()
|
||||
}
|
||||
.disabled(!cacheDownloads)
|
||||
}
|
||||
Spacer()
|
||||
VStack {
|
||||
PathControl(path: $cacheDirectory)
|
||||
.disabled(true)
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
FooterText("Cache directory currently contains \(cacheSize) of data.")
|
||||
Spacer()
|
||||
Button("Empty Cache...") {
|
||||
buttonClicked.toggle()
|
||||
}
|
||||
FooterText(cacheSize)
|
||||
}
|
||||
.disabled(!cacheDownloads)
|
||||
}
|
||||
.onAppear {
|
||||
getCacheSize()
|
||||
}
|
||||
.onChange(of: cacheDirectory) { _ in
|
||||
getCacheSize()
|
||||
}
|
||||
.alert(isPresented: $buttonClicked) {
|
||||
Alert(
|
||||
title: Text("Empty Cache Directory?"),
|
||||
|
@ -41,9 +56,28 @@ struct SettingsInstallersCacheView: View {
|
|||
}
|
||||
}
|
||||
|
||||
private func selectCacheDirectory() {
|
||||
openPanel.prompt = "Select"
|
||||
openPanel.canCreateDirectories = true
|
||||
openPanel.canChooseFiles = false
|
||||
openPanel.canChooseDirectories = true
|
||||
openPanel.resolvesAliases = true
|
||||
openPanel.allowsMultipleSelection = false
|
||||
openPanel.isAccessoryViewDisclosed = true
|
||||
|
||||
let response: NSApplication.ModalResponse = openPanel.runModal()
|
||||
|
||||
guard response == .OK,
|
||||
let url: URL = openPanel.url else {
|
||||
return
|
||||
}
|
||||
|
||||
cacheDirectory = url.path
|
||||
}
|
||||
|
||||
private func getCacheSize() {
|
||||
|
||||
let url: URL = URL(fileURLWithPath: .cacheDirectory)
|
||||
let url: URL = URL(fileURLWithPath: cacheDirectory)
|
||||
var isDirectory: ObjCBool = false
|
||||
|
||||
do {
|
||||
|
@ -61,10 +95,10 @@ struct SettingsInstallersCacheView: View {
|
|||
private func emptyCache() {
|
||||
|
||||
do {
|
||||
let paths: [String] = try FileManager.default.contentsOfDirectory(atPath: .cacheDirectory)
|
||||
let paths: [String] = try FileManager.default.contentsOfDirectory(atPath: cacheDirectory)
|
||||
|
||||
for path in paths {
|
||||
let url: URL = URL(fileURLWithPath: .cacheDirectory + "/" + path)
|
||||
let url: URL = URL(fileURLWithPath: cacheDirectory + "/" + path)
|
||||
try FileManager.default.removeItem(at: url)
|
||||
}
|
||||
} catch {
|
||||
|
@ -75,6 +109,6 @@ struct SettingsInstallersCacheView: View {
|
|||
|
||||
struct SettingsInstallersCacheView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
SettingsInstallersCacheView(enabled: .constant(true))
|
||||
SettingsInstallersCacheView(cacheDownloads: .constant(true), cacheDirectory: .constant(.cacheDirectory))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@ import SwiftUI
|
|||
|
||||
struct SettingsInstallersView: View {
|
||||
@AppStorage("cacheDownloads") private var cacheDownloads: Bool = false
|
||||
@AppStorage("cacheDirectory") private var cacheDirectory: String = .cacheDirectory
|
||||
@State private var catalogRows: [CatalogRow] = []
|
||||
@State private var selectedCatalogRow: CatalogRow?
|
||||
private let cacheDownloadsDefault: Bool = false
|
||||
private let cacheDirectoryDefault: String = .cacheDirectory
|
||||
private var defaultCatalogRows: [CatalogRow] = Catalog.urls.map { CatalogRow(url: $0) }
|
||||
private let imageName: String = "Installer"
|
||||
private let title: String = "Installers"
|
||||
|
@ -21,7 +23,7 @@ struct SettingsInstallersView: View {
|
|||
VStack(alignment: .leading) {
|
||||
SettingsHeaderView(imageName: imageName, title: title, description: description, fade: .constant(false))
|
||||
PaddedDivider()
|
||||
SettingsInstallersCacheView(enabled: $cacheDownloads)
|
||||
SettingsInstallersCacheView(cacheDownloads: $cacheDownloads, cacheDirectory: $cacheDirectory)
|
||||
PaddedDivider()
|
||||
SettingsInstallersCatalogsView(catalogRows: $catalogRows, selectedCatalogRow: $selectedCatalogRow)
|
||||
PaddedDivider()
|
||||
|
@ -50,6 +52,7 @@ struct SettingsInstallersView: View {
|
|||
|
||||
private func reset() {
|
||||
cacheDownloads = cacheDownloadsDefault
|
||||
cacheDirectory = cacheDirectoryDefault
|
||||
catalogRows = defaultCatalogRows
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue