From 39bf3473ea5dacf1d21889ffd0e4133ed58cefb4 Mon Sep 17 00:00:00 2001 From: w1zdun <19057733+w1zdun@users.noreply.github.com> Date: Sun, 7 Jun 2026 09:41:50 +0200 Subject: [PATCH] feat(commands): add --project-directory flag for alternate working directory Docker Compose ships --project-directory to override the working directory independently of the process CWD. Needed when running compose from a parent dir with -f pointing to a nested compose file. Resolution priority: --project-directory > process.cwd > currentDirectoryPath. Applies to up, down, and build commands via shared ComposeFileOptions. --- .../Commands/ComposeBuild.swift | 2 +- .../Commands/ComposeDown.swift | 2 +- .../Commands/ComposeFileOptions.swift | 17 ++++++++++++++++- .../Container-Compose/Commands/ComposeUp.swift | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Sources/Container-Compose/Commands/ComposeBuild.swift b/Sources/Container-Compose/Commands/ComposeBuild.swift index 5abde194..f54a9a79 100644 --- a/Sources/Container-Compose/Commands/ComposeBuild.swift +++ b/Sources/Container-Compose/Commands/ComposeBuild.swift @@ -51,7 +51,7 @@ public struct ComposeBuild: AsyncParsableCommand, @unchecked Sendable { @OptionGroup var logging: Flags.Logging - private var cwd: String { process.cwd ?? FileManager.default.currentDirectoryPath } + private var cwd: String { composeFileOptions.effectiveCwd(processCwd: process.cwd) } private var cwdURL: URL { URL(fileURLWithPath: cwd) } diff --git a/Sources/Container-Compose/Commands/ComposeDown.swift b/Sources/Container-Compose/Commands/ComposeDown.swift index 30240c65..9a7c1730 100644 --- a/Sources/Container-Compose/Commands/ComposeDown.swift +++ b/Sources/Container-Compose/Commands/ComposeDown.swift @@ -41,7 +41,7 @@ public struct ComposeDown: AsyncParsableCommand { @OptionGroup var process: Flags.Process - private var cwd: String { process.cwd ?? FileManager.default.currentDirectoryPath } + private var cwd: String { composeFileOptions.effectiveCwd(processCwd: process.cwd) } @OptionGroup var composeFileOptions: ComposeFileOptions diff --git a/Sources/Container-Compose/Commands/ComposeFileOptions.swift b/Sources/Container-Compose/Commands/ComposeFileOptions.swift index e27782af..c69bf5c5 100644 --- a/Sources/Container-Compose/Commands/ComposeFileOptions.swift +++ b/Sources/Container-Compose/Commands/ComposeFileOptions.swift @@ -15,10 +15,25 @@ //===----------------------------------------------------------------------===// import ArgumentParser +import Foundation public struct ComposeFileOptions: ParsableArguments, Sendable { public init() {} - + @Option(name: [.customShort("f"), .customLong("file")], help: "The path to your Docker Compose file") public var composeFilename: String? + + @Option(name: .customLong("project-directory"), help: "Specify an alternate working directory") + public var projectDirectory: String? + + /// Resolves the effective working directory with priority: + /// 1. `projectDirectory` (--project-directory flag) + /// 2. `processCwd` (from Flags.Process) + /// 3. `FileManager.default.currentDirectoryPath` (fallback) + public func effectiveCwd(processCwd: String?) -> String { + if let dir = projectDirectory { + return resolvedPath(for: dir, relativeTo: URL(fileURLWithPath: FileManager.default.currentDirectoryPath, isDirectory: true)) + } + return processCwd ?? FileManager.default.currentDirectoryPath + } } diff --git a/Sources/Container-Compose/Commands/ComposeUp.swift b/Sources/Container-Compose/Commands/ComposeUp.swift index 3a874f08..44ff9e6c 100644 --- a/Sources/Container-Compose/Commands/ComposeUp.swift +++ b/Sources/Container-Compose/Commands/ComposeUp.swift @@ -96,7 +96,7 @@ public struct ComposeUp: AsyncParsableCommand, @unchecked Sendable { @OptionGroup var logging: Flags.Logging - private var cwd: String { process.cwd ?? FileManager.default.currentDirectoryPath } + private var cwd: String { composeFileOptions.effectiveCwd(processCwd: process.cwd) } private var fileManager: FileManager { FileManager.default } private var projectName: String?