mirror of https://github.com/buresdv/Cork
~ More work…
This commit is contained in:
parent
7ca67cfe76
commit
5e0222f167
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkPackagesModels
|
||||
import CorkTerminalFunctions
|
||||
|
||||
extension MassAppAdoptionView.MassAppAdoptionTacker
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,16 +8,19 @@
|
|||
import AppIntents
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkPackagesModels
|
||||
|
||||
struct GetInstalledCasksIntent: AppIntent
|
||||
public struct GetInstalledCasksIntent: AppIntent
|
||||
{
|
||||
static let title: LocalizedStringResource = "intent.get-installed-casks.title"
|
||||
static let description: LocalizedStringResource = "intent.get-installed-casks.description"
|
||||
public init() {}
|
||||
|
||||
public static let title: LocalizedStringResource = "intent.get-installed-casks.title"
|
||||
public static let description: LocalizedStringResource = "intent.get-installed-casks.description"
|
||||
|
||||
static let isDiscoverable: Bool = true
|
||||
static let openAppWhenRun: Bool = false
|
||||
public static let isDiscoverable: Bool = true
|
||||
public static let openAppWhenRun: Bool = false
|
||||
|
||||
func perform() async throws -> some ReturnsValue<[MinimalHomebrewPackage]>
|
||||
public func perform() async throws -> some ReturnsValue<[MinimalHomebrewPackage]>
|
||||
{
|
||||
let allowAccessToFile: Bool = AppConstants.shared.brewCaskPath.startAccessingSecurityScopedResource()
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkTerminalFunctions
|
||||
|
||||
/* enum CachePurgeError: Error
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkTerminalFunctions
|
||||
|
||||
enum OrphanUninstallationError: LocalizedError
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkTerminalFunctions
|
||||
|
||||
enum HomebrewCachePurgeError: LocalizedError
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkTerminalFunctions
|
||||
|
||||
enum OrphanRemovalError: LocalizedError
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
import CorkShared
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import CorkPackagesModels
|
||||
import CorkTerminalFunctions
|
||||
|
||||
enum OutdatedPackageRetrievalError: LocalizedError
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import CorkPackagesModels
|
||||
|
||||
extension BrewPackagesTracker
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import CorkPackagesModels
|
||||
|
||||
struct InstallPackageButton: View
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import CorkPackagesModels
|
||||
|
||||
struct UpgradePackagesButton: View
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import SwiftUI
|
||||
import CorkShared
|
||||
import ButtonKit
|
||||
import CorkPackagesModels
|
||||
|
||||
/// Preview a package according to its name
|
||||
struct PreviewPackageButton: View
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import Defaults
|
||||
import CorkPackagesModels
|
||||
|
||||
struct RevealPackageInFinderButton: View
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import CorkPackagesModels
|
||||
|
||||
struct AddTapButton: View
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import CorkShared
|
||||
import SwiftUI
|
||||
import CorkPackagesModels
|
||||
|
||||
struct TagUntagButton: View
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright ©. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
// swiftlint:disable:this file_name
|
||||
// swiftlint:disable all
|
||||
// swift-format-ignore-file
|
||||
// swiftformat:disable all
|
||||
// Generated using tuist — https://github.com/tuist/tuist
|
||||
|
||||
#if os(macOS)
|
||||
import AppKit
|
||||
#elseif os(iOS)
|
||||
import UIKit
|
||||
#elseif os(tvOS) || os(watchOS)
|
||||
import UIKit
|
||||
#endif
|
||||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
|
||||
// MARK: - Asset Catalogs
|
||||
|
||||
public enum CorkPackagesLogicAsset: Sendable {
|
||||
public enum Assets {
|
||||
public static let accentColor = CorkPackagesLogicColors(name: "AccentColor")
|
||||
public static let customAppleTerminalBadgeMagnifyingglass = CorkPackagesLogicImages(name: "custom.apple.terminal.badge.magnifyingglass")
|
||||
public static let customBrainSlash = CorkPackagesLogicImages(name: "custom.brain.slash")
|
||||
public static let customMacwindowBadgeMagnifyingglass = CorkPackagesLogicImages(name: "custom.macwindow.badge.magnifyingglass")
|
||||
public static let customMacwindowBadgeXmark = CorkPackagesLogicImages(name: "custom.macwindow.badge.xmark")
|
||||
public static let customPinFillQuestionmark = CorkPackagesLogicImages(name: "custom.pin.fill.questionmark")
|
||||
public static let customShippingbox2BadgeArrowDown = CorkPackagesLogicImages(name: "custom.shippingbox.2.badge.arrow.down")
|
||||
public static let customShippingboxBadgeMagnifyingglass = CorkPackagesLogicImages(name: "custom.shippingbox.badge.magnifyingglass")
|
||||
public static let customShippingboxBadgePlus = CorkPackagesLogicImages(name: "custom.shippingbox.badge.plus")
|
||||
public static let customSparklesSlash = CorkPackagesLogicImages(name: "custom.sparkles.slash")
|
||||
public static let customSpigotBadgePlus = CorkPackagesLogicImages(name: "custom.spigot.badge.plus")
|
||||
public static let customSpigotBadgeXmark = CorkPackagesLogicImages(name: "custom.spigot.badge.xmark")
|
||||
public static let customSquareStackBadgePause = CorkPackagesLogicImages(name: "custom.square.stack.badge.pause")
|
||||
public static let customSquareStackBadgePlay = CorkPackagesLogicImages(name: "custom.square.stack.badge.play")
|
||||
public static let customSquareStackBadgeQuestionmark = CorkPackagesLogicImages(name: "custom.square.stack.badge.questionmark")
|
||||
public static let customSquareStackTrianglebadgeExclamationmark = CorkPackagesLogicImages(name: "custom.square.stack.trianglebadge.exclamationmark")
|
||||
public static let customTerminalBadgeXmark = CorkPackagesLogicImages(name: "custom.terminal.badge.xmark")
|
||||
public static let customTrashTriangleFill = CorkPackagesLogicImages(name: "custom.trash.triangle.fill")
|
||||
}
|
||||
public enum PreviewAssets {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
public final class CorkPackagesLogicColors: Sendable {
|
||||
public let name: String
|
||||
|
||||
#if os(macOS)
|
||||
public typealias Color = NSColor
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
|
||||
public typealias Color = UIColor
|
||||
#endif
|
||||
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, visionOS 1.0, *)
|
||||
public var color: Color {
|
||||
guard let color = Color(asset: self) else {
|
||||
fatalError("Unable to load color asset named \(name).")
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, visionOS 1.0, *)
|
||||
public var swiftUIColor: SwiftUI.Color {
|
||||
return SwiftUI.Color(asset: self)
|
||||
}
|
||||
#endif
|
||||
|
||||
fileprivate init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
public extension CorkPackagesLogicColors.Color {
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, visionOS 1.0, *)
|
||||
convenience init?(asset: CorkPackagesLogicColors) {
|
||||
let bundle = Bundle.module
|
||||
#if os(iOS) || os(tvOS) || os(visionOS)
|
||||
self.init(named: asset.name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
self.init(named: NSColor.Name(asset.name), bundle: bundle)
|
||||
#elseif os(watchOS)
|
||||
self.init(named: asset.name)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, visionOS 1.0, *)
|
||||
public extension SwiftUI.Color {
|
||||
init(asset: CorkPackagesLogicColors) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public struct CorkPackagesLogicImages: Sendable {
|
||||
public let name: String
|
||||
|
||||
#if os(macOS)
|
||||
public typealias Image = NSImage
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)
|
||||
public typealias Image = UIImage
|
||||
#endif
|
||||
|
||||
public var image: Image {
|
||||
let bundle = Bundle.module
|
||||
#if os(iOS) || os(tvOS) || os(visionOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let image = bundle.image(forResource: NSImage.Name(name))
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, visionOS 1.0, *)
|
||||
public var swiftUIImage: SwiftUI.Image {
|
||||
SwiftUI.Image(asset: self)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, visionOS 1.0, *)
|
||||
public extension SwiftUI.Image {
|
||||
init(asset: CorkPackagesLogicImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
|
||||
init(asset: CorkPackagesLogicImages, label: Text) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle, label: label)
|
||||
}
|
||||
|
||||
init(decorative asset: CorkPackagesLogicImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(decorative: asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
// periphery:ignore:all
|
||||
// swiftlint:disable:this file_name
|
||||
// swiftlint:disable all
|
||||
// swift-format-ignore-file
|
||||
// swiftformat:disable all
|
||||
#if hasFeature(InternalImportsByDefault)
|
||||
public import Foundation
|
||||
#else
|
||||
import Foundation
|
||||
#endif
|
||||
// MARK: - Swift Bundle Accessor - for SPM
|
||||
private class BundleFinder {}
|
||||
extension Foundation.Bundle {
|
||||
/// Since CorkPackagesLogic is a static library, the bundle containing the resources is copied into the final product.
|
||||
static let module: Bundle = {
|
||||
let bundleName = "Cork_CorkPackagesLogic"
|
||||
let bundleFinderResourceURL = Bundle(for: BundleFinder.self).resourceURL
|
||||
var candidates = [
|
||||
Bundle.main.resourceURL,
|
||||
bundleFinderResourceURL,
|
||||
Bundle.main.bundleURL,
|
||||
]
|
||||
// This is a fix to make Previews work with bundled resources.
|
||||
// Logic here is taken from SPM's generated `resource_bundle_accessors.swift` file,
|
||||
// which is located under the derived data directory after building the project.
|
||||
if let override = ProcessInfo.processInfo.environment["PACKAGE_RESOURCE_BUNDLE_PATH"] {
|
||||
candidates.append(URL(fileURLWithPath: override))
|
||||
// Deleting derived data and not rebuilding the frameworks containing resources may result in a state
|
||||
// where the bundles are only available in the framework's directory that is actively being previewed.
|
||||
// Since we don't know which framework this is, we also need to look in all the framework subpaths.
|
||||
if let subpaths = try? Foundation.FileManager.default.contentsOfDirectory(atPath: override) {
|
||||
for subpath in subpaths {
|
||||
if subpath.hasSuffix(".framework") {
|
||||
candidates.append(URL(fileURLWithPath: override + "/" + subpath))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a fix to make unit tests work with bundled resources.
|
||||
// Making this change allows unit tests to search one directory up for a bundle.
|
||||
// More context can be found in this PR: https://github.com/tuist/tuist/pull/6895
|
||||
#if canImport(XCTest)
|
||||
candidates.append(bundleFinderResourceURL?.appendingPathComponent(".."))
|
||||
#endif
|
||||
|
||||
for candidate in candidates {
|
||||
let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
|
||||
if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
|
||||
return bundle
|
||||
}
|
||||
}
|
||||
fatalError("unable to find bundle named Cork_CorkPackagesLogic")
|
||||
}()
|
||||
}
|
||||
// MARK: - Objective-C Bundle Accessor
|
||||
@objc
|
||||
public class CorkPackagesLogicResources: NSObject {
|
||||
@objc public class var bundle: Bundle {
|
||||
return .module
|
||||
}
|
||||
}
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
//
|
||||
|
||||
import AppKit
|
||||
import CorkNotifications
|
||||
import CorkShared
|
||||
import Foundation
|
||||
import Observation
|
||||
|
|
@ -28,31 +27,31 @@ public final class AppState
|
|||
case selfCompiled
|
||||
}
|
||||
|
||||
var licensingState: LicensingState = .notBoughtOrHasNotActivatedDemo
|
||||
public var licensingState: LicensingState = .notBoughtOrHasNotActivatedDemo
|
||||
|
||||
/// Class for controlling the opened panes, and providing information about the status of the currently opened pane
|
||||
@Observable @MainActor
|
||||
final class NavigationManager
|
||||
public final class NavigationManager
|
||||
{
|
||||
/// Possible things to show in the detail pane
|
||||
/// Can be either a ``BrewPackage`` for a Formula or Cask, or ``BrewTap`` for a Tap
|
||||
enum DetailDestination: Hashable
|
||||
public enum DetailDestination: Hashable
|
||||
{
|
||||
case package(package: BrewPackage)
|
||||
case tap(tap: BrewTap)
|
||||
}
|
||||
|
||||
/// Which pane is opened in the detail
|
||||
var openedScreen: DetailDestination?
|
||||
public var openedScreen: DetailDestination?
|
||||
|
||||
/// Dismiss the currently opened screen and return to the status page
|
||||
func dismissScreen()
|
||||
public func dismissScreen()
|
||||
{
|
||||
self.openedScreen = nil
|
||||
}
|
||||
|
||||
/// Check whether any panes are currently opened
|
||||
var isAnyScreenOpened: Bool
|
||||
public var isAnyScreenOpened: Bool
|
||||
{
|
||||
if self.openedScreen == nil
|
||||
{
|
||||
|
|
@ -65,71 +64,71 @@ public final class AppState
|
|||
}
|
||||
}
|
||||
|
||||
var navigationManager: NavigationManager = .init()
|
||||
public var navigationManager: NavigationManager = .init()
|
||||
|
||||
// MARK: - Notifications
|
||||
|
||||
var notificationEnabledInSystemSettings: Bool?
|
||||
var notificationAuthStatus: UNAuthorizationStatus = .notDetermined
|
||||
public var notificationEnabledInSystemSettings: Bool?
|
||||
public var notificationAuthStatus: UNAuthorizationStatus = .notDetermined
|
||||
|
||||
// MARK: - Stuff for controlling the UI in general
|
||||
|
||||
var isSearchFieldFocused: Bool = false
|
||||
public var isSearchFieldFocused: Bool = false
|
||||
|
||||
// MARK: - Brewfile importing and exporting
|
||||
|
||||
var brewfileImportingStage: BrewfileImportStage = .importing
|
||||
public var brewfileImportingStage: BrewfileImportStage = .importing
|
||||
|
||||
var isShowingUninstallationProgressView: Bool = false
|
||||
var isShowingFatalError: Bool = false
|
||||
var fatalAlertType: DisplayableAlert?
|
||||
public var isShowingUninstallationProgressView: Bool = false
|
||||
public var isShowingFatalError: Bool = false
|
||||
public var fatalAlertType: DisplayableAlert?
|
||||
|
||||
var isShowingConfirmationDialog: Bool = false
|
||||
var confirmationDialogType: ConfirmationDialog?
|
||||
public var isShowingConfirmationDialog: Bool = false
|
||||
public var confirmationDialogType: ConfirmationDialog?
|
||||
|
||||
var sheetToShow: DisplayableSheet?
|
||||
public var sheetToShow: DisplayableSheet?
|
||||
|
||||
var packageTryingToBeUninstalledWithSudo: BrewPackage?
|
||||
public var packageTryingToBeUninstalledWithSudo: BrewPackage?
|
||||
|
||||
var isShowingRemoveTapFailedAlert: Bool = false
|
||||
public var isShowingRemoveTapFailedAlert: Bool = false
|
||||
|
||||
// MARK: - Loading of packages and taps
|
||||
|
||||
var isLoadingFormulae: Bool = true
|
||||
var isLoadingCasks: Bool = true
|
||||
var isLoadingTaps: Bool = true
|
||||
public var isLoadingFormulae: Bool = true
|
||||
public var isLoadingCasks: Bool = true
|
||||
public var isLoadingTaps: Bool = true
|
||||
|
||||
var isLoadingTopPackages: Bool = false
|
||||
public var isLoadingTopPackages: Bool = false
|
||||
|
||||
// MARK: - Loading errors
|
||||
|
||||
var failedWhileLoadingFormulae: Bool = false
|
||||
var failedWhileLoadingCasks: Bool = false
|
||||
var failedWhileLoadingTaps: Bool = false
|
||||
public var failedWhileLoadingFormulae: Bool = false
|
||||
public var failedWhileLoadingCasks: Bool = false
|
||||
public var failedWhileLoadingTaps: Bool = false
|
||||
|
||||
var failedWhileLoadingTopPackages: Bool = false
|
||||
public var failedWhileLoadingTopPackages: Bool = false
|
||||
|
||||
// MARK: - Tagging
|
||||
|
||||
var corruptedPackage: String = ""
|
||||
public var corruptedPackage: String = ""
|
||||
|
||||
// MARK: - Other
|
||||
|
||||
var enableExtraAnimations: Bool
|
||||
public var enableExtraAnimations: Bool
|
||||
{
|
||||
return UserDefaults.standard.bool(forKey: "enableExtraAnimations")
|
||||
}
|
||||
|
||||
// MARK: - Showing errors
|
||||
|
||||
func showAlert(errorToShow: DisplayableAlert)
|
||||
public func showAlert(errorToShow: DisplayableAlert)
|
||||
{
|
||||
fatalAlertType = errorToShow
|
||||
|
||||
isShowingFatalError = true
|
||||
}
|
||||
|
||||
func dismissAlert()
|
||||
public func dismissAlert()
|
||||
{
|
||||
isShowingFatalError = false
|
||||
|
||||
|
|
@ -138,25 +137,25 @@ public final class AppState
|
|||
|
||||
// MARK: - Showing sheets
|
||||
|
||||
func showSheet(ofType sheetType: DisplayableSheet)
|
||||
public func showSheet(ofType sheetType: DisplayableSheet)
|
||||
{
|
||||
self.sheetToShow = sheetType
|
||||
}
|
||||
|
||||
func dismissSheet()
|
||||
public func dismissSheet()
|
||||
{
|
||||
self.sheetToShow = nil
|
||||
}
|
||||
|
||||
// MARK: Showing confirmation dialogs
|
||||
|
||||
func showConfirmationDialog(ofType confirmationDialogType: ConfirmationDialog)
|
||||
public func showConfirmationDialog(ofType confirmationDialogType: ConfirmationDialog)
|
||||
{
|
||||
self.confirmationDialogType = confirmationDialogType
|
||||
self.isShowingConfirmationDialog = true
|
||||
}
|
||||
|
||||
func dismissConfirmationDialog()
|
||||
public func dismissConfirmationDialog()
|
||||
{
|
||||
self.isShowingConfirmationDialog = false
|
||||
self.confirmationDialogType = nil
|
||||
|
|
@ -164,7 +163,7 @@ public final class AppState
|
|||
|
||||
// MARK: - Notification setup
|
||||
|
||||
func setupNotifications() async
|
||||
public func setupNotifications() async
|
||||
{
|
||||
let notificationCenter: UNUserNotificationCenter = AppConstants.shared.notificationCenter
|
||||
|
||||
|
|
@ -196,7 +195,7 @@ public final class AppState
|
|||
notificationAuthStatus = authStatus
|
||||
}
|
||||
|
||||
func requestNotificationAuthorization() async
|
||||
public func requestNotificationAuthorization() async
|
||||
{
|
||||
let notificationCenter: UNUserNotificationCenter = AppConstants.shared.notificationCenter
|
||||
|
||||
|
|
@ -216,11 +215,11 @@ public final class AppState
|
|||
|
||||
// MARK: - Initiating the update process from legacy contexts
|
||||
|
||||
@objc func startUpdateProcessForLegacySelectors(_: NSMenuItem!)
|
||||
@objc public func startUpdateProcessForLegacySelectors(_: NSMenuItem!)
|
||||
{
|
||||
self.showSheet(ofType: .fullUpdate)
|
||||
|
||||
sendNotification(title: String(localized: "notification.upgrade-process-started"))
|
||||
//sendNotification(title: String(localized: "notification.upgrade-process-started"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public extension DisplayableAlert
|
|||
case .homePathNotSet:
|
||||
return String(localized: "alert.home-not-set.title")
|
||||
case .numberOfLoadedPackagesDoesNotMatchNumberOfPackageFolders:
|
||||
return PackageLoadingError.numberOLoadedPackagesDosNotMatchNumberOfPackageFolders.localizedDescription
|
||||
return BrewPackage.PackageLoadingError.numberOLoadedPackagesDosNotMatchNumberOfPackageFolders.localizedDescription
|
||||
case .couldNotObtainNotificationPermissions:
|
||||
return String(localized: "alert.notifications-error-while-obtaining-permissions.title")
|
||||
case .couldNotRemoveTapDueToPackagesFromItStillBeingInstalled(let offendingTapProhibitingRemovalOfTap):
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public extension DisplayableAlert
|
|||
case .tapLoadingFailedDueToTapItself(let localizedDescription):
|
||||
return localizedDescription
|
||||
case .triedToThreatFolderContainingPackagesAsPackage(let packageType):
|
||||
return PackageLoadingError.triedToThreatFolderContainingPackagesAsPackage(packageType: packageType).localizedDescription
|
||||
return BrewPackage.PackageLoadingError.triedToThreatFolderContainingPackagesAsPackage(packageType: packageType).localizedDescription
|
||||
case .couldNotDeleteCachedDownloads(let associatedError):
|
||||
return associatedError
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import CorkPackagesLogic
|
||||
|
||||
public extension BrewPackage
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,18 +15,18 @@ public extension BrewPackagesTracker
|
|||
{
|
||||
public let id: UUID = .init()
|
||||
|
||||
let caskName: String
|
||||
let appExecutable: String
|
||||
public let caskName: String
|
||||
public let appExecutable: String
|
||||
|
||||
let description: String?
|
||||
public let description: String?
|
||||
|
||||
let fullAppUrl: URL
|
||||
public let fullAppUrl: URL
|
||||
|
||||
var isMarkedForAdoption: Bool
|
||||
public var isMarkedForAdoption: Bool
|
||||
|
||||
var app: Application?
|
||||
public var app: Application?
|
||||
|
||||
init(caskName: String, description: String?, appExecutable: String)
|
||||
public init(caskName: String, description: String?, appExecutable: String)
|
||||
{
|
||||
self.caskName = caskName
|
||||
self.appExecutable = appExecutable
|
||||
|
|
@ -38,26 +38,26 @@ public extension BrewPackagesTracker
|
|||
self.isMarkedForAdoption = true
|
||||
}
|
||||
|
||||
mutating func changeMarkedState()
|
||||
public mutating func changeMarkedState()
|
||||
{
|
||||
self.isMarkedForAdoption.toggle()
|
||||
}
|
||||
|
||||
func constructAppBundle() async -> Application?
|
||||
public func constructAppBundle() async -> Application?
|
||||
{
|
||||
return try? .init(from: self.fullAppUrl)
|
||||
}
|
||||
|
||||
func excludeSelf() async
|
||||
public func excludeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
let excludedAppRepresentation: ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.saveSelfToDatabase()
|
||||
}
|
||||
|
||||
func includeSelf() async
|
||||
public func includeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
let excludedAppRepresentation: ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.deleteSelfFromDatabase()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,50 +9,47 @@ import Foundation
|
|||
import SwiftData
|
||||
import CorkShared
|
||||
|
||||
public extension BrewPackagesTracker
|
||||
@Model
|
||||
public final class ExcludedAdoptableApp
|
||||
{
|
||||
@Model
|
||||
final class ExcludedAdoptableApp
|
||||
@Attribute(.unique) @Attribute(.spotlight)
|
||||
public var appExecutable: String
|
||||
|
||||
public init(appExecutable: String)
|
||||
{
|
||||
@Attribute(.unique) @Attribute(.spotlight)
|
||||
var appExecutable: String
|
||||
|
||||
init(appExecutable: String)
|
||||
{
|
||||
self.appExecutable = appExecutable
|
||||
}
|
||||
|
||||
init(fromAdoptableApp app: BrewPackagesTracker.AdoptableApp)
|
||||
{
|
||||
self.appExecutable = app.appExecutable
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func saveSelfToDatabase()
|
||||
{
|
||||
AppConstants.shared.modelContainer.mainContext.insert(self)
|
||||
}
|
||||
self.appExecutable = appExecutable
|
||||
}
|
||||
|
||||
public init(fromAdoptableApp app: BrewPackagesTracker.AdoptableApp)
|
||||
{
|
||||
self.appExecutable = app.appExecutable
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func saveSelfToDatabase()
|
||||
{
|
||||
AppConstants.shared.modelContainer.mainContext.insert(self)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func deleteSelfFromDatabase()
|
||||
{
|
||||
let modelContext: ModelContext = AppConstants.shared.modelContainer.mainContext
|
||||
@MainActor
|
||||
public func deleteSelfFromDatabase()
|
||||
{
|
||||
let modelContext: ModelContext = AppConstants.shared.modelContainer.mainContext
|
||||
|
||||
do
|
||||
do
|
||||
{
|
||||
let descriptor = FetchDescriptor<ExcludedAdoptableApp>(
|
||||
predicate: #Predicate { $0.appExecutable == appExecutable }
|
||||
)
|
||||
|
||||
if let existingPackage = try modelContext.fetch(descriptor).first
|
||||
{
|
||||
let descriptor = FetchDescriptor<ExcludedAdoptableApp>(
|
||||
predicate: #Predicate { $0.appExecutable == appExecutable }
|
||||
)
|
||||
|
||||
if let existingPackage = try modelContext.fetch(descriptor).first
|
||||
{
|
||||
modelContext.delete(existingPackage)
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
AppConstants.shared.logger.error("Failed to fetch excluded adoptable app for deletion: \(error.localizedDescription)")
|
||||
modelContext.delete(existingPackage)
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
AppConstants.shared.logger.error("Failed to fetch excluded adoptable app for deletion: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,34 +14,33 @@ import Charts
|
|||
import AppIntents
|
||||
import SwiftUI
|
||||
import CorkTerminalFunctions
|
||||
import CorkPackagesLogic
|
||||
|
||||
/// A representation of the loaded ``BrewPackage``s
|
||||
/// Includes packages that were loaded properly, along those whose loading failed
|
||||
typealias BrewPackages = Set<Result<BrewPackage, BrewPackage.PackageLoadingError>>
|
||||
public typealias BrewPackages = Set<Result<BrewPackage, BrewPackage.PackageLoadingError>>
|
||||
|
||||
/// A representation of a Homebrew package
|
||||
public struct BrewPackage: Identifiable, Equatable, Hashable, Codable, Sendable
|
||||
{
|
||||
public var id: UUID = .init()
|
||||
let name: String
|
||||
public let name: String
|
||||
|
||||
let type: PackageType
|
||||
var isTagged: Bool = false
|
||||
|
||||
var isPinned: Bool = false
|
||||
|
||||
let installedOn: Date?
|
||||
let versions: [String]
|
||||
public let installedOn: Date?
|
||||
public let versions: [String]
|
||||
|
||||
let url: URL?
|
||||
public let url: URL?
|
||||
|
||||
var installedIntentionally: Bool = true
|
||||
|
||||
let sizeInBytes: Int64?
|
||||
public let sizeInBytes: Int64?
|
||||
|
||||
/// Download count for top packages
|
||||
let downloadCount: Int?
|
||||
public let downloadCount: Int?
|
||||
|
||||
var isBeingModified: Bool = false
|
||||
|
||||
|
|
@ -298,7 +297,7 @@ public struct BrewPackage: Identifiable, Equatable, Hashable, Codable, Sendable
|
|||
}
|
||||
|
||||
/// Open the location of this package in Finder
|
||||
func revealInFinder() throws
|
||||
public func revealInFinder() throws
|
||||
{
|
||||
enum FinderRevealError: LocalizedError
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,21 +8,21 @@
|
|||
import AppIntents
|
||||
import Foundation
|
||||
|
||||
struct MinimalHomebrewPackage: Identifiable, Hashable, AppEntity, Codable
|
||||
public struct MinimalHomebrewPackage: Identifiable, Hashable, AppEntity, Codable
|
||||
{
|
||||
var id: UUID = .init()
|
||||
public var id: UUID = .init()
|
||||
|
||||
var name: String
|
||||
public var name: String
|
||||
|
||||
var type: BrewPackage.PackageType
|
||||
public var type: BrewPackage.PackageType
|
||||
|
||||
var installDate: Date?
|
||||
public var installDate: Date?
|
||||
|
||||
var installedIntentionally: Bool
|
||||
public var installedIntentionally: Bool
|
||||
|
||||
static let typeDisplayRepresentation: TypeDisplayRepresentation = .init(name: "intents.type.minimal-homebrew-package")
|
||||
public static let typeDisplayRepresentation: TypeDisplayRepresentation = .init(name: "intents.type.minimal-homebrew-package")
|
||||
|
||||
var displayRepresentation: DisplayRepresentation
|
||||
public var displayRepresentation: DisplayRepresentation
|
||||
{
|
||||
DisplayRepresentation(
|
||||
title: "\(name)",
|
||||
|
|
@ -30,10 +30,10 @@ struct MinimalHomebrewPackage: Identifiable, Hashable, AppEntity, Codable
|
|||
)
|
||||
}
|
||||
|
||||
static let defaultQuery: MinimalHomebrewPackageIntentQuery = .init()
|
||||
public static let defaultQuery: MinimalHomebrewPackageIntentQuery = .init()
|
||||
}
|
||||
|
||||
extension MinimalHomebrewPackage
|
||||
public extension MinimalHomebrewPackage
|
||||
{
|
||||
init?(from homebrewPackage: BrewPackage?)
|
||||
{
|
||||
|
|
@ -51,10 +51,12 @@ extension MinimalHomebrewPackage
|
|||
}
|
||||
}
|
||||
|
||||
struct MinimalHomebrewPackageIntentQuery: EntityQuery
|
||||
public struct MinimalHomebrewPackageIntentQuery: EntityQuery
|
||||
{
|
||||
func entities(for _: [UUID]) async throws -> [MinimalHomebrewPackage]
|
||||
public func entities(for _: [UUID]) async throws -> [MinimalHomebrewPackage]
|
||||
{
|
||||
return .init()
|
||||
}
|
||||
|
||||
public init() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import Foundation
|
|||
|
||||
public struct OutdatedPackage: Identifiable, Equatable, Hashable
|
||||
{
|
||||
enum PackageUpdatingType
|
||||
public enum PackageUpdatingType
|
||||
{
|
||||
/// The package is updating through Homebrew
|
||||
case homebrew
|
||||
|
|
@ -31,14 +31,14 @@ public struct OutdatedPackage: Identifiable, Equatable, Hashable
|
|||
|
||||
public let id: UUID = .init()
|
||||
|
||||
let package: BrewPackage
|
||||
public let package: BrewPackage
|
||||
|
||||
let installedVersions: [String]
|
||||
let newerVersion: String
|
||||
public let installedVersions: [String]
|
||||
public let newerVersion: String
|
||||
|
||||
var isMarkedForUpdating: Bool = true
|
||||
public var isMarkedForUpdating: Bool = true
|
||||
|
||||
var updatingManagedBy: PackageUpdatingType
|
||||
public var updatingManagedBy: PackageUpdatingType
|
||||
|
||||
public static func == (lhs: OutdatedPackage, rhs: OutdatedPackage) -> Bool
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,12 +12,14 @@ import Defaults
|
|||
@Observable @MainActor
|
||||
public class BrewPackagesTracker
|
||||
{
|
||||
var installedFormulae: BrewPackages = .init()
|
||||
var installedCasks: BrewPackages = .init()
|
||||
public init() {}
|
||||
|
||||
public var installedFormulae: BrewPackages = .init()
|
||||
public var installedCasks: BrewPackages = .init()
|
||||
|
||||
// MARK: - Successfully loaded packages
|
||||
/// Formulae that were successfuly loaded from disk
|
||||
var successfullyLoadedFormulae: Set<BrewPackage>
|
||||
public var successfullyLoadedFormulae: Set<BrewPackage>
|
||||
{
|
||||
return Set(installedFormulae.compactMap
|
||||
{ rawResult in
|
||||
|
|
@ -33,7 +35,7 @@ public class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Formulae than can be displayed, depending on whether the user set only to display intentionally installed packages
|
||||
var displayableSuccessfullyLoadedFormulae: Set<BrewPackage>
|
||||
public var displayableSuccessfullyLoadedFormulae: Set<BrewPackage>
|
||||
{
|
||||
let displayOnlyIntentionallyInstalledPackagesByDefault: Bool = Defaults[.displayOnlyIntentionallyInstalledPackagesByDefault]
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ public class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Collected errors from failed Formulae loading
|
||||
var unsuccessfullyLoadedFormulaeErrors: [BrewPackage.PackageLoadingError]
|
||||
public var unsuccessfullyLoadedFormulaeErrors: [BrewPackage.PackageLoadingError]
|
||||
{
|
||||
return installedFormulae.compactMap
|
||||
{ rawResult in
|
||||
|
|
@ -63,7 +65,7 @@ public class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Casks that were successfuly loaded from disk
|
||||
var successfullyLoadedCasks: Set<BrewPackage>
|
||||
public var successfullyLoadedCasks: Set<BrewPackage>
|
||||
{
|
||||
return Set(installedCasks.compactMap
|
||||
{ rawResult in
|
||||
|
|
@ -78,7 +80,7 @@ public class BrewPackagesTracker
|
|||
})
|
||||
}
|
||||
|
||||
var displayableSuccessfullyLoadedCasks: Set<BrewPackage>
|
||||
public var displayableSuccessfullyLoadedCasks: Set<BrewPackage>
|
||||
{
|
||||
let displayOnlyIntentionallyInstalledPackagesByDefault: Bool = Defaults[.displayOnlyIntentionallyInstalledPackagesByDefault]
|
||||
|
||||
|
|
@ -93,7 +95,7 @@ public class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Collected errors from failed Casks loading
|
||||
var unsuccessfullyLoadedCasksErrors: [BrewPackage.PackageLoadingError]
|
||||
public var unsuccessfullyLoadedCasksErrors: [BrewPackage.PackageLoadingError]
|
||||
{
|
||||
return installedCasks.compactMap
|
||||
{ rawResult in
|
||||
|
|
@ -108,7 +110,7 @@ public class BrewPackagesTracker
|
|||
}
|
||||
|
||||
// MARK: - Functions
|
||||
func insertPackageIntoTracker(_ package: BrewPackage)
|
||||
public func insertPackageIntoTracker(_ package: BrewPackage)
|
||||
{
|
||||
if package.type == .formula
|
||||
{
|
||||
|
|
@ -120,14 +122,14 @@ public class BrewPackagesTracker
|
|||
}
|
||||
}
|
||||
|
||||
var adoptableApps: [AdoptableApp] = .init()
|
||||
public var adoptableApps: [AdoptableApp] = .init()
|
||||
|
||||
var adoptableAppsSelectedToBeAdopted: [AdoptableApp]
|
||||
public var adoptableAppsSelectedToBeAdopted: [AdoptableApp]
|
||||
{
|
||||
return self.adoptableApps.filter(\.isMarkedForAdoption)
|
||||
}
|
||||
|
||||
var hasSelectedOnlySomeAppsToAdopt: Bool
|
||||
public var hasSelectedOnlySomeAppsToAdopt: Bool
|
||||
{
|
||||
if adoptableApps.count != adoptableAppsSelectedToBeAdopted.count
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ func corkTarget(configureWithSelfCompiled: Bool) -> ProjectDescription.Target {
|
|||
.target(corkSharedTarget),
|
||||
.target(corkNotificationsTarget),
|
||||
.target(corkPackages_modelsTarget),
|
||||
.target(corkPackages_logicTarget),
|
||||
.target(corkTerminalFunctionsTarget),
|
||||
.target(corkIntentsTarget),
|
||||
.external(name: "LaunchAtLogin"),
|
||||
|
|
@ -41,9 +40,9 @@ func corkTarget(configureWithSelfCompiled: Bool) -> ProjectDescription.Target {
|
|||
.external(name: "ApplicationInspector"),
|
||||
.external(name: "ButtonKit"),
|
||||
.external(name: "FactoryKit"),
|
||||
.package(product: "SwiftLintBuildToolPlugin", type: .plugin),
|
||||
.external(name: "Defaults"),
|
||||
.external(name: "DefaultsMacros")
|
||||
.external(name: "DefaultsMacros"),
|
||||
.package(product: "SwiftLintBuildToolPlugin", type: .plugin)
|
||||
], settings: .settings(configurations: [
|
||||
.debug(
|
||||
name: "Debug",
|
||||
|
|
@ -100,7 +99,7 @@ let corkNotificationsTarget: ProjectDescription.Target = .target(
|
|||
"Modules/Notifications/**/*.swift"
|
||||
],
|
||||
dependencies: [
|
||||
.target(name: "CorkShared")
|
||||
.target(corkSharedTarget)
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
.debug(
|
||||
|
|
@ -124,6 +123,7 @@ let corkTerminalFunctionsTarget: ProjectDescription.Target = .target(
|
|||
"Modules/TerminalSupport/**/*.swift"
|
||||
],
|
||||
dependencies: [
|
||||
.target(corkSharedTarget),
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
|
|
@ -154,36 +154,8 @@ let corkPackages_modelsTarget: ProjectDescription.Target = .target(
|
|||
"Cork/Logic/Helpers/Programs/Sudo Helper",
|
||||
],
|
||||
dependencies: [
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
.debug(
|
||||
name: "Debug",
|
||||
xcconfig: .relativeToRoot("xcconfigs/Cork.xcconfig")
|
||||
),
|
||||
.release(
|
||||
name: "Release",
|
||||
xcconfig: .relativeToRoot("xcconfigs/Cork.xcconfig")
|
||||
)
|
||||
])
|
||||
)
|
||||
|
||||
let corkPackages_logicTarget: ProjectDescription.Target = .target(
|
||||
name: "CorkPackagesLogic",
|
||||
destinations: [.mac],
|
||||
product: .staticLibrary,
|
||||
bundleId: "eu.davidbures.cork-packages-logic",
|
||||
deploymentTargets: .macOS("14.0.0"),
|
||||
sources: [
|
||||
"Modules/Packages/PackagesLogic/**/*.swift"
|
||||
],
|
||||
resources: [
|
||||
"Cork/**/*.xcassets",
|
||||
"Cork/**/*.xcstrings",
|
||||
"PrivacyInfo.xcprivacy",
|
||||
"Cork/Logic/Helpers/Programs/Sudo Helper",
|
||||
],
|
||||
dependencies: [
|
||||
.target(corkSharedTarget),
|
||||
.target(corkNotificationsTarget),
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
|
|
@ -208,6 +180,7 @@ let corkIntentsTarget: ProjectDescription.Target = .target(
|
|||
"Modules/Intents/**/*.swift"
|
||||
],
|
||||
dependencies: [
|
||||
.target(corkSharedTarget),
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
|
|
@ -287,7 +260,6 @@ let project = Project(
|
|||
corkSharedTarget,
|
||||
corkTerminalFunctionsTarget,
|
||||
corkPackages_modelsTarget,
|
||||
corkPackages_logicTarget,
|
||||
corkIntentsTarget,
|
||||
corkNotificationsTarget,
|
||||
corkHelpTarget,
|
||||
|
|
|
|||
Loading…
Reference in New Issue