48 lines
1.8 KiB
Swift
48 lines
1.8 KiB
Swift
import SwiftUI
|
|
import AppKit
|
|
|
|
@MainActor final class ComposeModel: ObservableObject {
|
|
@Published var projectURL: URL?
|
|
@Published var services: [ComposeService] = []
|
|
@Published var selectedService: String?
|
|
@Published var status = "Ready"
|
|
@Published var busy = false
|
|
@Published var output = "Open a compose.yaml file to begin.\n"
|
|
func openProject() {
|
|
let panel = NSOpenPanel()
|
|
panel.allowedContentTypes = [.yaml, .init(filenameExtension: "yml")!]
|
|
panel.canChooseDirectories = false
|
|
if panel.runModal() == .OK, let url = panel.url { load(url) }
|
|
}
|
|
func load(_ url: URL) {
|
|
do {
|
|
let project = try ComposeProject(file: url)
|
|
projectURL = url; services = project.services
|
|
selectedService = services.first?.id
|
|
output += "Loaded \(url.path) (\(services.count) services)\n"
|
|
} catch { output += "ERROR: \(error)\n" }
|
|
}
|
|
func clearLog() { output = "" }
|
|
func checkRuntime() {
|
|
guard let url = projectURL else { output += "Open a Compose project first.\n"; return }
|
|
run(url: url, action: "doctor")
|
|
}
|
|
func perform(_ action: String) {
|
|
guard let url = projectURL else { return }
|
|
run(url: url, action: action)
|
|
}
|
|
private func run(url: URL, action: String) {
|
|
guard !busy else { return }
|
|
busy = true; status = "Running \(action)…"; output += "\n$ acccompose \(action)\n"
|
|
Task.detached {
|
|
let result: String
|
|
do { result = try ComposeEngine(ComposeProject(file: url)).execute(action) }
|
|
catch { result = "ERROR: \(error)\n" }
|
|
await MainActor.run {
|
|
self.output += result + "\n"
|
|
self.busy = false; self.status = "Ready"
|
|
}
|
|
}
|
|
}
|
|
}
|