diff --git a/Plugins/OpenAPIGeneratorCommand/plugin.swift b/Plugins/OpenAPIGeneratorCommand/plugin.swift index fc1c4dea6..9b3d6524d 100644 --- a/Plugins/OpenAPIGeneratorCommand/plugin.swift +++ b/Plugins/OpenAPIGeneratorCommand/plugin.swift @@ -65,27 +65,39 @@ extension SwiftOpenAPIGeneratorPlugin: CommandPlugin { var hadASuccessfulRun = false for target in targets { - print("Considering target '\(target.name)':") + log("Considering target '\(target.name)':") guard let swiftTarget = target as? SwiftSourceModuleTarget else { - print("- Not a swift source module. Can't generate OpenAPI code.") + log("- Not a swift source module. Can't generate OpenAPI code.") continue } do { - print("- Trying OpenAPI code generation.") + log("- Trying OpenAPI code generation.") try runCommand( targetWorkingDirectory: target.directory, tool: context.tool, sourceFiles: swiftTarget.sourceFiles, targetName: target.name ) - print("- ✅ OpenAPI code generation for target '\(target.name)' successfully completed.") + log("- ✅ OpenAPI code generation for target '\(target.name)' successfully completed.") hadASuccessfulRun = true } catch let error as PluginError { + if targetNameArguments.isEmpty, case .fileErrors(let errors) = error, + Set(errors.map(\.fileKind)) == Set(FileError.Kind.allCases), + errors.map(\.issue).allSatisfy({ $0 == FileError.Issue.noFilesFound }) + { + // The command plugin was run with no --target argument so its looping over all targets. + // If a target does not have any of the required files, this should only be considered an error + // if the plugin is being explicitly run on a target, either using the build plugin, or using the + // command plugin with a --target argument. + log("- Skipping because target isn't configured for OpenAPI code generation.") + continue + } + if error.isMisconfigurationError { - print("- Stopping because target isn't configured for OpenAPI code generation.") + log("- Stopping because target is misconfigured for OpenAPI code generation.") throw error } else { - print("- OpenAPI code generation failed with error.") + log("- OpenAPI code generation failed with error.") throw error } } @@ -94,3 +106,7 @@ extension SwiftOpenAPIGeneratorPlugin: CommandPlugin { guard hadASuccessfulRun else { throw PluginError.noTargetsWithExpectedFiles(targetNames: targets.map(\.name)) } } } + +private func log(_ message: @autoclosure () -> String) { + FileHandle.standardError.write(Data(message().appending("\n").utf8)) +} diff --git a/Plugins/PluginsShared/PluginError.swift b/Plugins/PluginsShared/PluginError.swift index a0a411d8e..6341f9af3 100644 --- a/Plugins/PluginsShared/PluginError.swift +++ b/Plugins/PluginsShared/PluginError.swift @@ -14,7 +14,7 @@ import PackagePlugin import Foundation -enum PluginError: Swift.Error, CustomStringConvertible, LocalizedError { +enum PluginError: Swift.Error, Equatable, CustomStringConvertible, LocalizedError { case incompatibleTarget(name: String) case generatorFailure(targetName: String) case noTargetsWithExpectedFiles(targetNames: [String]) @@ -55,10 +55,10 @@ enum PluginError: Swift.Error, CustomStringConvertible, LocalizedError { } } -struct FileError: Swift.Error, CustomStringConvertible, LocalizedError { +struct FileError: Swift.Error, Equatable, CustomStringConvertible, LocalizedError { /// The kind of the file. - enum Kind: CaseIterable { + enum Kind: Equatable, CaseIterable { /// Config file. case config /// OpenAPI document file. @@ -73,7 +73,7 @@ struct FileError: Swift.Error, CustomStringConvertible, LocalizedError { } /// Encountered issue. - enum Issue { + enum Issue: Equatable { /// File wasn't found. case noFilesFound /// More than 1 file found. diff --git a/scripts/run-integration-test.sh b/scripts/run-integration-test.sh index 613785881..f4196cfab 100755 --- a/scripts/run-integration-test.sh +++ b/scripts/run-integration-test.sh @@ -45,4 +45,8 @@ swift package --package-path "${INTEGRATION_TEST_PACKAGE_PATH}" \ log "Building integration test package: ${INTEGRATION_TEST_PACKAGE_PATH}" swift build --package-path "${INTEGRATION_TEST_PACKAGE_PATH}" +log "Running command plugin on integration test package: ${INTEGRATION_TEST_PACKAGE_PATH}" +swift package --package-path "${INTEGRATION_TEST_PACKAGE_PATH}" \ + --allow-writing-to-package-directory generate-code-from-openapi + log "✅ Successfully built integration test package."