forked from Carthage/Carthage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Archive.swift
74 lines (63 loc) · 2.98 KB
/
Archive.swift
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
import Foundation
import Result
import ReactiveSwift
import ReactiveTask
/// Zips the given input paths (recursively) into an archive that will be
/// located at the given URL.
public func zip(paths: [String], into archiveURL: URL, workingDirectory: String) -> SignalProducer<(), CarthageError> {
precondition(!paths.isEmpty)
precondition(archiveURL.isFileURL)
let task = Task("/usr/bin/env", arguments: [ "zip", "-q", "-r", "--symlinks", archiveURL.path ] + paths, workingDirectoryPath: workingDirectory)
return task.launch()
.mapError(CarthageError.taskError)
.then(SignalProducer<(), CarthageError>.empty)
}
/// Unarchives the given file URL into a temporary directory, using its
/// extension to detect archive type, then sends the file URL to that directory.
public func unarchive(archive fileURL: URL) -> SignalProducer<URL, CarthageError> {
switch fileURL.pathExtension {
case "gz", "tgz", "bz2", "xz":
return untar(archive: fileURL)
default:
return unzip(archive: fileURL)
}
}
/// Unzips the archive at the given file URL, extracting into the given
/// directory URL (which must already exist).
private func unzip(archive fileURL: URL, to destinationDirectoryURL: URL) -> SignalProducer<(), CarthageError> {
precondition(fileURL.isFileURL)
precondition(destinationDirectoryURL.isFileURL)
let task = Task("/usr/bin/env", arguments: [ "unzip", "-uo", "-qq", "-d", destinationDirectoryURL.path, fileURL.path ])
return task.launch()
.mapError(CarthageError.taskError)
.then(SignalProducer<(), CarthageError>.empty)
}
/// Untars an archive at the given file URL, extracting into the given
/// directory URL (which must already exist).
private func untar(archive fileURL: URL, to destinationDirectoryURL: URL) -> SignalProducer<(), CarthageError> {
precondition(fileURL.isFileURL)
precondition(destinationDirectoryURL.isFileURL)
let task = Task("/usr/bin/env", arguments: [ "tar", "-xf", fileURL.path, "-C", destinationDirectoryURL.path ])
return task.launch()
.mapError(CarthageError.taskError)
.then(SignalProducer<(), CarthageError>.empty)
}
private let archiveTemplate = "carthage-archive.XXXXXX"
/// Unzips the archive at the given file URL into a temporary directory, then
/// sends the file URL to that directory.
private func unzip(archive fileURL: URL) -> SignalProducer<URL, CarthageError> {
return FileManager.default.reactive.createTemporaryDirectoryWithTemplate(archiveTemplate)
.flatMap(.merge) { directoryURL in
return unzip(archive: fileURL, to: directoryURL)
.then(SignalProducer<URL, CarthageError>(value: directoryURL))
}
}
/// Untars an archive at the given file URL into a temporary directory,
/// then sends the file URL to that directory.
private func untar(archive fileURL: URL) -> SignalProducer<URL, CarthageError> {
return FileManager.default.reactive.createTemporaryDirectoryWithTemplate(archiveTemplate)
.flatMap(.merge) { directoryURL in
return untar(archive: fileURL, to: directoryURL)
.then(SignalProducer<URL, CarthageError>(value: directoryURL))
}
}