Skip to content

Commit

Permalink
Merge branch 'main' into hd-mime-type-params
Browse files Browse the repository at this point in the history
  • Loading branch information
czechboy0 committed Nov 28, 2024
2 parents d6af31e + e971af5 commit 60f1c75
Show file tree
Hide file tree
Showing 49 changed files with 1,753 additions and 249 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
32 changes: 32 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Main

on:
push:
branches: [main]
schedule:
- cron: "0 8,20 * * *"

jobs:
unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_9_arguments_override: "--explicit-target-dependency-import-check error"
linux_5_10_arguments_override: "--explicit-target-dependency-import-check error"
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error"

integration-test:
name: Integration test
uses: apple/swift-nio/.github/workflows/swift_matrix.yml@main
with:
name: "Integration test"
matrix_linux_command: "apt-get update -yq && apt-get install -yq jq && SWIFT_OPENAPI_GENERATOR_REPO_URL=file://${GITHUB_WORKSPACE} ./scripts/run-integration-test.sh"

example-packages:
name: Example packages
uses: apple/swift-nio/.github/workflows/swift_matrix.yml@main
with:
name: "Example packages"
matrix_linux_command: "./scripts/test-examples.sh"
20 changes: 4 additions & 16 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,19 @@ on:
jobs:
soundness:
name: Soundness
uses: apple/swift-nio/.github/workflows/soundness.yml@main
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main
with:
api_breakage_check_enabled: true
broken_symlink_check_enabled: true
docs_check_enabled: true
format_check_enabled: true
license_header_check_enabled: true
api_breakage_check_enabled: false
license_header_check_project_name: "SwiftOpenAPIGenerator"
shell_check_enabled: true
unacceptable_language_check_enabled: true
yamllint_check_enabled: false

unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_8_enabled: false
linux_5_9_arguments_override: "--explicit-target-dependency-import-check error"
linux_5_10_arguments_override: "--explicit-target-dependency-import-check error"
linux_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error"
linux_nightly_main_enabled: false

Expand All @@ -34,7 +29,6 @@ jobs:
with:
name: "Integration test"
matrix_linux_command: "apt-get update -yq && apt-get install -yq jq && SWIFT_OPENAPI_GENERATOR_REPO_URL=file://${GITHUB_WORKSPACE} ./scripts/run-integration-test.sh"
matrix_linux_5_8_enabled: false
matrix_linux_nightly_main_enabled: false

compatibility-test:
Expand Down Expand Up @@ -62,10 +56,4 @@ jobs:
with:
name: "Example packages"
matrix_linux_command: "./scripts/test-examples.sh"
matrix_linux_5_8_enabled: false
matrix_linux_nightly_main_enabled: false

swift-6-language-mode:
name: Swift 6 Language Mode
uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main
if: false # Disabled for now.
32 changes: 0 additions & 32 deletions .github/workflows/scheduled.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .licenseignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ Examples/HelloWorldiOSClientAppExample/HelloWorldiOSClientApp/Assets.xcassets/*
Examples/HelloWorldiOSClientAppExample/HelloWorldiOSClientApp/Preview*
Examples/**/Generated*
**/Makefile
**/*.html
**/*.html
.editorconfig
7 changes: 5 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ let package = Package(

// General algorithms
.package(url: "https://github.com/apple/swift-algorithms", from: "1.2.0"),
.package(url: "https://github.com/apple/swift-collections", from: "1.1.4"),

// Read OpenAPI documents
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "3.1.2"),
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "3.3.0"),
.package(url: "https://github.com/jpsim/Yams", "4.0.0"..<"6.0.0"),

// CLI Tool
Expand All @@ -72,7 +73,9 @@ let package = Package(
.product(name: "OpenAPIKit", package: "OpenAPIKit"),
.product(name: "OpenAPIKit30", package: "OpenAPIKit"),
.product(name: "OpenAPIKitCompat", package: "OpenAPIKit"),
.product(name: "Algorithms", package: "swift-algorithms"), .product(name: "Yams", package: "Yams"),
.product(name: "Algorithms", package: "swift-algorithms"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Yams", package: "Yams"),
],
swiftSettings: swiftSettings
),
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ platforms, listed below.
| Generator plugin and CLI | ✅ 10.15+ || ✖️ | ✖️ | ✖️ | ✖️ |
| Generated code and runtime library | ✅ 10.15+ || ✅ 13+ | ✅ 13+ | ✅ 6+ | ✅ 1+ |

> [!NOTE]
> When using Visual Studio Code or other editors that rely on [SourceKit-LSP](https://github.com/swiftlang/sourcekit-lsp), the editor may not correctly recognize generated code within the same module. As a workaround, consider creating a separate target for code generation and then importing it into your main module. For more details, see the discussion in [swiftlang/sourcekit-lsp#665](https://github.com/swiftlang/sourcekit-lsp/issues/665#issuecomment-2093169169).
## Documentation and example projects

To get started, check out the [documentation][docs-generator], which contains
Expand Down
2 changes: 1 addition & 1 deletion Sources/_OpenAPIGeneratorCore/Diagnostics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ public struct StdErrPrintingDiagnosticCollector: DiagnosticCollector, Sendable {
/// Emits a diagnostic message to standard error.
///
/// - Parameter diagnostic: The diagnostic message to emit.
public func emit(_ diagnostic: Diagnostic) { stdErrHandle.write(diagnostic.description) }
public func emit(_ diagnostic: Diagnostic) { stdErrHandle.write(diagnostic.description + "\n") }
}

/// A no-op collector, silently ignores all diagnostics.
Expand Down
1 change: 1 addition & 0 deletions Sources/_OpenAPIGeneratorCore/Hooks/FilteredDocument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ private extension FilteredDocumentBuilder {
guard predicate(endpoint) else { continue }
if requiredEndpoints[path] == nil { requiredEndpoints[path] = Set() }
if requiredEndpoints[path]!.insert(endpoint.method).inserted {
for parameter in originalPathItem.parameters { try includeParameter(parameter) }
try includeComponentsReferencedBy(endpoint.operation)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1628,9 +1628,15 @@ extension KeywordKind {
}

extension Declaration {
/// Returns a new deprecated variant of the declaration if the provided `description` is not `nil`.
func deprecate(if description: DeprecationDescription?) -> Self {
if let description { return .deprecated(description, self) }
return self
}

/// Returns a new deprecated variant of the declaration if `shouldDeprecate` is true.
func deprecate(if shouldDeprecate: Bool) -> Self {
if shouldDeprecate { return .deprecated(.init(), self) }
func deprecate(if shouldDeprecate: Bool, description: @autoclosure () -> DeprecationDescription = .init()) -> Self {
if shouldDeprecate { return .deprecated(description(), self) }
return self
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/_OpenAPIGeneratorCore/Parser/YamsParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ public struct YamsParser: ParserProtocol {
do {
let document: OpenAPIKit.OpenAPI.Document
switch openAPIVersion {
case "3.0.0", "3.0.1", "3.0.2", "3.0.3":
case "3.0.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4":
let openAPI30Document = try decoder.decode(OpenAPIKit30.OpenAPI.Document.self, from: input.contents)
document = openAPI30Document.convert(to: .v3_1_0)
case "3.1.0": document = try decoder.decode(OpenAPIKit.OpenAPI.Document.self, from: input.contents)
case "3.1.0", "3.1.1": document = try decoder.decode(OpenAPIKit.OpenAPI.Document.self, from: input.contents)
default:
throw Diagnostic.openAPIVersionError(
versionString: "openapi: \(openAPIVersion)",
Expand Down Expand Up @@ -139,7 +139,7 @@ extension Diagnostic {
static func openAPIMissingVersionError(location: Location) -> Diagnostic {
error(
message:
"No openapi key found, please provide a valid OpenAPI document with OpenAPI versions in the 3.0.x or 3.1.x sets.",
"No key named openapi found. Please provide a valid OpenAPI document with OpenAPI versions in the 3.0.x or 3.1.x sets.",
location: location
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftOpenAPIGenerator open source project
//
// Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import OpenAPIKit
import OrderedCollections

/// The backing type of a raw enum.
enum RawEnumBackingType {

/// Backed by a `String`.
case string

/// Backed by an `Int`.
case integer
}

/// The extracted enum value's identifier.
private enum EnumCaseID: Hashable, CustomStringConvertible {

/// A string value.
case string(String)

/// An integer value.
case integer(Int)

var description: String {
switch self {
case .string(let value): return "\"\(value)\""
case .integer(let value): return String(value)
}
}
}

/// A wrapper for the metadata about the raw enum case.
private struct EnumCase {

/// Used for checking uniqueness.
var id: EnumCaseID

/// The raw Swift-safe name for the case.
var caseName: String

/// The literal value of the enum case.
var literal: LiteralDescription
}

extension EnumCase: Equatable { static func == (lhs: EnumCase, rhs: EnumCase) -> Bool { lhs.id == rhs.id } }

extension EnumCase: Hashable { func hash(into hasher: inout Hasher) { hasher.combine(id) } }

extension FileTranslator {

/// Returns a declaration of the specified raw value-based enum schema.
/// - Parameters:
/// - backingType: The backing type of the enum.
/// - typeName: The name of the type to give to the declared enum.
/// - userDescription: A user-specified description from the OpenAPI
/// document.
/// - isNullable: Whether the enum schema is nullable.
/// - allowedValues: The enumerated allowed values.
/// - Throws: A `GenericError` if a disallowed value is encountered.
/// - Returns: A declaration of the specified raw value-based enum schema.
func translateRawEnum(
backingType: RawEnumBackingType,
typeName: TypeName,
userDescription: String?,
isNullable: Bool,
allowedValues: [AnyCodable]
) throws -> Declaration {
var cases: OrderedSet<EnumCase> = []
func addIfUnique(id: EnumCaseID, caseName: String) throws {
let literal: LiteralDescription
switch id {
case .string(let string): literal = .string(string)
case .integer(let int): literal = .int(int)
}
guard cases.append(.init(id: id, caseName: caseName, literal: literal)).inserted else {
try diagnostics.emit(
.warning(
message: "Duplicate enum value, skipping",
context: ["id": "\(id)", "foundIn": typeName.description]
)
)
return
}
}
for anyValue in allowedValues.map(\.value) {
switch backingType {
case .string:
// In nullable enum schemas, empty strings are parsed as Void.
// This is unlikely to be fixed, so handling that case here.
// https://github.com/apple/swift-openapi-generator/issues/118
if isNullable && anyValue is Void {
try addIfUnique(id: .string(""), caseName: context.asSwiftSafeName(""))
} else {
guard let rawValue = anyValue as? String else {
throw GenericError(message: "Disallowed value for a string enum '\(typeName)': \(anyValue)")
}
let caseName = context.asSwiftSafeName(rawValue)
try addIfUnique(id: .string(rawValue), caseName: caseName)
}
case .integer:
let rawValue: Int
if let intRawValue = anyValue as? Int {
rawValue = intRawValue
} else if let stringRawValue = anyValue as? String, let intRawValue = Int(stringRawValue) {
rawValue = intRawValue
} else {
throw GenericError(message: "Disallowed value for an integer enum '\(typeName)': \(anyValue)")
}
let caseName = rawValue < 0 ? "_n\(abs(rawValue))" : "_\(rawValue)"
try addIfUnique(id: .integer(rawValue), caseName: caseName)
}
}
let baseConformance: String
switch backingType {
case .string: baseConformance = Constants.RawEnum.baseConformanceString
case .integer: baseConformance = Constants.RawEnum.baseConformanceInteger
}
let conformances = [baseConformance] + Constants.RawEnum.conformances
return try translateRawRepresentableEnum(
typeName: typeName,
conformances: conformances,
userDescription: userDescription,
cases: cases.map { ($0.caseName, $0.literal) },
unknownCaseName: nil,
unknownCaseDescription: nil
)
}
}
Loading

0 comments on commit 60f1c75

Please sign in to comment.