Skip to content

Commit

Permalink
Merge pull request #25 from jamf/CON-4576_modernize
Browse files Browse the repository at this point in the history
CON-4576 minor updates to explicit Sendability
  • Loading branch information
mlink authored Feb 12, 2024
2 parents 5568e42 + a8d3659 commit 2fdacca
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 3.0.2 - 2024-02-07

### Added
- Additional `Sendable` conformance where it can't be implicitly determined outside of this package.

### Removed
- `open` scope from `Subprocess` since none of its members were `open`.

## 3.0.1 - 2023-11-27

### Added
Expand Down
25 changes: 21 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

import PackageDescription

#if swift(<6)
let swiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("StrictConcurrency"),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("ForwardTrailingClosures"),
.enableUpcomingFeature("ImplicitOpenExistentials"),
.enableUpcomingFeature("BareSlashRegexLiterals"),
.enableUpcomingFeature("ConciseMagicFile"),
]
#else
let swiftSettings: [SwiftSetting] = []
#endif

let package = Package(
name: "Subprocess",
platforms: [ .macOS("10.15.4") ],
Expand Down Expand Up @@ -33,26 +46,30 @@ let package = Package(
targets: [
.target(
name: "Subprocess",
dependencies: []
dependencies: [],
swiftSettings: swiftSettings
),
.target(
name: "SubprocessMocks",
dependencies: [
.target(name: "Subprocess")
]
],
swiftSettings: swiftSettings
),
.testTarget(
name: "UnitTests",
dependencies: [
.target(name: "Subprocess"),
.target(name: "SubprocessMocks")
]
],
swiftSettings: swiftSettings
),
.testTarget(
name: "SystemTests",
dependencies: [
.target(name: "Subprocess")
]
],
swiftSettings: swiftSettings
)
]
)
10 changes: 5 additions & 5 deletions Sources/Subprocess/Subprocess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import Foundation
import Combine

/// Class used for asynchronous process execution
open class Subprocess: @unchecked Sendable {
public class Subprocess: @unchecked Sendable {
/// Output options.
public struct OutputOptions: OptionSet {
public let rawValue: Int
Expand Down Expand Up @@ -240,7 +240,7 @@ open class Subprocess: @unchecked Sendable {
// Methods for typical one-off acquisition of output from running some command.
extension Subprocess {
/// Additional configuration options.
public struct RunOptions: OptionSet {
public struct RunOptions: OptionSet, Sendable {
public let rawValue: Int

/// Throw an error if the process exited with a non-zero exit code.
Expand All @@ -259,7 +259,7 @@ extension Subprocess {
/// - command: An external command to run with optional arguments.
/// - standardInput: A type conforming to `DataProtocol` (typically a `Data` type) from which to read input to the external command.
/// - options: Options used to specify runtime behavior.
public static func data(for command: [String], standardInput: (any DataProtocol)? = nil, options: RunOptions = .throwErrorOnNonZeroExit) async throws -> Data {
public static func data(for command: [String], standardInput: (any DataProtocol & Sendable)? = nil, options: RunOptions = .throwErrorOnNonZeroExit) async throws -> Data {
let subprocess = Self(command)
let (standardOutput, standardError, waitForExit) = if let standardInput {
try subprocess.run(standardInput: AsyncStream(UInt8.self, { continuation in
Expand Down Expand Up @@ -422,7 +422,7 @@ extension Subprocess {
/// - standardInput: A type conforming to `DataProtocol` (typically a `Data` type) from which to read input to the external command.
/// - options: Options used to specify runtime behavior.
@inlinable
public static func string(for command: [String], standardInput: (any DataProtocol)? = nil, options: RunOptions = .throwErrorOnNonZeroExit) async throws -> String {
public static func string(for command: [String], standardInput: (any DataProtocol & Sendable)? = nil, options: RunOptions = .throwErrorOnNonZeroExit) async throws -> String {
String(decoding: try await data(for: command, standardInput: standardInput, options: options), as: UTF8.self)
}

Expand Down Expand Up @@ -455,7 +455,7 @@ extension Subprocess {
/// - options: Options used to specify runtime behavior.
/// - decoder: A `TopLevelDecoder` that will be used to decode the data.
@inlinable
public static func value<Content, Decoder>(for command: [String], standardInput: (any DataProtocol)? = nil, options: RunOptions = .throwErrorOnNonZeroExit, decoder: Decoder) async throws -> Content where Content : Decodable, Decoder : TopLevelDecoder, Decoder.Input == Data {
public static func value<Content, Decoder>(for command: [String], standardInput: (any DataProtocol & Sendable)? = nil, options: RunOptions = .throwErrorOnNonZeroExit, decoder: Decoder) async throws -> Content where Content : Decodable, Decoder : TopLevelDecoder, Decoder.Input == Data {
try await decoder.decode(Content.self, from: data(for: command, standardInput: standardInput, options: options))
}

Expand Down

0 comments on commit 2fdacca

Please sign in to comment.