Skip to content

Commit 27c24b9

Browse files
committed
Use TSC.Process
1 parent c0c4208 commit 27c24b9

File tree

2 files changed

+23
-111
lines changed

2 files changed

+23
-111
lines changed

Sources/Basics/Archiver/ZipArchiver.swift

Lines changed: 22 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Dispatch
14-
import class Foundation.Pipe
15-
import class Foundation.Process
16-
import struct Foundation.URL
1714
import struct TSCBasic.FileSystemError
1815
import class TSCBasic.Process
1916

20-
#if USE_IMPL_ONLY_IMPORTS
21-
@_implementationOnly import TSCclibc
22-
#else
23-
import TSCclibc
24-
#endif
25-
2617
/// An `Archiver` that handles ZIP archives using the command-line `zip` and `unzip` tools.
2718
public struct ZipArchiver: Archiver, Cancellable {
2819
public var supportedExtensions: Set<String> { ["zip"] }
@@ -99,107 +90,40 @@ public struct ZipArchiver: Archiver, Cancellable {
9990
arguments: ["tar.exe", "-a", "-c", "-f", destinationPath.pathString, directory.basename],
10091
workingDirectory: directory.parentDirectory.underlying
10192
)
102-
try self.launchAndWait(process: process, completion: completion)
103-
#elseif os(Linux)
93+
#else
10494
// This is to work around `swift package-registry publish` tool failing on
10595
// Amazon Linux 2 due to it having an earlier Glibc version (rdar://116370323)
10696
// 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",
119103
"-c",
120104
"cd \(directory.parentDirectory.underlying.pathString) && zip -r \(destinationPath.pathString) \(directory.basename)",
121105
]
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
140106
)
141107
#endif
142-
} catch {
143-
return completion(.failure(error))
144-
}
145-
}
146108

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+
}
189112

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))
200125
}
201126
}
202-
#endif
203127

204128
public func validate(path: AbsolutePath, completion: @escaping (Result<Bool, Error>) -> Void) {
205129
do {

Sources/Basics/Cancellator.swift

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift open source project
44
//
5-
// Copyright (c) 2022-2023 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See http://swift.org/LICENSE.txt for license information
@@ -211,18 +211,6 @@ public struct CancellationError: Error, CustomStringConvertible {
211211
"""
212212
)
213213
}
214-
215-
#if !os(iOS) && !os(watchOS) && !os(tvOS)
216-
static func failedToRegisterProcess(_ process: Foundation.Process) -> Self {
217-
Self(
218-
description: """
219-
failed to register a cancellation handler for this process invocation `\(
220-
process.arguments?.joined(separator: " ") ?? ""
221-
)`
222-
"""
223-
)
224-
}
225-
#endif
226214
}
227215

228216
extension TSCBasic.Process {

0 commit comments

Comments
 (0)