Skip to content

Commit

Permalink
Update package
Browse files Browse the repository at this point in the history
  • Loading branch information
vmanot committed Oct 28, 2024
1 parent dbe09e5 commit 33b8b3e
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 404 deletions.
14 changes: 7 additions & 7 deletions Sources/Merge/Intermodular/Extensions/Foundation/Process++.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ extension Process {
public static func run(
command: String,
arguments: [String]
) async throws -> _ProcessResult {
) async throws -> Process.RunResult {
let process = Process()

process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
Expand All @@ -82,7 +82,7 @@ extension Process {
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
package func _runRedirectingAllOutput(
package func _runSynchronouslyRedirectingAllOutput(
to sink: Process.StandardOutputSink
) throws {
_installSigintIfNeeded()
Expand All @@ -97,7 +97,7 @@ extension Process {
}
}

public func _runSynchronously() throws -> _ProcessResult {
public func _runSynchronously() throws -> Process.RunResult {
_installSigintIfNeeded()

let stdout = _UnsafeStandardOutputOrErrorPipeBuffer(id: .stdout)
Expand All @@ -110,15 +110,15 @@ extension Process {

self.waitUntilExit()

return _ProcessResult(
return Process.RunResult(
process: self,
stdout: try stdout.closeReturningData(),
stderr: try stderr.closeReturningData(),
terminationError: terminationError
)
}

public func _runAsynchronously() async throws -> _ProcessResult {
public func _runAsynchronously() async throws -> Process.RunResult {
_installSigintIfNeeded()

let stdout = _UnsafeAsyncStandardOutputOrErrorPipeBuffer(id: .stdout)
Expand All @@ -130,12 +130,12 @@ extension Process {
let isRunning = _OSUnfairLocked<Bool>(wrappedValue: false)

return try await withTaskCancellationHandler {
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<_ProcessResult, Error>) in
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Process.RunResult, Error>) in
self.terminationHandler = { process in
_Concurrency.Task {
do {
continuation.resume(
returning: _ProcessResult(
returning: Process.RunResult(
process: self,
stdout: try await stdout.closeReturningData(),
stderr: try await stderr.closeReturningData(),
Expand Down
81 changes: 81 additions & 0 deletions Sources/Merge/Intramodular/Process/Process.PipeName.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// Copyright (c) Vatsal Manot
//

#if os(macOS)

import FoundationX
import Swift
import System

extension Process {
public enum PipeName: Codable, Hashable, Sendable {
case standardInput
case standardOutput
case standardError
}
}

// MARK: - Supplementary

public protocol _ProcessPipeProviding {
func pipe(
named name: Process.PipeName
) -> Pipe?
}

extension _ProcessPipeProviding {
public func name(of pipe: Pipe) throws -> Process.PipeName {
if pipe === self.pipe(named: .standardInput) {
return .standardInput
} else if pipe === self.pipe(named: .standardOutput) {
return .standardOutput
} else if pipe === self.pipe(named: .standardError) {
return .standardError
} else {
throw Process.UnrecognizedPipeError.pipe(pipe)
}
}
}

extension Process: _ProcessPipeProviding {
public func pipe(
named name: PipeName
) -> Pipe? {
switch name {
case .standardInput:
return standardInput as? Pipe
case .standardOutput:
return standardOutput as? Pipe
case .standardError:
return standardError as? Pipe
}
}
}

extension _AsyncProcess: _ProcessPipeProviding {
public typealias PipeName = Process.PipeName

public func pipe(
named name: Process.PipeName
) -> Pipe? {
switch name {
case .standardInput:
return _standardInputPipe
case .standardOutput:
return _standardOutputPipe
case .standardError:
return _standardErrorPipe
}
}
}

// MARK: - Error Handling

extension Process {
public enum UnrecognizedPipeError: Swift.Error, @unchecked Sendable {
case pipe(Pipe)
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import Swallow

/// A type that represents the result of a running a `Process`.
@Hashable
public struct _ProcessResult: Logging, @unchecked Sendable {
#if os(macOS) || targetEnvironment(macCatalyst)
public struct _ProcessRunResult: Logging, @unchecked Sendable {
#if os(macOS) || targetEnvironment(macCatalyst)
public let process: Process
#endif
#endif
public let stdout: Data
public let stderr: Data
public let terminationError: ProcessTerminationError?

#if os(macOS)
#if os(macOS)
package init(
process: Process,
stdout: Data,
Expand All @@ -27,8 +27,8 @@ public struct _ProcessResult: Logging, @unchecked Sendable {
self.stderr = stderr
self.terminationError = terminationError
}
#endif
#endif

@_transparent
public func validate() throws {
if let terminationError {
Expand All @@ -41,7 +41,7 @@ public struct _ProcessResult: Logging, @unchecked Sendable {
}
}

extension _ProcessResult {
extension _ProcessRunResult {
/// A convenience property to get lines of the standard output, whitespace and newline trimmed.
public var lines: [String] {
get throws {
Expand Down Expand Up @@ -75,7 +75,7 @@ extension _ProcessResult {
#if os(macOS) || targetEnvironment(macCatalyst)
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension _ProcessResult {
extension Process.RunResult {
package init(
process: Process,
stdout: String,
Expand All @@ -92,11 +92,23 @@ extension _ProcessResult {
}
#endif

// MARK: - Supplementary

#if os(macOS)
extension Process {
public typealias RunResult = _ProcessRunResult
}
#endif

// MARK: - Deprecated

@available(*, deprecated, renamed: "Process.RunResult")
public typealias _ProcessResult = _ProcessRunResult

#if os(macOS)
extension Process {
@available(*, deprecated, renamed: "_ProcessResult")
public typealias AllOutput = _ProcessResult
@available(*, deprecated, renamed: "Process.RunResult")
public typealias AllOutput = Process.RunResult
}

#endif
26 changes: 13 additions & 13 deletions Sources/Merge/Intramodular/Process/SystemShell.Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Foundation
import Combine
import Swallow

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension SystemShell {
public struct Environment {
let launchPath: String?
Expand All @@ -21,6 +23,8 @@ extension SystemShell {
}
}

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension SystemShell.Environment {
func resolve(
launchPath: String,
Expand Down Expand Up @@ -53,13 +57,14 @@ extension SystemShell.Environment {
var arguments = [String]()

if commands.count > 1 {
try await SystemShell.run(
arguments = try await SystemShell.run(
command: "echo " + commands[1...].joined(separator: " "),
environment: .bash,
outputHandler: .block {
arguments = $0.split(separator: " ").map(String.init)
}
environment: .bash
)
.stdoutString
.unwrap()
.split(separator: " ")
.map(String.init)
}

return (launchPath, arguments)
Expand All @@ -69,21 +74,16 @@ extension SystemShell.Environment {
private func resolveLaunchPath(
from x: String
) async throws -> String {
var result: String = ""

try await SystemShell.run(
command: "which \(x)",
outputHandler: .block {
result = $0
}
)
let result: String = try await SystemShell.run(command: "which \(x)").stdoutString.unwrap()

return result
}
}

// MARK: - Initializers

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension SystemShell.Environment {
public static var bash: Self {
Self(
Expand Down
51 changes: 26 additions & 25 deletions Sources/Merge/Intramodular/Process/SystemShell.run.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,56 @@
import Foundation
import Swallow

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension SystemShell {
public func run(
shell: SystemShell.Environment,
command: String,
currentDirectoryURL: URL? = nil,
environmentVariables: [String: String] = [:]
) async throws -> _ProcessResult {
command: String
) async throws -> _ProcessRunResult {
try await run(
executableURL: shell.launchURL.unwrap(),
arguments: shell.deriveArguments(command),
currentDirectoryURL: nil,
environment: shell,
environmentVariables: [:]
environment: shell
)
}

public func run(m
public func run(
executablePath: String,
arguments: [String],
currentDirectoryURL: URL? = nil,
environment: Environment = .zsh,
environmentVariables: [String: String] = [:]
) async throws -> _ProcessResult {
environment: Environment = .zsh
) async throws -> _ProcessRunResult {
try await run(
executableURL: try URL(string: executablePath).unwrap(),
arguments: arguments,
currentDirectoryURL: nil,
environment: environment,
environmentVariables: [:]
environment: environment
)
}

}

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@available(macCatalyst, unavailable)
extension SystemShell {
@discardableResult
public static func run(
command: String,
input: String? = nil,
environment: Environment = .zsh,
environmentVariables: [String: String] = [:],
currentDirectoryURL: URL? = nil,
outputHandler: SystemShell.StandardOutputHandler = .print,
options: [_AsyncProcessOption]? = nil
) async throws -> _ProcessResult {
try await SystemShell(options: options).run(
options: [_AsyncProcess.Option]? = nil
) async throws -> _ProcessRunResult {
let shell = SystemShell(options: options)

shell.environmentVariables.merge(environmentVariables, uniquingKeysWith: { lhs, rhs in rhs })
shell.currentDirectoryURL = currentDirectoryURL

let result: _ProcessRunResult = try await shell.run(
command: command,
input: input,
environment: environment,
environmentVariables: environmentVariables,
currentDirectoryURL: currentDirectoryURL,
outputHandler: outputHandler
environment: environment
)

return result
}
}
Loading

0 comments on commit 33b8b3e

Please sign in to comment.