Skip to content

Commit

Permalink
Swift 6 updates
Browse files Browse the repository at this point in the history
  • Loading branch information
mlink committed Jul 1, 2024
1 parent 9044073 commit 33c99cc
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 61 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ 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.4] - 2024-07-01

### Changes
- Swift 6 compatibility updates.

## 3.0.3 - 2024-04-15

### Changed
Expand Down
69 changes: 17 additions & 52 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ let package = Package(
.target(name: "Subprocess")
]
)
]
],
swiftLanguageVersions: [.v5, .version("6")]
)

for target in package.targets {
Expand All @@ -65,60 +66,24 @@ for target in package.targets {
// as upcoming features will result in a compiler error. Currently in the
// latest 5.10 compiler this doesn't happen, the compiler ignores it.
//
// If the situation does change and enabling default language features
// does result in an error in future versions we attempt to guard against
// this by using the hasFeature(x) compiler directive to see if we have a
// feature already, or if we can enable it. It's safe to enable features
// that don't exist in older compiler versions as the compiler will ignore
// features it doesn't have implemented.

// swift 6
#if !hasFeature(ConciseMagicFile)
swiftSettings.append(.enableUpcomingFeature("ConciseMagicFile"))
#endif

#if !hasFeature(ForwardTrailingClosures)
swiftSettings.append(.enableUpcomingFeature("ForwardTrailingClosures"))
#endif

#if !hasFeature(StrictConcurrency)
swiftSettings.append(.enableUpcomingFeature("StrictConcurrency"))
// StrictConcurrency is under experimental features in Swift <=5.10 contrary to some posts and documentation
swiftSettings.append(.enableExperimentalFeature("StrictConcurrency"))
#endif

#if !hasFeature(BareSlashRegexLiterals)
swiftSettings.append(.enableUpcomingFeature("BareSlashRegexLiterals"))
#endif

#if !hasFeature(ImplicitOpenExistentials)
swiftSettings.append(.enableUpcomingFeature("ImplicitOpenExistentials"))
#endif

#if !hasFeature(ImportObjcForwardDeclarations)
swiftSettings.append(.enableUpcomingFeature("ImportObjcForwardDeclarations"))
#endif

#if !hasFeature(DisableOutwardActorInference)
swiftSettings.append(.enableUpcomingFeature("DisableOutwardActorInference"))
#endif

#if !hasFeature(InternalImportsByDefault)
swiftSettings.append(.enableUpcomingFeature("InternalImportsByDefault"))
#endif

#if !hasFeature(IsolatedDefaultValues)
swiftSettings.append(.enableUpcomingFeature("IsolatedDefaultValues"))
#endif

#if !hasFeature(GlobalConcurrency)
swiftSettings.append(.enableUpcomingFeature("GlobalConcurrency"))
#endif
// The Swift 6 compiler on the other hand does emit errors when features
// are enabled. Unfortunately it appears that the preprocessor
// !hasFeature(xxx) cannot be used to test for this situation nor does
// #if swift(<6) guard against this. There must be some sort of magic
// used that is special for compiling the Package.swift manifest.
// Instead a versioned Package.swift can be used (e.g. [email protected])
// and the implemented now default features can be removed in Package.swift.
//
// Or you can just delete the Swift 6 features that are enabled instead of
// creating another manifest file and test to see if building under Swift 5
// still works (it should almost always work).
//
// It's still safe to enable features that don't exist in older compiler
// versions as the compiler will ignore features it doesn't have implemented.

// swift 7
#if !hasFeature(ExistentialAny)
swiftSettings.append(.enableUpcomingFeature("ExistentialAny"))
#endif
swiftSettings.append(.enableUpcomingFeature("InternalImportsByDefault"))

target.swiftSettings = swiftSettings
}
4 changes: 4 additions & 0 deletions Sources/Subprocess/AsyncSequence+Additions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

extension AsyncSequence {
/// Returns a sequence of all the elements.
Expand Down
4 changes: 4 additions & 0 deletions Sources/Subprocess/AsyncStream+Yield.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

extension AsyncStream.Continuation where Element == UInt8 {
/// Resume the task awaiting the next iteration point by having it return
Expand Down
5 changes: 5 additions & 0 deletions Sources/Subprocess/Input.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

/// Interface representing input to the process
public struct Input {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Subprocess/Pipe+AsyncBytes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

// `FileHandle.AsyncBytes` has a bug that can block reading of stdout when also reading stderr.
// We can avoid this problem if we create independent handlers.
Expand Down
4 changes: 4 additions & 0 deletions Sources/Subprocess/Shell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

/// Class used for synchronous process execution
@available(*, deprecated, message: "Use Swift Concurrency methods instead which are part of the Subprocess class")
Expand Down
5 changes: 5 additions & 0 deletions Sources/Subprocess/Subprocess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
public import Combine
#else
import Foundation
import Combine
#endif

/// Class used for asynchronous process execution
public class Subprocess: @unchecked Sendable {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Subprocess/SubprocessDependencyBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

/// Protocol call used for dependency injection
public protocol SubprocessDependencyFactory {
Expand Down
4 changes: 4 additions & 0 deletions Sources/SubprocessMocks/MockOutput.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#endif

/// A way to supply data to mock methods
public protocol MockOutput: Sendable {
Expand Down
8 changes: 5 additions & 3 deletions Sources/SubprocessMocks/MockProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#if !COCOA_PODS
import Subprocess
#endif
import Subprocess

/// Interface used for mocking a process
public struct MockProcess: Sendable {
Expand Down Expand Up @@ -66,7 +68,7 @@ public struct MockProcess: Sendable {
}

/// Subclass of `Process` used for mocking
open class MockProcessReference: Process {
open class MockProcessReference: Process, @unchecked Sendable {
/// Context information and values used for overriden properties
public struct Context {

Expand Down
5 changes: 4 additions & 1 deletion Sources/SubprocessMocks/MockShell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
public import Subprocess
#else
import Foundation
#if !COCOA_PODS
import Subprocess
#endif

Expand Down
6 changes: 5 additions & 1 deletion Sources/SubprocessMocks/MockSubprocess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
public import Combine
public import Subprocess
#else
import Foundation
import Combine
#if !COCOA_PODS
import Subprocess
#endif

Expand Down
10 changes: 6 additions & 4 deletions Sources/SubprocessMocks/MockSubprocessDependencyBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
// SOFTWARE.
//

#if swift(>=6.0)
public import Foundation
#else
import Foundation
#if !COCOA_PODS
import Subprocess
#endif
import Subprocess

/// Error representing a failed call to Subprocess.expect or Shell.expect
public struct ExpectationError: Error {
Expand Down Expand Up @@ -66,11 +68,11 @@ public extension SubprocessMockObject {
static func reset() { MockSubprocessDependencyBuilder.shared.reset() }
}

public class MockFileHandle: FileHandle {
public class MockFileHandle: FileHandle, @unchecked Sendable {
public var url: URL?
}

public final class MockPipe: Pipe {
public final class MockPipe: Pipe, @unchecked Sendable {
private static let queue = DispatchQueue(label: "\(MockPipe.self)")
private var _data: Data?
public var data: Data? {
Expand Down

0 comments on commit 33c99cc

Please sign in to comment.