new features

This commit is contained in:
Mark Gregory
2026-11-09 08:20:57 +00:00
parent ecfa74a35f
commit 965ae923c2
27 changed files with 1474 additions and 168 deletions
+27 -7
View File
@@ -2,17 +2,23 @@ import Foundation
@main
struct AppleComposeCLI {
static func main() {
do { try execute() }
catch { fputs("accompose: \(error)\n", stderr); exit(1) }
static func main() async {
do {
let args = Array(CommandLine.arguments.dropFirst())
if args.first == "monitor" { try await MonitorCLI.run(Array(args.dropFirst())); return }
try execute()
}
catch { fputs("container-compose: \(error)\n", stderr); exit(1) }
}
static func execute() throws {
var arguments = Array(CommandLine.arguments.dropFirst())
let help = """
accompose — Apple Container Compose CLI
Usage: accompose [-f FILE] [-p PROJECT] COMMAND [OPTIONS]
container-compose — Container Compose CLI
Usage: container-compose [-f FILE] [-p PROJECT] COMMAND [OPTIONS]
Commands:
monitor [COMMAND] acdry resource manager; monitor --help for commands
monitor watch Live CPU, memory and network terminal dashboard
init Create a starter compose.yaml
doctor Check Apple Container runtime
config Validate Compose file and display configuration
@@ -36,6 +42,7 @@ struct AppleComposeCLI {
-f, --file FILE Compose file path
-p, --project-name N Override project name
-v, -vv, -vvv Increase diagnostics (independent of detach)
--version Display CLI version
-h, --help Display help
Supported: basic images, Dockerfile builds, ports, directory binds,
@@ -43,6 +50,7 @@ struct AppleComposeCLI {
Other service keys are rejected instead of silently ignored.
This is NOT a complete Docker Compose implementation.
"""
if arguments == ["--version"] { print("container-compose 0.2.0 (Compose + acdry native monitor)"); return }
if arguments.contains("--help") || arguments.contains("-h") || arguments.isEmpty {
print(help)
return
@@ -66,7 +74,7 @@ struct AppleComposeCLI {
}
guard let command = arguments.first else { throw ComposeError.message("Missing command") }
if command == "doctor" && file == nil && (try? ComposeProject.discover()) == nil {
print("Apple Container Compose diagnostics")
print("Container Compose diagnostics")
guard let binary = Shell.executable("container") else { throw ComposeError.message("Apple container CLI not found. Install from https://github.com/apple/container/releases") }
print("CLI: \(binary)")
print(try Shell.checked("container", ["--version"]))
@@ -76,7 +84,7 @@ struct AppleComposeCLI {
return
}
if command == "import" {
guard arguments.count >= 2 else { throw ComposeError.message("Usage: accompose import PATH") }
guard arguments.count >= 2 else { throw ComposeError.message("Usage: container-compose import PATH") }
let url = URL(fileURLWithPath: arguments[1]).standardizedFileURL
var isDir: ObjCBool = false
guard FileManager.default.fileExists(atPath: url.path, isDirectory: &isDir) else { throw ComposeError.message("Path not found: \(url.path)") }
@@ -97,6 +105,18 @@ struct AppleComposeCLI {
print("Created \(target.path)"); return
}
let commandArgs = Array(arguments.dropFirst())
let allowed: [String: Set<String>] = [
"up": ["-d", "--detach", "--build"], "down": ["--volumes"],
"clean": ["--all", "--project", "--dry-run"], "prune": ["--images", "--dry-run"],
"config": [], "ps": [], "pull": [], "build": [], "logs": [],
"start": [], "stop": [], "restart": [], "doctor": []
]
if let options = allowed[command], let unknown = commandArgs.first(where: { $0.hasPrefix("-") && !options.contains($0) }) {
throw ComposeError.message("Unsupported \(command) option: \(unknown)")
}
if ["config", "ps", "pull", "build", "down", "doctor", "prune"].contains(command), commandArgs.contains(where: { !$0.hasPrefix("-") }) {
throw ComposeError.message("Unexpected argument for \(command)")
}
if command == "up" {
let supported: Set<String> = ["-d", "--detach", "--build"]
if let unknown = commandArgs.first(where: { !supported.contains($0) }) {