diff --git a/Sources/Container-Compose/Commands/ComposeUp.swift b/Sources/Container-Compose/Commands/ComposeUp.swift index 126d637..fe52d00 100644 --- a/Sources/Container-Compose/Commands/ComposeUp.swift +++ b/Sources/Container-Compose/Commands/ComposeUp.swift @@ -664,13 +664,15 @@ public struct ComposeUp: AsyncParsableCommand, @unchecked Sendable { var isDirectory: ObjCBool = false // Ensure the path is absolute or relative to the current directory for FileManager let fullHostPath = (source.starts(with: "/") || source.starts(with: "~")) ? source : (cwd + "/" + source) + // Normalize the path to remove ./ and ../ components, and convert to absolute path + let normalizedHostPath = URL(fileURLWithPath: fullHostPath).standardizedFileURL.path(percentEncoded: false) - if fileManager.fileExists(atPath: fullHostPath, isDirectory: &isDirectory) { + if fileManager.fileExists(atPath: normalizedHostPath, isDirectory: &isDirectory) { if isDirectory.boolValue { // Host path exists and is a directory, add the volume runCommandArgs.append("-v") - // Reconstruct the volume string without mode, ensuring it's source:destination - runCommandArgs.append("\(source):\(destination)") // Use original source for command argument + // Use normalized absolute path for container command (container tool requires absolute paths) + runCommandArgs.append("\(normalizedHostPath):\(destination)") } else { // Host path exists but is a file print("Warning: Volume mount source '\(source)' is a file. The 'container' tool does not support direct file mounts. Skipping this volume.") @@ -678,12 +680,13 @@ public struct ComposeUp: AsyncParsableCommand, @unchecked Sendable { } else { // Host path does not exist, assume it's meant to be a directory and try to create it. do { - try fileManager.createDirectory(atPath: fullHostPath, withIntermediateDirectories: true, attributes: nil) - print("Info: Created missing host directory for volume: \(fullHostPath)") + try fileManager.createDirectory(atPath: normalizedHostPath, withIntermediateDirectories: true, attributes: nil) + print("Info: Created missing host directory for volume: \(normalizedHostPath)") runCommandArgs.append("-v") - runCommandArgs.append("\(source):\(destination)") // Use original source for command argument + // Use normalized absolute path for container command (container tool requires absolute paths) + runCommandArgs.append("\(normalizedHostPath):\(destination)") } catch { - print("Error: Could not create host directory '\(fullHostPath)' for volume '\(resolvedVolume)': \(error.localizedDescription). Skipping this volume.") + print("Error: Could not create host directory '\(normalizedHostPath)' for volume '\(resolvedVolume)': \(error.localizedDescription). Skipping this volume.") } } } else {