~ More work…

This commit is contained in:
David Bureš 2025-10-31 12:16:55 +01:00
parent 7ca67cfe76
commit 5e0222f167
No known key found for this signature in database
32 changed files with 162 additions and 413 deletions

View File

@ -7,6 +7,8 @@
import Foundation
import CorkShared
import CorkPackagesModels
import CorkTerminalFunctions
extension MassAppAdoptionView.MassAppAdoptionTacker
{

View File

@ -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()

View File

@ -7,6 +7,7 @@
import Foundation
import CorkShared
import CorkTerminalFunctions
/* enum CachePurgeError: Error
{

View File

@ -7,6 +7,7 @@
import Foundation
import CorkShared
import CorkTerminalFunctions
enum OrphanUninstallationError: LocalizedError
{

View File

@ -7,6 +7,7 @@
import Foundation
import CorkShared
import CorkTerminalFunctions
enum HomebrewCachePurgeError: LocalizedError
{

View File

@ -7,6 +7,7 @@
import Foundation
import CorkShared
import CorkTerminalFunctions
enum OrphanRemovalError: LocalizedError
{

View File

@ -8,6 +8,8 @@
import CorkShared
import Foundation
import SwiftUI
import CorkPackagesModels
import CorkTerminalFunctions
enum OutdatedPackageRetrievalError: LocalizedError
{

View File

@ -6,6 +6,7 @@
//
import Foundation
import CorkPackagesModels
extension BrewPackagesTracker
{

View File

@ -6,6 +6,7 @@
//
import SwiftUI
import CorkPackagesModels
struct InstallPackageButton: View
{

View File

@ -6,6 +6,7 @@
//
import SwiftUI
import CorkPackagesModels
struct UpgradePackagesButton: View
{

View File

@ -8,6 +8,7 @@
import SwiftUI
import CorkShared
import ButtonKit
import CorkPackagesModels
/// Preview a package according to its name
struct PreviewPackageButton: View

View File

@ -7,6 +7,7 @@
import SwiftUI
import Defaults
import CorkPackagesModels
struct RevealPackageInFinderButton: View
{

View File

@ -6,6 +6,7 @@
//
import SwiftUI
import CorkPackagesModels
struct AddTapButton: View
{

View File

@ -7,6 +7,7 @@
import CorkShared
import SwiftUI
import CorkPackagesModels
struct TagUntagButton: View
{

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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"))
}
}

View File

@ -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):

View File

@ -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
}

View File

@ -6,7 +6,6 @@
//
import Foundation
import CorkPackagesLogic
public extension BrewPackage
{

View File

@ -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()
}

View File

@ -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)")
}
}
}

View File

@ -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
{

View File

@ -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() {}
}

View File

@ -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
{

View File

@ -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
{

View File

@ -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,