mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 16:24:32 +00:00
- Deleted `init-port-forwards.sh`, removing deprecated placeholder script. - Introduced `dbStatus` command in `PFScriptBridge.swift` for querying database status with `kubecolor`. - Improved `StatusView` UI: refined button interactivity and font standardization. - Added `DBStatusWindowController` to `AppDelegate` for better database status visibility and control. - Updated `OverlayWindow`: adjusted window levels and interaction behavior for smoother UX.
116 lines
5.3 KiB
Swift
116 lines
5.3 KiB
Swift
import Foundation
|
|
|
|
// Bridge to invoke Prole Tools environment wrapper for status/restart.
|
|
// Use the environment defined in env.sh and execute scripts via $PROLE_SERVICE
|
|
// e.g. "$PROLE_SERVICE/init_port_forwards.sh <cmd>" so we don't rely on PATH.
|
|
enum PFScriptBridge {
|
|
// Keep the last command description actually used, for display in the UI.
|
|
private static var lastInvocation: String = "$PROLE_SERVICE/init_port_forwards.sh"
|
|
|
|
/// Public accessor for display purposes. Shows the last invocation we used.
|
|
static func invocationDescription() -> String { lastInvocation }
|
|
|
|
@discardableResult
|
|
static func restart() -> (code: Int32, out: String, err: String) { runScript(arg: "restart") }
|
|
|
|
static func status() -> (code: Int32, out: String, err: String) { runScript(arg: "status") }
|
|
|
|
static func dbStatus() -> (code: Int32, out: String, err: String) {
|
|
runRawCommand(command: "kubecolor cnpg status prole-db", description: "kubecolor cnpg status prole-db")
|
|
}
|
|
|
|
private static func runRawCommand(command: String, description: String) -> (code: Int32, out: String, err: String) {
|
|
lastInvocation = description
|
|
let p = Process()
|
|
p.executableURL = URL(fileURLWithPath: "/bin/bash")
|
|
p.arguments = ["-lc", command]
|
|
// Use home as default CWD
|
|
let env = ProcessInfo.processInfo.environment
|
|
let home = env["HOME"] ?? NSHomeDirectory()
|
|
let proleHomeEnv = env["PROLE_HOME"]
|
|
p.currentDirectoryURL = URL(fileURLWithPath: proleHomeEnv ?? home)
|
|
|
|
Logger.shared.info("invoking raw: \(description)")
|
|
|
|
let outPipe = Pipe(); let errPipe = Pipe()
|
|
p.standardOutput = outPipe
|
|
p.standardError = errPipe
|
|
do { try p.run() } catch {
|
|
let errStr = String(describing: error)
|
|
Logger.shared.error("spawn error: \(errStr)")
|
|
return (-1, "", errStr)
|
|
}
|
|
p.waitUntilExit()
|
|
let out = String(data: outPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
|
let err = String(data: errPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
|
let code = p.terminationStatus
|
|
|
|
return (code, out, err)
|
|
}
|
|
|
|
private static func runScript(arg: String) -> (code: Int32, out: String, err: String) {
|
|
let fm = FileManager.default
|
|
let env = ProcessInfo.processInfo.environment
|
|
let home = env["HOME"] ?? NSHomeDirectory()
|
|
let proleHomeEnv = env["PROLE_HOME"]
|
|
// Candidate locations for env.sh
|
|
let envCandidates: [String] = [
|
|
(proleHomeEnv != nil ? (proleHomeEnv! + "/env.sh") : nil),
|
|
home + "/dev/prole/env.sh",
|
|
].compactMap { $0 }
|
|
|
|
// Candidate locations for the script if we can't use env.sh
|
|
let scriptCandidates: [String] = [
|
|
(proleHomeEnv != nil ? (proleHomeEnv! + "/etc/init_port_forwards.sh") : nil),
|
|
home + "/dev/prole/etc/init_port_forwards.sh",
|
|
].compactMap { $0 }
|
|
|
|
// Build the command using the best available method.
|
|
var command: String
|
|
var cwd: String = proleHomeEnv ?? home
|
|
if let envPath = envCandidates.first(where: { fm.fileExists(atPath: $0) }) {
|
|
// Use env.sh to populate PROLE_* and invoke via $PROLE_SERVICE
|
|
command = "export PROLE_HOME=\"${PROLE_HOME:-$HOME}\"; . \"\(envPath)\"; \"${PROLE_SERVICE}/init_port_forwards.sh\" \(arg)"
|
|
lastInvocation = ". \(envPath) && $PROLE_SERVICE/init_port_forwards.sh \(arg)"
|
|
} else if let scriptPath = scriptCandidates.first(where: { fm.fileExists(atPath: $0) }) {
|
|
// Fallback: directly execute the repo script
|
|
command = "\"\(scriptPath)\" \(arg)"
|
|
lastInvocation = scriptPath + " \(arg)"
|
|
} else {
|
|
// Nothing found; construct a failing but explicit command for diagnostics
|
|
command = "echo '[prole-tools] env.sh and init_port_forwards.sh not found' 1>&2; exit 127"
|
|
lastInvocation = "<not found> init_port_forwards.sh \(arg)"
|
|
}
|
|
|
|
let p = Process()
|
|
p.executableURL = URL(fileURLWithPath: "/bin/bash")
|
|
p.arguments = ["-lc", command]
|
|
p.currentDirectoryURL = URL(fileURLWithPath: cwd)
|
|
Logger.shared.info("invoking: \(lastInvocation)")
|
|
|
|
let outPipe = Pipe(); let errPipe = Pipe()
|
|
p.standardOutput = outPipe
|
|
p.standardError = errPipe
|
|
do { try p.run() } catch {
|
|
let errStr = String(describing: error)
|
|
Logger.shared.error("spawn error: \(errStr)")
|
|
return (-1, "", errStr)
|
|
}
|
|
p.waitUntilExit()
|
|
let out = String(data: outPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
|
let err = String(data: errPipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) ?? ""
|
|
let code = p.terminationStatus
|
|
|
|
// Combine to match UI exactly
|
|
var combined = out
|
|
if !err.isEmpty { combined += (combined.isEmpty ? "" : "\n") + err }
|
|
let trimmedCombined = combined.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
if trimmedCombined.isEmpty {
|
|
Logger.shared.info("exit code: \(code); (no output)")
|
|
} else {
|
|
Logger.shared.info("output (exit=\(code)):\n\(combined)")
|
|
}
|
|
return (code, out, err)
|
|
}
|
|
}
|