All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.name.remal.gradle_plugins.plugins.generate_sources.GenerateSourcesPlugin.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
package name.remal.gradle_plugins.plugins.generate_sources

import name.remal.gradle_plugins.api.AutoService
import name.remal.gradle_plugins.dsl.BaseReflectiveProjectPlugin
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.PluginActionsGroup
import name.remal.gradle_plugins.dsl.WithPlugins
import name.remal.gradle_plugins.dsl.extensions.SourceSetTaskNameGettersFactory
import name.remal.gradle_plugins.dsl.extensions.all
import name.remal.gradle_plugins.dsl.extensions.classifierCompatible
import name.remal.gradle_plugins.dsl.extensions.compileGroovyTaskName
import name.remal.gradle_plugins.dsl.extensions.compileKotlin2JsTaskName
import name.remal.gradle_plugins.dsl.extensions.compileKotlinTaskName
import name.remal.gradle_plugins.dsl.extensions.dependsOn
import name.remal.gradle_plugins.dsl.extensions.doSetup
import name.remal.gradle_plugins.dsl.extensions.generatedSourcesDir
import name.remal.gradle_plugins.dsl.extensions.get
import name.remal.gradle_plugins.dsl.extensions.groovy
import name.remal.gradle_plugins.dsl.extensions.isProcessingSourceSet
import name.remal.gradle_plugins.dsl.extensions.kotlin
import name.remal.gradle_plugins.dsl.extensions.withPlugin
import name.remal.gradle_plugins.plugins.generate_sources.groovy.GenerateGroovy
import name.remal.gradle_plugins.plugins.generate_sources.java.GenerateJava
import name.remal.gradle_plugins.plugins.generate_sources.kotlin.GenerateKotlin
import name.remal.gradle_plugins.plugins.generate_sources.resources.GenerateResources
import name.remal.gradle_plugins.plugins.groovy.GroovyPluginId
import name.remal.gradle_plugins.plugins.java.JavaPluginId
import name.remal.gradle_plugins.plugins.kotlin.KotlinAnyPluginId
import name.remal.gradle_plugins.plugins.kotlin.KotlinJsPluginId
import name.remal.gradle_plugins.plugins.kotlin.KotlinJvmPluginId
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.GroovyCompile
import org.gradle.api.tasks.compile.JavaCompile
import java.nio.charset.StandardCharsets.UTF_8

@Plugin(
    id = "name.remal.generate-sources",
    description = "Plugin that provides such task as generateJavaSources, generateKotlinSources, etc...",
    tags = ["java", "sources", "generating", "generate-sources", "kotlin", "groovy"]
)
class GenerateSourcesPlugin : BaseReflectiveProjectPlugin() {

    @PluginActionsGroup(order = -10)
    @WithPlugins(JavaPluginId::class)
    inner class `If 'java' plugin is applied` {

        @PluginAction(order = -20)
        fun SourceSetContainer.`Create generateResources tasks for all SourceSets`(tasks: TaskContainer, project: Project) {
            all { sourceSet ->
                val outputDir = project.generatedSourcesDir.resolve("resources/${sourceSet.name}")
                sourceSet.resources.srcDir(outputDir)
                val processResourcesTask = tasks[sourceSet.processResourcesTaskName]
                tasks.create(sourceSet.generateResourcesTaskName, GenerateResources::class.java) { generateResourcesTask ->
                    generateResourcesTask.description = "Generates resources for $sourceSet"
                    generateResourcesTask.classpath = sourceSet.compileClasspath
                    generateResourcesTask.outputDir = outputDir
                    generateResourcesTask.dependsOn { sourceSet.compileClasspath }
                    processResourcesTask.dependsOn(generateResourcesTask)
                    generateResourcesTask.configureAdditionalDependents(sourceSet)
                }
            }
        }

        @PluginAction(order = -10)
        @WithPlugins(JavaPluginId::class)
        fun SourceSetContainer.`Create generateJava tasks for all SourceSets`(tasks: TaskContainer, project: Project) {
            all { sourceSet ->
                val outputDir = project.generatedSourcesDir.resolve("java/${sourceSet.name}")
                sourceSet.java.srcDir(outputDir)
                val compileJavaTask = tasks[JavaCompile::class.java, sourceSet.compileJavaTaskName]
                val generateJavaTask = tasks.create(sourceSet.generateJavaTaskName, GenerateJava::class.java) { generateJavaTask ->
                    generateJavaTask.description = "Generates Java sources for $sourceSet"
                    generateJavaTask.doSetup { it.charset = compileJavaTask.options.encoding ?: UTF_8.name() }
                    generateJavaTask.doSetup { it.classpath += compileJavaTask.classpath }
                    generateJavaTask.outputDir = outputDir
                    generateJavaTask.dependsOn { compileJavaTask.classpath }
                    compileJavaTask.dependsOn(generateJavaTask)
                    generateJavaTask.configureAdditionalDependents(sourceSet)
                }

                project.withPlugin(KotlinJvmPluginId) { _ ->
                    tasks[sourceSet.compileKotlinTaskName].dependsOn(generateJavaTask)
                }
            }
        }

    }


    @PluginActionsGroup
    @WithPlugins(JavaPluginId::class, KotlinAnyPluginId::class)
    inner class `If 'kotlin' plugin is applied` {

        @PluginAction
        fun SourceSetContainer.`Create generateKotlin tasks for all SourceSets`(tasks: TaskContainer, project: Project) {
            all { sourceSet ->
                val outputDir = project.generatedSourcesDir.resolve("kotlin/${sourceSet.name}")
                sourceSet.kotlin.srcDir(outputDir)
                val generateKotlinTask = tasks.create(sourceSet.generateKotlinTaskName, GenerateKotlin::class.java) { generateKotlinTask ->
                    generateKotlinTask.description = "Generates Kotlin sources for $sourceSet"
                    generateKotlinTask.classpath = sourceSet.compileClasspath
                    generateKotlinTask.outputDir = outputDir
                    generateKotlinTask.dependsOn { sourceSet.compileClasspath }
                    generateKotlinTask.configureAdditionalDependents(sourceSet)
                }

                project.withPlugin(KotlinJvmPluginId) { _ ->
                    tasks[AbstractCompile::class.java, sourceSet.compileKotlinTaskName].also { compileKotlinTask ->
                        compileKotlinTask.doSetup { generateKotlinTask.classpath += compileKotlinTask.classpath }
                        compileKotlinTask.dependsOn(generateKotlinTask)
                    }
                }

                project.withPlugin(KotlinJsPluginId) { _ ->
                    tasks[AbstractCompile::class.java, sourceSet.compileKotlin2JsTaskName].also { compileKotlin2JsTask ->
                        compileKotlin2JsTask.doSetup { generateKotlinTask.classpath += compileKotlin2JsTask.classpath }
                        compileKotlin2JsTask.dependsOn(generateKotlinTask)
                    }
                }
            }
        }

    }


    @PluginActionsGroup
    @WithPlugins(GroovyPluginId::class)
    inner class `If 'groovy' plugin is applied` {

        @PluginAction
        fun SourceSetContainer.`Create generateGroovy tasks for all SourceSets`(tasks: TaskContainer, project: Project) {
            all { sourceSet ->
                val outputDir = project.generatedSourcesDir.resolve("groovy/${sourceSet.name}")
                sourceSet.groovy.srcDir(outputDir)
                val compileGroovyTask = tasks[GroovyCompile::class.java, sourceSet.compileGroovyTaskName]
                tasks.create(sourceSet.generateGroovyTaskName, GenerateGroovy::class.java) { generateGroovyTask ->
                    generateGroovyTask.description = "Generates Groovy sources for $sourceSet"
                    generateGroovyTask.doSetup { it.charset = compileGroovyTask.options.encoding ?: UTF_8.name() }
                    generateGroovyTask.doSetup { it.classpath += compileGroovyTask.classpath }
                    generateGroovyTask.classpath = sourceSet.compileClasspath
                    generateGroovyTask.outputDir = outputDir
                    generateGroovyTask.dependsOn { compileGroovyTask.classpath }
                    compileGroovyTask.dependsOn(generateGroovyTask)
                    generateGroovyTask.configureAdditionalDependents(sourceSet)
                }
            }
        }

    }


    private fun BaseGenerateTask.configureAdditionalDependents(sourceSet: SourceSet) {
        val generateTask = this

        arrayOf(
            "sources",
            "javadoc",
            "groovydoc"
        ).forEach { classifier ->
            arrayOf(classifier, "${classifier}Jar").forEach { baseTaskName ->
                val taskName = sourceSet.getTaskName(null, baseTaskName)
                project.tasks.all(AbstractArchiveTask::class.java, taskName) { task ->
                    task.dependsOn {
                        if (classifier == task.classifierCompatible) {
                            return@dependsOn listOf(generateTask)
                        } else {
                            return@dependsOn emptyList()
                        }
                    }
                }
            }
        }

        project.tasks.all(SourceTask::class.java) { task ->
            task.dependsOn {
                if (task.isProcessingSourceSet(sourceSet)) {
                    return@dependsOn listOf(generateTask)
                } else {
                    return@dependsOn emptyList()
                }
            }
        }
    }

}


val SourceSet.generateResourcesTaskName: String get() = getTaskName("generate", "Resources")
val SourceSet.generateJavaTaskName: String get() = getTaskName("generate", "Java")
val SourceSet.generateKotlinTaskName: String get() = getTaskName("generate", "Kotlin")
val SourceSet.generateGroovyTaskName: String get() = getTaskName("generate", "Groovy")


@AutoService
class SourceSetGenerateSourcesTaskNameGettersFactory : SourceSetTaskNameGettersFactory {
    companion object {
        private val staticGetters = listOf(
            SourceSet::generateResourcesTaskName,
            SourceSet::generateJavaTaskName,
            SourceSet::generateKotlinTaskName,
            SourceSet::generateGroovyTaskName
        )
    }

    override val getters = staticGetters
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy