Skip to content

Merge main into 6.2 #510

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions Sources/TSCBasic/Await.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@
/// should be passed to the async method's completion handler.
/// - Returns: The value wrapped by the async method's result.
/// - Throws: The error wrapped by the async method's result
//#if compiler(>=5.8)
//@available(*, noasync)
//#endif
@available(*, noasync)
public func tsc_await<T, ErrorType>(_ body: (@escaping (Result<T, ErrorType>) -> Void) -> Void) throws -> T {
return try tsc_await(body).get()
}

//#if compiler(>=5.8)
//@available(*, noasync)
//#endif
@available(*, noasync)
public func tsc_await<T>(_ body: (@escaping (T) -> Void) -> Void) -> T {
let condition = Condition()
var result: T? = nil
Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCBasic/Closable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

/// Closable entity is one that manages underlying resources and needs to be closed for cleanup
/// The intent of this method is for the sole owner of the refernece/handle of the resource to close it completely, comapred to releasing a shared resource.
/// The intent of this method is for the sole owner of the reference/handle of the resource to close it completely, compared to releasing a shared resource.
public protocol Closable {
func close() throws
}
2 changes: 1 addition & 1 deletion Sources/TSCBasic/CollectionExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension Collection {
extension Collection where Element: Hashable {
/// Returns a new list of element removing duplicate elements.
///
/// Note: The order of elements is preseved.
/// Note: The order of elements is preserved.
/// Complexity: O(n)
public func spm_uniqueElements() -> [Element] {
var set = Set<Element>()
Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCBasic/DeltaAlgorithm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public struct DeltaAlgorithm<Change: Hashable>: Sendable {
return result
}

/// Minimizes a set of `changes` which has been partioned into smaller sets,
/// Minimizes a set of `changes` which has been partitioned into smaller sets,
/// by attempting to remove individual subsets.
func delta(
changes: Set<Change>,
Expand Down
4 changes: 2 additions & 2 deletions Sources/TSCBasic/HashAlgorithms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct InternalSHA256: HashAlgorithm {
private static let blockBitSize = 512

/// The initial hash value.
private static let initalHashValue: [UInt32] = [
private static let initialHashValue: [UInt32] = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
]

Expand Down Expand Up @@ -89,7 +89,7 @@ struct InternalSHA256: HashAlgorithm {
let messageBlocks = input.blocks(size: Self.blockBitSize / 8)

/// The hash that is being computed.
var hash = Self.initalHashValue
var hash = Self.initialHashValue

// Process each block.
for block in messageBlocks {
Expand Down
43 changes: 14 additions & 29 deletions Sources/TSCBasic/Process/Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ public final class Process {

/// The result of the process execution. Available after process is terminated.
/// This will block while the process is awaiting result
@available(*, noasync)
@available(*, deprecated, message: "use waitUntilExit instead")
public var result: ProcessResult? {
return self.stateLock.withLock {
Expand Down Expand Up @@ -679,24 +680,11 @@ public final class Process {
defer { posix_spawn_file_actions_destroy(&fileActions) }

if let workingDirectory = workingDirectory?.pathString {
#if canImport(Darwin)
// The only way to set a workingDirectory is using an availability-gated initializer, so we don't need
// to handle the case where the posix_spawn_file_actions_addchdir_np method is unavailable. This check only
// exists here to make the compiler happy.
if #available(macOS 10.15, *) {
posix_spawn_file_actions_addchdir_np(&fileActions, workingDirectory)
}
#elseif os(FreeBSD)
posix_spawn_file_actions_addchdir_np(&fileActions, workingDirectory)
#elseif os(Linux)
guard SPM_posix_spawn_file_actions_addchdir_np_supported() else {
throw Process.Error.workingDirectoryNotSupported
}

SPM_posix_spawn_file_actions_addchdir_np(&fileActions, workingDirectory)
#else
throw Process.Error.workingDirectoryNotSupported
#endif
}

var stdinPipe: [Int32] = [-1, -1]
Expand Down Expand Up @@ -856,7 +844,9 @@ public final class Process {
public func waitUntilExit() async throws -> ProcessResult {
try await withCheckedThrowingContinuation { continuation in
DispatchQueue.processConcurrent.async {
self.waitUntilExit(continuation.resume(with:))
self.waitUntilExit {
continuation.resume(with: $0)
}
}
}
}
Expand Down Expand Up @@ -1127,9 +1117,7 @@ extension Process {
/// - loggingHandler: Handler for logging messages
/// - queue: Queue to use for callbacks
/// - completion: A completion handler to return the process result
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
static public func popen(
arguments: [String],
environmentBlock: ProcessEnvironmentBlock = ProcessEnv.block,
Expand Down Expand Up @@ -1157,6 +1145,7 @@ extension Process {
}

@_disfavoredOverload
@available(*, noasync)
@available(*, deprecated, renamed: "popen(arguments:environmentBlock:loggingHandler:queue:completion:)")
static public func popen(
arguments: [String],
Expand All @@ -1182,9 +1171,7 @@ extension Process {
/// will be inherited.
/// - loggingHandler: Handler for logging messages
/// - Returns: The process result.
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
@discardableResult
static public func popen(
arguments: [String],
Expand All @@ -1202,6 +1189,7 @@ extension Process {
}

@_disfavoredOverload
@available(*, noasync)
@available(*, deprecated, renamed: "popen(arguments:environmentBlock:loggingHandler:)")
@discardableResult
static public func popen(
Expand All @@ -1220,9 +1208,7 @@ extension Process {
/// will be inherited.
/// - loggingHandler: Handler for logging messages
/// - Returns: The process result.
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
@discardableResult
static public func popen(
args: String...,
Expand All @@ -1233,6 +1219,7 @@ extension Process {
}

@_disfavoredOverload
@available(*, noasync)
@available(*, deprecated, renamed: "popen(args:environmentBlock:loggingHandler:)")
@discardableResult
static public func popen(
Expand All @@ -1251,9 +1238,7 @@ extension Process {
/// will be inherited.
/// - loggingHandler: Handler for logging messages
/// - Returns: The process output (stdout + stderr).
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
@discardableResult
static public func checkNonZeroExit(
arguments: [String],
Expand All @@ -1276,6 +1261,7 @@ extension Process {
}

@_disfavoredOverload
@available(*, noasync)
@available(*, deprecated, renamed: "checkNonZeroExit(arguments:environmentBlock:loggingHandler:)")
@discardableResult
static public func checkNonZeroExit(
Expand All @@ -1294,9 +1280,7 @@ extension Process {
/// will be inherited.
/// - loggingHandler: Handler for logging messages
/// - Returns: The process output (stdout + stderr).
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
@discardableResult
static public func checkNonZeroExit(
args: String...,
Expand All @@ -1307,6 +1291,7 @@ extension Process {
}

@_disfavoredOverload
@available(*, noasync)
@available(*, deprecated, renamed: "checkNonZeroExit(args:environmentBlock:loggingHandler:)")
@discardableResult
static public func checkNonZeroExit(
Expand Down
4 changes: 1 addition & 3 deletions Sources/TSCBasic/Process/ProcessSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ public final class ProcessSet {
/// Terminate all the processes. This method blocks until all processes in the set are terminated.
///
/// A process set cannot be used once it has been asked to terminate.
// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
public func terminate() {
// Mark a process set as cancelled.
serialQueue.sync {
Expand Down
1 change: 1 addition & 0 deletions Sources/TSCBasic/RegEx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Foundation

/// A helpful wrapper around NSRegularExpression.
/// - SeeAlso: NSRegularExpression
@available(*, deprecated, message: "Use Swift `Regex` type instead")
public struct RegEx {
private let regex: NSRegularExpression
public typealias Options = NSRegularExpression.Options
Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCBasic/SortedArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public struct SortedArray<Element>: CustomStringConvertible {

var lhs = elements[lhsIndex], rhs = newElements[rhsIndex]

// Equivalent to a merge sort, "pop" and append the max elemeent of
// Equivalent to a merge sort, "pop" and append the max element of
// each array until either array is empty.
for index in elements.indices.reversed() {
if areInIncreasingOrder(lhs, rhs) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCBasic/TemporaryFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public func determineTempDirectory(_ dir: AbsolutePath? = nil) throws -> Absolut
return tmpDir
}

/// The closure argument of the `body` closue of `withTemporaryFile`.
/// The closure argument of the `body` closure of `withTemporaryFile`.
public struct TemporaryFile {
/// If specified during init, the temporary file name begins with this prefix.
let prefix: String
Expand Down
4 changes: 4 additions & 0 deletions Sources/TSCTestSupport/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ public func testWithTemporaryDirectory(
}
}

@available(*, noasync)
@available(*, deprecated, message: "Use Process.checkNonZeroExit(arguments:) instead.")
public func systemQuietly(_ args: [String]) throws {
// Discard the output, by default.
//
// FIXME: Find a better default behavior here.
try Process.checkNonZeroExit(arguments: args)
}

@available(*, noasync)
@available(*, deprecated, message: "Use Process.checkNonZeroExit(_:) instead.")
public func systemQuietly(_ args: String...) throws {
try systemQuietly(args)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCclibc/include/process.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if defined(__linux__)
#if !defined(_WIN32)

#include <spawn.h>
#include <stdbool.h>
Expand Down
46 changes: 33 additions & 13 deletions Sources/TSCclibc/process.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,54 @@
#if defined(__linux__)
#if !defined(_WIN32)

#if defined(__linux__)
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* for posix_spawn_file_actions_addchdir_np */
#endif
#endif

#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(maj, min) 0
#endif

#include <errno.h>

#include "process.h"

int SPM_posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t *restrict file_actions, const char *restrict path) {
#if defined(__GLIBC__)
# if __GLIBC_PREREQ(2, 29)
return posix_spawn_file_actions_addchdir_np(file_actions, path);
# else
#if defined(__GLIBC__) && !__GLIBC_PREREQ(2, 29)
// Glibc versions prior to 2.29 don't support posix_spawn_file_actions_addchdir_np, impacting:
// - Amazon Linux 2 (EoL mid-2025)
return ENOSYS;
# endif
#else
#elif defined(__ANDROID__) && __ANDROID_API__ < 34
// Android versions prior to 14 (API level 34) don't support posix_spawn_file_actions_addchdir_np
return ENOSYS;
#elif defined(__OpenBSD__) || defined(__QNX__)
// Currently missing as of:
// - OpenBSD 7.5 (April 2024)
// - QNX 8 (December 2023)
return ENOSYS;
#elif defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(__musl__)
// Pre-standard posix_spawn_file_actions_addchdir_np version available in:
// - Solaris 11.3 (October 2015)
// - Glibc 2.29 (February 2019)
// - macOS 10.15 (October 2019)
// - musl 1.1.24 (October 2019)
// - FreeBSD 13.1 (May 2022)
// - Android 14 (October 2023)
return posix_spawn_file_actions_addchdir_np((posix_spawn_file_actions_t *)file_actions, path);
#else
// Standardized posix_spawn_file_actions_addchdir version (POSIX.1-2024, June 2024) available in:
// - Solaris 11.4 (August 2018)
// - NetBSD 10.0 (March 2024)
return posix_spawn_file_actions_addchdir((posix_spawn_file_actions_t *)file_actions, path);
#endif
}

bool SPM_posix_spawn_file_actions_addchdir_np_supported() {
#if defined(__GLIBC__)
# if __GLIBC_PREREQ(2, 29)
return true;
# else
#if (defined(__GLIBC__) && !__GLIBC_PREREQ(2, 29)) || (defined(__OpenBSD__)) || (defined(__ANDROID__) && __ANDROID_API__ < 34) || (defined(__QNX__))
return false;
# endif
#else
return false;
return true;
#endif
}

Expand Down
15 changes: 3 additions & 12 deletions Tests/TSCBasicTests/ProcessTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,7 @@ class ProcessTests: XCTestCase {
}

func testWorkingDirectory() throws {
guard #available(macOS 10.15, *) else {
// Skip this test since it's not supported in this OS.
return
}

#if os(Linux) || os(Android)
#if !os(Windows)
guard SPM_posix_spawn_file_actions_addchdir_np_supported() else {
// Skip this test since it's not supported in this OS.
return
Expand Down Expand Up @@ -478,9 +473,7 @@ fileprivate extension Process {
self.init(arguments: [Self.script(scriptName)] + arguments, environment: Self.env(), outputRedirection: outputRedirection)
}

// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
static func checkNonZeroExit(
scriptName: String,
environment: [String: String] = ProcessEnv.vars,
Expand All @@ -498,9 +491,7 @@ fileprivate extension Process {
return try await checkNonZeroExit(args: script(scriptName), environment: environment, loggingHandler: loggingHandler)
}

// #if compiler(>=5.8)
// @available(*, noasync)
// #endif
@available(*, noasync)
@discardableResult
static func popen(
scriptName: String,
Expand Down