Skip to content

Commit a6a83b2

Browse files
committed
Add support for Windows
Disable tests relying on the executable since those aren't yet supported by SwiftPM, and tweak a couple platform-conditional pieces of code to support the Windows path.
1 parent aa37de7 commit a6a83b2

File tree

7 files changed

+55
-14
lines changed

7 files changed

+55
-14
lines changed

.github/workflows/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ jobs:
1616
linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
1717
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error"
1818
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
19+
windows_6_0_enabled: true
20+
windows_nightly_6_1_enabled: true
21+
windows_nightly_main_enabled: true
22+
windows_6_0_arguments_override: "--explicit-target-dependency-import-check error"
23+
windows_nightly_6_1_arguments_override: "--explicit-target-dependency-import-check error"
24+
windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
1925

2026
integration-test:
2127
name: Integration test

.github/workflows/pull_request.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ jobs:
2222
linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
2323
linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error"
2424
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
25+
windows_6_0_enabled: true
26+
windows_nightly_6_1_enabled: true
27+
windows_nightly_main_enabled: true
28+
windows_6_0_arguments_override: "--explicit-target-dependency-import-check error"
29+
windows_nightly_6_1_arguments_override: "--explicit-target-dependency-import-check error"
30+
windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"
2531

2632
integration-test:
2733
name: Integration test

Package.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let package = Package(
5454
// Tests-only: Runtime library linked by generated code, and also
5555
// helps keep the runtime library new enough to work with the generated
5656
// code.
57-
.package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.3.2"),
57+
.package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.8.2"),
5858
.package(url: "https://github.com/apple/swift-http-types", from: "1.0.2"),
5959
],
6060
targets: [
@@ -111,7 +111,10 @@ let package = Package(
111111
.testTarget(
112112
name: "OpenAPIGeneratorTests",
113113
dependencies: [
114-
"swift-openapi-generator", .product(name: "ArgumentParser", package: "swift-argument-parser"),
114+
"_OpenAPIGeneratorCore",
115+
// Everything except windows: https://github.com/swiftlang/swift-package-manager/issues/6367
116+
.target(name: "swift-openapi-generator", condition: .when(platforms: [.android, .linux, .macOS, .openbsd, .wasi, .custom("freebsd")])),
117+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
115118
],
116119
resources: [.copy("Resources")],
117120
swiftSettings: swiftSettings

Plugins/PluginsShared/PluginUtils.swift

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ enum PluginUtils {
6464

6565
/// Find the config file.
6666
private static func findConfig(inputFiles: FileList, targetName: String) -> Result<Path, FileError> {
67-
let matchedConfigs = inputFiles.filter { supportedConfigFiles.contains($0.path.lastComponent) }.map(\.path)
67+
let matchedConfigs = inputFiles.filter { supportedConfigFiles.contains($0.path.lastComponent_fixed) }
68+
.map(\.path)
6869
guard matchedConfigs.count > 0 else {
6970
return .failure(FileError(targetName: targetName, fileKind: .config, issue: .noFilesFound))
7071
}
@@ -78,7 +79,8 @@ enum PluginUtils {
7879

7980
/// Find the document file.
8081
private static func findDocument(inputFiles: FileList, targetName: String) -> Result<Path, FileError> {
81-
let matchedDocs = inputFiles.filter { supportedDocFiles.contains($0.path.lastComponent) }.map(\.path)
82+
let matchedDocs = inputFiles.filter { supportedDocFiles.contains($0.path.lastComponent_fixed) }
83+
.map(\.path)
8284
guard matchedDocs.count > 0 else {
8385
return .failure(FileError(targetName: targetName, fileKind: .document, issue: .noFilesFound))
8486
}
@@ -97,3 +99,24 @@ extension Array where Element == String {
9799
return "\(self.dropLast().joined(separator: separator))\(lastSeparator)\(self.last!)"
98100
}
99101
}
102+
103+
extension PackagePlugin.Path {
104+
/// Workaround for the ``lastComponent`` property being broken on Windows
105+
/// due to hardcoded assumptions about the path separator being forward slash.
106+
@available(_PackageDescription, deprecated: 6.0, message: "Use `URL` type instead of `Path`.") public
107+
var lastComponent_fixed: String
108+
{
109+
#if !os(Windows)
110+
lastComponent
111+
#else
112+
// Find the last path separator.
113+
guard let idx = string.lastIndex(where: { $0 == "/" || $0 == "\\" }) else {
114+
// No path separators, so the basename is the whole string.
115+
return self.string
116+
}
117+
// Otherwise, it's the string from (but not including) the last path
118+
// separator.
119+
return String(self.string.suffix(from: self.string.index(after: idx)))
120+
#endif
121+
}
122+
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ See also [Supported OpenAPI features][supported-openapi-features].
9999

100100
### Supported platforms and minimum versions
101101

102-
The generator is used during development and is supported on macOS and Linux.
102+
The generator is used during development and is supported on macOS, Linux, and Windows.
103103

104104
The generated code, runtime library, and transports are supported on more
105105
platforms, listed below.
106106

107-
| Component | macOS | Linux | iOS | tvOS | watchOS | visionOS |
107+
| Component | macOS | Linux, Windows | iOS | tvOS | watchOS | visionOS |
108108
| ----------------------------------: | :--- | :--- | :- | :-- | :----- | :------ |
109109
| Generator plugin and CLI | ✅ 10.15+ || ✖️ | ✖️ | ✖️ | ✖️ |
110110
| Generated code and runtime library | ✅ 10.15+ || ✅ 13+ | ✅ 13+ | ✅ 6+ | ✅ 1+ |

Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -358,14 +358,12 @@ fileprivate extension CompatibilityTest {
358358
func log(_ message: String) { print("\(name) \(message)") }
359359

360360
var testCaseName: String {
361-
/// The `name` property is `<test-suite-name>.<test-case-name>` on Linux,
362-
/// and `-[<test-suite-name> <test-case-name>]` on macOS.
361+
/// The `name` property is `-[<test-suite-name> <test-case-name>]` on Apple platforms (e.g. with an Objective-C runtime),
362+
/// and `<test-suite-name>.<test-case-name>` elsewhere.
363363
#if canImport(Darwin)
364364
return String(name.split(separator: " ", maxSplits: 2).last!.dropLast())
365-
#elseif os(Linux)
366-
return String(name.split(separator: ".", maxSplits: 2).last!)
367365
#else
368-
#error("Platform not supported")
366+
return String(name.split(separator: ".", maxSplits: 2).last!)
369367
#endif
370368
}
371369
}
@@ -417,7 +415,7 @@ fileprivate extension URLSession {
417415
func data(from url: URL) async throws -> (Data, URLResponse) {
418416
#if canImport(Darwin)
419417
return try await data(from: url, delegate: nil)
420-
#elseif os(Linux)
418+
#else
421419
return try await withCheckedThrowingContinuation { continuation in
422420
dataTask(with: URLRequest(url: url)) { data, response, error in
423421
if let error {
@@ -432,8 +430,6 @@ fileprivate extension URLSession {
432430
}
433431
.resume()
434432
}
435-
#else
436-
#error("Platform not supported")
437433
#endif
438434
}
439435
}

Tests/OpenAPIGeneratorTests/Test_GenerateOptions.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import XCTest
1515
import _OpenAPIGeneratorCore
1616
import OpenAPIKit
1717
import ArgumentParser
18+
19+
// https://github.com/swiftlang/swift-package-manager/issues/6367
20+
#if !os(Windows)
1821
@testable import swift_openapi_generator
22+
#endif
1923

2024
final class Test_GenerateOptions: XCTestCase {
2125

@@ -29,6 +33,8 @@ final class Test_GenerateOptions: XCTestCase {
2933
)
3034
}
3135

36+
// https://github.com/swiftlang/swift-package-manager/issues/6367
37+
#if !os(Windows)
3238
func testRunGeneratorThrowsErrorDiagnostic() async throws {
3339
let outputDirectory = URL(fileURLWithPath: "/invalid/path")
3440
let docsDirectory = resourcesDirectory.appendingPathComponent("Docs")
@@ -45,4 +51,5 @@ final class Test_GenerateOptions: XCTestCase {
4551
XCTAssertEqual(diagnostic.severity, .error, "Expected diagnostic severity to be `.error`")
4652
} catch { XCTFail("Expected to throw a Diagnostic `.error`, but threw a different error: \(error)") }
4753
}
54+
#endif
4855
}

0 commit comments

Comments
 (0)