Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Sources/ScipioKit/Executor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ private actor ProcessOutputBuffer {

@_spi(Internals)
public protocol Executor: Sendable {
associatedtype Result: ExecutorResult
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
associatedtype Result: ExecutorResult
associatedtype Result: ExecutorResult

/// Executes the command with the given arguments and environment variables.
///
/// - Parameters:
Expand All @@ -23,7 +24,7 @@ public protocol Executor: Sendable {
/// - Note:
/// This does not merge with the existing environment.
@discardableResult
func execute(_ arguments: [String], environment: [String: String]?) async throws -> ExecutorResult
func execute(_ arguments: [String], environment: [String: String]?) async throws -> Result
}

@_spi(Internals)
Expand Down Expand Up @@ -55,12 +56,12 @@ public protocol ExecutorResult: Sendable {

public extension Executor {
@discardableResult
func execute(_ arguments: [String]) async throws -> ExecutorResult {
func execute(_ arguments: [String]) async throws -> some ExecutorResult {
try await execute(arguments, environment: nil)
}

@discardableResult
func execute(_ arguments: String...) async throws -> ExecutorResult {
func execute(_ arguments: String...) async throws -> some ExecutorResult {
try await execute(arguments)
}
}
Expand Down Expand Up @@ -114,7 +115,10 @@ public struct ProcessExecutor<Decoder: ErrorDecoder>: Executor, Sendable {

public var streamOutput: (@Sendable ([UInt8]) async -> Void)?

public func execute(_ arguments: [String], environment: [String: String]?) async throws -> ExecutorResult {
public func execute(
_ arguments: [String],
environment: [String: String]?
) async throws -> some ExecutorResult {
guard let executable = arguments.first, !executable.isEmpty else {
throw ProcessExecutorError.executableNotFound
}
Expand Down Expand Up @@ -185,7 +189,7 @@ public struct ProcessExecutor<Decoder: ErrorDecoder>: Executor, Sendable {
let finalErrorOutput = try await errorOutputTask.value

// Wait for process to complete
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<ExecutorResult, Error>) in
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<FoundationProcessResult, Error>) in
process.terminationHandler = { process in
outputHandle.readabilityHandler = nil
errorHandle.readabilityHandler = nil
Expand Down
2 changes: 1 addition & 1 deletion Tests/ScipioKitTests/CacheSystemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ final class CacheSystemTests: XCTestCase {
}

// Ensure that the cache key is properly calculated when the package is in a repository with the correct tag."
let processExecutor: Executor = ProcessExecutor()
let processExecutor = ProcessExecutor()
let tempTestingPackagePathString = tempTestingPackagePath.path(percentEncoded: false)
try await processExecutor.execute(["/usr/bin/xcrun", "git", "init", tempTestingPackagePathString])
try await processExecutor.execute([
Expand Down
8 changes: 4 additions & 4 deletions Tests/ScipioKitTests/TestingExecutor.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import Foundation
@testable @_spi(Internals) import ScipioKit

actor StubbableExecutor: Executor {
init(executeHook: @escaping (([String]) throws -> ExecutorResult)) {
actor StubbableExecutor<R: ExecutorResult>: Executor {
init(executeHook: @escaping (([String]) throws -> R)) {
self.executeHook = executeHook
}

let executeHook: (([String]) throws -> any ExecutorResult)
let executeHook: (([String]) throws -> R)
private(set) var calledArguments: [[String]] = []

var calledCount: Int {
calledArguments.count
}

func execute(_ arguments: [String], environment: [String: String]?) async throws -> ExecutorResult {
func execute(_ arguments: [String], environment: [String: String]?) async throws -> R {
calledArguments.append(arguments)
return try executeHook(arguments)
}
Expand Down