首页 > 解决方案 > 用于 git 命令的 swift 命令行工具,但它没有

问题描述

我想使用 swift 为 git 命令创建一个工具。


import Foundation

struct Task {
    static let shared = Task()

    func run(with args: String...){
        let task = Process()
        task.launchPath = "/usr/bin/git"
        task.arguments = ["-c", args.joined(separator: " ")]

        let pipe = Pipe()
        task.standardOutput = pipe
        task.launch()

        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(data: data, encoding: .utf8)!
        print(output)
        task.waitUntilExit()
    }
}


let task = Task.shared
task.run(with: "status")
task.run(with: "fetch --all")
task.run(with: "add --all")

标签: swiftgit

解决方案


您在代码中使用了不推荐使用的方法,并且缺少其他一些东西。

首先我们应该设置要使用的shell

func run(with args: String...){
    let task = Process()
    task.executableURL = URL(fileURLWithPath: "/bin/zsh")

然后,我们不使用已弃用的,而是使用launchPath完整的命令构建一个字符串,并将其设置为任务的参数

let arguments = "/usr/bin/git \(args.joined(separator: " "))"
task.arguments = ["-c", arguments]

我也认为通过检查标准错误来处理任何错误是个好主意

let pipe = Pipe()
let errorPipe = Pipe()
task.standardOutput = pipe
task.standardError = errorPipe

而不是使用不推荐使用的launch方法,使用run并读取标准输出和标准错误

do {
    try task.run()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    if !data.isEmpty {
        if let output = String(data: data, encoding: .utf8) {
            print(output)
        }
    }

    let error = errorPipe.fileHandleForReading.readDataToEndOfFile()
    if !error.isEmpty {
        if let errorMessage = String(data: error, encoding: .utf8) {
            print(errorMessage)
        }
    }
} catch {
    print(error)
}

对于一个简单的命令,可能值得在其中处理标准输出和标准错误,if/else因此可以随意更改,但对于更复杂的命令,例如处理多个文件,它可能会同时产生输出和错误


推荐阅读