Skip to content

Commit f067fd4

Browse files
committed
Archive directory root as well
1 parent fb1e84b commit f067fd4

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

Sources/ContainerizationArchive/ArchiveWriter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ extension ArchiveWriter {
325325
throw POSIXError(.ENOTDIR)
326326
}
327327

328+
try archive(relativePath, dirPath: base)
328329
for case let child as String in enumerator {
329330
let childPath = relativePath.appending(child)
330331

Tests/ContainerizationArchiveTests/ArchiveTests.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,37 @@ struct ArchiveTests {
714714
#expect(try String(contentsOf: extractDir.appendingPathComponent("subdir/nested/deep.txt"), encoding: .utf8) == "deep content")
715715
}
716716

717+
@Test func archiveURLsDirectoryPreservesPermissions() throws {
718+
let testDir = createTemporaryDirectory(baseName: "ArchiveTests.archiveURLsDirPerms")!
719+
defer { try? FileManager.default.removeItem(at: testDir) }
720+
721+
let sourceDir = testDir.appendingPathComponent("source")
722+
let readonlyDir = sourceDir.appendingPathComponent("readonly")
723+
try FileManager.default.createDirectory(at: readonlyDir, withIntermediateDirectories: true)
724+
try "content".write(to: readonlyDir.appendingPathComponent("file.txt"), atomically: true, encoding: .utf8)
725+
try FileManager.default.setAttributes([.posixPermissions: 0o777], ofItemAtPath: readonlyDir.path)
726+
defer {
727+
try? FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: readonlyDir.path)
728+
}
729+
730+
let archiveURL = testDir.appendingPathComponent("test.tar.gz")
731+
let writer = try ArchiveWriter(format: .pax, filter: .gzip, file: archiveURL)
732+
try writer.archive([FilePath(readonlyDir.path)], base: FilePath(sourceDir.path))
733+
try writer.finishEncoding()
734+
735+
let extractDir = testDir.appendingPathComponent("extract")
736+
let reader = try ArchiveReader(file: archiveURL)
737+
let rejected = try reader.extractContents(to: extractDir)
738+
739+
#expect(rejected.isEmpty)
740+
#expect(
741+
try String(contentsOf: extractDir.appendingPathComponent("readonly/file.txt"), encoding: .utf8)
742+
== "content")
743+
let attrs = try FileManager.default.attributesOfItem(atPath: extractDir.appendingPathComponent("readonly").path)
744+
let perms = (attrs[.posixPermissions] as? NSNumber)?.uint16Value ?? 0
745+
#expect((perms & 0o777) == 0o777, "Read-only directory permissions should be preserved")
746+
}
747+
717748
@Test func archiveURLsSymlinks() throws {
718749
let testDir = createTemporaryDirectory(baseName: "ArchiveTests.archiveURLsSymlinks")!
719750
defer { try? FileManager.default.removeItem(at: testDir) }

0 commit comments

Comments
 (0)