From 078546c2d528be5142dd0a5b29d52835c1feffa6 Mon Sep 17 00:00:00 2001 From: Jim Schubert Date: Thu, 30 Jan 2020 22:52:13 -0500 Subject: [PATCH] [gradle] Add recommendations to validate task --- .../README.adoc | 6 +++ .../gradle/wrapper/gradle-wrapper.properties | 5 ++- .../samples/local-spec/build.gradle | 1 + .../gradle/plugin/OpenApiGeneratorPlugin.kt | 1 + .../OpenApiGeneratorValidateExtension.kt | 14 +++++++ .../gradle/plugin/tasks/ValidateTask.kt | 40 ++++++++++++++++++- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/modules/openapi-generator-gradle-plugin/README.adoc b/modules/openapi-generator-gradle-plugin/README.adoc index e107d0956f91..e5ff27cf32d3 100644 --- a/modules/openapi-generator-gradle-plugin/README.adoc +++ b/modules/openapi-generator-gradle-plugin/README.adoc @@ -377,6 +377,11 @@ openApiGenerate { |None |The input specification to validate. Supports all formats supported by the Parser. +|recommend +|Boolean +|true +|Whether or not to offer recommendations related to the validated specification document. + |=== === openApiMeta @@ -521,6 +526,7 @@ BUILD SUCCESSFUL in 0s ---- openApiValidate { inputSpec = "/src/openapi-generator/modules/openapi-generator/src/test/resources/3_0/petstore.yaml" + recommend = true } ---- diff --git a/modules/openapi-generator-gradle-plugin/gradle/wrapper/gradle-wrapper.properties b/modules/openapi-generator-gradle-plugin/gradle/wrapper/gradle-wrapper.properties index 44e7c4d1d7bb..5b9bdfe705b8 100644 --- a/modules/openapi-generator-gradle-plugin/gradle/wrapper/gradle-wrapper.properties +++ b/modules/openapi-generator-gradle-plugin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Jan 30 22:14:34 EST 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle b/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle index c8c7e25dc0bb..22a21f46c6ff 100644 --- a/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle +++ b/modules/openapi-generator-gradle-plugin/samples/local-spec/build.gradle @@ -28,6 +28,7 @@ openApiMeta { openApiValidate { inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString() + recommend = true } // Builds a Kotlin client by default. diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt index f69052bc6748..82105777a664 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt @@ -84,6 +84,7 @@ class OpenApiGeneratorPlugin : Plugin { description = "Validates an Open API 2.0 or 3.x specification document." inputSpec.set(validate.inputSpec) + recommend.set(validate.recommend) } create("openApiGenerate", GenerateTask::class.java) { diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorValidateExtension.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorValidateExtension.kt index cbf525bd7cba..72b9fb6bf2af 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorValidateExtension.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorValidateExtension.kt @@ -29,4 +29,18 @@ open class OpenApiGeneratorValidateExtension(project: Project) { * The input specification to validate. Supports all formats supported by the Parser. */ val inputSpec = project.objects.property() + + /** + * Whether or not to offer recommendations related to the validated specification document. + */ + val recommend = project.objects.property() + + init { + applyDefaults() + } + + @Suppress("MemberVisibilityCanBePrivate") + fun applyDefaults(){ + recommend.set(true) + } } \ No newline at end of file diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/ValidateTask.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/ValidateTask.kt index 6e5283163ba2..81e8d2ee9847 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/ValidateTask.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/ValidateTask.kt @@ -14,6 +14,8 @@ * limitations under the License. */ +@file:Suppress("UnstableApiUsage") + package org.openapitools.generator.gradle.plugin.tasks import io.swagger.parser.OpenAPIParser @@ -22,9 +24,12 @@ import org.gradle.api.GradleException import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option +import org.gradle.api.logging.Logging import org.gradle.internal.logging.text.StyledTextOutput import org.gradle.internal.logging.text.StyledTextOutputFactory import org.gradle.kotlin.dsl.property +import org.openapitools.codegen.validations.oas.OpenApiEvaluator +import org.openapitools.codegen.validations.oas.RuleConfiguration /** * A generator which validates an Open API spec. This task outputs a list of validation issues and errors. @@ -46,6 +51,9 @@ open class ValidateTask : DefaultTask() { @get:Internal var inputSpec = project.objects.property() + @get:Internal + var recommend = project.objects.property() + @Suppress("unused") @get:Internal @set:Option(option = "input", description = "The input specification.") @@ -57,13 +65,35 @@ open class ValidateTask : DefaultTask() { @Suppress("unused") @TaskAction fun doWork() { + val logger = Logging.getLogger(javaClass) + val spec = inputSpec.get() + val recommendations = recommend.get() + logger.quiet("Validating spec $spec") val result = OpenAPIParser().readLocation(spec, null, null) val messages = result.messages.toSet() val out = services.get(StyledTextOutputFactory::class.java).create("openapi") - if (messages.isNotEmpty()) { + + val ruleConfiguration = RuleConfiguration() + ruleConfiguration.isEnableRecommendations = recommendations + + val evaluator = OpenApiEvaluator(ruleConfiguration) + val validationResult = evaluator.validate(result.openAPI) + + if (validationResult.warnings.isNotEmpty()) { + out.withStyle(StyledTextOutput.Style.Info) + out.println("\nSpec has issues or recommendations.\nIssues:\n") + + validationResult.warnings.forEach { + out.withStyle(StyledTextOutput.Style.Info) + out.println("\t${it.message}\n") + logger.debug("WARNING: ${it.message}|${it.details}") + } + } + + if (messages.isNotEmpty() || validationResult.errors.isNotEmpty()) { out.withStyle(StyledTextOutput.Style.Error) out.println("\nSpec is invalid.\nIssues:\n") @@ -71,11 +101,19 @@ open class ValidateTask : DefaultTask() { messages.forEach { out.withStyle(StyledTextOutput.Style.Error) out.println("\t$it\n") + logger.debug("ERROR: $it") + } + + validationResult.errors.forEach { + out.withStyle(StyledTextOutput.Style.Error) + out.println("\t${it.message}\n") + logger.debug("ERROR: ${it.message}|${it.details}") } throw GradleException("Validation failed.") } else { out.withStyle(StyledTextOutput.Style.Success) + logger.debug("No error validations from swagger-parser or internal validations.") out.println("Spec is valid.") } }