1
0
Fork 0
gobject-generator/Sources/GObjectGeneratorCommandPlugin/CommandPlugin.swift

76 lines
2.9 KiB
Swift

import PackagePlugin
import Foundation
/// SwiftPM command plugin for manual GIR binding regeneration.
///
/// Invoked via `swift package generate-gir-bindings`. Forwards all
/// user-provided arguments directly to the `generator` monorepo CLI,
/// defaulting `--output` to the package directory when the caller omits it.
/// The generator itself decides what to plan, render, and write from the
/// monorepo TOML config passed via `--monorepo-config`.
@main
struct GObjectGeneratorCommandPlugin: CommandPlugin {
/// Runs `generator` as a subprocess with the caller's arguments.
///
/// Stdout and stderr are piped through to the caller. Throws if the
/// subprocess exits non-zero.
///
/// - Parameters:
/// - context: The plugin context providing access to tools and the package directory.
/// - arguments: User-provided arguments forwarded to the generator, e.g.
/// `--monorepo-config regression/tier1/config.toml --format-config .swift-format`.
func performCommand(context: PluginContext, arguments: [String]) async throws {
guard !arguments.isEmpty else {
print("Usage: swift package generate-gir-bindings --monorepo-config <cfg> [--skip-report] [--smoke-target] [--format-config <path>]")
return
}
let executable = try context.tool(named: "generator")
var procArgs = arguments
if !procArgs.contains("--output") {
procArgs.append(contentsOf: ["--output", context.package.directoryURL.path()])
}
let process = Process()
process.executableURL = executable.url
process.arguments = procArgs
let stdoutPipe = Pipe()
let stderrPipe = Pipe()
process.standardOutput = stdoutPipe
process.standardError = stderrPipe
try process.run()
process.waitUntilExit()
let stdoutData = stdoutPipe.fileHandleForReading.readDataToEndOfFile()
let stderrData = stderrPipe.fileHandleForReading.readDataToEndOfFile()
if let stdoutStr = String(data: stdoutData, encoding: .utf8), !stdoutStr.isEmpty {
print(stdoutStr, terminator: "")
}
if let stderrStr = String(data: stderrData, encoding: .utf8), !stderrStr.isEmpty {
FileHandle.standardError.write(Data(stderrStr.utf8))
}
guard process.terminationStatus == 0 else {
throw GObjectGeneratorPluginError.generationFailed
}
}
}
/// Errors that can occur during command-plugin GIR generation.
enum GObjectGeneratorPluginError: Error {
/// The `generator` subprocess exited non-zero.
case generationFailed
}
extension GObjectGeneratorPluginError: CustomStringConvertible {
/// A human-readable description of the error.
var description: String {
switch self {
case .generationFailed:
return "gobject-generator generation failed; see output above for details."
}
}
}