|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | import Dispatch
|
14 |
| -import class Foundation.Pipe |
15 |
| -import class Foundation.Process |
16 |
| -import struct Foundation.URL |
17 | 14 | import struct TSCBasic.FileSystemError
|
18 | 15 | import class TSCBasic.Process
|
19 | 16 |
|
20 |
| -#if USE_IMPL_ONLY_IMPORTS |
21 |
| -@_implementationOnly import TSCclibc |
22 |
| -#else |
23 |
| -import TSCclibc |
24 |
| -#endif |
25 |
| - |
26 | 17 | /// An `Archiver` that handles ZIP archives using the command-line `zip` and `unzip` tools.
|
27 | 18 | public struct ZipArchiver: Archiver, Cancellable {
|
28 | 19 | public var supportedExtensions: Set<String> { ["zip"] }
|
@@ -99,107 +90,40 @@ public struct ZipArchiver: Archiver, Cancellable {
|
99 | 90 | arguments: ["tar.exe", "-a", "-c", "-f", destinationPath.pathString, directory.basename],
|
100 | 91 | workingDirectory: directory.parentDirectory.underlying
|
101 | 92 | )
|
102 |
| - try self.launchAndWait(process: process, completion: completion) |
103 |
| - #elseif os(Linux) |
| 93 | + #else |
104 | 94 | // This is to work around `swift package-registry publish` tool failing on
|
105 | 95 | // Amazon Linux 2 due to it having an earlier Glibc version (rdar://116370323)
|
106 | 96 | // and therefore posix_spawn_file_actions_addchdir_np is unavailable.
|
107 |
| - // Instead of TSC.Process, we shell out to Foundation.Process and do `cd` |
108 |
| - // explicitly before `zip`. |
109 |
| - if SPM_posix_spawn_file_actions_addchdir_np_supported() { |
110 |
| - try self.compress_zip( |
111 |
| - directory: directory, |
112 |
| - destinationPath: destinationPath, |
113 |
| - completion: completion |
114 |
| - ) |
115 |
| - } else { |
116 |
| - let process = Foundation.Process() |
117 |
| - process.executableURL = URL(fileURLWithPath: "/bin/sh") |
118 |
| - process.arguments = [ |
| 97 | + // Instead of passing `workingDirectory` param to TSC.Process, which will trigger |
| 98 | + // SPM_posix_spawn_file_actions_addchdir_np_supported check, we shell out and |
| 99 | + // do `cd` explicitly before `zip`. |
| 100 | + let process = TSCBasic.Process( |
| 101 | + arguments: [ |
| 102 | + "/bin/sh", |
119 | 103 | "-c",
|
120 | 104 | "cd \(directory.parentDirectory.underlying.pathString) && zip -r \(destinationPath.pathString) \(directory.basename)",
|
121 | 105 | ]
|
122 |
| - |
123 |
| - let stdoutPipe = Pipe() |
124 |
| - let stderrPipe = Pipe() |
125 |
| - process.standardOutput = stdoutPipe |
126 |
| - process.standardError = stderrPipe |
127 |
| - |
128 |
| - try self.launchAndWait( |
129 |
| - process: process, |
130 |
| - stdoutPipe: stdoutPipe, |
131 |
| - stderrPipe: stderrPipe, |
132 |
| - completion: completion |
133 |
| - ) |
134 |
| - } |
135 |
| - #else |
136 |
| - try self.compress_zip( |
137 |
| - directory: directory, |
138 |
| - destinationPath: destinationPath, |
139 |
| - completion: completion |
140 | 106 | )
|
141 | 107 | #endif
|
142 |
| - } catch { |
143 |
| - return completion(.failure(error)) |
144 |
| - } |
145 |
| - } |
146 | 108 |
|
147 |
| - private func compress_zip( |
148 |
| - directory: AbsolutePath, |
149 |
| - destinationPath: AbsolutePath, |
150 |
| - completion: @escaping (Result<Void, Error>) -> Void |
151 |
| - ) throws { |
152 |
| - let process = TSCBasic.Process( |
153 |
| - arguments: ["zip", "-r", destinationPath.pathString, directory.basename], |
154 |
| - workingDirectory: directory.parentDirectory.underlying |
155 |
| - ) |
156 |
| - try self.launchAndWait(process: process, completion: completion) |
157 |
| - } |
158 |
| - |
159 |
| - private func launchAndWait( |
160 |
| - process: TSCBasic.Process, |
161 |
| - completion: @escaping (Result<Void, Error>) -> Void |
162 |
| - ) throws { |
163 |
| - guard let registrationKey = self.cancellator.register(process) else { |
164 |
| - throw CancellationError.failedToRegisterProcess(process) |
165 |
| - } |
166 |
| - |
167 |
| - DispatchQueue.sharedConcurrent.async { |
168 |
| - defer { self.cancellator.deregister(registrationKey) } |
169 |
| - completion(.init(catching: { |
170 |
| - try process.launch() |
171 |
| - let processResult = try process.waitUntilExit() |
172 |
| - guard processResult.exitStatus == .terminated(code: 0) else { |
173 |
| - throw try StringError(processResult.utf8stderrOutput()) |
174 |
| - } |
175 |
| - })) |
176 |
| - } |
177 |
| - } |
178 |
| - |
179 |
| - #if os(Linux) |
180 |
| - private func launchAndWait( |
181 |
| - process: Foundation.Process, |
182 |
| - stdoutPipe: Pipe, |
183 |
| - stderrPipe: Pipe, |
184 |
| - completion: @escaping (Result<Void, Error>) -> Void |
185 |
| - ) throws { |
186 |
| - guard let registrationKey = self.cancellator.register(process) else { |
187 |
| - throw CancellationError.failedToRegisterProcess(process) |
188 |
| - } |
| 109 | + guard let registrationKey = self.cancellator.register(process) else { |
| 110 | + throw CancellationError.failedToRegisterProcess(process) |
| 111 | + } |
189 | 112 |
|
190 |
| - DispatchQueue.sharedConcurrent.async { |
191 |
| - defer { self.cancellator.deregister(registrationKey) } |
192 |
| - completion(.init(catching: { |
193 |
| - try process.run() |
194 |
| - process.waitUntilExit() |
195 |
| - guard process.terminationStatus == 0 else { |
196 |
| - let stderr = stderrPipe.fileHandleForReading.readDataToEndOfFile() |
197 |
| - throw StringError(String(decoding: stderr, as: UTF8.self)) |
198 |
| - } |
199 |
| - })) |
| 113 | + DispatchQueue.sharedConcurrent.async { |
| 114 | + defer { self.cancellator.deregister(registrationKey) } |
| 115 | + completion(.init(catching: { |
| 116 | + try process.launch() |
| 117 | + let processResult = try process.waitUntilExit() |
| 118 | + guard processResult.exitStatus == .terminated(code: 0) else { |
| 119 | + throw try StringError(processResult.utf8stderrOutput()) |
| 120 | + } |
| 121 | + })) |
| 122 | + } |
| 123 | + } catch { |
| 124 | + return completion(.failure(error)) |
200 | 125 | }
|
201 | 126 | }
|
202 |
| - #endif |
203 | 127 |
|
204 | 128 | public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
|
205 | 129 | do {
|
|
0 commit comments