This is an automated email from the ASF dual-hosted git repository.

snazy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new a0e31b058 Fix bunch of OpenAPI generation issues (#2005)
a0e31b058 is described below

commit a0e31b0584437602f30a97ed5fc110c50802d9c1
Author: Robert Stupp <sn...@snazy.de>
AuthorDate: Wed Jul 9 13:07:56 2025 +0200

    Fix bunch of OpenAPI generation issues (#2005)
    
    The current way how OpenAPI Java code is generated suffers from a bunch of 
issues:
    * Changes to any of the source spec files requires a Gradle `clean`, 
otherwise old generated Java source will remain - i.e. "no longer" existing 
sources are not removed. This is addressed by adding an additional action to 
`GenerateTask`.
    * The output of `GenerateTask` was explicitly not cached, this is removed, 
so the output is cached.
    * Add explicit inputs to `GenerateTask` to the whole templates and spec 
folders.
---
 api/iceberg-service/build.gradle.kts               | 35 +++++++++++++++-------
 api/management-model/build.gradle.kts              | 33 ++++++++++++++------
 api/management-service/build.gradle.kts            | 33 ++++++++++++++------
 api/polaris-catalog-service/build.gradle.kts       | 35 +++++++++++++++-------
 .../src/main/kotlin/polaris-java.gradle.kts        |  2 +-
 5 files changed, 97 insertions(+), 41 deletions(-)

diff --git a/api/iceberg-service/build.gradle.kts 
b/api/iceberg-service/build.gradle.kts
index 3ae10f821..44256e0d6 100644
--- a/api/iceberg-service/build.gradle.kts
+++ b/api/iceberg-service/build.gradle.kts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
+
 plugins {
   alias(libs.plugins.openapi.generator)
   id("polaris-client")
@@ -49,14 +51,25 @@ dependencies {
   compileOnly(libs.microprofile.fault.tolerance.api)
 }
 
+val rootDir = rootProject.layout.projectDirectory
+val specsDir = rootDir.dir("spec")
+val templatesDir = rootDir.dir("server-templates")
+// Use a different directory than 'generated/', because OpenAPI generator's 
`GenerateTask` adds the
+// whole directory to its task output, but 'generated/' is not exclusive to 
that task and in turn
+// breaks Gradle's caching.
+val generatedDir = project.layout.buildDirectory.dir("generated-openapi")
+val generatedOpenApiSrcDir = 
project.layout.buildDirectory.dir("generated-openapi/src/main/java")
+
 openApiGenerate {
-  inputSpec = "$rootDir/spec/polaris-catalog-service.yaml"
+  // The OpenAPI generator does NOT resolve relative paths correctly against 
the Gradle project
+  // directory
+  inputSpec = specsDir.file("polaris-catalog-service.yaml").asFile.absolutePath
   generatorName = "jaxrs-resteasy"
-  outputDir = "$projectDir/build/generated"
+  outputDir = generatedDir.get().asFile.absolutePath
   apiPackage = "org.apache.polaris.service.catalog.api"
-  ignoreFileOverride = "$rootDir/.openapi-generator-ignore"
+  ignoreFileOverride = 
rootDir.file(".openapi-generator-ignore").asFile.absolutePath
   removeOperationIdPrefix = true
-  templateDir = "$rootDir/server-templates"
+  templateDir = templatesDir.asFile.absolutePath
   globalProperties.put("apis", "CatalogApi,ConfigurationApi,OAuth2Api")
   globalProperties.put("models", "false")
   globalProperties.put("apiDocs", "false")
@@ -109,16 +122,16 @@ openApiGenerate {
     )
 }
 
-listOf("sourcesJar", "compileJava").forEach { task ->
+listOf("sourcesJar", "compileJava", "processResources").forEach { task ->
   tasks.named(task) { dependsOn("openApiGenerate") }
 }
 
-sourceSets {
-  main { java { 
srcDir(project.layout.buildDirectory.dir("generated/src/main/java")) } }
+sourceSets { main { java { srcDir(generatedOpenApiSrcDir) } } }
+
+tasks.named<GenerateTask>("openApiGenerate") {
+  inputs.dir(templatesDir)
+  inputs.dir(specsDir)
+  actions.addFirst { delete { delete(generatedDir) } }
 }
 
 tasks.named("javadoc") { dependsOn("jandex") }
-
-tasks.named("processResources") { dependsOn("openApiGenerate") }
-
-tasks.named("openApiGenerate") { outputs.cacheIf { false } }
diff --git a/api/management-model/build.gradle.kts 
b/api/management-model/build.gradle.kts
index 8292711c4..962ec1671 100644
--- a/api/management-model/build.gradle.kts
+++ b/api/management-model/build.gradle.kts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
+
 plugins {
   alias(libs.plugins.openapi.generator)
   id("polaris-client")
@@ -36,14 +38,25 @@ dependencies {
   testImplementation("com.fasterxml.jackson.core:jackson-databind")
 }
 
+val rootDir = rootProject.layout.projectDirectory
+val specsDir = rootDir.dir("spec")
+val templatesDir = rootDir.dir("server-templates")
+// Use a different directory than 'generated/', because OpenAPI generator's 
`GenerateTask` adds the
+// whole directory to its task output, but 'generated/' is not exclusive to 
that task and in turn
+// breaks Gradle's caching.
+val generatedDir = project.layout.buildDirectory.dir("generated-openapi")
+val generatedOpenApiSrcDir = 
project.layout.buildDirectory.dir("generated-openapi/src/main/java")
+
 openApiGenerate {
-  inputSpec = "$rootDir/spec/polaris-management-service.yml"
+  // The OpenAPI generator does NOT resolve relative paths correctly against 
the Gradle project
+  // directory
+  inputSpec = 
specsDir.file("polaris-management-service.yml").asFile.absolutePath
   generatorName = "jaxrs-resteasy"
-  outputDir = "$projectDir/build/generated"
+  outputDir = generatedDir.get().asFile.absolutePath
   modelPackage = "org.apache.polaris.core.admin.model"
-  ignoreFileOverride = "$rootDir/.openapi-generator-ignore"
+  ignoreFileOverride = 
rootDir.file(".openapi-generator-ignore").asFile.absolutePath
   removeOperationIdPrefix = true
-  templateDir = "$rootDir/server-templates"
+  templateDir = templatesDir.asFile.absolutePath
   globalProperties.put("apis", "false")
   globalProperties.put("models", "")
   globalProperties.put("apiDocs", "false")
@@ -64,14 +77,16 @@ openApiGenerate {
   serverVariables = mapOf("basePath" to "api/v1")
 }
 
-listOf("sourcesJar", "compileJava").forEach { task ->
+listOf("sourcesJar", "compileJava", "processResources").forEach { task ->
   tasks.named(task) { dependsOn("openApiGenerate") }
 }
 
-sourceSets {
-  main { java { 
srcDir(project.layout.buildDirectory.dir("generated/src/main/java")) } }
+sourceSets { main { java { srcDir(generatedOpenApiSrcDir) } } }
+
+tasks.named<GenerateTask>("openApiGenerate") {
+  inputs.dir(templatesDir)
+  inputs.dir(specsDir)
+  actions.addFirst { delete { delete(generatedDir) } }
 }
 
 tasks.named("javadoc") { dependsOn("jandex") }
-
-tasks.named("processResources") { dependsOn("openApiGenerate") }
diff --git a/api/management-service/build.gradle.kts 
b/api/management-service/build.gradle.kts
index 7ebae4a15..31f493ac9 100644
--- a/api/management-service/build.gradle.kts
+++ b/api/management-service/build.gradle.kts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
+
 plugins {
   alias(libs.plugins.openapi.generator)
   id("polaris-client")
@@ -45,15 +47,26 @@ dependencies {
   implementation(libs.slf4j.api)
 }
 
+val rootDir = rootProject.layout.projectDirectory
+val specsDir = rootDir.dir("spec")
+val templatesDir = rootDir.dir("server-templates")
+// Use a different directory than 'generated/', because OpenAPI generator's 
`GenerateTask` adds the
+// whole directory to its task output, but 'generated/' is not exclusive to 
that task and in turn
+// breaks Gradle's caching.
+val generatedDir = project.layout.buildDirectory.dir("generated-openapi")
+val generatedOpenApiSrcDir = 
project.layout.buildDirectory.dir("generated-openapi/src/main/java")
+
 openApiGenerate {
-  inputSpec = "$rootDir/spec/polaris-management-service.yml"
+  // The OpenAPI generator does NOT resolve relative paths correctly against 
the Gradle project
+  // directory
+  inputSpec = 
specsDir.file("polaris-management-service.yml").asFile.absolutePath
   generatorName = "jaxrs-resteasy"
-  outputDir = "$projectDir/build/generated"
+  outputDir = generatedDir.get().asFile.absolutePath
   apiPackage = "org.apache.polaris.service.admin.api"
   modelPackage = "org.apache.polaris.core.admin.model"
-  ignoreFileOverride = "$rootDir/.openapi-generator-ignore"
+  ignoreFileOverride = 
rootDir.file(".openapi-generator-ignore").asFile.absolutePath
   removeOperationIdPrefix = true
-  templateDir = "$rootDir/server-templates"
+  templateDir = templatesDir.asFile.absolutePath
   globalProperties.put("apis", "")
   globalProperties.put("models", "false")
   globalProperties.put("apiDocs", "false")
@@ -70,14 +83,16 @@ openApiGenerate {
   serverVariables.put("basePath", "api/v1")
 }
 
-listOf("sourcesJar", "compileJava").forEach { task ->
+listOf("sourcesJar", "compileJava", "processResources").forEach { task ->
   tasks.named(task) { dependsOn("openApiGenerate") }
 }
 
-sourceSets {
-  main { java { 
srcDir(project.layout.buildDirectory.dir("generated/src/main/java")) } }
+sourceSets { main { java { srcDir(generatedOpenApiSrcDir) } } }
+
+tasks.named<GenerateTask>("openApiGenerate") {
+  inputs.dir(templatesDir)
+  inputs.dir(specsDir)
+  actions.addFirst { delete { delete(generatedDir) } }
 }
 
 tasks.named("javadoc") { dependsOn("jandex") }
-
-tasks.named("processResources") { dependsOn("openApiGenerate") }
diff --git a/api/polaris-catalog-service/build.gradle.kts 
b/api/polaris-catalog-service/build.gradle.kts
index 9afb3ccf6..cab5f0cf9 100644
--- a/api/polaris-catalog-service/build.gradle.kts
+++ b/api/polaris-catalog-service/build.gradle.kts
@@ -17,6 +17,8 @@
  * under the License.
  */
 
+import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
+
 plugins {
   alias(libs.plugins.openapi.generator)
   id("polaris-client")
@@ -75,15 +77,26 @@ dependencies {
   compileOnly(libs.microprofile.fault.tolerance.api)
 }
 
+val rootDir = rootProject.layout.projectDirectory
+val specsDir = rootDir.dir("spec")
+val templatesDir = rootDir.dir("server-templates")
+// Use a different directory than 'generated/', because OpenAPI generator's 
`GenerateTask` adds the
+// whole directory to its task output, but 'generated/' is not exclusive to 
that task and in turn
+// breaks Gradle's caching.
+val generatedDir = project.layout.buildDirectory.dir("generated-openapi")
+val generatedOpenApiSrcDir = 
project.layout.buildDirectory.dir("generated-openapi/src/main/java")
+
 openApiGenerate {
-  inputSpec = "$rootDir/spec/polaris-catalog-service.yaml"
+  // The OpenAPI generator does NOT resolve relative paths correctly against 
the Gradle project
+  // directory
+  inputSpec = specsDir.file("polaris-catalog-service.yaml").asFile.absolutePath
   generatorName = "jaxrs-resteasy"
-  outputDir = "$projectDir/build/generated"
+  outputDir = generatedDir.get().asFile.absolutePath
   apiPackage = "org.apache.polaris.service.catalog.api"
   modelPackage = "org.apache.polaris.service.types"
-  ignoreFileOverride = "$rootDir/.openapi-generator-ignore"
+  ignoreFileOverride = 
rootDir.file(".openapi-generator-ignore").asFile.absolutePath
   removeOperationIdPrefix = true
-  templateDir = "$rootDir/server-templates"
+  templateDir = templatesDir.asFile.absolutePath
   globalProperties.put("apis", "GenericTableApi,PolicyApi")
   globalProperties.put("models", models)
   globalProperties.put("apiDocs", "false")
@@ -112,16 +125,16 @@ openApiGenerate {
     )
 }
 
-listOf("sourcesJar", "compileJava").forEach { task ->
+listOf("sourcesJar", "compileJava", "processResources").forEach { task ->
   tasks.named(task) { dependsOn("openApiGenerate") }
 }
 
-sourceSets {
-  main { java { 
srcDir(project.layout.buildDirectory.dir("generated/src/main/java")) } }
+sourceSets { main { java { srcDir(generatedOpenApiSrcDir) } } }
+
+tasks.named<GenerateTask>("openApiGenerate") {
+  inputs.dir(templatesDir)
+  inputs.dir(specsDir)
+  actions.addFirst { delete { delete(generatedDir) } }
 }
 
 tasks.named("javadoc") { dependsOn("jandex") }
-
-tasks.named("processResources") { dependsOn("openApiGenerate") }
-
-tasks.named("openApiGenerate") { outputs.cacheIf { false } }
diff --git a/build-logic/src/main/kotlin/polaris-java.gradle.kts 
b/build-logic/src/main/kotlin/polaris-java.gradle.kts
index 4370b5518..980a144b7 100644
--- a/build-logic/src/main/kotlin/polaris-java.gradle.kts
+++ b/build-logic/src/main/kotlin/polaris-java.gradle.kts
@@ -60,7 +60,7 @@ tasks.withType(JavaCompile::class.java).configureEach {
   options.errorprone.disableAllWarnings = true
   options.errorprone.disableWarningsInGeneratedCode = true
   options.errorprone.excludedPaths =
-    
".*/${project.layout.buildDirectory.get().asFile.relativeTo(projectDir)}/generated/.*"
+    
".*/${project.layout.buildDirectory.get().asFile.relativeTo(projectDir)}/generated(-openapi)?/.*"
   val errorproneRules = 
rootProject.projectDir.resolve("codestyle/errorprone-rules.properties")
   inputs.file(errorproneRules).withPathSensitivity(PathSensitivity.RELATIVE)
   options.errorprone.checks.putAll(provider { 
memoizedErrorproneRules(errorproneRules) })

Reply via email to