Skip to content

Commit e8687d2

Browse files
authored
Merge branch 'main' into docc-options-list-update
2 parents cdccaac + d075877 commit e8687d2

File tree

6 files changed

+87
-3
lines changed

6 files changed

+87
-3
lines changed

.github/workflows/pull_request.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
with:
2727
windows_exclude_swift_versions: "[{\"swift_version\": \"5.9\"}]"
2828
enable_macos_checks: true
29+
macos_exclude_xcode_versions: "[{\"xcode_version\": \"16.0\"}, {\"xcode_version\": \"16.1\"}]"
2930

3031
cmake-build:
3132
name: CMake Build
@@ -50,6 +51,25 @@ jobs:
5051
- name: Build
5152
run: cmake --build .cmake-build
5253

54+
wasm-build:
55+
name: Wasm Build
56+
runs-on: ubuntu-latest
57+
container:
58+
image: swift:6.1-noble
59+
steps:
60+
- name: Checkout repo
61+
uses: actions/checkout@v4
62+
- name: Install Swift SDKs for WebAssembly
63+
run: |
64+
# TODO: We can replace these Swift SDKs with the swift.org one once it supports Foundation.
65+
swift sdk install https://github.com/swiftwasm/swift/releases/download/swift-wasm-6.1-RELEASE/swift-wasm-6.1-RELEASE-wasm32-unknown-wasi.artifactbundle.zip --checksum 7550b4c77a55f4b637c376f5d192f297fe185607003a6212ad608276928db992
66+
swift sdk install https://github.com/swiftwasm/swift/releases/download/swift-wasm-6.1-RELEASE/swift-wasm-6.1-RELEASE-wasm32-unknown-wasip1-threads.artifactbundle.zip --checksum 0dd273be28741f8e1eb00682c39bdc956361ed24b5572e183dd8a4e9d1c5f6ec
67+
swift sdk list
68+
- name: Build
69+
run: |
70+
swift build --swift-sdk wasm32-unknown-wasi --target ArgumentParser
71+
swift build --swift-sdk wasm32-unknown-wasip1-threads --target ArgumentParser
72+
5373
soundness:
5474
name: Soundness
5575
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ Add new items at the end of the relevant section under **Unreleased**.
88

99
---
1010

11+
## [1.6.1] - 2025-07-01
12+
13+
### Fixes
14+
15+
- Resolves a source break for clients that have conditional conformances
16+
to `ExpressibleByArgument` or `ParsableArguments`. ([#792])
17+
1118
## [1.6.0] - 2025-06-30
1219

1320
### Additions
@@ -953,7 +960,8 @@ This changelog's format is based on [Keep a Changelog](https://keepachangelog.co
953960

954961
<!-- Link references for releases -->
955962

956-
[Unreleased]: https://github.com/apple/swift-argument-parser/compare/1.6.0...HEAD
963+
[Unreleased]: https://github.com/apple/swift-argument-parser/compare/1.6.1...HEAD
964+
[1.6.1]: https://github.com/apple/swift-argument-parser/compare/1.6.0...1.6.1
957965
[1.6.0]: https://github.com/apple/swift-argument-parser/compare/1.5.1...1.6.0
958966
[1.5.1]: https://github.com/apple/swift-argument-parser/compare/1.5.0...1.5.1
959967
[1.5.0]: https://github.com/apple/swift-argument-parser/compare/1.4.0...1.5.0
@@ -1144,6 +1152,7 @@ This changelog's format is based on [Keep a Changelog](https://keepachangelog.co
11441152
[#782]: https://github.com/apple/swift-argument-parser/pull/782
11451153
[#783]: https://github.com/apple/swift-argument-parser/pull/783
11461154
[#789]: https://github.com/apple/swift-argument-parser/pull/789
1155+
[#792]: https://github.com/apple/swift-argument-parser/pull/792
11471156

11481157
<!-- Link references for contributors -->
11491158

Sources/ArgumentParser/Parsable Properties/CompletionKind.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public struct CompletionKind {
4141
case directory
4242
case shellCommand(String)
4343
case custom(@Sendable ([String], Int, String) -> [String])
44+
#if !canImport(Dispatch)
45+
@available(*, unavailable, message: "DispatchSemaphore is unavailable")
46+
#endif
4447
case customAsync(@Sendable ([String], Int, String) async -> [String])
4548
case customDeprecated(@Sendable ([String]) -> [String])
4649
}
@@ -181,11 +184,18 @@ public struct CompletionKind {
181184
///
182185
/// The same as `custom(@Sendable @escaping ([String], Int, String) -> [String])`,
183186
/// except that the closure is asynchronous.
187+
#if !canImport(Dispatch)
188+
@available(*, unavailable, message: "DispatchSemaphore is unavailable")
189+
#endif
184190
@available(macOS 10.15, macCatalyst 13, iOS 13, tvOS 13, watchOS 6, *)
185191
public static func custom(
186192
_ completion: @Sendable @escaping ([String], Int, String) async -> [String]
187193
) -> CompletionKind {
194+
#if !canImport(Dispatch)
195+
fatalError("DispatchSemaphore is unavailable")
196+
#else
188197
CompletionKind(kind: .customAsync(completion))
198+
#endif
189199
}
190200

191201
/// Deprecated; only kept for backwards compatibility.

Sources/ArgumentParser/Parsing/CommandParser.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
#if swift(>=6.0)
13+
#if canImport(Dispatch)
1314
@preconcurrency private import class Dispatch.DispatchSemaphore
15+
#endif
1416
internal import class Foundation.NSLock
1517
internal import class Foundation.ProcessInfo
1618
#else
19+
#if canImport(Dispatch)
1720
@preconcurrency import class Dispatch.DispatchSemaphore
21+
#endif
1822
import class Foundation.NSLock
1923
import class Foundation.ProcessInfo
2024
#endif
@@ -474,12 +478,16 @@ extension CommandParser {
474478
completingPrefix
475479
)
476480
case .customAsync(let complete):
481+
#if canImport(Dispatch)
477482
if #available(macOS 10.15, macCatalyst 13, iOS 13, tvOS 13, watchOS 6, *)
478483
{
479484
completions = try asyncCustomCompletions(from: args, complete: complete)
480485
} else {
481486
throw ParserError.invalidState
482487
}
488+
#else
489+
throw ParserError.invalidState
490+
#endif
483491
case .customDeprecated(let complete):
484492
completions = complete(args)
485493
default:
@@ -528,11 +536,17 @@ private func parseCustomCompletionArguments(
528536
return (Array(args), completingArgumentIndex, completingPrefix)
529537
}
530538

539+
#if !canImport(Dispatch)
540+
@available(*, unavailable, message: "DispatchSemaphore is unavailable")
541+
#endif
531542
@available(macOS 10.15, macCatalyst 13, iOS 13, tvOS 13, watchOS 6, *)
532543
private func asyncCustomCompletions(
533544
from args: [String],
534545
complete: @escaping @Sendable ([String], Int, String) async -> [String]
535546
) throws -> [String] {
547+
#if !canImport(Dispatch)
548+
throw ParserError.invalidState
549+
#else
536550
let (args, completingArgumentIndex, completingPrefix) =
537551
try parseCustomCompletionArguments(from: args)
538552

@@ -550,6 +564,7 @@ private func asyncCustomCompletions(
550564

551565
semaphore.wait()
552566
return completionsBox.value
567+
#endif
553568
}
554569

555570
// Helper class to make values sendable across concurrency boundaries

Sources/ArgumentParser/Utilities/SwiftExtensions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#if compiler(>=6.2)
1313
/// Designates a type as having a sendable metatype.
14-
public protocol _SendableMetatype: SendableMetatype {}
14+
@_marker public protocol _SendableMetatype: SendableMetatype {}
1515
#else
16-
public protocol _SendableMetatype {}
16+
@_marker public protocol _SendableMetatype {}
1717
#endif

Tests/ArgumentParserEndToEndTests/PositionalEndToEndTests.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,33 @@ extension PositionalEndToEndTests {
241241
}
242242
}
243243
}
244+
245+
// MARK: Conditional ExpressibleByArgument conformance
246+
247+
// Note: This retroactive conformance is a compilation test
248+
extension Range<Int>: ArgumentParser.ExpressibleByArgument {
249+
public init?(argument: String) {
250+
guard let i = argument.firstIndex(of: ":"),
251+
let low = Int(String(argument[..<i])),
252+
let high = Int(String(argument[i...].dropFirst())),
253+
low <= high
254+
else { return nil }
255+
self = low..<high
256+
}
257+
}
258+
259+
extension PositionalEndToEndTests {
260+
struct HasRange: ParsableArguments {
261+
@Argument var range: Range<Int>
262+
}
263+
264+
func testParseCustomRangeConformance() throws {
265+
AssertParse(HasRange.self, ["0:4"]) { args in
266+
XCTAssertEqual(args.range, 0..<4)
267+
}
268+
269+
XCTAssertThrowsError(try HasRange.parse([]))
270+
XCTAssertThrowsError(try HasRange.parse(["1"]))
271+
XCTAssertThrowsError(try HasRange.parse(["1:0"]))
272+
}
273+
}

0 commit comments

Comments
 (0)