|  | 
| 1 |  | -@file:Suppress("unused") | 
| 2 |  | - | 
| 3 | 1 | package org.springdoc.openapi.gradle.plugin | 
| 4 | 2 | 
 | 
| 5 | 3 | import com.github.psxpaul.task.JavaExecFork | 
| 6 | 4 | import org.gradle.api.Plugin | 
| 7 | 5 | import org.gradle.api.Project | 
|  | 6 | +import org.gradle.api.Task | 
| 8 | 7 | import org.gradle.api.logging.Logging | 
|  | 8 | +import org.gradle.api.tasks.TaskProvider | 
|  | 9 | +import org.gradle.internal.jvm.Jvm | 
| 9 | 10 | import org.springframework.boot.gradle.tasks.run.BootRun | 
| 10 | 11 | 
 | 
| 11 | 12 | open class OpenApiGradlePlugin : Plugin<Project> { | 
| 12 |  | -	private val logger = Logging.getLogger(OpenApiGradlePlugin::class.java) | 
|  | 13 | +    private val logger = Logging.getLogger(OpenApiGradlePlugin::class.java) | 
|  | 14 | + | 
|  | 15 | +    override fun apply(project: Project) { | 
|  | 16 | +        with(project) { | 
|  | 17 | +            // Run time dependency on the following plugins | 
|  | 18 | +            plugins.apply(SPRING_BOOT_PLUGIN) | 
|  | 19 | +            plugins.apply(EXEC_FORK_PLUGIN) | 
|  | 20 | + | 
|  | 21 | +            extensions.create(EXTENSION_NAME, OpenApiExtension::class.java, this) | 
|  | 22 | + | 
|  | 23 | +            afterEvaluate { generate(this) } | 
|  | 24 | +        } | 
|  | 25 | +    } | 
| 13 | 26 | 
 | 
| 14 |  | -	override fun apply(project: Project) { | 
| 15 |  | -		// Run time dependency on the following plugins | 
| 16 |  | -		project.plugins.apply(SPRING_BOOT_PLUGIN) | 
| 17 |  | -		project.plugins.apply(EXEC_FORK_PLUGIN) | 
|  | 27 | +    private fun generate(project: Project) = project.run { | 
|  | 28 | +        springBoot3CompatibilityCheck() | 
| 18 | 29 | 
 | 
| 19 |  | -		project.extensions.create(EXTENSION_NAME, OpenApiExtension::class.java, project) | 
|  | 30 | +        // The task, used to run the Spring Boot application (`bootRun`) | 
|  | 31 | +        val bootRunTask = tasks.named(SPRING_BOOT_RUN_TASK_NAME) | 
|  | 32 | +        // The task, used to resolve the application's main class (`bootRunMainClassName`) | 
|  | 33 | +        val bootRunMainClassNameTask = tasks.find { it.name ==  SPRING_BOOT_RUN_MAIN_CLASS_NAME_TASK_NAME} | 
|  | 34 | +            ?:tasks.named(SPRING_BOOT_3_RUN_MAIN_CLASS_NAME_TASK_NAME) | 
| 20 | 35 | 
 | 
| 21 |  | -		project.afterEvaluate { | 
| 22 |  | -			// The task, used to run the Spring Boot application (`bootRun`) | 
| 23 |  | -			val bootRunTask = project.tasks.named(SPRING_BOOT_RUN_TASK_NAME) | 
| 24 |  | -			// The task, used to resolve the application's main class (`bootRunMainClassName`) | 
| 25 |  | -			val bootRunMainClassNameTask = | 
| 26 |  | -				project.tasks.named(SPRING_BOOT_RUN_MAIN_CLASS_NAME_TASK_NAME) | 
|  | 36 | +        val extension = extensions.findByName(EXTENSION_NAME) as OpenApiExtension | 
|  | 37 | +        val customBootRun = extension.customBootRun | 
|  | 38 | +        // Create a forked version spring boot run task | 
|  | 39 | +        val forkedSpringBoot = tasks.register(FORKED_SPRING_BOOT_RUN_TASK_NAME, JavaExecFork::class.java) { fork -> | 
|  | 40 | +            fork.dependsOn(bootRunMainClassNameTask) | 
|  | 41 | +            fork.onlyIf { needToFork(bootRunTask, customBootRun, fork) } | 
|  | 42 | +        } | 
| 27 | 43 | 
 | 
| 28 |  | -			val extension = project.extensions.findByName(EXTENSION_NAME) as OpenApiExtension | 
| 29 |  | -			val customBootRun = extension.customBootRun | 
| 30 |  | -			// Create a forked version spring boot run task | 
| 31 |  | -			val forkedSpringBoot = | 
| 32 |  | -				project.tasks.register( | 
| 33 |  | -					FORKED_SPRING_BOOT_RUN_TASK_NAME, | 
| 34 |  | -					JavaExecFork::class.java | 
| 35 |  | -				) { fork -> | 
| 36 |  | -					fork.dependsOn(bootRunMainClassNameTask) | 
|  | 44 | +        // This is my task. Before I can run it, I have to run the dependent tasks | 
|  | 45 | +        tasks.register(OPEN_API_TASK_NAME, OpenApiGeneratorTask::class.java) { | 
|  | 46 | +            it.dependsOn(forkedSpringBoot) | 
|  | 47 | +        } | 
| 37 | 48 | 
 | 
| 38 |  | -					fork.onlyIf { | 
| 39 |  | -						val bootRun = bootRunTask.get() as BootRun | 
|  | 49 | +        // The forked task need to be terminated as soon as my task is finished | 
|  | 50 | +        forkedSpringBoot.get().stopAfter = tasks.named(OPEN_API_TASK_NAME) | 
|  | 51 | +    } | 
| 40 | 52 | 
 | 
| 41 |  | -						val baseSystemProperties = customBootRun.systemProperties.orNull?.takeIf { it.isNotEmpty() } | 
| 42 |  | -							?: bootRun.systemProperties | 
| 43 |  | -						// copy all system properties, excluding those starting with `java.class.path` | 
| 44 |  | -						fork.systemProperties = baseSystemProperties.filter { | 
| 45 |  | -							!it.key.startsWith( | 
| 46 |  | -								CLASS_PATH_PROPERTY_NAME | 
| 47 |  | -							) | 
| 48 |  | -						} | 
|  | 53 | +    private fun Project.springBoot3CompatibilityCheck() { | 
|  | 54 | +        val tasksNames = tasks.names | 
|  | 55 | +        val boot2TaskName = "bootRunMainClassName" | 
|  | 56 | +        val boot3TaskName = "resolveMainClassName" | 
|  | 57 | +        if (!tasksNames.contains(boot2TaskName) && tasksNames.contains(boot3TaskName)) | 
|  | 58 | +            tasks.register(boot2TaskName) { it.dependsOn(tasks.named(boot3TaskName)) } | 
|  | 59 | +    } | 
| 49 | 60 | 
 | 
| 50 |  | -						// use original bootRun parameter if the list-type customBootRun properties is empty | 
| 51 |  | -						fork.workingDir = customBootRun.workingDir.asFile.orNull | 
| 52 |  | -							?: bootRun.workingDir | 
| 53 |  | -						fork.args = customBootRun.args.orNull?.takeIf { it.isNotEmpty() }?.toMutableList() | 
| 54 |  | -							?: bootRun.args?.toMutableList() ?: mutableListOf() | 
| 55 |  | -						fork.classpath = customBootRun.classpath.takeIf { !it.isEmpty } | 
| 56 |  | -							?: bootRun.classpath | 
| 57 |  | -						fork.main = customBootRun.mainClass.orNull | 
| 58 |  | -							?: bootRun.mainClass.get() | 
| 59 |  | -						fork.jvmArgs = customBootRun.jvmArgs.orNull?.takeIf { it.isNotEmpty() } | 
| 60 |  | -							?: bootRun.jvmArgs | 
| 61 |  | -						fork.environment = customBootRun.environment.orNull?.takeIf { it.isNotEmpty() } | 
| 62 |  | -							?: bootRun.environment | 
| 63 |  | -						if (org.gradle.internal.jvm.Jvm.current().toString() | 
| 64 |  | -								.startsWith("1.8") | 
| 65 |  | -						) { | 
| 66 |  | -							fork.killDescendants = false | 
| 67 |  | -						} | 
| 68 |  | -						true | 
| 69 |  | -					} | 
| 70 |  | -				} | 
|  | 61 | +    private fun needToFork( | 
|  | 62 | +        bootRunTask: TaskProvider<Task>, | 
|  | 63 | +        customBootRun: CustomBootRunAction, | 
|  | 64 | +        fork: JavaExecFork | 
|  | 65 | +    ): Boolean { | 
|  | 66 | +        val bootRun = bootRunTask.get() as BootRun | 
| 71 | 67 | 
 | 
| 72 |  | -			// This is my task. Before I can run it I have to run the dependent tasks | 
| 73 |  | -			project.tasks.register( | 
| 74 |  | -				OPEN_API_TASK_NAME, | 
| 75 |  | -				OpenApiGeneratorTask::class.java | 
| 76 |  | -			) { openApiGenTask -> | 
| 77 |  | -				openApiGenTask.dependsOn(forkedSpringBoot) | 
| 78 |  | -			} | 
|  | 68 | +        val baseSystemProperties = customBootRun.systemProperties.orNull?.takeIf { it.isNotEmpty() } | 
|  | 69 | +            ?: bootRun.systemProperties | 
|  | 70 | +        with(fork) { | 
|  | 71 | +            // copy all system properties, excluding those starting with `java.class.path` | 
|  | 72 | +            systemProperties = baseSystemProperties.filter { | 
|  | 73 | +                !it.key.startsWith(CLASS_PATH_PROPERTY_NAME) | 
|  | 74 | +            } | 
| 79 | 75 | 
 | 
| 80 |  | -			// The forked task need to be terminated as soon as my task is finished | 
| 81 |  | -			forkedSpringBoot.get().stopAfter = project.tasks.named(OPEN_API_TASK_NAME) | 
| 82 |  | -		} | 
| 83 |  | -	} | 
|  | 76 | +            // use original bootRun parameter if the list-type customBootRun properties are empty | 
|  | 77 | +            workingDir = customBootRun.workingDir.asFile.orNull | 
|  | 78 | +                ?: bootRun.workingDir | 
|  | 79 | +            args = customBootRun.args.orNull?.takeIf { it.isNotEmpty() }?.toMutableList() | 
|  | 80 | +                ?: bootRun.args?.toMutableList() ?: mutableListOf() | 
|  | 81 | +            classpath = customBootRun.classpath.takeIf { !it.isEmpty } | 
|  | 82 | +                ?: bootRun.classpath | 
|  | 83 | +            main = customBootRun.mainClass.orNull | 
|  | 84 | +                ?: bootRun.mainClass.get() | 
|  | 85 | +            jvmArgs = customBootRun.jvmArgs.orNull?.takeIf { it.isNotEmpty() } | 
|  | 86 | +                ?: bootRun.jvmArgs | 
|  | 87 | +            environment = customBootRun.environment.orNull?.takeIf { it.isNotEmpty() } | 
|  | 88 | +                ?: bootRun.environment | 
|  | 89 | +            if (Jvm.current().toString().startsWith("1.8")) { | 
|  | 90 | +                killDescendants = false | 
|  | 91 | +            } | 
|  | 92 | +        } | 
|  | 93 | +        return true | 
|  | 94 | +    } | 
| 84 | 95 | } | 
0 commit comments