Skip to content

Commit f4f6f9b

Browse files
Command plugin should skip irrelevant targets when run without --target argument (#798)
### Motivation In #795 we adjusted the logic of the command plugin because errors were not propagating properly. As a result, we regressed behaviour when the command plugin was run without any `--target` argument. In this mode, the plugin runs on all targets. When it detects a misconfigured target it errors, as it should. However, the classification of misconfigured target included targets that were not intended for code generation at all, resulting in errors running the command plugin on packages with others targets. ### Modifications - Add command plugin generation step to integration test - If the command plugin is running without a `--target` argument and cannot find _any_ of the required files, skip that target. ### Result - Manual code generation with the command plugin fixed for packages with other targets. - Fixes #797. ### Test Plan This PR includes two commits. The first adds a step to the integration test, which runs the command plugin on the integration test package. This will fail in CI. Then the second commit will provide the fix, which should pass in CI. The commits will then be squash merged.
1 parent f876c5a commit f4f6f9b

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

Plugins/OpenAPIGeneratorCommand/plugin.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,27 +65,39 @@ extension SwiftOpenAPIGeneratorPlugin: CommandPlugin {
6565
var hadASuccessfulRun = false
6666

6767
for target in targets {
68-
print("Considering target '\(target.name)':")
68+
log("Considering target '\(target.name)':")
6969
guard let swiftTarget = target as? SwiftSourceModuleTarget else {
70-
print("- Not a swift source module. Can't generate OpenAPI code.")
70+
log("- Not a swift source module. Can't generate OpenAPI code.")
7171
continue
7272
}
7373
do {
74-
print("- Trying OpenAPI code generation.")
74+
log("- Trying OpenAPI code generation.")
7575
try runCommand(
7676
targetWorkingDirectory: target.directory,
7777
tool: context.tool,
7878
sourceFiles: swiftTarget.sourceFiles,
7979
targetName: target.name
8080
)
81-
print("- ✅ OpenAPI code generation for target '\(target.name)' successfully completed.")
81+
log("- ✅ OpenAPI code generation for target '\(target.name)' successfully completed.")
8282
hadASuccessfulRun = true
8383
} catch let error as PluginError {
84+
if targetNameArguments.isEmpty, case .fileErrors(let errors) = error,
85+
Set(errors.map(\.fileKind)) == Set(FileError.Kind.allCases),
86+
errors.map(\.issue).allSatisfy({ $0 == FileError.Issue.noFilesFound })
87+
{
88+
// The command plugin was run with no --target argument so its looping over all targets.
89+
// If a target does not have any of the required files, this should only be considered an error
90+
// if the plugin is being explicitly run on a target, either using the build plugin, or using the
91+
// command plugin with a --target argument.
92+
log("- Skipping because target isn't configured for OpenAPI code generation.")
93+
continue
94+
}
95+
8496
if error.isMisconfigurationError {
85-
print("- Stopping because target isn't configured for OpenAPI code generation.")
97+
log("- Stopping because target is misconfigured for OpenAPI code generation.")
8698
throw error
8799
} else {
88-
print("- OpenAPI code generation failed with error.")
100+
log("- OpenAPI code generation failed with error.")
89101
throw error
90102
}
91103
}
@@ -94,3 +106,7 @@ extension SwiftOpenAPIGeneratorPlugin: CommandPlugin {
94106
guard hadASuccessfulRun else { throw PluginError.noTargetsWithExpectedFiles(targetNames: targets.map(\.name)) }
95107
}
96108
}
109+
110+
private func log(_ message: @autoclosure () -> String) {
111+
FileHandle.standardError.write(Data(message().appending("\n").utf8))
112+
}

Plugins/PluginsShared/PluginError.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import PackagePlugin
1515
import Foundation
1616

17-
enum PluginError: Swift.Error, CustomStringConvertible, LocalizedError {
17+
enum PluginError: Swift.Error, Equatable, CustomStringConvertible, LocalizedError {
1818
case incompatibleTarget(name: String)
1919
case generatorFailure(targetName: String)
2020
case noTargetsWithExpectedFiles(targetNames: [String])
@@ -55,10 +55,10 @@ enum PluginError: Swift.Error, CustomStringConvertible, LocalizedError {
5555
}
5656
}
5757

58-
struct FileError: Swift.Error, CustomStringConvertible, LocalizedError {
58+
struct FileError: Swift.Error, Equatable, CustomStringConvertible, LocalizedError {
5959

6060
/// The kind of the file.
61-
enum Kind: CaseIterable {
61+
enum Kind: Equatable, CaseIterable {
6262
/// Config file.
6363
case config
6464
/// OpenAPI document file.
@@ -73,7 +73,7 @@ struct FileError: Swift.Error, CustomStringConvertible, LocalizedError {
7373
}
7474

7575
/// Encountered issue.
76-
enum Issue {
76+
enum Issue: Equatable {
7777
/// File wasn't found.
7878
case noFilesFound
7979
/// More than 1 file found.

scripts/run-integration-test.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,8 @@ swift package --package-path "${INTEGRATION_TEST_PACKAGE_PATH}" \
4545
log "Building integration test package: ${INTEGRATION_TEST_PACKAGE_PATH}"
4646
swift build --package-path "${INTEGRATION_TEST_PACKAGE_PATH}"
4747

48+
log "Running command plugin on integration test package: ${INTEGRATION_TEST_PACKAGE_PATH}"
49+
swift package --package-path "${INTEGRATION_TEST_PACKAGE_PATH}" \
50+
--allow-writing-to-package-directory generate-code-from-openapi
51+
4852
log "✅ Successfully built integration test package."

0 commit comments

Comments
 (0)