Nucleic: Gitea Runner macOS VM Support
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import ArgumentParser
|
||||
import Foundation
|
||||
import RunnerCore
|
||||
import RunnerHost
|
||||
|
||||
/// `gitea-macos-runner doctor` — verify the host before anything else.
|
||||
///
|
||||
/// Every check corresponds to a failure that would otherwise show up as an
|
||||
/// opaque error deep inside a VM boot: wrong architecture, unsigned binary,
|
||||
/// locked keychain, non-admin Gitea token, dead download URL. Run this first,
|
||||
/// and again after `service install`.
|
||||
struct DoctorCommand: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
commandName: "doctor",
|
||||
abstract: "Check that this host can build and run macOS guests."
|
||||
)
|
||||
|
||||
@OptionGroup var options: GlobalOptions
|
||||
|
||||
/// Emit machine-readable JSON instead of aligned text.
|
||||
@Flag(name: .long, help: "Emit results as JSON.")
|
||||
var json: Bool = false
|
||||
|
||||
/// By default `doctor` exits non-zero when any check fails, so it can gate a
|
||||
/// setup script. This makes it always exit zero.
|
||||
@Flag(name: .customLong("no-fail"), help: "Exit zero even when checks fail.")
|
||||
var noFail: Bool = false
|
||||
|
||||
func run() async throws {
|
||||
// Deliberately does not use options.loadConfig(): a broken or missing
|
||||
// config is exactly the state doctor exists to diagnose, so it is
|
||||
// reported as a check rather than thrown as an error.
|
||||
let checks = await Doctor.runChecks(configPath: options.configPath)
|
||||
|
||||
if json {
|
||||
let payload: [[String: Any]] = checks.map { check in
|
||||
var entry: [String: Any] = [
|
||||
"name": check.name,
|
||||
"result": check.result.label,
|
||||
"detail": check.detail,
|
||||
"blocking": check.isBlocking,
|
||||
]
|
||||
if let remediation = check.remediation {
|
||||
entry["remediation"] = remediation
|
||||
}
|
||||
return entry
|
||||
}
|
||||
let data = try JSONSerialization.data(
|
||||
withJSONObject: payload,
|
||||
options: [.prettyPrinted, .sortedKeys]
|
||||
)
|
||||
print(String(data: data, encoding: .utf8) ?? "[]")
|
||||
} else {
|
||||
print(Doctor.format(checks))
|
||||
}
|
||||
|
||||
if !noFail, checks.contains(where: \.isBlocking) {
|
||||
throw ExitCode(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user