diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
new file mode 100644
index 0000000..4fdd333
--- /dev/null
+++ b/.github/workflows/master.yml
@@ -0,0 +1,33 @@
+name: Test CI
+on: [ push, fork ]
+
+jobs:
+ TEST_ALL:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ java: [ '11', '17' ]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - uses: actions/cache@v3
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+
+ - name: 🪜 Setup java ${{ matrix.java }}
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.java }}
+ distribution: temurin
+
+ - name: 🦞 chmod /gradlew
+ run: chmod +x ./gradlew
+
+ - name: 🔦 Test
+ run: ./gradlew test --info
diff --git a/.run/TEST.run.xml b/.run/TEST.run.xml
new file mode 100644
index 0000000..7376a7c
--- /dev/null
+++ b/.run/TEST.run.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 65f2ee1..fc5d941 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ Gradle Groovy DSL
```groovy
plugins {
id "org.springframework.boot" version "2.7.0"
- id "org.springdoc.openapi-gradle-plugin" version "1.5.0"
+ id "org.springdoc.openapi-gradle-plugin" version "1.6.0"
}
```
@@ -35,7 +35,7 @@ Gradle Kotlin DSL
```groovy
plugins {
id("org.springframework.boot") version "2.7.0"
- id("org.springdoc.openapi-gradle-plugin") version "1.5.0"
+ id("org.springdoc.openapi-gradle-plugin") version "1.6.0"
}
```
@@ -133,7 +133,7 @@ The `groupedApiMappings` customization allows you to specify multiple URLs/file
2. Update the version for the plugin to match the current version found in `build.gradle.kts`
```
- id("org.springdoc.openapi-gradle-plugin") version "1.5.0"
+ id("org.springdoc.openapi-gradle-plugin") version "1.6.0"
```
3. Add the following to the spring boot apps `settings.gradle`
diff --git a/build.gradle.kts b/build.gradle.kts
index f35ed5c..3a9b4f2 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -9,7 +9,7 @@ plugins {
}
group = "org.springdoc"
-version = "1.5.0"
+version = "1.6.0"
sonarqube {
properties {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 626792f..1012b6d 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,2 +1,8 @@
rootProject.name = "springdoc-openapi-gradle-plugin"
+pluginManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
diff --git a/src/main/kotlin/org/springdoc/openapi/gradle/plugin/Constants.kt b/src/main/kotlin/org/springdoc/openapi/gradle/plugin/Constants.kt
index f3afed4..95dae65 100644
--- a/src/main/kotlin/org/springdoc/openapi/gradle/plugin/Constants.kt
+++ b/src/main/kotlin/org/springdoc/openapi/gradle/plugin/Constants.kt
@@ -6,6 +6,7 @@ const val OPEN_API_TASK_NAME = "generateOpenApiDocs"
const val OPEN_API_TASK_DESCRIPTION = "Generates the spring doc openapi file"
const val SPRING_BOOT_RUN_TASK_NAME = "bootRun"
const val SPRING_BOOT_RUN_MAIN_CLASS_NAME_TASK_NAME = "bootRunMainClassName"
+const val SPRING_BOOT_3_RUN_MAIN_CLASS_NAME_TASK_NAME = "bootRun"
const val FORKED_SPRING_BOOT_RUN_TASK_NAME = "forkedSpringBootRun"
const val DEFAULT_API_DOCS_URL = "http://localhost:8080/v3/api-docs"
diff --git a/src/main/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePlugin.kt b/src/main/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePlugin.kt
index 9e10aaf..5899e2c 100644
--- a/src/main/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePlugin.kt
+++ b/src/main/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePlugin.kt
@@ -1,84 +1,95 @@
-@file:Suppress("unused")
-
package org.springdoc.openapi.gradle.plugin
import com.github.psxpaul.task.JavaExecFork
import org.gradle.api.Plugin
import org.gradle.api.Project
+import org.gradle.api.Task
import org.gradle.api.logging.Logging
+import org.gradle.api.tasks.TaskProvider
+import org.gradle.internal.jvm.Jvm
import org.springframework.boot.gradle.tasks.run.BootRun
open class OpenApiGradlePlugin : Plugin {
- private val logger = Logging.getLogger(OpenApiGradlePlugin::class.java)
+ private val logger = Logging.getLogger(OpenApiGradlePlugin::class.java)
+
+ override fun apply(project: Project) {
+ with(project) {
+ // Run time dependency on the following plugins
+ plugins.apply(SPRING_BOOT_PLUGIN)
+ plugins.apply(EXEC_FORK_PLUGIN)
+
+ extensions.create(EXTENSION_NAME, OpenApiExtension::class.java, this)
+
+ afterEvaluate { generate(this) }
+ }
+ }
- override fun apply(project: Project) {
- // Run time dependency on the following plugins
- project.plugins.apply(SPRING_BOOT_PLUGIN)
- project.plugins.apply(EXEC_FORK_PLUGIN)
+ private fun generate(project: Project) = project.run {
+ springBoot3CompatibilityCheck()
- project.extensions.create(EXTENSION_NAME, OpenApiExtension::class.java, project)
+ // The task, used to run the Spring Boot application (`bootRun`)
+ val bootRunTask = tasks.named(SPRING_BOOT_RUN_TASK_NAME)
+ // The task, used to resolve the application's main class (`bootRunMainClassName`)
+ val bootRunMainClassNameTask = tasks.find { it.name == SPRING_BOOT_RUN_MAIN_CLASS_NAME_TASK_NAME}
+ ?:tasks.named(SPRING_BOOT_3_RUN_MAIN_CLASS_NAME_TASK_NAME)
- project.afterEvaluate {
- // The task, used to run the Spring Boot application (`bootRun`)
- val bootRunTask = project.tasks.named(SPRING_BOOT_RUN_TASK_NAME)
- // The task, used to resolve the application's main class (`bootRunMainClassName`)
- val bootRunMainClassNameTask =
- project.tasks.named(SPRING_BOOT_RUN_MAIN_CLASS_NAME_TASK_NAME)
+ val extension = extensions.findByName(EXTENSION_NAME) as OpenApiExtension
+ val customBootRun = extension.customBootRun
+ // Create a forked version spring boot run task
+ val forkedSpringBoot = tasks.register(FORKED_SPRING_BOOT_RUN_TASK_NAME, JavaExecFork::class.java) { fork ->
+ fork.dependsOn(bootRunMainClassNameTask)
+ fork.onlyIf { needToFork(bootRunTask, customBootRun, fork) }
+ }
- val extension = project.extensions.findByName(EXTENSION_NAME) as OpenApiExtension
- val customBootRun = extension.customBootRun
- // Create a forked version spring boot run task
- val forkedSpringBoot =
- project.tasks.register(
- FORKED_SPRING_BOOT_RUN_TASK_NAME,
- JavaExecFork::class.java
- ) { fork ->
- fork.dependsOn(bootRunMainClassNameTask)
+ // This is my task. Before I can run it, I have to run the dependent tasks
+ tasks.register(OPEN_API_TASK_NAME, OpenApiGeneratorTask::class.java) {
+ it.dependsOn(forkedSpringBoot)
+ }
- fork.onlyIf {
- val bootRun = bootRunTask.get() as BootRun
+ // The forked task need to be terminated as soon as my task is finished
+ forkedSpringBoot.get().stopAfter = tasks.named(OPEN_API_TASK_NAME)
+ }
- val baseSystemProperties = customBootRun.systemProperties.orNull?.takeIf { it.isNotEmpty() }
- ?: bootRun.systemProperties
- // copy all system properties, excluding those starting with `java.class.path`
- fork.systemProperties = baseSystemProperties.filter {
- !it.key.startsWith(
- CLASS_PATH_PROPERTY_NAME
- )
- }
+ private fun Project.springBoot3CompatibilityCheck() {
+ val tasksNames = tasks.names
+ val boot2TaskName = "bootRunMainClassName"
+ val boot3TaskName = "resolveMainClassName"
+ if (!tasksNames.contains(boot2TaskName) && tasksNames.contains(boot3TaskName))
+ tasks.register(boot2TaskName) { it.dependsOn(tasks.named(boot3TaskName)) }
+ }
- // use original bootRun parameter if the list-type customBootRun properties is empty
- fork.workingDir = customBootRun.workingDir.asFile.orNull
- ?: bootRun.workingDir
- fork.args = customBootRun.args.orNull?.takeIf { it.isNotEmpty() }?.toMutableList()
- ?: bootRun.args?.toMutableList() ?: mutableListOf()
- fork.classpath = customBootRun.classpath.takeIf { !it.isEmpty }
- ?: bootRun.classpath
- fork.main = customBootRun.mainClass.orNull
- ?: bootRun.mainClass.get()
- fork.jvmArgs = customBootRun.jvmArgs.orNull?.takeIf { it.isNotEmpty() }
- ?: bootRun.jvmArgs
- fork.environment = customBootRun.environment.orNull?.takeIf { it.isNotEmpty() }
- ?: bootRun.environment
- if (org.gradle.internal.jvm.Jvm.current().toString()
- .startsWith("1.8")
- ) {
- fork.killDescendants = false
- }
- true
- }
- }
+ private fun needToFork(
+ bootRunTask: TaskProvider,
+ customBootRun: CustomBootRunAction,
+ fork: JavaExecFork
+ ): Boolean {
+ val bootRun = bootRunTask.get() as BootRun
- // This is my task. Before I can run it I have to run the dependent tasks
- project.tasks.register(
- OPEN_API_TASK_NAME,
- OpenApiGeneratorTask::class.java
- ) { openApiGenTask ->
- openApiGenTask.dependsOn(forkedSpringBoot)
- }
+ val baseSystemProperties = customBootRun.systemProperties.orNull?.takeIf { it.isNotEmpty() }
+ ?: bootRun.systemProperties
+ with(fork) {
+ // copy all system properties, excluding those starting with `java.class.path`
+ systemProperties = baseSystemProperties.filter {
+ !it.key.startsWith(CLASS_PATH_PROPERTY_NAME)
+ }
- // The forked task need to be terminated as soon as my task is finished
- forkedSpringBoot.get().stopAfter = project.tasks.named(OPEN_API_TASK_NAME)
- }
- }
+ // use original bootRun parameter if the list-type customBootRun properties are empty
+ workingDir = customBootRun.workingDir.asFile.orNull
+ ?: bootRun.workingDir
+ args = customBootRun.args.orNull?.takeIf { it.isNotEmpty() }?.toMutableList()
+ ?: bootRun.args?.toMutableList() ?: mutableListOf()
+ classpath = customBootRun.classpath.takeIf { !it.isEmpty }
+ ?: bootRun.classpath
+ main = customBootRun.mainClass.orNull
+ ?: bootRun.mainClass.get()
+ jvmArgs = customBootRun.jvmArgs.orNull?.takeIf { it.isNotEmpty() }
+ ?: bootRun.jvmArgs
+ environment = customBootRun.environment.orNull?.takeIf { it.isNotEmpty() }
+ ?: bootRun.environment
+ if (Jvm.current().toString().startsWith("1.8")) {
+ killDescendants = false
+ }
+ }
+ return true
+ }
}
diff --git a/src/test/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePluginTest.kt b/src/test/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePluginTest.kt
index 4aae9dd..b1912a3 100644
--- a/src/test/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePluginTest.kt
+++ b/src/test/kotlin/org/springdoc/openapi/gradle/plugin/OpenApiGradlePluginTest.kt
@@ -28,8 +28,8 @@ class OpenApiGradlePluginTest {
private val baseBuildGradle = """plugins {
id 'java'
- id 'org.springframework.boot' version '2.4.5'
- id 'io.spring.dependency-management' version '1.0.11.RELEASE'
+ id 'org.springframework.boot' version '2.7.6'
+ id 'io.spring.dependency-management' version '1.1.15.RELEASE'
id 'org.springdoc.openapi-gradle-plugin'
}
@@ -43,7 +43,7 @@ class OpenApiGradlePluginTest {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
- implementation 'org.springdoc:springdoc-openapi-webmvc-core:1.6.12'
+ implementation 'org.springdoc:springdoc-openapi-webmvc-core:1.6.13'
}
""".trimIndent()
diff --git a/src/test/resources/acceptance-project/src/main/java/com/example/demo/DemoApplication.java b/src/test/resources/acceptance-project/src/main/java/com/example/demo/DemoApplication.java
index 322b2b6..0f77539 100644
--- a/src/test/resources/acceptance-project/src/main/java/com/example/demo/DemoApplication.java
+++ b/src/test/resources/acceptance-project/src/main/java/com/example/demo/DemoApplication.java
@@ -1,14 +1,15 @@
package com.example.demo;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import javax.annotation.PostConstruct;
import java.time.Duration;
@SpringBootApplication
-public class DemoApplication {
+public class DemoApplication implements ApplicationRunner{
@Value("${slower:false}")
boolean slower;
@@ -16,9 +17,9 @@ public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
-
- @PostConstruct
- public void afterBeanStuff() throws InterruptedException {
+ @Override
+ public void run(ApplicationArguments arg0) throws Exception {
+ System.out.println("Hello World from Application Runner");
if (slower) {
Duration waitTime = Duration.ofSeconds(40);
System.out.println("Waiting for " + waitTime + " before starting");