Skip to content

Commit 41ba003

Browse files
authored
Move availability inline (#47)
Motivation: It's hard for packages to incrementally adopt gRPC with platforms in the package manifest as it requires packages to include platforms in their manifest or mint a new major version. Modifications: - Move platform availability onto source code - Check annotations in CI Result: Easier to adopt
1 parent 7b8507d commit 41ba003

27 files changed

+152
-61
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
with:
1414
linux_5_9_enabled: false
1515
linux_5_10_enabled: false
16-
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
17-
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
18-
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
19-
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
16+
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -warnings-as-errors -Xswiftc -require-explicit-availability"
17+
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -warnings-as-errors -Xswiftc -require-explicit-availability"
18+
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-availability"
19+
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-availability"
2020

2121
static-sdk:
2222
name: Static SDK

.github/workflows/pull_request.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ jobs:
2525
with:
2626
linux_5_9_enabled: false
2727
linux_5_10_enabled: false
28-
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
29-
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
30-
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
31-
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
28+
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -warnings-as-errors -Xswiftc -require-explicit-availability"
29+
linux_6_1_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -warnings-as-errors -Xswiftc -require-explicit-availability"
30+
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-availability"
31+
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-availability"
3232

3333
cxx-interop:
3434
name: Cxx interop

Package.swift

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ let dependencies: [Package.Dependency] = [
4747
),
4848
.package(
4949
url: "https://github.com/grpc/grpc-swift-protobuf.git",
50-
from: "1.0.0"
50+
from: "1.3.0"
5151
),
5252
.package(
5353
url: "https://github.com/apple/swift-protobuf.git",
@@ -59,16 +59,32 @@ let dependencies: [Package.Dependency] = [
5959
),
6060
.package(
6161
url: "https://github.com/swift-server/swift-service-lifecycle.git",
62-
from: "2.6.3"
62+
from: "2.8.0"
6363
),
6464
]
6565

66-
let defaultSwiftSettings: [SwiftSetting] = [
67-
.swiftLanguageMode(.v6),
68-
.enableUpcomingFeature("ExistentialAny"),
69-
.enableUpcomingFeature("InternalImportsByDefault"),
70-
.enableUpcomingFeature("MemberImportVisibility"),
71-
]
66+
// -------------------------------------------------------------------------------------------------
67+
68+
// This adds some build settings which allow us to map "@available(gRPCSwiftExtras 1.x, *)" to
69+
// the appropriate OS platforms.
70+
let nextMinorVersion = 1
71+
let availabilitySettings: [SwiftSetting] = (0 ... nextMinorVersion).map { minor in
72+
let name = "gRPCSwiftExtras"
73+
let version = "1.\(minor)"
74+
let platforms = "macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0"
75+
let setting = "AvailabilityMacro=\(name) \(version):\(platforms)"
76+
return .enableExperimentalFeature(setting)
77+
}
78+
79+
let defaultSwiftSettings: [SwiftSetting] =
80+
availabilitySettings + [
81+
.swiftLanguageMode(.v6),
82+
.enableUpcomingFeature("ExistentialAny"),
83+
.enableUpcomingFeature("InternalImportsByDefault"),
84+
.enableUpcomingFeature("MemberImportVisibility"),
85+
]
86+
87+
// -------------------------------------------------------------------------------------------------
7288

7389
let targets: [Target] = [
7490
// An implementation of the gRPC Health service.
@@ -177,13 +193,6 @@ let targets: [Target] = [
177193

178194
let package = Package(
179195
name: "grpc-swift-extras",
180-
platforms: [
181-
.macOS(.v15),
182-
.iOS(.v18),
183-
.tvOS(.v18),
184-
.watchOS(.v11),
185-
.visionOS(.v2),
186-
],
187196
products: products,
188197
dependencies: dependencies,
189198
targets: targets

Sources/GRPCHealthService/HealthService+Service.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
internal import GRPCCore
1818
private import Synchronization
1919

20+
@available(gRPCSwiftExtras 1.0, *)
2021
extension HealthService {
2122
internal struct Service: Grpc_Health_V1_Health.ServiceProtocol {
2223
private let state = Self.State()
2324
}
2425
}
2526

27+
@available(gRPCSwiftExtras 1.0, *)
2628
extension HealthService.Service {
2729
func check(
2830
request: ServerRequest<Grpc_Health_V1_HealthCheckRequest>,
@@ -69,6 +71,7 @@ extension HealthService.Service {
6971
}
7072
}
7173

74+
@available(gRPCSwiftExtras 1.0, *)
7275
extension HealthService.Service {
7376
private final class State: Sendable {
7477
// The state of each service keyed by the fully qualified service name.

Sources/GRPCHealthService/HealthService.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public import GRPCCore
4141
/// // ...
4242
/// }
4343
/// ```
44+
@available(gRPCSwiftExtras 1.0, *)
4445
public struct HealthService: Sendable, RegistrableRPCService {
4546
/// An implementation of the `grpc.health.v1.Health` service.
4647
private let service: Service
@@ -62,6 +63,7 @@ public struct HealthService: Sendable, RegistrableRPCService {
6263
}
6364
}
6465

66+
@available(gRPCSwiftExtras 1.0, *)
6567
extension HealthService {
6668
/// Provides status updates to ``HealthService``.
6769
public struct Provider: Sendable {
@@ -105,6 +107,7 @@ extension HealthService {
105107
}
106108
}
107109

110+
@available(gRPCSwiftExtras 1.0, *)
108111
extension Grpc_Health_V1_HealthCheckResponse.ServingStatus {
109112
package init(_ status: ServingStatus) {
110113
switch status.value {

Sources/GRPCHealthService/ServingStatus.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
///
1919
/// - ``ServingStatus/serving`` indicates that a service is healthy.
2020
/// - ``ServingStatus/notServing`` indicates that a service is unhealthy.
21+
@available(gRPCSwiftExtras 1.0, *)
2122
public struct ServingStatus: Sendable, Hashable {
2223
internal enum Value: Sendable, Hashable {
2324
case serving

Sources/GRPCInteropTests/AssertionFailure.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
/// Failure assertion for interoperability testing.
1818
///
1919
/// This is required because the tests must be able to run without XCTest.
20+
@available(gRPCSwiftExtras 1.0, *)
2021
public struct AssertionFailure: Error {
2122
public var message: String
2223
public var file: String
@@ -30,6 +31,7 @@ public struct AssertionFailure: Error {
3031
}
3132

3233
/// Asserts that the value of an expression is `true`.
34+
@available(gRPCSwiftExtras 1.0, *)
3335
public func assertTrue(
3436
_ expression: @autoclosure () throws -> Bool,
3537
_ message: String = "The statement is not true.",
@@ -42,6 +44,7 @@ public func assertTrue(
4244
}
4345

4446
/// Asserts that the two given values are equal.
47+
@available(gRPCSwiftExtras 1.0, *)
4548
public func assertEqual<T: Equatable>(
4649
_ value1: T,
4750
_ value2: T,

Sources/GRPCInteropTests/InteroperabilityTestCase.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
public import GRPCCore
1717

18+
@available(gRPCSwiftExtras 1.0, *)
1819
public protocol InteroperabilityTest {
1920
/// Run a test case using the given connection.
2021
///
@@ -47,6 +48,7 @@ public protocol InteroperabilityTest {
4748
/// Note: Tests for compression have not been implemented yet as compression is
4849
/// not supported. Once the API which allows for compression will be implemented
4950
/// these tests should be added.
51+
@available(gRPCSwiftExtras 1.0, *)
5052
public enum InteroperabilityTestCase: String, CaseIterable, Sendable {
5153
case emptyUnary = "empty_unary"
5254
case largeUnary = "large_unary"
@@ -68,6 +70,7 @@ public enum InteroperabilityTestCase: String, CaseIterable, Sendable {
6870
}
6971
}
7072

73+
@available(gRPCSwiftExtras 1.0, *)
7174
extension InteroperabilityTestCase {
7275
/// Return a new instance of the test case.
7376
public func makeTest() -> any InteroperabilityTest {

Sources/GRPCInteropTests/InteroperabilityTestCases.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ private import struct Foundation.Data
3636
/// Client asserts:
3737
/// - call was successful
3838
/// - response is non-null
39+
@available(gRPCSwiftExtras 1.0, *)
3940
struct EmptyUnary: InteroperabilityTest {
4041
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
4142
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -69,6 +70,7 @@ struct EmptyUnary: InteroperabilityTest {
6970
/// - response payload body is 314159 bytes in size
7071
/// - clients are free to assert that the response payload body contents are zero and comparing
7172
/// the entire response message against a golden response
73+
@available(gRPCSwiftExtras 1.0, *)
7274
struct LargeUnary: InteroperabilityTest {
7375
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
7476
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -144,6 +146,7 @@ struct LargeUnary: InteroperabilityTest {
144146
/// - Response payload body is 314159 bytes in size.
145147
/// - Clients are free to assert that the response payload body contents are zeros and comparing the
146148
/// entire response message against a golden response.
149+
@available(gRPCSwiftExtras 1.0, *)
147150
class ClientCompressedUnary: InteroperabilityTest {
148151
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
149152
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -253,6 +256,7 @@ class ClientCompressedUnary: InteroperabilityTest {
253256
/// - response payload body is 314159 bytes in size in both cases.
254257
/// - clients are free to assert that the response payload body contents are zero and comparing the
255258
/// entire response message against a golden response
259+
@available(gRPCSwiftExtras 1.0, *)
256260
class ServerCompressedUnary: InteroperabilityTest {
257261
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
258262
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -342,6 +346,7 @@ class ServerCompressedUnary: InteroperabilityTest {
342346
/// Client asserts:
343347
/// - call was successful
344348
/// - response aggregated_payload_size is 74922
349+
@available(gRPCSwiftExtras 1.0, *)
345350
struct ClientStreaming: InteroperabilityTest {
346351
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
347352
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -392,6 +397,7 @@ struct ClientStreaming: InteroperabilityTest {
392397
/// - response payload bodies are sized (in order): 31415, 9, 2653, 58979
393398
/// - clients are free to assert that the response payload body contents are zero and
394399
/// comparing the entire response messages against golden responses
400+
@available(gRPCSwiftExtras 1.0, *)
395401
struct ServerStreaming: InteroperabilityTest {
396402
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
397403
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -467,6 +473,7 @@ struct ServerStreaming: InteroperabilityTest {
467473
/// - response payload bodies are sized (in order): 31415, 92653
468474
/// - clients are free to assert that the response payload body contents are zero and comparing the
469475
/// entire response messages against golden responses
476+
@available(gRPCSwiftExtras 1.0, *)
470477
class ServerCompressedStreaming: InteroperabilityTest {
471478
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
472479
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -579,6 +586,7 @@ class ServerCompressedStreaming: InteroperabilityTest {
579586
/// - response payload bodies are sized (in order): 31415, 9, 2653, 58979
580587
/// - clients are free to assert that the response payload body contents are zero and
581588
/// comparing the entire response messages against golden responses
589+
@available(gRPCSwiftExtras 1.0, *)
582590
struct PingPong: InteroperabilityTest {
583591
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
584592
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -645,6 +653,7 @@ struct PingPong: InteroperabilityTest {
645653
/// Client asserts:
646654
/// - call was successful
647655
/// - exactly zero responses
656+
@available(gRPCSwiftExtras 1.0, *)
648657
struct EmptyStream: InteroperabilityTest {
649658
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
650659
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -700,6 +709,7 @@ struct EmptyStream: InteroperabilityTest {
700709
/// received in the initial metadata for calls in Procedure steps 1 and 2.
701710
/// - metadata with key "x-grpc-test-echo-trailing-bin" and value 0xababab is received in the
702711
/// trailing metadata for calls in Procedure steps 1 and 2.
712+
@available(gRPCSwiftExtras 1.0, *)
703713
struct CustomMetadata: InteroperabilityTest {
704714
let initialMetadataName = "x-grpc-test-echo-initial"
705715
let initialMetadataValue = "test_initial_metadata_value"
@@ -820,6 +830,7 @@ struct CustomMetadata: InteroperabilityTest {
820830
/// Client asserts:
821831
/// - received status code is the same as the sent code for both Procedure steps 1 and 2
822832
/// - received status message is the same as the sent message for both Procedure steps 1 and 2
833+
@available(gRPCSwiftExtras 1.0, *)
823834
struct StatusCodeAndMessage: InteroperabilityTest {
824835
let expectedCode = 2
825836
let expectedMessage = "test status message"
@@ -897,6 +908,7 @@ struct StatusCodeAndMessage: InteroperabilityTest {
897908
/// - received status code is the same as the sent code for Procedure step 1
898909
/// - received status message is the same as the sent message for Procedure step 1, including all
899910
/// whitespace characters
911+
@available(gRPCSwiftExtras 1.0, *)
900912
struct SpecialStatusMessage: InteroperabilityTest {
901913
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
902914
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -939,6 +951,7 @@ struct SpecialStatusMessage: InteroperabilityTest {
939951
///
940952
/// Client asserts:
941953
/// - received status code is 12 (UNIMPLEMENTED)
954+
@available(gRPCSwiftExtras 1.0, *)
942955
struct UnimplementedMethod: InteroperabilityTest {
943956
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
944957
let testServiceClient = Grpc_Testing_TestService.Client(wrapping: client)
@@ -971,6 +984,7 @@ struct UnimplementedMethod: InteroperabilityTest {
971984
///
972985
/// Client asserts:
973986
/// - received status code is 12 (UNIMPLEMENTED)
987+
@available(gRPCSwiftExtras 1.0, *)
974988
struct UnimplementedService: InteroperabilityTest {
975989
func run<Transport: ClientTransport>(client: GRPCClient<Transport>) async throws {
976990
let unimplementedServiceClient = Grpc_Testing_UnimplementedService.Client(wrapping: client)

Sources/GRPCInteropTests/TestService.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ private import struct FoundationEssentials.Data
2323
private import struct Foundation.Data
2424
#endif
2525

26+
@available(gRPCSwiftExtras 1.0, *)
2627
public struct TestService: Grpc_Testing_TestService.ServiceProtocol {
2728
public init() {}
2829

@@ -233,6 +234,7 @@ public struct TestService: Grpc_Testing_TestService.ServiceProtocol {
233234
}
234235
}
235236

237+
@available(gRPCSwiftExtras 1.0, *)
236238
extension Metadata {
237239
fileprivate func makeInitialAndTrailingMetadata() -> (Metadata, Metadata) {
238240
var initialMetadata = Metadata()

Sources/GRPCOTelTracingInterceptors/HookedAsyncSequence.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
@available(gRPCSwiftExtras 1.0, *)
1718
internal struct HookedRPCAsyncSequence<Wrapped: AsyncSequence & Sendable>: AsyncSequence, Sendable
1819
where Wrapped.Element: Sendable {
1920
private let wrapped: Wrapped

Sources/GRPCOTelTracingInterceptors/HookedWriter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
internal import GRPCCore
1717
internal import Tracing
1818

19+
@available(gRPCSwiftExtras 1.0, *)
1920
struct HookedWriter<Element: Sendable>: RPCWriterProtocol {
2021
private let writer: any RPCWriterProtocol<Element>
2122
private let afterEachWrite: @Sendable () -> Void

Sources/GRPCOTelTracingInterceptors/Tracing/ClientOTelTracingInterceptor.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ package import Tracing
2929
/// OpenTelemetry's documentation on:
3030
/// - https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans
3131
/// - https://opentelemetry.io/docs/specs/semconv/rpc/grpc/
32+
@available(gRPCSwiftExtras 1.0, *)
3233
public struct ClientOTelTracingInterceptor: ClientInterceptor {
3334
private let injector: ClientRequestInjector
3435
private var serverHostname: String
@@ -241,6 +242,7 @@ public struct ClientOTelTracingInterceptor: ClientInterceptor {
241242

242243
/// An injector responsible for injecting the required instrumentation keys from the `ServiceContext` into
243244
/// the request metadata.
245+
@available(gRPCSwiftExtras 1.0, *)
244246
struct ClientRequestInjector: Instrumentation.Injector {
245247
typealias Carrier = Metadata
246248

@@ -249,6 +251,7 @@ struct ClientRequestInjector: Instrumentation.Injector {
249251
}
250252
}
251253

254+
@available(gRPCSwiftExtras 1.0, *)
252255
extension Error {
253256
var grpcErrorCode: RPCError.Code? {
254257
if let rpcError = self as? RPCError {

Sources/GRPCOTelTracingInterceptors/Tracing/ServerOTelTracingInterceptor.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ package import Tracing
2828
/// OpenTelemetry's documentation on:
2929
/// - https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans
3030
/// - https://opentelemetry.io/docs/specs/semconv/rpc/grpc/
31+
@available(gRPCSwiftExtras 1.0, *)
3132
public struct ServerOTelTracingInterceptor: ServerInterceptor {
3233
private let extractor: ServerRequestExtractor
3334
private var serverHostname: String
@@ -217,6 +218,7 @@ public struct ServerOTelTracingInterceptor: ServerInterceptor {
217218
}
218219

219220
/// An extractor responsible for extracting the required instrumentation keys from request metadata.
221+
@available(gRPCSwiftExtras 1.0, *)
220222
struct ServerRequestExtractor: Instrumentation.Extractor {
221223
typealias Carrier = Metadata
222224

Sources/GRPCOTelTracingInterceptors/Tracing/SpanAttributes+GRPCTracingKeys.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ enum GRPCTracingKeys {
4040
fileprivate static let responseMetadataPrefix = "rpc.grpc.response.metadata."
4141
}
4242

43+
@available(gRPCSwiftExtras 1.0, *)
4344
extension Span {
4445
// See: https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans/
4546
func setOTelClientSpanGRPCAttributes(

0 commit comments

Comments
 (0)