From 28cd619365252723741460269d4ca34fabb37d7c Mon Sep 17 00:00:00 2001 From: Chris George Date: Sat, 2 May 2026 14:07:51 -0700 Subject: [PATCH] feat(flags): add Flags.ProcessBase short-flag-free subset of Flags.Process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a new public 'Flags.ProcessBase' struct alongside the existing 'Flags.Process'. ProcessBase is a minimal subset that does NOT claim the common short flags (-e, -u, -w, -i, -t), so downstream tools that wrap 'container' can @OptionGroup ProcessBase without colliding on those names. Motivation ---------- Tools like 'compose run' and 'compose exec' need to expose their own '-e KEY=VALUE' / '-u USER' / '-w DIR' UX (the docker-compose convention) but currently can't @OptionGroup Flags.Process because swift-argument-parser hits a parse-time clash on the short flags. The compose tooling's workaround is to declare verbose '--run-env', '--run-user', '--run-workdir' aliases that nobody types willingly. Adding ProcessBase upstream lets those wrappers inherit the safe long-form options (--cwd, --env-file) while reclaiming the short flags for their own subcommand-specific UX. What this PR changes -------------------- - Sources/Services/ContainerAPIService/Client/Flags.swift: a new public struct 'Flags.ProcessBase' with two fields ('cwd: String?', 'envFile: [String]'), declared with the same long-form @Option attributes as the matching fields on 'Flags.Process'. No short flags. Existing 'Flags.Process' is unchanged. Total: 1 file, +37/-0. Wire compatibility ------------------ Pure additive — 'Flags.Process' is unchanged. Existing callers see no diff; new callers can opt into ProcessBase explicitly. Verification ------------ Full 'swift build' clean on macOS 26 / Apple silicon (release config, all targets). --- .../ContainerAPIService/Client/Flags.swift | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/Sources/Services/ContainerAPIService/Client/Flags.swift b/Sources/Services/ContainerAPIService/Client/Flags.swift index f8361ef68..8f7d5edd2 100644 --- a/Sources/Services/ContainerAPIService/Client/Flags.swift +++ b/Sources/Services/ContainerAPIService/Client/Flags.swift @@ -30,6 +30,43 @@ public struct Flags { public var debug = false } + /// Minimal subset of process-related options that intentionally does NOT + /// claim the common short flags (`-e`, `-u`, `-w`, `-i`, `-t`). + /// + /// Downstream tools that wrap `container` (e.g. `compose run` / + /// `compose exec`) collide with `Flags.Process` because that struct + /// registers the short flags itself. Embedding ``ProcessBase`` instead + /// of ``Process`` lets the wrapping tool reclaim those short names for + /// its own subcommand-specific options while still inheriting the safe + /// long-form options (`--cwd`, `--env-file`). + /// + /// Long-form behavior is identical to the matching fields in + /// ``Process`` so a caller can switch between them without touching the + /// rest of its `@OptionGroup` wiring. + public struct ProcessBase: ParsableArguments { + public init() {} + + public init(cwd: String?, envFile: [String]) { + self.cwd = cwd + self.envFile = envFile + } + + @Option( + name: .long, + help: .init( + "Set the initial working directory inside the container", + valueName: "dir" + ) + ) + public var cwd: String? + + @Option( + name: .long, + help: "Read in a file of environment variables (key=value format, ignores # comments and blank lines)" + ) + public var envFile: [String] = [] + } + public struct Process: ParsableArguments { public init() {}