1717//
1818
1919import Foundation
20+ import SystemPackage
2021import Testing
2122
2223@testable import ContainerizationArchive
@@ -559,7 +560,7 @@ struct ArchiveTests {
559560 #expect( try String ( contentsOf: extractDir. appendingPathComponent ( " only.txt " ) , encoding: . utf8) == " only file " )
560561 }
561562
562- // MARK: - archiveURLs tests
563+ // MARK: - archive tests
563564
564565 @Test func archiveURLsBasic( ) throws {
565566 let testDir = createTemporaryDirectory ( baseName: " ArchiveTests.archiveURLsBasic " ) !
@@ -568,13 +569,13 @@ struct ArchiveTests {
568569 try " alpha content " . write ( to: testDir. appendingPathComponent ( " alpha.txt " ) , atomically: true , encoding: . utf8)
569570 try " beta content " . write ( to: testDir. appendingPathComponent ( " beta.txt " ) , atomically: true , encoding: . utf8)
570571
571- let files = [
572- testDir. appendingPathComponent ( " alpha.txt " ) ,
573- testDir. appendingPathComponent ( " beta.txt " ) ,
572+ let files : [ FilePath ] = [
573+ FilePath ( testDir. appendingPathComponent ( " alpha.txt " ) . path ) ,
574+ FilePath ( testDir. appendingPathComponent ( " beta.txt " ) . path ) ,
574575 ]
575576 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
576577 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
577- try writer. archiveURLs ( files, base: testDir)
578+ try writer. archive ( files, base: FilePath ( testDir. path ) )
578579 try writer. finishEncoding ( )
579580
580581 var entries : [ String : String ] = [ : ]
@@ -595,7 +596,7 @@ struct ArchiveTests {
595596 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
596597 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
597598 #expect( throws: Never . self) {
598- try writer. archiveURLs ( [ ] , base: testDir)
599+ try writer. archive ( [ ] , base: FilePath ( testDir. path ) )
599600 }
600601 try writer. finishEncoding ( )
601602
@@ -613,7 +614,7 @@ struct ArchiveTests {
613614
614615 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
615616 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
616- try writer. archiveURLs ( [ testDir. appendingPathComponent ( " only.txt " ) ] , base: testDir)
617+ try writer. archive ( [ FilePath ( testDir. appendingPathComponent ( " only.txt " ) . path ) ] , base: FilePath ( testDir. path ) )
617618 try writer. finishEncoding ( )
618619
619620 var entries : [ String : String ] = [ : ]
@@ -637,7 +638,7 @@ struct ArchiveTests {
637638
638639 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
639640 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
640- try writer. archiveURLs ( [ execFile] , base: testDir)
641+ try writer. archive ( [ FilePath ( execFile. path ) ] , base: FilePath ( testDir. path ) )
641642 try writer. finishEncoding ( )
642643
643644 let extractDir = testDir. appendingPathComponent ( " extract " )
@@ -661,14 +662,14 @@ struct ArchiveTests {
661662 try " a content " . write ( to: sourceDir. appendingPathComponent ( " a/deep.txt " ) , atomically: true , encoding: . utf8)
662663 try " nested content " . write ( to: sourceDir. appendingPathComponent ( " b/c/nested.txt " ) , atomically: true , encoding: . utf8)
663664
664- let files = [
665- sourceDir. appendingPathComponent ( " top.txt " ) ,
666- sourceDir. appendingPathComponent ( " a/deep.txt " ) ,
667- sourceDir. appendingPathComponent ( " b/c/nested.txt " ) ,
665+ let files : [ FilePath ] = [
666+ FilePath ( sourceDir. appendingPathComponent ( " top.txt " ) . path ) ,
667+ FilePath ( sourceDir. appendingPathComponent ( " a/deep.txt " ) . path ) ,
668+ FilePath ( sourceDir. appendingPathComponent ( " b/c/nested.txt " ) . path ) ,
668669 ]
669670 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
670671 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
671- try writer. archiveURLs ( files, base: sourceDir)
672+ try writer. archive ( files, base: FilePath ( sourceDir. path ) )
672673 try writer. finishEncoding ( )
673674
674675 let extractDir = testDir. appendingPathComponent ( " extract " )
@@ -694,13 +695,13 @@ struct ArchiveTests {
694695 try " sub content " . write ( to: subDir. appendingPathComponent ( " sub.txt " ) , atomically: true , encoding: . utf8)
695696 try " deep content " . write ( to: subDir. appendingPathComponent ( " nested/deep.txt " ) , atomically: true , encoding: . utf8)
696697
697- let urls = [
698- sourceDir. appendingPathComponent ( " top.txt " ) ,
699- subDir,
698+ let urls : [ FilePath ] = [
699+ FilePath ( sourceDir. appendingPathComponent ( " top.txt " ) . path ) ,
700+ FilePath ( subDir. path ) ,
700701 ]
701702 let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
702703 let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
703- try writer. archiveURLs ( urls, base: sourceDir)
704+ try writer. archive ( urls, base: FilePath ( sourceDir. path ) )
704705 try writer. finishEncoding ( )
705706
706707 let extractDir = testDir. appendingPathComponent ( " extract " )
@@ -713,6 +714,55 @@ struct ArchiveTests {
713714 #expect( try String ( contentsOf: extractDir. appendingPathComponent ( " subdir/nested/deep.txt " ) , encoding: . utf8) == " deep content " )
714715 }
715716
717+ @Test func archiveURLsSymlinks( ) throws {
718+ let testDir = createTemporaryDirectory ( baseName: " ArchiveTests.archiveURLsSymlinks " ) !
719+ defer { try ? FileManager . default. removeItem ( at: testDir) }
720+
721+ let sourceDir = testDir. appendingPathComponent ( " source " )
722+ try FileManager . default. createDirectory ( at: sourceDir, withIntermediateDirectories: true )
723+
724+ let fileURL = sourceDir. appendingPathComponent ( " file.txt " )
725+ try " symlink content " . write ( to: fileURL, atomically: true , encoding: . utf8)
726+
727+ try FileManager . default. createSymbolicLink (
728+ atPath: sourceDir. appendingPathComponent ( " absolute " ) . path,
729+ withDestinationPath: fileURL. path
730+ )
731+ try FileManager . default. createSymbolicLink (
732+ atPath: sourceDir. appendingPathComponent ( " relative " ) . path,
733+ withDestinationPath: " file.txt "
734+ )
735+
736+ let archiveURL = testDir. appendingPathComponent ( " test.tar.gz " )
737+ let writer = try ArchiveWriter ( format: . pax, filter: . gzip, file: archiveURL)
738+ try writer. archive ( [ FilePath ( sourceDir. path) ] , base: FilePath ( testDir. path) )
739+ try writer. finishEncoding ( )
740+
741+ let extractDir = testDir. appendingPathComponent ( " extract " )
742+ let reader = try ArchiveReader ( file: archiveURL)
743+ let rejected = try reader. extractContents ( to: extractDir)
744+
745+ #expect( rejected. isEmpty)
746+
747+ let extractedSource = extractDir. appendingPathComponent ( " source " )
748+ #expect(
749+ try String ( contentsOf: extractedSource. appendingPathComponent ( " file.txt " ) , encoding: . utf8)
750+ == " symlink content " )
751+
752+ let relTarget = try FileManager . default. destinationOfSymbolicLink (
753+ atPath: extractedSource. appendingPathComponent ( " relative " ) . path)
754+ #expect( relTarget == " file.txt " )
755+ #expect(
756+ try String ( contentsOf: extractedSource. appendingPathComponent ( " relative " ) , encoding: . utf8)
757+ == " symlink content " )
758+
759+ let absTarget = try FileManager . default. destinationOfSymbolicLink (
760+ atPath: extractedSource. appendingPathComponent ( " absolute " ) . path)
761+
762+ print ( " absTarget: \( absTarget) , fileURL: \( fileURL. path) " )
763+ #expect( absTarget == fileURL. path)
764+ }
765+
716766 @Test func archiveDirectorySymlinkRelativeSubdir( ) throws {
717767 let testDir = createTemporaryDirectory ( baseName: " ArchiveTests.archiveDirSymlinkRelSubdir " ) !
718768 defer { try ? FileManager . default. removeItem ( at: testDir) }
0 commit comments