mirror of https://github.com/buresdv/Cork
Fuck off
This commit is contained in:
parent
acdff554a0
commit
7ca67cfe76
|
|
@ -1,13 +0,0 @@
|
|||
//
|
||||
// Brewfile Import Stage.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 11.11.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum BrewfileImportStage
|
||||
{
|
||||
case importing, finished
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// Licensing State.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 18.03.2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum LicensingState
|
||||
{
|
||||
case notBoughtOrHasNotActivatedDemo
|
||||
|
||||
case demo
|
||||
case bought
|
||||
|
||||
case selfCompiled
|
||||
}
|
||||
|
|
@ -7,64 +7,3 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
/// Error representing failures while loading
|
||||
enum PackageLoadingError: LocalizedError, Hashable, Identifiable
|
||||
{
|
||||
/// Tried to treat the folder `Cellar` or `Caskroom` itself as a package - means Homebrew itself is broken
|
||||
case triedToThreatFolderContainingPackagesAsPackage(packageType: BrewPackage.PackageType)
|
||||
|
||||
/// The `Cellar` and `Caskroom` folder itself couldn't be loaded
|
||||
case couldNotReadContentsOfParentFolder(failureReason: String, folderURL: URL)
|
||||
|
||||
/// Failed while trying to read contents of package folder
|
||||
case failedWhileReadingContentsOfPackageFolder(folderURL: URL, reportedError: String)
|
||||
|
||||
case failedWhileTryingToDetermineIntentionalInstallation(folderURL: URL, associatedIntentionalDiscoveryError: IntentionalInstallationDiscoveryError)
|
||||
|
||||
/// The package root folder exists, but the package itself doesn't have any versions
|
||||
case packageDoesNotHaveAnyVersionsInstalled(packageURL: URL)
|
||||
|
||||
/// A folder that should have contained the package is not actually a folder
|
||||
case packageIsNotAFolder(String, packageURL: URL)
|
||||
|
||||
/// The number of loaded packages does not match the number of package parent folders
|
||||
case numberOLoadedPackagesDosNotMatchNumberOfPackageFolders
|
||||
|
||||
var errorDescription: String?
|
||||
{
|
||||
switch self
|
||||
{
|
||||
case .couldNotReadContentsOfParentFolder(let failureReason, _):
|
||||
return String(localized: "error.package-loading.could-not-read-contents-of-parent-folder.\(failureReason)")
|
||||
|
||||
case .triedToThreatFolderContainingPackagesAsPackage(let packageType):
|
||||
switch packageType
|
||||
{
|
||||
case .formula:
|
||||
return "error.package-loading.last-path-component-of-checked-package-url-is-folder-containing-packages-itself.formulae"
|
||||
case .cask:
|
||||
return "error.package-loading.last-path-component-of-checked-package-url-is-folder-containing-packages-itself.casks"
|
||||
}
|
||||
|
||||
case .failedWhileReadingContentsOfPackageFolder(let folderURL, let reportedError):
|
||||
return String(localized: "error.package-loading.could-not-load-\(folderURL.packageNameFromURL())-at-\(folderURL.absoluteString)-because-\(reportedError)", comment: "Couldn't load package (package name) at (package URL) because (failure reason)")
|
||||
|
||||
case .failedWhileTryingToDetermineIntentionalInstallation(_, let associatedIntentionalDiscoveryError):
|
||||
return associatedIntentionalDiscoveryError.localizedDescription
|
||||
|
||||
case .packageDoesNotHaveAnyVersionsInstalled(let packageURL):
|
||||
return String(localized: "error.package-loading.\(packageURL.packageNameFromURL())-does-not-have-any-versions-installed")
|
||||
|
||||
case .packageIsNotAFolder(let string, _):
|
||||
return String(localized: "error.package-loading.\(string)-not-a-folder", comment: "Package folder in this context means a folder that encloses package versions. Every package has its own folder, and this error occurs when the provided URL does not point to a folder that encloses package versions")
|
||||
|
||||
case .numberOLoadedPackagesDosNotMatchNumberOfPackageFolders:
|
||||
return String(localized: "error.package-loading.number-of-loaded-poackages-does-not-match-number-of-package-folders", comment: "This error occurs when there's a mismatch between the number of loaded packages, and the number of package folders in the package folders")
|
||||
}
|
||||
}
|
||||
|
||||
var id: UUID
|
||||
{
|
||||
return UUID()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,6 @@
|
|||
import CorkShared
|
||||
import Foundation
|
||||
|
||||
/// A representation of the loaded ``BrewPackage``s
|
||||
/// Includes packages that were loaded properly, along those whose loading failed
|
||||
typealias BrewPackages = Set<Result<BrewPackage, PackageLoadingError>>
|
||||
|
||||
extension BrewPackagesTracker
|
||||
{
|
||||
/// Parent function for loading installed packages from disk
|
||||
|
|
|
|||
|
|
@ -119,104 +119,6 @@ extension BrewPackagesTracker
|
|||
throw .failedToParseJson(error: casksJsonParsingError.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct for holding a Cask's name and its executable
|
||||
struct AdoptableApp: Identifiable, Hashable, Sendable
|
||||
{
|
||||
let id: UUID = .init()
|
||||
|
||||
let caskName: String
|
||||
let appExecutable: String
|
||||
|
||||
let description: String?
|
||||
|
||||
let fullAppUrl: URL
|
||||
|
||||
var isMarkedForAdoption: Bool
|
||||
|
||||
var app: Application?
|
||||
|
||||
init(caskName: String, description: String?, appExecutable: String)
|
||||
{
|
||||
self.caskName = caskName
|
||||
self.appExecutable = appExecutable
|
||||
|
||||
self.description = description
|
||||
|
||||
self.fullAppUrl = URL.applicationDirectory.appendingPathComponent(appExecutable, conformingTo: .application)
|
||||
|
||||
self.isMarkedForAdoption = true
|
||||
}
|
||||
|
||||
mutating func changeMarkedState()
|
||||
{
|
||||
self.isMarkedForAdoption.toggle()
|
||||
}
|
||||
|
||||
func constructAppBundle() async -> Application?
|
||||
{
|
||||
return try? .init(from: self.fullAppUrl)
|
||||
}
|
||||
|
||||
func excludeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.saveSelfToDatabase()
|
||||
}
|
||||
|
||||
func includeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.deleteSelfFromDatabase()
|
||||
}
|
||||
}
|
||||
|
||||
@Model
|
||||
final class ExcludedAdoptableApp
|
||||
{
|
||||
@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)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func deleteSelfFromDatabase()
|
||||
{
|
||||
let modelContext: ModelContext = AppConstants.shared.modelContainer.mainContext
|
||||
|
||||
do
|
||||
{
|
||||
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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Take the array that contains all Casks, and transform them into a list of Cask names, associated with their executable names for comparing with the contents of the Applications folder
|
||||
private nonisolated
|
||||
|
|
|
|||
|
|
@ -1,141 +0,0 @@
|
|||
//
|
||||
// Application.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 07.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import CorkShared
|
||||
|
||||
// TODO: Move this over to the `ApplicationInspector` external library once we figure out how to use Tuist projects as external dependencies
|
||||
|
||||
public struct Application: Identifiable, Hashable, Sendable
|
||||
{
|
||||
public let id: UUID = .init()
|
||||
|
||||
public let name: String
|
||||
|
||||
public let url: URL
|
||||
|
||||
public let iconPath: URL?
|
||||
|
||||
public let iconImage: Image?
|
||||
|
||||
public static func == (lhs: Application, rhs: Application) -> Bool
|
||||
{
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher)
|
||||
{
|
||||
hasher.combine(name)
|
||||
hasher.combine(id)
|
||||
}
|
||||
|
||||
public enum ApplicationInitializationError: LocalizedError
|
||||
{
|
||||
public enum MandatoryAppInformation: String, Sendable
|
||||
{
|
||||
case name
|
||||
|
||||
public var description: String
|
||||
{
|
||||
switch self {
|
||||
case .name:
|
||||
return "Name"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case applicationExecutableNotReadable(checkedPath: String)
|
||||
case couldNotAccessApplicationExecutable(error: Error)
|
||||
case couldNotReadBundle(applicationPath: String)
|
||||
case couldNotGetInfoDictionary
|
||||
case couldNotGetMandatoryAppInformation(_ mandatoryInformation: MandatoryAppInformation)
|
||||
|
||||
public var errorDescription: String?
|
||||
{
|
||||
switch self {
|
||||
case .applicationExecutableNotReadable(let checkedPath):
|
||||
return "Couldn't read application executable at \(checkedPath)"
|
||||
case .couldNotAccessApplicationExecutable(let error):
|
||||
return "Couldn't read application executable: \(error)"
|
||||
case .couldNotReadBundle(let applicationPath):
|
||||
return "Couldn't read application bundle at \(applicationPath)"
|
||||
case .couldNotGetInfoDictionary:
|
||||
return "Couldn't read application info.plist"
|
||||
case .couldNotGetMandatoryAppInformation(let mandatoryInformation):
|
||||
return "Couldn't read mandatory app information: \(mandatoryInformation.description)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public init(from appURL: URL) throws(ApplicationInitializationError)
|
||||
{
|
||||
do
|
||||
{
|
||||
guard FileManager.default.isReadableFile(atPath: appURL.path) == true else
|
||||
{
|
||||
throw ApplicationInitializationError.applicationExecutableNotReadable(checkedPath: appURL.path)
|
||||
}
|
||||
|
||||
guard let appBundle: Bundle = .init(url: appURL)
|
||||
else
|
||||
{
|
||||
throw ApplicationInitializationError.couldNotReadBundle(applicationPath: appURL.absoluteString)
|
||||
}
|
||||
|
||||
AppConstants.shared.logger.debug("Will try to initialize and App object form bundle \(appBundle)")
|
||||
|
||||
guard let appBundleInfoDictionary: [String: Any] = appBundle.infoDictionary
|
||||
else
|
||||
{
|
||||
throw ApplicationInitializationError.couldNotGetInfoDictionary
|
||||
}
|
||||
|
||||
guard let appName: String = Application.getAppName(fromInfoDictionary: appBundleInfoDictionary) else
|
||||
{
|
||||
throw ApplicationInitializationError.couldNotGetMandatoryAppInformation(.name)
|
||||
}
|
||||
|
||||
self.name = appName
|
||||
|
||||
self.url = appURL
|
||||
|
||||
self.iconPath = Application.getAppIconPath(fromInfoDictionary: appBundleInfoDictionary, appBundle: appBundle)
|
||||
|
||||
if let iconPath = self.iconPath
|
||||
{
|
||||
self.iconImage = .init(
|
||||
nsImage: .init(byReferencing: iconPath)
|
||||
)
|
||||
}
|
||||
else
|
||||
{
|
||||
self.iconImage = nil
|
||||
}
|
||||
}
|
||||
catch let applicationDirectoryAccessError
|
||||
{
|
||||
throw .couldNotAccessApplicationExecutable(error: applicationDirectoryAccessError)
|
||||
}
|
||||
}
|
||||
|
||||
private static func getAppName(fromInfoDictionary infoDictionary: [String: Any]) -> String?
|
||||
{
|
||||
return infoDictionary["CFBundleName"] as? String
|
||||
}
|
||||
|
||||
private static func getAppIconPath(fromInfoDictionary infoDictionary: [String: Any], appBundle: Bundle) -> URL?
|
||||
{
|
||||
guard let iconFileName: String = infoDictionary["CFBundleIconFile"] as? String
|
||||
else
|
||||
{
|
||||
return nil
|
||||
}
|
||||
|
||||
return appBundle.resourceURL?.appendingPathComponent(iconFileName, conformingTo: .icns)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
//
|
||||
// Corrupted Package.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 28.03.2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct CorruptedPackage: Identifiable, Equatable
|
||||
{
|
||||
let id: UUID = .init()
|
||||
let name: String
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// Terminal Output.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 12.02.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TerminalOutput
|
||||
{
|
||||
var standardOutput: String
|
||||
var standardError: String
|
||||
}
|
||||
|
||||
enum StreamedTerminalOutput
|
||||
{
|
||||
case standardOutput(String)
|
||||
case standardError(String)
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import ApplicationInspector
|
||||
|
||||
/// Show the icon of a linked app
|
||||
struct AppIconDisplay: View
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// 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
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// 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 CorkPackagesModelsAsset: Sendable {
|
||||
public enum Assets {
|
||||
public static let accentColor = CorkPackagesModelsColors(name: "AccentColor")
|
||||
public static let customAppleTerminalBadgeMagnifyingglass = CorkPackagesModelsImages(name: "custom.apple.terminal.badge.magnifyingglass")
|
||||
public static let customBrainSlash = CorkPackagesModelsImages(name: "custom.brain.slash")
|
||||
public static let customMacwindowBadgeMagnifyingglass = CorkPackagesModelsImages(name: "custom.macwindow.badge.magnifyingglass")
|
||||
public static let customMacwindowBadgeXmark = CorkPackagesModelsImages(name: "custom.macwindow.badge.xmark")
|
||||
public static let customPinFillQuestionmark = CorkPackagesModelsImages(name: "custom.pin.fill.questionmark")
|
||||
public static let customShippingbox2BadgeArrowDown = CorkPackagesModelsImages(name: "custom.shippingbox.2.badge.arrow.down")
|
||||
public static let customShippingboxBadgeMagnifyingglass = CorkPackagesModelsImages(name: "custom.shippingbox.badge.magnifyingglass")
|
||||
public static let customShippingboxBadgePlus = CorkPackagesModelsImages(name: "custom.shippingbox.badge.plus")
|
||||
public static let customSparklesSlash = CorkPackagesModelsImages(name: "custom.sparkles.slash")
|
||||
public static let customSpigotBadgePlus = CorkPackagesModelsImages(name: "custom.spigot.badge.plus")
|
||||
public static let customSpigotBadgeXmark = CorkPackagesModelsImages(name: "custom.spigot.badge.xmark")
|
||||
public static let customSquareStackBadgePause = CorkPackagesModelsImages(name: "custom.square.stack.badge.pause")
|
||||
public static let customSquareStackBadgePlay = CorkPackagesModelsImages(name: "custom.square.stack.badge.play")
|
||||
public static let customSquareStackBadgeQuestionmark = CorkPackagesModelsImages(name: "custom.square.stack.badge.questionmark")
|
||||
public static let customSquareStackTrianglebadgeExclamationmark = CorkPackagesModelsImages(name: "custom.square.stack.trianglebadge.exclamationmark")
|
||||
public static let customTerminalBadgeXmark = CorkPackagesModelsImages(name: "custom.terminal.badge.xmark")
|
||||
public static let customTrashTriangleFill = CorkPackagesModelsImages(name: "custom.trash.triangle.fill")
|
||||
}
|
||||
public enum PreviewAssets {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
public final class CorkPackagesModelsColors: 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 CorkPackagesModelsColors.Color {
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, visionOS 1.0, *)
|
||||
convenience init?(asset: CorkPackagesModelsColors) {
|
||||
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: CorkPackagesModelsColors) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public struct CorkPackagesModelsImages: 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: CorkPackagesModelsImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
|
||||
init(asset: CorkPackagesModelsImages, label: Text) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle, label: label)
|
||||
}
|
||||
|
||||
init(decorative asset: CorkPackagesModelsImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(decorative: asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// 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 CorkSharedAsset: Sendable {
|
||||
public enum Assets {
|
||||
public static let accentColor = CorkSharedColors(name: "AccentColor")
|
||||
public static let customAppleTerminalBadgeMagnifyingglass = CorkSharedImages(name: "custom.apple.terminal.badge.magnifyingglass")
|
||||
public static let customBrainSlash = CorkSharedImages(name: "custom.brain.slash")
|
||||
public static let customMacwindowBadgeMagnifyingglass = CorkSharedImages(name: "custom.macwindow.badge.magnifyingglass")
|
||||
public static let customMacwindowBadgeXmark = CorkSharedImages(name: "custom.macwindow.badge.xmark")
|
||||
public static let customPinFillQuestionmark = CorkSharedImages(name: "custom.pin.fill.questionmark")
|
||||
public static let customShippingbox2BadgeArrowDown = CorkSharedImages(name: "custom.shippingbox.2.badge.arrow.down")
|
||||
public static let customShippingboxBadgeMagnifyingglass = CorkSharedImages(name: "custom.shippingbox.badge.magnifyingglass")
|
||||
public static let customShippingboxBadgePlus = CorkSharedImages(name: "custom.shippingbox.badge.plus")
|
||||
public static let customSparklesSlash = CorkSharedImages(name: "custom.sparkles.slash")
|
||||
public static let customSpigotBadgePlus = CorkSharedImages(name: "custom.spigot.badge.plus")
|
||||
public static let customSpigotBadgeXmark = CorkSharedImages(name: "custom.spigot.badge.xmark")
|
||||
public static let customSquareStackBadgePause = CorkSharedImages(name: "custom.square.stack.badge.pause")
|
||||
public static let customSquareStackBadgePlay = CorkSharedImages(name: "custom.square.stack.badge.play")
|
||||
public static let customSquareStackBadgeQuestionmark = CorkSharedImages(name: "custom.square.stack.badge.questionmark")
|
||||
public static let customSquareStackTrianglebadgeExclamationmark = CorkSharedImages(name: "custom.square.stack.trianglebadge.exclamationmark")
|
||||
public static let customTerminalBadgeXmark = CorkSharedImages(name: "custom.terminal.badge.xmark")
|
||||
public static let customTrashTriangleFill = CorkSharedImages(name: "custom.trash.triangle.fill")
|
||||
}
|
||||
public enum PreviewAssets {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Implementation Details
|
||||
|
||||
public final class CorkSharedColors: 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 CorkSharedColors.Color {
|
||||
@available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, visionOS 1.0, *)
|
||||
convenience init?(asset: CorkSharedColors) {
|
||||
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: CorkSharedColors) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public struct CorkSharedImages: 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: CorkSharedImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle)
|
||||
}
|
||||
|
||||
init(asset: CorkSharedImages, label: Text) {
|
||||
let bundle = Bundle.module
|
||||
self.init(asset.name, bundle: bundle, label: label)
|
||||
}
|
||||
|
||||
init(decorative asset: CorkSharedImages) {
|
||||
let bundle = Bundle.module
|
||||
self.init(decorative: asset.name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// 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
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// 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 CorkPackagesModels is a static library, the bundle containing the resources is copied into the final product.
|
||||
static let module: Bundle = {
|
||||
let bundleName = "Cork_CorkPackagesModels"
|
||||
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_CorkPackagesModels")
|
||||
}()
|
||||
}
|
||||
// MARK: - Objective-C Bundle Accessor
|
||||
@objc
|
||||
public class CorkPackagesModelsResources: NSObject {
|
||||
@objc public class var bundle: Bundle {
|
||||
return .module
|
||||
}
|
||||
}
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// 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 CorkShared is a static library, the bundle containing the resources is copied into the final product.
|
||||
static let module: Bundle = {
|
||||
let bundleName = "Cork_CorkShared"
|
||||
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_CorkShared")
|
||||
}()
|
||||
}
|
||||
// MARK: - Objective-C Bundle Accessor
|
||||
@objc
|
||||
public class CorkSharedResources: NSObject {
|
||||
@objc public class var bundle: Bundle {
|
||||
return .module
|
||||
}
|
||||
}
|
||||
// swiftformat:enable all
|
||||
// swiftlint:enable all
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
//
|
||||
// Check if Package Was Installed Intentionally.swift
|
||||
// Check if Package was Installed Intentionally.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 13.11.2024.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
|
||||
enum IntentionalInstallationDiscoveryError: Error, Hashable
|
||||
public enum IntentionalInstallationDiscoveryError: Error, Hashable
|
||||
{
|
||||
/// The function could not determine the most relevant version of the package to read the recepit from
|
||||
case failedToDetermineMostRelevantVersion(packageURL: URL)
|
||||
|
|
@ -26,7 +26,7 @@ enum IntentionalInstallationDiscoveryError: Error, Hashable
|
|||
case unexpectedFolderName(packageURL: URL)
|
||||
}
|
||||
|
||||
extension URL
|
||||
public extension URL
|
||||
{
|
||||
/// This function checks whether the package was installed intentionally.
|
||||
/// - For Formulae, this info gets read from the install receipt
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// App State.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 05.02.2023.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
|
@ -14,9 +14,19 @@ import Observation
|
|||
|
||||
/// Class that holds the global state of the app, excluding services
|
||||
@Observable @MainActor
|
||||
final class AppState
|
||||
public final class AppState
|
||||
{
|
||||
// MARK: - Licensing
|
||||
|
||||
public enum LicensingState
|
||||
{
|
||||
case notBoughtOrHasNotActivatedDemo
|
||||
|
||||
case demo
|
||||
case bought
|
||||
|
||||
case selfCompiled
|
||||
}
|
||||
|
||||
var licensingState: LicensingState = .notBoughtOrHasNotActivatedDemo
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum DisplayableAlert: LocalizedError
|
||||
public enum DisplayableAlert: LocalizedError
|
||||
{
|
||||
case couldNotGetContentsOfPackageFolder(String), couldNotLoadAnyPackages(LocalizedError), couldNotLoadCertainPackage(String, URL, failureReason: String)
|
||||
case licenseCheckingFailedDueToAuthorizationComplexNotBeingEncodedProperly, licenseCheckingFailedDueToNoInternet, licenseCheckingFailedDueToTimeout, licenseCheckingFailedForOtherReason(localizedDescription: String)
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
extension DisplayableAlert
|
||||
public extension DisplayableAlert
|
||||
{
|
||||
/// The bold text at the top of the error
|
||||
var errorDescription: String?
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
extension DisplayableAlert
|
||||
public extension DisplayableAlert
|
||||
{
|
||||
/// Message in the alert
|
||||
var recoverySuggestion: String?
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Brewfile import Stage.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum BrewfileImportStage
|
||||
{
|
||||
case importing, finished
|
||||
}
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
//
|
||||
// Confirmation Dialog - Main Window.swift
|
||||
// Confirmation Dialog.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 21.04.2025.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum ConfirmationDialog: Identifiable, Equatable
|
||||
public enum ConfirmationDialog: Identifiable, Equatable
|
||||
{
|
||||
case uninstallPackage(_ packageToUninstall: BrewPackage)
|
||||
|
||||
case purgePackage(_ packageToPurge: BrewPackage)
|
||||
|
||||
var id: UUID
|
||||
public var id: UUID
|
||||
{
|
||||
return .init()
|
||||
}
|
||||
|
||||
var title: LocalizedStringKey
|
||||
public var title: LocalizedStringKey
|
||||
{
|
||||
switch self
|
||||
{
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// Sheets - Main Window.swift
|
||||
// Displayable Sheet.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 19.01.2025.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum DisplayableSheet: Identifiable, Equatable
|
||||
public enum DisplayableSheet: Identifiable, Equatable
|
||||
{
|
||||
|
||||
case packageInstallation
|
||||
|
|
@ -20,13 +20,13 @@ enum DisplayableSheet: Identifiable, Equatable
|
|||
|
||||
case corruptedPackageFix(corruptedPackage: CorruptedPackage)
|
||||
|
||||
case sudoRequiredForPackageRemoval
|
||||
case sudoRequiredForPackageRemoval
|
||||
|
||||
case maintenance(fastCacheDeletion: Bool)
|
||||
|
||||
case brewfileExport, brewfileImport
|
||||
|
||||
var id: UUID
|
||||
public var id: UUID
|
||||
{
|
||||
return .init()
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// Package Loading Error.swift
|
||||
// CorkPackagesModels
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CorkPackagesLogic
|
||||
|
||||
public extension BrewPackage
|
||||
{
|
||||
/// Error representing failures while loading
|
||||
enum PackageLoadingError: LocalizedError, Hashable, Identifiable
|
||||
{
|
||||
/// Tried to treat the folder `Cellar` or `Caskroom` itself as a package - means Homebrew itself is broken
|
||||
case triedToThreatFolderContainingPackagesAsPackage(packageType: BrewPackage.PackageType)
|
||||
|
||||
/// The `Cellar` and `Caskroom` folder itself couldn't be loaded
|
||||
case couldNotReadContentsOfParentFolder(failureReason: String, folderURL: URL)
|
||||
|
||||
/// Failed while trying to read contents of package folder
|
||||
case failedWhileReadingContentsOfPackageFolder(folderURL: URL, reportedError: String)
|
||||
|
||||
case failedWhileTryingToDetermineIntentionalInstallation(
|
||||
folderURL: URL,
|
||||
associatedIntentionalDiscoveryError: IntentionalInstallationDiscoveryError
|
||||
)
|
||||
|
||||
/// The package root folder exists, but the package itself doesn't have any versions
|
||||
case packageDoesNotHaveAnyVersionsInstalled(packageURL: URL)
|
||||
|
||||
/// A folder that should have contained the package is not actually a folder
|
||||
case packageIsNotAFolder(String, packageURL: URL)
|
||||
|
||||
/// The number of loaded packages does not match the number of package parent folders
|
||||
case numberOLoadedPackagesDosNotMatchNumberOfPackageFolders
|
||||
|
||||
public var errorDescription: String?
|
||||
{
|
||||
switch self
|
||||
{
|
||||
case .couldNotReadContentsOfParentFolder(let failureReason, _):
|
||||
return String(localized: "error.package-loading.could-not-read-contents-of-parent-folder.\(failureReason)")
|
||||
|
||||
case .triedToThreatFolderContainingPackagesAsPackage(let packageType):
|
||||
switch packageType
|
||||
{
|
||||
case .formula:
|
||||
return "error.package-loading.last-path-component-of-checked-package-url-is-folder-containing-packages-itself.formulae"
|
||||
case .cask:
|
||||
return "error.package-loading.last-path-component-of-checked-package-url-is-folder-containing-packages-itself.casks"
|
||||
}
|
||||
|
||||
case .failedWhileReadingContentsOfPackageFolder(let folderURL, let reportedError):
|
||||
return String(localized: "error.package-loading.could-not-load-\(folderURL.packageNameFromURL())-at-\(folderURL.absoluteString)-because-\(reportedError)", comment: "Couldn't load package (package name) at (package URL) because (failure reason)")
|
||||
|
||||
case .failedWhileTryingToDetermineIntentionalInstallation(_, let associatedIntentionalDiscoveryError):
|
||||
return associatedIntentionalDiscoveryError.localizedDescription
|
||||
|
||||
case .packageDoesNotHaveAnyVersionsInstalled(let packageURL):
|
||||
return String(localized: "error.package-loading.\(packageURL.packageNameFromURL())-does-not-have-any-versions-installed")
|
||||
|
||||
case .packageIsNotAFolder(let string, _):
|
||||
return String(localized: "error.package-loading.\(string)-not-a-folder", comment: "Package folder in this context means a folder that encloses package versions. Every package has its own folder, and this error occurs when the provided URL does not point to a folder that encloses package versions")
|
||||
|
||||
case .numberOLoadedPackagesDosNotMatchNumberOfPackageFolders:
|
||||
return String(localized: "error.package-loading.number-of-loaded-poackages-does-not-match-number-of-package-folders", comment: "This error occurs when there's a mismatch between the number of loaded packages, and the number of package folders in the package folders")
|
||||
}
|
||||
}
|
||||
|
||||
public var id: UUID
|
||||
{
|
||||
return UUID()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// Adoptable App.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ApplicationInspector
|
||||
|
||||
public extension BrewPackagesTracker
|
||||
{
|
||||
/// A struct for holding a Cask's name and its executable
|
||||
struct AdoptableApp: Identifiable, Hashable, Sendable
|
||||
{
|
||||
public let id: UUID = .init()
|
||||
|
||||
let caskName: String
|
||||
let appExecutable: String
|
||||
|
||||
let description: String?
|
||||
|
||||
let fullAppUrl: URL
|
||||
|
||||
var isMarkedForAdoption: Bool
|
||||
|
||||
var app: Application?
|
||||
|
||||
init(caskName: String, description: String?, appExecutable: String)
|
||||
{
|
||||
self.caskName = caskName
|
||||
self.appExecutable = appExecutable
|
||||
|
||||
self.description = description
|
||||
|
||||
self.fullAppUrl = URL.applicationDirectory.appendingPathComponent(appExecutable, conformingTo: .application)
|
||||
|
||||
self.isMarkedForAdoption = true
|
||||
}
|
||||
|
||||
mutating func changeMarkedState()
|
||||
{
|
||||
self.isMarkedForAdoption.toggle()
|
||||
}
|
||||
|
||||
func constructAppBundle() async -> Application?
|
||||
{
|
||||
return try? .init(from: self.fullAppUrl)
|
||||
}
|
||||
|
||||
func excludeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.saveSelfToDatabase()
|
||||
}
|
||||
|
||||
func includeSelf() async
|
||||
{
|
||||
let excludedAppRepresentation: BrewPackagesTracker.ExcludedAdoptableApp = .init(fromAdoptableApp: self)
|
||||
|
||||
await excludedAppRepresentation.deleteSelfFromDatabase()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Excluded Adptable App.swift
|
||||
// CorkPackagesModels
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftData
|
||||
import CorkShared
|
||||
|
||||
public extension BrewPackagesTracker
|
||||
{
|
||||
@Model
|
||||
final class ExcludedAdoptableApp
|
||||
{
|
||||
@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)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public func deleteSelfFromDatabase()
|
||||
{
|
||||
let modelContext: ModelContext = AppConstants.shared.modelContainer.mainContext
|
||||
|
||||
do
|
||||
{
|
||||
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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// Application.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
|
@ -13,11 +13,17 @@ import SwiftData
|
|||
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>>
|
||||
|
||||
/// A representation of a Homebrew package
|
||||
struct BrewPackage: Identifiable, Equatable, Hashable, Codable
|
||||
public struct BrewPackage: Identifiable, Equatable, Hashable, Codable, Sendable
|
||||
{
|
||||
var id: UUID = .init()
|
||||
public var id: UUID = .init()
|
||||
let name: String
|
||||
|
||||
let type: PackageType
|
||||
|
|
@ -44,13 +50,13 @@ struct BrewPackage: Identifiable, Equatable, Hashable, Codable
|
|||
return versions.formatted(.list(type: .and))
|
||||
}
|
||||
|
||||
enum PackageType: String, CustomStringConvertible, Plottable, AppEntity, Codable
|
||||
public enum PackageType: String, CustomStringConvertible, Plottable, AppEntity, Codable
|
||||
{
|
||||
case formula
|
||||
case cask
|
||||
|
||||
/// User-readable description of the package type
|
||||
var description: String
|
||||
public var description: String
|
||||
{
|
||||
switch self
|
||||
{
|
||||
|
|
@ -62,7 +68,7 @@ struct BrewPackage: Identifiable, Equatable, Hashable, Codable
|
|||
}
|
||||
|
||||
/// Localization keys for description of the package type
|
||||
var localizableDescription: LocalizedStringKey
|
||||
public var localizableDescription: LocalizedStringKey
|
||||
{
|
||||
switch self
|
||||
{
|
||||
|
|
@ -97,9 +103,9 @@ struct BrewPackage: Identifiable, Equatable, Hashable, Codable
|
|||
}
|
||||
}
|
||||
|
||||
static let typeDisplayRepresentation: TypeDisplayRepresentation = .init(name: "package-details.type")
|
||||
public static let typeDisplayRepresentation: TypeDisplayRepresentation = .init(name: "package-details.type")
|
||||
|
||||
var displayRepresentation: DisplayRepresentation
|
||||
public var displayRepresentation: DisplayRepresentation
|
||||
{
|
||||
switch self
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
// Brew Tap.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 10.02.2023.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct BrewTap: Identifiable, Hashable
|
||||
public struct BrewTap: Identifiable, Hashable
|
||||
{
|
||||
let id: UUID = .init()
|
||||
public let id: UUID = .init()
|
||||
let name: String
|
||||
|
||||
var isBeingModified: Bool = false
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Corrupted Package.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct CorruptedPackage: Identifiable, Equatable
|
||||
{
|
||||
public let id: UUID = .init()
|
||||
let name: String
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Minimal Homebrew Package.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 25.05.2024.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import AppIntents
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
// Outdated Package.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 05.04.2023.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct OutdatedPackage: Identifiable, Equatable, Hashable
|
||||
public struct OutdatedPackage: Identifiable, Equatable, Hashable
|
||||
{
|
||||
enum PackageUpdatingType
|
||||
{
|
||||
|
|
@ -29,7 +29,7 @@ struct OutdatedPackage: Identifiable, Equatable, Hashable
|
|||
}
|
||||
}
|
||||
|
||||
let id: UUID = .init()
|
||||
public let id: UUID = .init()
|
||||
|
||||
let package: BrewPackage
|
||||
|
||||
|
|
@ -39,13 +39,14 @@ struct OutdatedPackage: Identifiable, Equatable, Hashable
|
|||
var isMarkedForUpdating: Bool = true
|
||||
|
||||
var updatingManagedBy: PackageUpdatingType
|
||||
|
||||
static func == (lhs: OutdatedPackage, rhs: OutdatedPackage) -> Bool
|
||||
|
||||
public static func == (lhs: OutdatedPackage, rhs: OutdatedPackage) -> Bool
|
||||
{
|
||||
return lhs.package.name == rhs.package.name
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
|
||||
public func hash(into hasher: inout Hasher)
|
||||
{
|
||||
hasher.combine(package.name)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,15 @@
|
|||
//
|
||||
// Get Names of Pinned Packages.swift
|
||||
// Cork
|
||||
// CorkPackagesModels
|
||||
//
|
||||
// Created by David Bureš - P on 12.06.2025.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
import CorkTerminalFunctions
|
||||
|
||||
extension BrewPackagesTracker
|
||||
public extension BrewPackagesTracker
|
||||
{
|
||||
/// Get the names of tagged packages as set, for fas comparing
|
||||
///
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// URL - Package Name from URL.swift
|
||||
// Get Package Name from URL.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 18.01.2025.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension URL
|
||||
public extension URL
|
||||
{
|
||||
func packageNameFromURL() -> String
|
||||
{
|
||||
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import Defaults
|
||||
|
||||
@Observable @MainActor
|
||||
class BrewPackagesTracker
|
||||
public class BrewPackagesTracker
|
||||
{
|
||||
var installedFormulae: BrewPackages = .init()
|
||||
var installedCasks: BrewPackages = .init()
|
||||
|
|
@ -47,7 +48,7 @@ class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Collected errors from failed Formulae loading
|
||||
var unsuccessfullyLoadedFormulaeErrors: [PackageLoadingError]
|
||||
var unsuccessfullyLoadedFormulaeErrors: [BrewPackage.PackageLoadingError]
|
||||
{
|
||||
return installedFormulae.compactMap
|
||||
{ rawResult in
|
||||
|
|
@ -92,7 +93,7 @@ class BrewPackagesTracker
|
|||
}
|
||||
|
||||
/// Collected errors from failed Casks loading
|
||||
var unsuccessfullyLoadedCasksErrors: [PackageLoadingError]
|
||||
var unsuccessfullyLoadedCasksErrors: [BrewPackage.PackageLoadingError]
|
||||
{
|
||||
return installedCasks.compactMap
|
||||
{ rawResult in
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@
|
|||
// Check if URL is Symlink.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 25.02.2023.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
|
||||
extension URL
|
||||
public extension URL
|
||||
{
|
||||
func isSymlink() -> Bool?
|
||||
{
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
//
|
||||
// Filter Symlinks.swift
|
||||
// Filter Out Symlinks.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 13.11.2024.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension [URL]
|
||||
public extension [URL]
|
||||
{
|
||||
/// Filter out all symlinks from an array of URLs
|
||||
var withoutSymlinks: [URL]
|
||||
|
|
@ -2,16 +2,16 @@
|
|||
// REGEX Match.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 19.02.2023.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum RegexError: LocalizedError
|
||||
public enum RegexError: LocalizedError
|
||||
{
|
||||
case regexFunctionCouldNotMatchAnything
|
||||
|
||||
var errorDescription: String?
|
||||
public var errorDescription: String?
|
||||
{
|
||||
switch self
|
||||
{
|
||||
|
|
@ -21,7 +21,7 @@ enum RegexError: LocalizedError
|
|||
}
|
||||
}
|
||||
|
||||
extension String
|
||||
public extension String
|
||||
{
|
||||
|
||||
/// Match a string according to a specified REGEX
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
//
|
||||
// Shell Interface.swift
|
||||
// Shell Commands.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš on 03.07.2022.
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CorkShared
|
||||
|
||||
@discardableResult
|
||||
func shell(
|
||||
public func shell(
|
||||
_ launchPath: URL,
|
||||
_ arguments: [String],
|
||||
environment: [String: String]? = nil,
|
||||
|
|
@ -46,7 +46,7 @@ func shell(
|
|||
/// // Do something with `errorLine`
|
||||
/// }
|
||||
/// }
|
||||
func shell(
|
||||
public func shell(
|
||||
_ launchPath: URL,
|
||||
_ arguments: [String],
|
||||
environment: [String: String]? = nil,
|
||||
|
|
@ -166,7 +166,7 @@ func shell(
|
|||
}
|
||||
}
|
||||
|
||||
func shell(
|
||||
public func shell(
|
||||
_ launchPath: URL,
|
||||
_ arguments: [String],
|
||||
environment: [String: String]? = nil,
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Terminal Output.swift
|
||||
// Cork
|
||||
//
|
||||
// Created by David Bureš - P on 28.10.2025.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct TerminalOutput
|
||||
{
|
||||
public var standardOutput: String
|
||||
public var standardError: String
|
||||
}
|
||||
|
||||
public enum StreamedTerminalOutput
|
||||
{
|
||||
case standardOutput(String)
|
||||
case standardError(String)
|
||||
}
|
||||
104
Project.swift
104
Project.swift
|
|
@ -33,9 +33,14 @@ func corkTarget(configureWithSelfCompiled: Bool) -> ProjectDescription.Target {
|
|||
.target(corkSharedTarget),
|
||||
.target(corkNotificationsTarget),
|
||||
.target(corkPackages_modelsTarget),
|
||||
.target(corkPackages_logicTarget),
|
||||
.target(corkTerminalFunctionsTarget),
|
||||
.target(corkIntentsTarget),
|
||||
.external(name: "LaunchAtLogin"),
|
||||
.external(name: "DavidFoundation"),
|
||||
.external(name: "ApplicationInspector"),
|
||||
.external(name: "ButtonKit"),
|
||||
.external(name: "FactoryKit"),
|
||||
.package(product: "SwiftLintBuildToolPlugin", type: .plugin),
|
||||
.external(name: "Defaults"),
|
||||
.external(name: "DefaultsMacros")
|
||||
|
|
@ -63,8 +68,15 @@ let corkSharedTarget: ProjectDescription.Target = .target(
|
|||
sources: [
|
||||
"Modules/Shared/**/*.swift"
|
||||
],
|
||||
resources: [
|
||||
"Cork/**/*.xcassets",
|
||||
"Cork/**/*.xcstrings",
|
||||
"PrivacyInfo.xcprivacy",
|
||||
"Cork/Logic/Helpers/Programs/Sudo Helper",
|
||||
],
|
||||
dependencies: [
|
||||
.external(name: "Defaults")
|
||||
.external(name: "Defaults"),
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
.debug(
|
||||
|
|
@ -102,6 +114,30 @@ let corkNotificationsTarget: ProjectDescription.Target = .target(
|
|||
])
|
||||
)
|
||||
|
||||
let corkTerminalFunctionsTarget: ProjectDescription.Target = .target(
|
||||
name: "CorkTerminalFunctions",
|
||||
destinations: [.mac],
|
||||
product: .staticLibrary,
|
||||
bundleId: "eu.davidbures.cork-terminal-functions",
|
||||
deploymentTargets: .macOS("14.0.0"),
|
||||
sources: [
|
||||
"Modules/TerminalSupport/**/*.swift"
|
||||
],
|
||||
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_modelsTarget: ProjectDescription.Target = .target(
|
||||
name: "CorkPackagesModels",
|
||||
destinations: [.mac],
|
||||
|
|
@ -111,6 +147,69 @@ let corkPackages_modelsTarget: ProjectDescription.Target = .target(
|
|||
sources: [
|
||||
"Modules/Packages/PackagesModels/**/*.swift"
|
||||
],
|
||||
resources: [
|
||||
"Cork/**/*.xcassets",
|
||||
"Cork/**/*.xcstrings",
|
||||
"PrivacyInfo.xcprivacy",
|
||||
"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: [
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
.debug(
|
||||
name: "Debug",
|
||||
xcconfig: .relativeToRoot("xcconfigs/Cork.xcconfig")
|
||||
),
|
||||
.release(
|
||||
name: "Release",
|
||||
xcconfig: .relativeToRoot("xcconfigs/Cork.xcconfig")
|
||||
)
|
||||
])
|
||||
)
|
||||
|
||||
let corkIntentsTarget: ProjectDescription.Target = .target(
|
||||
name: "CorkIntents",
|
||||
destinations: [.mac],
|
||||
product: .staticLibrary,
|
||||
bundleId: "eu.davidbures.cork-intents",
|
||||
deploymentTargets: .macOS("14.0.0"),
|
||||
sources: [
|
||||
"Modules/Intents/**/*.swift"
|
||||
],
|
||||
dependencies: [
|
||||
.external(name: "FactoryKit")
|
||||
],
|
||||
settings: .settings(configurations: [
|
||||
.debug(
|
||||
name: "Debug",
|
||||
|
|
@ -186,7 +285,10 @@ let project = Project(
|
|||
corkTarget(configureWithSelfCompiled: false),
|
||||
corkTarget(configureWithSelfCompiled: true),
|
||||
corkSharedTarget,
|
||||
corkTerminalFunctionsTarget,
|
||||
corkPackages_modelsTarget,
|
||||
corkPackages_logicTarget,
|
||||
corkIntentsTarget,
|
||||
corkNotificationsTarget,
|
||||
corkHelpTarget,
|
||||
corkTestsTarget
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "applicationinspector",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/buresdv/ApplicationInspector",
|
||||
"state" : {
|
||||
"revision" : "72d9888b3da342df026254a940553c31b72daec8",
|
||||
"version" : "1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "buttonkit",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
@ -27,6 +36,15 @@
|
|||
"version" : "9.0.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "factory",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/hmlongco/Factory",
|
||||
"state" : {
|
||||
"branch" : "develop",
|
||||
"revision" : "a46ce210c1535064beffd1f00caf9835507b656f"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "launchatlogin-modern",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ let package = Package(
|
|||
.package(url: "https://github.com/sindresorhus/LaunchAtLogin-Modern", .upToNextMajor(from: "1.0.0")),
|
||||
.package(url: "https://github.com/sindresorhus/Defaults", .upToNextMajor(from: "9.0.2")),
|
||||
.package(url: "https://github.com/buresdv/DavidFoundation", .upToNextMajor(from: "2.0.1")),
|
||||
.package(url: "https://github.com/buresdv/ApplicationInspector", .upToNextMajor(from: "1.0.0")),
|
||||
.package(url: "https://github.com/Dean151/ButtonKit", .upToNextMajor(from: "0.6.1")),
|
||||
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", .upToNextMajor(from: "0.56.1")),
|
||||
.package(url: "https://github.com/hmlongco/Factory", branch: "develop")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
|||
Loading…
Reference in New Issue