Parser: Support relative paths for --volume (#1013)

This commit is contained in:
Danny Canter
2026-01-04 11:11:09 -08:00
committed by GitHub
parent 028e7e109f
commit 20dc0bcfee
2 changed files with 57 additions and 2 deletions
+2 -2
View File
@@ -487,8 +487,8 @@ public struct Parser {
let src = String(parts[0])
let dst = String(parts[1])
// Check if it's an absolute directory path first
guard src.hasPrefix("/") else {
// Check if it's a filesystem path
guard src.contains("/") else {
// Named volume - validate name syntax only
guard VolumeStorage.isValidVolumeName(src) else {
throw ContainerizationError(.invalidArgument, message: "invalid volume name '\(src)': must match \(VolumeStorage.volumeNamePattern)")
@@ -382,6 +382,61 @@ struct ParserTest {
}
}
@Test
func testVolumeRelativePath() throws {
let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-\(UUID().uuidString)")
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
defer {
try? FileManager.default.removeItem(at: tempDir)
}
let originalDir = FileManager.default.currentDirectoryPath
FileManager.default.changeCurrentDirectoryPath(tempDir.path)
defer {
FileManager.default.changeCurrentDirectoryPath(originalDir)
}
let result = try Parser.volume("./:/foo")
switch result {
case .filesystem(let fs):
let expectedPath = URL(filePath: ".").absoluteURL.path
// Normalize trailing slashes for comparison
#expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/")))
#expect(fs.destination == "/foo")
case .volume:
#expect(Bool(false), "Expected filesystem mount, got volume")
}
}
@Test
func testVolumeRelativePathNested() throws {
let tempDir = FileManager.default.temporaryDirectory.appendingPathComponent("test-volume-rel-nested-\(UUID().uuidString)")
let nestedDir = tempDir.appendingPathComponent("subdir")
try FileManager.default.createDirectory(at: nestedDir, withIntermediateDirectories: true)
defer {
try? FileManager.default.removeItem(at: tempDir)
}
let originalDir = FileManager.default.currentDirectoryPath
FileManager.default.changeCurrentDirectoryPath(tempDir.path)
defer {
FileManager.default.changeCurrentDirectoryPath(originalDir)
}
let result = try Parser.volume("./subdir:/foo")
switch result {
case .filesystem(let fs):
let expectedPath = URL(filePath: "./subdir").absoluteURL.path
// Normalize trailing slashes for comparison
#expect(fs.source.trimmingCharacters(in: CharacterSet(charactersIn: "/")) == expectedPath.trimmingCharacters(in: CharacterSet(charactersIn: "/")))
#expect(fs.destination == "/foo")
case .volume:
#expect(Bool(false), "Expected filesystem mount, got volume")
}
}
@Test
func testIsValidDomainNameOk() throws {
let names = [