1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See http://swift.org/LICENSE.txt for license information
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
import TSCBasic
import Dispatch
/// The `Archiver` protocol abstracts away the different operations surrounding archives.
// FIXME: deprecate 2/2022, remove once clients transitioned
@available(*, deprecated, message: "moved to SwiftPM")
public protocol Archiver {
/// A set of extensions the current archiver supports.
var supportedExtensions: Set<String> { get }
/// Asynchronously extracts the contents of an archive to a destination folder.
///
/// - Parameters:
/// - archivePath: The `AbsolutePath` to the archive to extract.
/// - destinationPath: The `AbsolutePath` to the directory to extract to.
/// - completion: The completion handler that will be called when the operation finishes to notify of its success.
func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
)
}
/// An `Archiver` that handles ZIP archives using the command-line `zip` and `unzip` tools.
// FIXME: deprecate 2/2022, remove once clients transitioned
@available(*, deprecated, message: "moved to SwiftPM")
public struct ZipArchiver: Archiver {
public var supportedExtensions: Set<String> { ["zip"] }
/// The file-system implementation used for various file-system operations and checks.
private let fileSystem: FileSystem
/// Creates a `ZipArchiver`.
///
/// - Parameters:
/// - fileSystem: The file-system to used by the `ZipArchiver`.
public init(fileSystem: FileSystem = localFileSystem) {
self.fileSystem = fileSystem
}
public func extract(
from archivePath: AbsolutePath,
to destinationPath: AbsolutePath,
completion: @escaping (Result<Void, Error>) -> Void
) {
guard fileSystem.exists(archivePath) else {
completion(.failure(FileSystemError(.noEntry, archivePath)))
return
}
guard fileSystem.isDirectory(destinationPath) else {
completion(.failure(FileSystemError(.notDirectory, destinationPath)))
return
}
DispatchQueue.global(qos: .userInitiated).async {
do {
let result = try Process.popen(args: "unzip", archivePath.pathString, "-d", destinationPath.pathString)
guard result.exitStatus == .terminated(code: 0) else {
throw try StringError(result.utf8stderrOutput())
}
completion(.success(()))
} catch {
completion(.failure(error))
}
}
}
}
|