@@ -20,6 +20,7 @@ import ContainerResource
2020import Containerization
2121import ContainerizationError
2222import Foundation
23+ import SystemPackage
2324
2425extension Application {
2526 public struct ContainerCopy : AsyncLoggableCommand {
@@ -63,40 +64,42 @@ extension Application {
6364
6465 switch ( srcRef, dstRef) {
6566 case ( . container( let id, let path) , . local( let localPath) ) :
66- let srcURL = URL ( fileURLWithPath : path)
67- let destURL = URL ( fileURLWithPath : localPath) . standardizedFileURL
67+ let srcPath = FilePath ( path)
68+ let destPath = FilePath ( ( localPath as NSString ) . standardizingPath )
6869 var isDirectory : ObjCBool = false
69- let exists = FileManager . default. fileExists ( atPath: destURL . path , isDirectory: & isDirectory)
70+ let exists = FileManager . default. fileExists ( atPath: destPath . string , isDirectory: & isDirectory)
7071
7172 if exists && isDirectory. boolValue {
72- let finalDest = destURL. appendingPathComponent ( srcURL. lastPathComponent)
73- try await client. copyOut ( id: id, source: srcURL, destination: finalDest)
73+ guard let lastComponent = srcPath. lastComponent else {
74+ throw ContainerizationError ( . invalidArgument, message: " source path has no last component: \( path) " )
75+ }
76+ let finalDest = destPath. appending ( lastComponent)
77+ try await client. copyOut ( id: id, source: path, destination: finalDest. string)
7478 } else if localPath. hasSuffix ( " / " ) {
75- try await client. copyOut ( id: id, source: srcURL , destination: destURL )
79+ try await client. copyOut ( id: id, source: path , destination: destPath . string )
7680 var resultIsDir : ObjCBool = false
77- if FileManager . default. fileExists ( atPath: destURL . path , isDirectory: & resultIsDir) ,
81+ if FileManager . default. fileExists ( atPath: destPath . string , isDirectory: & resultIsDir) ,
7882 !resultIsDir. boolValue
7983 {
80- try ? FileManager . default. removeItem ( at : destURL )
84+ try ? FileManager . default. removeItem ( atPath : destPath . string )
8185 throw ContainerizationError (
8286 . invalidArgument,
8387 message: " destination is not a directory: \( localPath) " )
8488 }
8589 } else {
86- try await client. copyOut ( id: id, source: srcURL , destination: destURL )
90+ try await client. copyOut ( id: id, source: path , destination: destPath . string )
8791 }
8892 case ( . local( let localPath) , . container( let id, let path) ) :
89- let srcURL = URL ( fileURLWithPath : localPath) . standardizedFileURL
93+ let srcPath = FilePath ( ( localPath as NSString ) . standardizingPath )
9094 var isDirectory : ObjCBool = false
91- guard FileManager . default. fileExists ( atPath: srcURL . path , isDirectory: & isDirectory) else {
95+ guard FileManager . default. fileExists ( atPath: srcPath . string , isDirectory: & isDirectory) else {
9296 throw ContainerizationError ( . notFound, message: " source path does not exist: \( localPath) " )
9397 }
9498 if localPath. hasSuffix ( " / " ) && !isDirectory. boolValue {
9599 throw ContainerizationError ( . invalidArgument, message: " source path is not a directory: \( localPath) " )
96100 }
97101
98- let destURL = URL ( fileURLWithPath: path)
99- try await client. copyIn ( id: id, source: srcURL, destination: destURL, createParents: true )
102+ try await client. copyIn ( id: id, source: srcPath. string, destination: path, createParents: true )
100103 case ( . container, . container) :
101104 throw ContainerizationError ( . invalidArgument, message: " copying between containers is not supported " )
102105 case ( . local, . local) :
0 commit comments