76 lines
2.9 KiB
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."
|
|
}
|
|
}
|
|
}
|