Skip to content
1 change: 0 additions & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ jobs:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_10_arguments_override: "--explicit-target-dependency-import-check error"
linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
linux_6_1_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
linux_6_2_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
Expand Down
3 changes: 2 additions & 1 deletion Package@swift-5.10.swift → Package@swift-6.0.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.10
// swift-tools-version:6.0
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftOpenAPIGenerator open source project
Expand All @@ -20,6 +20,7 @@ var swiftSettings: [SwiftSetting] = [
// https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md
// Require `any` for existential types.
.enableUpcomingFeature("ExistentialAny"), .enableExperimentalFeature("StrictConcurrency=complete"),
.swiftLanguageMode(.v5),
]

let package = Package(
Expand Down
10 changes: 5 additions & 5 deletions Plugins/OpenAPIGenerator/plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation

@main struct SwiftOpenAPIGeneratorPlugin {
func createBuildCommands(
pluginWorkDirectory: Path,
pluginWorkDirectory: URL,
tool: (String) throws -> PluginContext.Tool,
sourceFiles: FileList,
targetName: String
Expand All @@ -29,11 +29,11 @@ import Foundation
pluginSource: .build
)

let outputFiles: [Path] = GeneratorMode.allCases.map { inputs.genSourcesDir.appending($0.outputFileName) }
let outputFiles = GeneratorMode.allCases.map { inputs.genSourcesDir.appending(component: $0.outputFileName) }
return [
.buildCommand(
displayName: "Running swift-openapi-generator",
executable: inputs.tool.path,
executable: inputs.tool.url,
arguments: inputs.arguments,
environment: [:],
inputFiles: [inputs.config, inputs.doc],
Expand All @@ -49,7 +49,7 @@ extension SwiftOpenAPIGeneratorPlugin: BuildToolPlugin {
throw PluginError.incompatibleTarget(name: target.name)
}
return try createBuildCommands(
pluginWorkDirectory: context.pluginWorkDirectory,
pluginWorkDirectory: context.pluginWorkDirectoryURL,
tool: context.tool,
sourceFiles: swiftTarget.sourceFiles,
targetName: target.name
Expand All @@ -63,7 +63,7 @@ import XcodeProjectPlugin
extension SwiftOpenAPIGeneratorPlugin: XcodeBuildToolPlugin {
func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] {
try createBuildCommands(
pluginWorkDirectory: context.pluginWorkDirectory,
pluginWorkDirectory: context.pluginWorkDirectoryURL,
tool: context.tool,
sourceFiles: target.inputFiles,
targetName: target.displayName
Expand Down
11 changes: 5 additions & 6 deletions Plugins/OpenAPIGeneratorCommand/plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation

@main struct SwiftOpenAPIGeneratorPlugin {
func runCommand(
targetWorkingDirectory: Path,
targetWorkingDirectory: URL,
tool: (String) throws -> PluginContext.Tool,
sourceFiles: FileList,
targetName: String
Expand All @@ -29,9 +29,8 @@ import Foundation
pluginSource: .command
)

let toolUrl = URL(fileURLWithPath: inputs.tool.path.string)
let process = Process()
process.executableURL = toolUrl
process.executableURL = inputs.tool.url
process.arguments = inputs.arguments
process.environment = [:]
try process.run()
Expand Down Expand Up @@ -66,16 +65,16 @@ extension SwiftOpenAPIGeneratorPlugin: CommandPlugin {

for target in targets {
log("Considering target '\(target.name)':")
guard let swiftTarget = target as? SwiftSourceModuleTarget else {
guard let target = target as? SwiftSourceModuleTarget else {
log("- Not a swift source module. Can't generate OpenAPI code.")
continue
}
do {
log("- Trying OpenAPI code generation.")
try runCommand(
targetWorkingDirectory: target.directory,
targetWorkingDirectory: target.directoryURL,
tool: context.tool,
sourceFiles: swiftTarget.sourceFiles,
sourceFiles: target.sourceFiles,
targetName: target.name
)
log("- ✅ OpenAPI code generation for target '\(target.name)' successfully completed.")
Expand Down
8 changes: 3 additions & 5 deletions Plugins/PluginsShared/PluginError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ struct FileError: Swift.Error, Equatable, CustomStringConvertible, LocalizedErro
/// File wasn't found.
case noFilesFound
/// More than 1 file found.
case multipleFilesFound(files: [String])

static func multipleFilesFound(files: [Path]) -> Self { .multipleFilesFound(files: files.map(\.description)) }
case multipleFilesFound(files: [URL])

/// The error is definitely due to misconfiguration of a target.
var isMisconfigurationError: Bool {
Expand All @@ -103,7 +101,7 @@ struct FileError: Swift.Error, Equatable, CustomStringConvertible, LocalizedErro
"No config file found in the target named '\(targetName)'. Add a file called 'openapi-generator-config.yaml' or 'openapi-generator-config.yml' to the target's source directory. See documentation for details."
case .multipleFilesFound(let files):
return
"Multiple config files found in the target named '\(targetName)', but exactly one is expected. Found \(files.map(\.description).joined(separator: " "))."
"Multiple config files found in the target named '\(targetName)', but exactly one is expected. Found \(files.map { $0.path() }.joined(separator: " "))."
}
case .document:
switch issue {
Expand All @@ -112,7 +110,7 @@ struct FileError: Swift.Error, Equatable, CustomStringConvertible, LocalizedErro
"No OpenAPI document found in the target named '\(targetName)'. Add a file called 'openapi.yaml', 'openapi.yml' or 'openapi.json' (can also be a symlink) to the target's source directory. See documentation for details."
case .multipleFilesFound(let files):
return
"Multiple OpenAPI documents found in the target named '\(targetName)', but exactly one is expected. Found \(files.map(\.description).joined(separator: " "))."
"Multiple OpenAPI documents found in the target named '\(targetName)', but exactly one is expected. Found \(files.map { $0.path() }.joined(separator: " "))."
}
}
}
Expand Down
51 changes: 17 additions & 34 deletions Plugins/PluginsShared/PluginUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
//
//===----------------------------------------------------------------------===//
import PackagePlugin
#if canImport(FoundationEssentials)
import struct FoundationEssentials.URL
#else
import struct Foundation.URL
#endif

enum PluginUtils {
private static var supportedConfigFiles: Set<String> {
Expand All @@ -21,27 +26,27 @@ enum PluginUtils {

/// Validated values to run a plugin with.
struct ValidatedInputs {
let doc: Path
let config: Path
let genSourcesDir: Path
let doc: URL
let config: URL
let genSourcesDir: URL
let arguments: [String]
let tool: PluginContext.Tool
}

/// Validates the inputs and returns the necessary values to run a plugin.
static func validateInputs(
workingDirectory: Path,
workingDirectory: URL,
tool: (String) throws -> PluginContext.Tool,
sourceFiles: FileList,
targetName: String,
pluginSource: PluginSource
) throws -> ValidatedInputs {
let (config, doc) = try findFiles(inputFiles: sourceFiles, targetName: targetName)
let genSourcesDir = workingDirectory.appending("GeneratedSources")
let genSourcesDir = workingDirectory.appending(component: "GeneratedSources")

let arguments = [
"generate", "\(doc)", "--config", "\(config)", "--output-directory", "\(genSourcesDir)", "--plugin-source",
"\(pluginSource.rawValue)",
"generate", doc.path(), "--config", config.path(), "--output-directory", genSourcesDir.path(),
"--plugin-source", "\(pluginSource.rawValue)",
]

let tool = try tool("swift-openapi-generator")
Expand All @@ -51,7 +56,7 @@ enum PluginUtils {

/// Finds the OpenAPI config and document files or throws an error including both possible
/// previous errors from the process of finding the config and document files.
private static func findFiles(inputFiles: FileList, targetName: String) throws -> (config: Path, doc: Path) {
private static func findFiles(inputFiles: FileList, targetName: String) throws -> (config: URL, doc: URL) {
let config = findConfig(inputFiles: inputFiles, targetName: targetName)
let doc = findDocument(inputFiles: inputFiles, targetName: targetName)
switch (config, doc) {
Expand All @@ -63,9 +68,8 @@ enum PluginUtils {
}

/// Find the config file.
private static func findConfig(inputFiles: FileList, targetName: String) -> Result<Path, FileError> {
let matchedConfigs = inputFiles.filter { supportedConfigFiles.contains($0.path.lastComponent_fixed) }
.map(\.path)
private static func findConfig(inputFiles: FileList, targetName: String) -> Result<URL, FileError> {
let matchedConfigs = inputFiles.map(\.url).filter { supportedConfigFiles.contains($0.lastPathComponent) }
guard matchedConfigs.count > 0 else {
return .failure(FileError(targetName: targetName, fileKind: .config, issue: .noFilesFound))
}
Expand All @@ -78,8 +82,8 @@ enum PluginUtils {
}

/// Find the document file.
private static func findDocument(inputFiles: FileList, targetName: String) -> Result<Path, FileError> {
let matchedDocs = inputFiles.filter { supportedDocFiles.contains($0.path.lastComponent_fixed) }.map(\.path)
private static func findDocument(inputFiles: FileList, targetName: String) -> Result<URL, FileError> {
let matchedDocs = inputFiles.map(\.url).filter { supportedDocFiles.contains($0.lastPathComponent) }
guard matchedDocs.count > 0 else {
return .failure(FileError(targetName: targetName, fileKind: .document, issue: .noFilesFound))
}
Expand All @@ -98,24 +102,3 @@ extension Array where Element == String {
return "\(self.dropLast().joined(separator: separator))\(lastSeparator)\(self.last!)"
}
}

extension PackagePlugin.Path {
/// Workaround for the ``lastComponent`` property being broken on Windows
/// due to hardcoded assumptions about the path separator being forward slash.
@available(_PackageDescription, deprecated: 6.0, message: "Use `URL` type instead of `Path`.") public
var lastComponent_fixed: String
{
#if !os(Windows)
lastComponent
#else
// Find the last path separator.
guard let idx = string.lastIndex(where: { $0 == "/" || $0 == "\\" }) else {
// No path separators, so the basename is the whole string.
return self.string
}
// Otherwise, it's the string from (but not including) the last path
// separator.
return String(self.string.suffix(from: self.string.index(after: idx)))
#endif
}
}
8 changes: 6 additions & 2 deletions Sources/swift-openapi-generator/GenerateOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ func handleFileOperation<T>(at url: URL, fileDescription: String = "Configuratio
let isCocoaFileNotFound = nsError.domain == NSCocoaErrorDomain && nsError.code == 260
if isPOSIXFileNotFound || isCocoaFileNotFound {
throw ValidationError(
"\(fileDescription) not found at path: \(url.path). Please ensure the file exists and the path is correct."
"\(fileDescription) not found at path: \(url.path()). Please ensure the file exists and the path is correct."
)
}
}
throw ValidationError("Failed to load \(fileDescription.lowercased()) at path \(url.path), error: \(error)")
throw ValidationError("Failed to load \(fileDescription.lowercased()) at path \(url.path()), error: \(error)")
}
}

Expand Down Expand Up @@ -186,3 +186,7 @@ extension _GenerateOptions {
return userConfig
}
}

#if swift(<6.1)
extension URL { func path() -> String { self.path } }
Comment thread
czechboy0 marked this conversation as resolved.
Outdated
#endif