🐚 Coquille

Build Status

一个简单的 Swift 封装,用于处理 Process,支持 Swift 并发和从 stdoutstderr 流式输出。

要求

macOS 10.15 及以上

安装

通过 Xcode (File > Add Packages...) 或将 Coquille 添加到项目的 Package.swift 文件中,将 Coquille 添加到你的项目中

dependencies: [
  .package(url: "https://github.com/alexrozanski/Coquille.git", from: "0.3.0")
]

用法

Coquille 公开了自己的 Process 类,你可以使用它来执行命令。Process.run() 是一个 async 函数,所以你可以直接 await 退出码

import Coquille

let process = Process(commandString: "pwd"))
_ = try await process.run() // Prints `pwd` to `stdout`

// Use `command:` for more easily working with variable command-line arguments
let deps = ["numpy", "torch"]
let process = Process(command: .init("python3", arguments: ["-m", "pip", "install"] + deps)))
_ = try await process.run()

I/O

默认情况下,Process 不会将产生的进程的任何输出管道到 stdoutstderr。 这可以通过 printStdoutprintStderr 进行配置

import Coquille

let process = Process(commandString: "brew install wget", printStdout: true))
_ = try await process.run() // Pipes standard output to `stdout` but will not pipe error output to `stderr`

你也可以为 stdout 和 stderr 传递一个 OutputHandler,它将流式传输来自两者的内容

import Coquille

let process = Process(
  commandString: "swift build",
  stdout: { stdout in
    ...
  },
  stderr: { stderr in
    ...
  })
_ = try await process.run() // Streams standard and error output to the handlers provided to `stdout:` and `stderr:`

退出码

// `isSuccess` can be used to test the exit code for success
let hasRuby = (try await Process(commandString: "which ruby").run()).isSuccess

// Use `errorCode` to get a nonzero exit code
if let errorCode = (try await Process(commandString: "swift build").run()).errorCode {
  switch errorCode {
    case 127:
      // Command not found
    default:
      ...
  }
}

取消

主要的 Process.run() 函数签名是

public func run() async throws -> Status

它允许你使用 Swift 并发来执行子进程并 await 退出状态。 但是,如果你想支持取消,你可以使用另一个 run() 函数

public func run(with completionHandler: @escaping ((Status) -> Void)) -> ProcessCancellationHandle

它立即返回一个不透明的 ProcessCancellationHandle 类型,你可以调用它的 cancel() 方法来取消执行,进程状态通过 completionHandler 闭包传递。

致谢

感谢 Ben Chatelain 撰写的关于拦截 stdout 的 博客文章,该文章用于实现测试套件中的一些测试。