diff --git a/Sources/TSCBasic/Await.swift b/Sources/TSCBasic/Await.swift index d61fd4e3..62a4435e 100644 --- a/Sources/TSCBasic/Await.swift +++ b/Sources/TSCBasic/Await.swift @@ -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(_ body: (@escaping (Result) -> Void) -> Void) throws -> T { return try tsc_await(body).get() } -//#if compiler(>=5.8) -//@available(*, noasync) -//#endif +@available(*, noasync) public func tsc_await(_ body: (@escaping (T) -> Void) -> Void) -> T { let condition = Condition() var result: T? = nil diff --git a/Sources/TSCBasic/Closable.swift b/Sources/TSCBasic/Closable.swift index 5a7bf71f..168fcc35 100644 --- a/Sources/TSCBasic/Closable.swift +++ b/Sources/TSCBasic/Closable.swift @@ -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 } diff --git a/Sources/TSCBasic/CollectionExtensions.swift b/Sources/TSCBasic/CollectionExtensions.swift index b0ba5df6..87383338 100644 --- a/Sources/TSCBasic/CollectionExtensions.swift +++ b/Sources/TSCBasic/CollectionExtensions.swift @@ -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() diff --git a/Sources/TSCBasic/DeltaAlgorithm.swift b/Sources/TSCBasic/DeltaAlgorithm.swift index 60391826..93ed3f5d 100644 --- a/Sources/TSCBasic/DeltaAlgorithm.swift +++ b/Sources/TSCBasic/DeltaAlgorithm.swift @@ -65,7 +65,7 @@ public struct DeltaAlgorithm: 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, diff --git a/Sources/TSCBasic/HashAlgorithms.swift b/Sources/TSCBasic/HashAlgorithms.swift index b3bbaa4a..59c706da 100644 --- a/Sources/TSCBasic/HashAlgorithms.swift +++ b/Sources/TSCBasic/HashAlgorithms.swift @@ -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 ] @@ -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 { diff --git a/Sources/TSCBasic/Process/Process.swift b/Sources/TSCBasic/Process/Process.swift index 8cd2efe6..fe82a799 100644 --- a/Sources/TSCBasic/Process/Process.swift +++ b/Sources/TSCBasic/Process/Process.swift @@ -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 { @@ -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] @@ -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) + } } } } @@ -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, @@ -1157,6 +1145,7 @@ extension Process { } @_disfavoredOverload + @available(*, noasync) @available(*, deprecated, renamed: "popen(arguments:environmentBlock:loggingHandler:queue:completion:)") static public func popen( arguments: [String], @@ -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], @@ -1202,6 +1189,7 @@ extension Process { } @_disfavoredOverload + @available(*, noasync) @available(*, deprecated, renamed: "popen(arguments:environmentBlock:loggingHandler:)") @discardableResult static public func popen( @@ -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..., @@ -1233,6 +1219,7 @@ extension Process { } @_disfavoredOverload + @available(*, noasync) @available(*, deprecated, renamed: "popen(args:environmentBlock:loggingHandler:)") @discardableResult static public func popen( @@ -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], @@ -1276,6 +1261,7 @@ extension Process { } @_disfavoredOverload + @available(*, noasync) @available(*, deprecated, renamed: "checkNonZeroExit(arguments:environmentBlock:loggingHandler:)") @discardableResult static public func checkNonZeroExit( @@ -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..., @@ -1307,6 +1291,7 @@ extension Process { } @_disfavoredOverload + @available(*, noasync) @available(*, deprecated, renamed: "checkNonZeroExit(args:environmentBlock:loggingHandler:)") @discardableResult static public func checkNonZeroExit( diff --git a/Sources/TSCBasic/Process/ProcessSet.swift b/Sources/TSCBasic/Process/ProcessSet.swift index 7235c5e0..3ebd1269 100644 --- a/Sources/TSCBasic/Process/ProcessSet.swift +++ b/Sources/TSCBasic/Process/ProcessSet.swift @@ -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 { diff --git a/Sources/TSCBasic/RegEx.swift b/Sources/TSCBasic/RegEx.swift index 14e8cc8a..86ad3698 100644 --- a/Sources/TSCBasic/RegEx.swift +++ b/Sources/TSCBasic/RegEx.swift @@ -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 diff --git a/Sources/TSCBasic/SortedArray.swift b/Sources/TSCBasic/SortedArray.swift index 3a9679a2..f236fafe 100644 --- a/Sources/TSCBasic/SortedArray.swift +++ b/Sources/TSCBasic/SortedArray.swift @@ -90,7 +90,7 @@ public struct SortedArray: 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) { diff --git a/Sources/TSCBasic/TemporaryFile.swift b/Sources/TSCBasic/TemporaryFile.swift index 76cddf75..feb4b680 100644 --- a/Sources/TSCBasic/TemporaryFile.swift +++ b/Sources/TSCBasic/TemporaryFile.swift @@ -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 diff --git a/Sources/TSCTestSupport/misc.swift b/Sources/TSCTestSupport/misc.swift index 3201b4c1..573164f2 100644 --- a/Sources/TSCTestSupport/misc.swift +++ b/Sources/TSCTestSupport/misc.swift @@ -44,6 +44,8 @@ public func testWithTemporaryDirectory( } } +@available(*, noasync) +@available(*, deprecated, message: "Use Process.checkNonZeroExit(arguments:) instead.") public func systemQuietly(_ args: [String]) throws { // Discard the output, by default. // @@ -51,6 +53,8 @@ public func systemQuietly(_ args: [String]) throws { try Process.checkNonZeroExit(arguments: args) } +@available(*, noasync) +@available(*, deprecated, message: "Use Process.checkNonZeroExit(_:) instead.") public func systemQuietly(_ args: String...) throws { try systemQuietly(args) } diff --git a/Sources/TSCclibc/include/process.h b/Sources/TSCclibc/include/process.h index 2d9c806e..da96606b 100644 --- a/Sources/TSCclibc/include/process.h +++ b/Sources/TSCclibc/include/process.h @@ -1,4 +1,4 @@ -#if defined(__linux__) +#if !defined(_WIN32) #include #include diff --git a/Sources/TSCclibc/process.c b/Sources/TSCclibc/process.c index 5bd1011a..d6ac2a06 100644 --- a/Sources/TSCclibc/process.c +++ b/Sources/TSCclibc/process.c @@ -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 #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 } diff --git a/Tests/TSCBasicTests/ProcessTests.swift b/Tests/TSCBasicTests/ProcessTests.swift index 9e2aec2c..6d3d208f 100644 --- a/Tests/TSCBasicTests/ProcessTests.swift +++ b/Tests/TSCBasicTests/ProcessTests.swift @@ -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 @@ -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, @@ -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,