Skip to content

Commit a07ebd2

Browse files
Compile with -warnings-as-errors in CI (incl. StrictSendability) (#281)
### Motivation We were not compiling with `-warnings-as-errors` in CI because some of the reference source code contained deprecation annotations. This meant that we are not getting CI failures for other warnings that we'd like to be clean of; specifically strict concurrency. However, in addition to the file-based reference tests, we now have in-memory snippet-based reference tests, which contain tests for deprecated OpenAPI schemas and operations. ### Modifications - Remove deprecated tests from file-based reference test. - Clean up warnings under StrictConcurrency. - Compile with -warnings-as-errors in CI. - Opt into StrictConcurrency and `-warnings-as-errors` locally with environment variable. ### Result - CI will catch sendability warning regressions. - Developing locally with `SWIFT_OPENAPI_STRICT_CONCURRENCY` will enable the same behaviour. ### Test Plan - Added a canary commit to the end of this PR with a sendability issue, which will be reverted before merging. --------- Signed-off-by: Si Beaumont <[email protected]>
1 parent 445e55b commit a07ebd2

File tree

9 files changed

+25
-59
lines changed

9 files changed

+25
-59
lines changed

Package.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// SPDX-License-Identifier: Apache-2.0
1313
//
1414
//===----------------------------------------------------------------------===//
15+
import Foundation
1516
import PackageDescription
1617

1718
// General Swift-settings for all targets.
@@ -23,6 +24,15 @@ swiftSettings.append(
2324
// Require `any` for existential types.
2425
.enableUpcomingFeature("ExistentialAny")
2526
)
27+
28+
// Strict concurrency is enabled in CI; use this environment variable to enable it locally.
29+
if ProcessInfo.processInfo.environment["SWIFT_OPENAPI_STRICT_CONCURRENCY"].flatMap(Bool.init) ?? false {
30+
#warning("Compiling with Strict Concurrency")
31+
swiftSettings.append(contentsOf: [
32+
.enableExperimentalFeature("StrictConcurrency"),
33+
.unsafeFlags(["-warnings-as-errors"]),
34+
])
35+
}
2636
#endif
2737

2838
let package = Package(

Sources/_OpenAPIGeneratorCore/GeneratorMode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
/// Describes the file to be generated from the specified OpenAPI document.
16-
public enum GeneratorMode: String, Codable, CaseIterable {
16+
public enum GeneratorMode: String, Codable, CaseIterable, Sendable {
1717

1818
/// A file that contains the API protocol, reusable types, and operation
1919
/// namespaces.

Sources/_OpenAPIGeneratorCore/Layers/RenderedSwiftRepresentation.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@
1111
// SPDX-License-Identifier: Apache-2.0
1212
//
1313
//===----------------------------------------------------------------------===//
14-
import Foundation
14+
#if os(Linux)
15+
@preconcurrency import struct Foundation.URL
16+
@preconcurrency import struct Foundation.Data
17+
#else
18+
import struct Foundation.URL
19+
import struct Foundation.Data
20+
#endif
1521

1622
/// An in-memory file that contains the generated Swift code.
1723
typealias RenderedSwiftRepresentation = InMemoryOutputFile
1824

1925
/// An in-memory input file that contains the raw data of an OpenAPI document.
2026
///
2127
/// Contents are formatted as either YAML or JSON.
22-
public struct InMemoryInputFile {
28+
public struct InMemoryInputFile: Sendable {
2329

2430
/// The absolute path to the file.
2531
public var absolutePath: URL
@@ -38,7 +44,7 @@ public struct InMemoryInputFile {
3844
}
3945

4046
/// An in-memory output file that contains the generated Swift source code.
41-
public struct InMemoryOutputFile {
47+
public struct InMemoryOutputFile: Sendable {
4248

4349
/// The base name of the file.
4450
public var baseName: String

Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ final class CompatibilityTest: XCTestCase {
2929
let compatibilityTestNumBuildJobs = getIntEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_NUM_BUILD_JOBS")
3030

3131
override func setUp() async throws {
32-
setbuf(stdout, nil)
3332
continueAfterFailure = false
3433
try XCTSkipUnless(compatibilityTestEnabled)
3534
if _isDebugAssertConfiguration() {
@@ -333,7 +332,7 @@ fileprivate extension CompatibilityTest {
333332
}
334333

335334
/// Records diagnostics into an array for testing.
336-
private final class RecordingDiagnosticCollector: DiagnosticCollector {
335+
private final class RecordingDiagnosticCollector: DiagnosticCollector, @unchecked Sendable {
337336
private let lock = NSLock()
338337
private var _diagnostics: [Diagnostic] = []
339338
var diagnostics: [Diagnostic] {

Tests/OpenAPIGeneratorReferenceTests/Resources/Docs/petstore.yaml

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ paths:
141141
/probe/:
142142
post:
143143
operationId: probe
144-
deprecated: true
145144
responses:
146145
'204':
147146
description: Ack
@@ -229,13 +228,6 @@ components:
229228
schema:
230229
type: integer
231230
format: int64
232-
header.deprecatedHeader:
233-
name: deprecatedHeader
234-
in: header
235-
deprecated: true
236-
description: A deprecated header parameter
237-
schema:
238-
type: string
239231
schemas:
240232
Pet:
241233
type: object
@@ -277,7 +269,6 @@ components:
277269
PetKind:
278270
type: string
279271
description: "Kind of pet"
280-
deprecated: true
281272
enum:
282273
- cat
283274
- dog
@@ -421,17 +412,6 @@ components:
421412
- $ref: '#/components/schemas/MessagedExercise'
422413
discriminator:
423414
propertyName: kind
424-
DeprecatedObject:
425-
deprecated: true
426-
type: object
427-
properties: {}
428-
additionalProperties: false
429-
ObjectWithDeprecatedProperty:
430-
type: object
431-
properties:
432-
message:
433-
type: string
434-
deprecated: true
435415
PetStats:
436416
type: object
437417
properties:

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ public struct Client: APIProtocol {
303303
}
304304
/// - Remark: HTTP `POST /probe/`.
305305
/// - Remark: Generated from `#/paths//probe//post(probe)`.
306-
@available(*, deprecated) public func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output
307-
{
306+
public func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output {
308307
try await client.send(
309308
input: input,
310309
forOperation: Operations.probe.id,

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ fileprivate extension UniversalServer where APIHandler: APIProtocol {
353353
}
354354
/// - Remark: HTTP `POST /probe/`.
355355
/// - Remark: Generated from `#/paths//probe//post(probe)`.
356-
@available(*, deprecated) func probe(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
356+
func probe(request: Request, metadata: ServerRequestMetadata) async throws -> Response {
357357
try await handle(
358358
request: request,
359359
with: metadata,

Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public protocol APIProtocol: Sendable {
3232
func postStats(_ input: Operations.postStats.Input) async throws -> Operations.postStats.Output
3333
/// - Remark: HTTP `POST /probe/`.
3434
/// - Remark: Generated from `#/paths//probe//post(probe)`.
35-
@available(*, deprecated) func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output
35+
func probe(_ input: Operations.probe.Input) async throws -> Operations.probe.Output
3636
/// Update just a specific property of an existing pet. Nothing is updated if no request body is provided.
3737
///
3838
/// - Remark: HTTP `PATCH /pets/{petId}`.
@@ -592,23 +592,6 @@ public enum Components {
592592
}
593593
}
594594
}
595-
/// - Remark: Generated from `#/components/schemas/DeprecatedObject`.
596-
@available(*, deprecated) public struct DeprecatedObject: Codable, Hashable, Sendable {
597-
/// Creates a new `DeprecatedObject`.
598-
public init() {}
599-
public init(from decoder: any Decoder) throws { try decoder.ensureNoAdditionalProperties(knownKeys: []) }
600-
}
601-
/// - Remark: Generated from `#/components/schemas/ObjectWithDeprecatedProperty`.
602-
public struct ObjectWithDeprecatedProperty: Codable, Hashable, Sendable {
603-
/// - Remark: Generated from `#/components/schemas/ObjectWithDeprecatedProperty/message`.
604-
@available(*, deprecated) public var message: Swift.String?
605-
/// Creates a new `ObjectWithDeprecatedProperty`.
606-
///
607-
/// - Parameters:
608-
/// - message:
609-
public init(message: Swift.String? = nil) { self.message = message }
610-
public enum CodingKeys: String, CodingKey { case message }
611-
}
612595
/// - Remark: Generated from `#/components/schemas/PetStats`.
613596
public struct PetStats: Codable, Hashable, Sendable {
614597
/// - Remark: Generated from `#/components/schemas/PetStats/count`.
@@ -631,10 +614,6 @@ public enum Components {
631614
///
632615
/// - Remark: Generated from `#/components/parameters/path.petId`.
633616
public typealias path_period_petId = Swift.Int64
634-
/// A deprecated header parameter
635-
///
636-
/// - Remark: Generated from `#/components/parameters/header.deprecatedHeader`.
637-
public typealias header_period_deprecatedHeader = Swift.String
638617
}
639618
/// Types generated from the `#/components/requestBodies` section of the OpenAPI document.
640619
public enum RequestBodies {

docker/docker-compose.2204.59.yaml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,7 @@ services:
1010
test:
1111
image: *image
1212
environment:
13-
# Because OpenAPI supports deprecation, the generated code could include
14-
# deprecated symbols, which will produce warnings.
15-
#
16-
# We'll disable -warnings-as-errors for now and revisit this when we
17-
# refactor the compilation of the generated code into a separate
18-
# pipeline.
19-
#
20-
# - WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
13+
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
2114
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
2215
- STRICT_CONCURRENCY_ARG=-Xswiftc -strict-concurrency=complete
2316

0 commit comments

Comments
 (0)