mirror of
https://github.com/maxgoedjen/secretive.git
synced 2025-09-15 08:50:57 +00:00
Cleanup
This commit is contained in:
parent
be28d59873
commit
e966203312
@ -21,13 +21,16 @@ let package = Package(
|
|||||||
targets: ["SmartCardSecretKit"]),
|
targets: ["SmartCardSecretKit"]),
|
||||||
.library(
|
.library(
|
||||||
name: "SecretAgentKit",
|
name: "SecretAgentKit",
|
||||||
targets: ["SecretAgentKit"]),
|
targets: ["SecretAgentKit", "XPCWrappers"]),
|
||||||
.library(
|
.library(
|
||||||
name: "SecretAgentKitHeaders",
|
name: "SecretAgentKitHeaders",
|
||||||
targets: ["SecretAgentKitHeaders"]),
|
targets: ["SecretAgentKitHeaders"]),
|
||||||
.library(
|
.library(
|
||||||
name: "Brief",
|
name: "Brief",
|
||||||
targets: ["Brief"]),
|
targets: ["Brief"]),
|
||||||
|
.library(
|
||||||
|
name: "XPCWrappers",
|
||||||
|
targets: ["XPCWrappers"]),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
],
|
],
|
||||||
@ -70,7 +73,7 @@ let package = Package(
|
|||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "Brief",
|
name: "Brief",
|
||||||
dependencies: [],
|
dependencies: ["XPCWrappers"],
|
||||||
resources: [localization],
|
resources: [localization],
|
||||||
swiftSettings: swiftSettings,
|
swiftSettings: swiftSettings,
|
||||||
),
|
),
|
||||||
@ -78,6 +81,10 @@ let package = Package(
|
|||||||
name: "BriefTests",
|
name: "BriefTests",
|
||||||
dependencies: ["Brief"],
|
dependencies: ["Brief"],
|
||||||
),
|
),
|
||||||
|
.target(
|
||||||
|
name: "XPCWrappers",
|
||||||
|
swiftSettings: swiftSettings,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Observation
|
import Observation
|
||||||
|
import XPCWrappers
|
||||||
|
|
||||||
/// A concrete implementation of ``UpdaterProtocol`` which considers the current release and OS version.
|
/// A concrete implementation of ``UpdaterProtocol`` which considers the current release and OS version.
|
||||||
@Observable public final class Updater: UpdaterProtocol, Sendable {
|
@Observable public final class Updater: UpdaterProtocol, Sendable {
|
||||||
@ -46,14 +47,9 @@ import Observation
|
|||||||
|
|
||||||
/// Manually trigger an update check.
|
/// Manually trigger an update check.
|
||||||
public func checkForUpdates() async throws {
|
public func checkForUpdates() async throws {
|
||||||
let session: XPCSession
|
let session = try XPCTypedSession<[Release], Never>(serviceName: "com.maxgoedjen.Secretive.ReleasesDownloader")
|
||||||
if #available(macOS 26.0, *) {
|
|
||||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.ReleasesDownloader", requirement: .isFromSameTeam())
|
|
||||||
} else {
|
|
||||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.ReleasesDownloader")
|
|
||||||
}
|
|
||||||
await evaluate(releases: try await session.send())
|
await evaluate(releases: try await session.send())
|
||||||
session.cancel(reason: "Done")
|
session.complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,33 +99,3 @@ extension Updater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension XPCSession {
|
|
||||||
|
|
||||||
func send<Response: Decodable & Sendable>(_ message: some Encodable = XPCSession.emptyMessage) async throws -> Response {
|
|
||||||
try await withCheckedThrowingContinuation { continuation in
|
|
||||||
do {
|
|
||||||
try send(message) { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let message):
|
|
||||||
do {
|
|
||||||
let decoded = try message.decode(as: Response.self)
|
|
||||||
continuation.resume(returning: decoded)
|
|
||||||
} catch {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static var emptyMessage: some Encodable {
|
|
||||||
Data()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
49
Sources/Packages/Sources/XPCWrappers/XPCWrappers.swift
Normal file
49
Sources/Packages/Sources/XPCWrappers/XPCWrappers.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct XPCTypedSession<ResponseType: Codable & Sendable, ErrorType: Error & Codable>: Sendable {
|
||||||
|
|
||||||
|
private let session: XPCSession
|
||||||
|
|
||||||
|
public init(serviceName: String, warmup: Bool = false) throws {
|
||||||
|
if #available(macOS 26.0, *) {
|
||||||
|
session = try XPCSession(xpcService: serviceName, requirement: .isFromSameTeam())
|
||||||
|
} else {
|
||||||
|
session = try XPCSession(xpcService: serviceName)
|
||||||
|
}
|
||||||
|
if warmup {
|
||||||
|
Task { [self] in
|
||||||
|
_ = try? await send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func send(_ message: some Encodable = Data()) async throws -> ResponseType {
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
do {
|
||||||
|
try session.send(message) { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let message):
|
||||||
|
if let result = try? message.decode(as: ResponseType.self) {
|
||||||
|
continuation.resume(returning: result)
|
||||||
|
} else if let error = try? message.decode(as: ErrorType.self) {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
} else {
|
||||||
|
continuation.resume(throwing: UnknownMessageError())
|
||||||
|
}
|
||||||
|
case .failure(let error):
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func complete() {
|
||||||
|
session.cancel(reason: "Done")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct UnknownMessageError: Error, Codable {}
|
@ -1,52 +1,23 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SecretAgentKit
|
import SecretAgentKit
|
||||||
import Brief
|
import Brief
|
||||||
|
import XPCWrappers
|
||||||
|
|
||||||
/// Delegates all agent input parsing to an XPC service which wraps OpenSSH
|
/// Delegates all agent input parsing to an XPC service which wraps OpenSSH
|
||||||
public final class XPCAgentInputParser: SSHAgentInputParserProtocol {
|
public final class XPCAgentInputParser: SSHAgentInputParserProtocol {
|
||||||
|
|
||||||
private let session: XPCSession
|
private let session: XPCTypedSession<SSHAgent.Request, SSHAgentInputParser.AgentParsingError>
|
||||||
private let queue = DispatchQueue(label: "com.maxgoedjen.Secretive.AgentRequestParser", qos: .userInteractive)
|
|
||||||
|
|
||||||
public init() throws {
|
public init() throws {
|
||||||
if #available(macOS 26.0, *) {
|
session = try XPCTypedSession(serviceName: "com.maxgoedjen.Secretive.AgentRequestParser", warmup: true)
|
||||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.AgentRequestParser", targetQueue: queue, requirement: .isFromSameTeam())
|
|
||||||
} else {
|
|
||||||
session = try XPCSession(xpcService: "com.maxgoedjen.Secretive.AgentRequestParser", targetQueue: queue)
|
|
||||||
}
|
|
||||||
Task {
|
|
||||||
// Warm up the XPC endpoint.
|
|
||||||
_ = try? await parse(data: Data())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parse(data: Data) async throws -> SSHAgent.Request {
|
public func parse(data: Data) async throws -> SSHAgent.Request {
|
||||||
try await withCheckedThrowingContinuation { continuation in
|
try await session.send(data)
|
||||||
do {
|
|
||||||
try session.send(data) { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let result):
|
|
||||||
if let result = try? result.decode(as: SSHAgent.Request.self) {
|
|
||||||
continuation.resume(returning: result)
|
|
||||||
} else if let error = try? result.decode(as: SSHAgentInputParser.AgentParsingError.self) {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
} else {
|
|
||||||
continuation.resume(throwing: UnknownMessageError())
|
|
||||||
}
|
|
||||||
case .failure(let error):
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
session.cancel(reason: "Done")
|
session.complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnknownMessageError: Error {}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user