Add plugin variants
Change configuration adding Gradle plugin variants. 'main' SourceSet is used for minimal supported Gradle versions, 'common' SourceSet for common code that is similar between versions, plus, currently, 'gradle70' SourceSet for Gradle 7.0+ versions. ^KT-49227 In Progress
This commit is contained in:
@@ -3,22 +3,48 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
||||
import org.gradle.api.attributes.plugin.GradlePluginApiVersion
|
||||
import org.gradle.api.plugins.JavaLibraryPlugin
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
|
||||
import org.jetbrains.dokka.DokkaVersion
|
||||
import org.jetbrains.dokka.gradle.DokkaTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute
|
||||
import plugins.configureDefaultPublishing
|
||||
import plugins.configureKotlinPomAttributes
|
||||
|
||||
/**
|
||||
* Gradle plugins common variants.
|
||||
*
|
||||
* [minimalSupportedGradleVersion] - minimal Gradle version that is supported in this variant
|
||||
* [gradleApiVersion] - Gradle API dependency version. Usually should be the same as [minimalSupportedGradleVersion].
|
||||
*/
|
||||
enum class GradlePluginVariant(
|
||||
val sourceSetName: String,
|
||||
val minimalSupportedGradleVersion: String,
|
||||
val gradleApiVersion: String
|
||||
) {
|
||||
GRADLE_MIN("main", "6.7", "6.9"),
|
||||
GRADLE_70("gradle70", "7.0", "7.0"),
|
||||
//GRADLE_71("gradle71", "7.1", "7.1"),
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures common pom configuration parameters
|
||||
*/
|
||||
@@ -62,10 +88,148 @@ fun Project.excludeGradleCommonDependencies(sourceSet: SourceSet) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 'main' sources are used for Gradle 6.1-6.9 versions.
|
||||
* Directories are renamed into 'src/gradle61'.
|
||||
* Common sources for all variants.
|
||||
* Should contain classes that are independent of Gradle API version or using minimal supported Gradle api.
|
||||
*/
|
||||
fun Project.configureGradlePluginCommonSettings() {
|
||||
fun Project.createGradleCommonSourceSet(): SourceSet {
|
||||
val commonSourceSet = sourceSets.create("common") {
|
||||
excludeGradleCommonDependencies(this)
|
||||
|
||||
dependencies {
|
||||
compileOnlyConfigurationName(kotlinStdlib())
|
||||
compileOnlyConfigurationName("dev.gradleplugins:gradle-api:7.2")
|
||||
if (this@createGradleCommonSourceSet.name != "kotlin-gradle-plugin-api" &&
|
||||
this@createGradleCommonSourceSet.name != "android-test-fixes"
|
||||
) {
|
||||
compileOnlyConfigurationName(project(":kotlin-gradle-plugin-api")) {
|
||||
capabilities {
|
||||
requireCapability("org.jetbrains.kotlin:kotlin-gradle-plugin-api-common")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withType<JavaLibraryPlugin>().configureEach {
|
||||
this@createGradleCommonSourceSet.extensions.configure<JavaPluginExtension> {
|
||||
registerFeature(commonSourceSet.name) {
|
||||
usingSourceSet(commonSourceSet)
|
||||
disablePublication()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return commonSourceSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes wired SourceSet does not expose compiled common classes and common resources as secondary variant
|
||||
* which is used in the Kotlin Project compilation.
|
||||
*/
|
||||
private fun Project.fixWiredSourceSetSecondaryVariants(
|
||||
wireSourceSet: SourceSet,
|
||||
commonSourceSet: SourceSet
|
||||
) {
|
||||
configurations
|
||||
.matching {
|
||||
it.name == wireSourceSet.apiElementsConfigurationName ||
|
||||
it.name == wireSourceSet.runtimeElementsConfigurationName
|
||||
}
|
||||
.configureEach {
|
||||
outgoing {
|
||||
variants.maybeCreate("classes").apply {
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES))
|
||||
}
|
||||
(commonSourceSet.output.classesDirs.files + wireSourceSet.output.classesDirs.files)
|
||||
.toSet()
|
||||
.forEach {
|
||||
if (!artifacts.files.contains(it)) {
|
||||
artifact(it) {
|
||||
type = ArtifactTypeDefinition.JVM_CLASS_DIRECTORY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations
|
||||
.matching { it.name == wireSourceSet.runtimeElementsConfigurationName }
|
||||
.configureEach {
|
||||
outgoing {
|
||||
val resourcesDirectories = listOfNotNull(
|
||||
commonSourceSet.output.resourcesDir,
|
||||
wireSourceSet.output.resourcesDir
|
||||
)
|
||||
|
||||
if (resourcesDirectories.isNotEmpty()) {
|
||||
variants.maybeCreate("resources").apply {
|
||||
attributes {
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.RESOURCES))
|
||||
}
|
||||
resourcesDirectories.forEach {
|
||||
if (!artifacts.files.contains(it)) {
|
||||
artifact(it) {
|
||||
type = ArtifactTypeDefinition.JVM_RESOURCES_DIRECTORY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make [wireSourceSet] to extend [commonSourceSet].
|
||||
*/
|
||||
fun Project.wireGradleVariantToCommonGradleVariant(
|
||||
wireSourceSet: SourceSet,
|
||||
commonSourceSet: SourceSet
|
||||
) {
|
||||
wireSourceSet.compileClasspath += commonSourceSet.output
|
||||
wireSourceSet.runtimeClasspath += commonSourceSet.output
|
||||
@Suppress("deprecation") // Needs support from KGP
|
||||
wireSourceSet.withConvention(KotlinSourceSet::class) {
|
||||
val wireKotlinSourceSet = this
|
||||
commonSourceSet.withConvention(KotlinSourceSet::class) {
|
||||
wireKotlinSourceSet.dependsOn(this)
|
||||
}
|
||||
}
|
||||
|
||||
configurations[wireSourceSet.apiConfigurationName].extendsFrom(
|
||||
configurations[commonSourceSet.apiConfigurationName]
|
||||
)
|
||||
configurations[wireSourceSet.implementationConfigurationName].extendsFrom(
|
||||
configurations[commonSourceSet.implementationConfigurationName]
|
||||
)
|
||||
configurations[wireSourceSet.runtimeOnlyConfigurationName].extendsFrom(
|
||||
configurations[commonSourceSet.runtimeOnlyConfigurationName]
|
||||
)
|
||||
configurations[wireSourceSet.compileOnlyConfigurationName].extendsFrom(
|
||||
configurations[commonSourceSet.compileOnlyConfigurationName]
|
||||
)
|
||||
|
||||
fixWiredSourceSetSecondaryVariants(wireSourceSet, commonSourceSet)
|
||||
|
||||
tasks.withType<Jar>().configureEach {
|
||||
if (name == wireSourceSet.jarTaskName) {
|
||||
from(wireSourceSet.output, commonSourceSet.output)
|
||||
setupPublicJar(archiveBaseName.get())
|
||||
addEmbeddedRuntime()
|
||||
} else if (name == wireSourceSet.sourcesJarTaskName) {
|
||||
from(wireSourceSet.allSource, commonSourceSet.allSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'main' sources are used for minimal supported Gradle versions (6.7) up to Gradle 7.0.
|
||||
*/
|
||||
fun Project.reconfigureMainSourcesSetForGradlePlugin(
|
||||
commonSourceSet: SourceSet
|
||||
) {
|
||||
sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) {
|
||||
plugins.withType<JavaGradlePluginPlugin>().configureEach {
|
||||
// Removing Gradle api default dependency added by 'java-gradle-plugin'
|
||||
@@ -76,15 +240,16 @@ fun Project.configureGradlePluginCommonSettings() {
|
||||
"compileOnly"(kotlinStdlib())
|
||||
// Decoupling gradle-api artifact from current project Gradle version. Later would be useful for
|
||||
// gradle plugin variants
|
||||
"compileOnly"("dev.gradleplugins:gradle-api:7.2")
|
||||
if (this@configureGradlePluginCommonSettings.name != "kotlin-gradle-plugin-api" &&
|
||||
this@configureGradlePluginCommonSettings.name != "android-test-fixes"
|
||||
"compileOnly"("dev.gradleplugins:gradle-api:${GradlePluginVariant.GRADLE_MIN.gradleApiVersion}")
|
||||
if (this@reconfigureMainSourcesSetForGradlePlugin.name != "kotlin-gradle-plugin-api" &&
|
||||
this@reconfigureMainSourcesSetForGradlePlugin.name != "android-test-fixes"
|
||||
) {
|
||||
"api"(project(":kotlin-gradle-plugin-api"))
|
||||
}
|
||||
}
|
||||
|
||||
excludeGradleCommonDependencies(this)
|
||||
wireGradleVariantToCommonGradleVariant(this, commonSourceSet)
|
||||
|
||||
tasks.withType<Jar>().configureEach {
|
||||
if (name == jarTaskName) {
|
||||
@@ -96,7 +261,7 @@ fun Project.configureGradlePluginCommonSettings() {
|
||||
}
|
||||
|
||||
plugins.withType<JavaLibraryPlugin>().configureEach {
|
||||
this@configureGradlePluginCommonSettings
|
||||
this@reconfigureMainSourcesSetForGradlePlugin
|
||||
.extensions
|
||||
.configure<JavaPluginExtension> {
|
||||
withSourcesJar()
|
||||
@@ -111,7 +276,17 @@ fun Project.configureGradlePluginCommonSettings() {
|
||||
}
|
||||
|
||||
plugins.withId("org.jetbrains.dokka") {
|
||||
val dokkaTask = tasks.named<DokkaTask>("dokkaJavadoc")
|
||||
val dokkaTask = tasks.named<DokkaTask>("dokkaJavadoc") {
|
||||
dokkaSourceSets {
|
||||
named(commonSourceSet.name) {
|
||||
suppress.set(false)
|
||||
}
|
||||
|
||||
named("main") {
|
||||
dependsOn(commonSourceSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Jar>().configureEach {
|
||||
if (name == javadocJarTaskName) {
|
||||
@@ -122,6 +297,130 @@ fun Project.configureGradlePluginCommonSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding plugin variants: https://docs.gradle.org/current/userguide/implementing_gradle_plugins.html#plugin-with-variants
|
||||
*/
|
||||
fun Project.createGradlePluginVariant(
|
||||
variant: GradlePluginVariant,
|
||||
commonSourceSet: SourceSet,
|
||||
isGradlePlugin: Boolean = true
|
||||
): SourceSet {
|
||||
val variantSourceSet = sourceSets.create(variant.sourceSetName) {
|
||||
excludeGradleCommonDependencies(this)
|
||||
wireGradleVariantToCommonGradleVariant(this, commonSourceSet)
|
||||
}
|
||||
|
||||
plugins.withType<JavaLibraryPlugin>().configureEach {
|
||||
extensions.configure<JavaPluginExtension> {
|
||||
registerFeature(variantSourceSet.name) {
|
||||
usingSourceSet(variantSourceSet)
|
||||
if (isGradlePlugin) {
|
||||
capability(project.group.toString(), project.name, project.version.toString())
|
||||
}
|
||||
|
||||
// Enabling publishing docs jars only on CI build
|
||||
// Currently dokka task runs non-incrementally and takes big amount of time
|
||||
if (kotlinBuildProperties.publishGradlePluginsJavadoc ||
|
||||
kotlinBuildProperties.isTeamcityBuild
|
||||
) {
|
||||
withJavadocJar()
|
||||
}
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
configurations.named(variantSourceSet.apiElementsConfigurationName, commonVariantAttributes())
|
||||
configurations.named(variantSourceSet.runtimeElementsConfigurationName, commonVariantAttributes())
|
||||
}
|
||||
|
||||
tasks.named<Jar>(variantSourceSet.sourcesJarTaskName) {
|
||||
addEmbeddedSources()
|
||||
}
|
||||
}
|
||||
|
||||
// Enabling publishing docs jars only on CI build
|
||||
// Currently dokka task runs non-incrementally and takes big amount of time
|
||||
if (kotlinBuildProperties.publishGradlePluginsJavadoc ||
|
||||
kotlinBuildProperties.isTeamcityBuild
|
||||
) {
|
||||
plugins.withId("org.jetbrains.dokka") {
|
||||
val dokkaTask = tasks.register<DokkaTask>("dokka${variantSourceSet.javadocTaskName.capitalize()}") {
|
||||
description = "Generates documentation in 'javadoc' format for '${variantSourceSet.javadocTaskName}' variant"
|
||||
|
||||
plugins.dependencies.add(
|
||||
project.dependencies.create("org.jetbrains.dokka:javadoc-plugin:${DokkaVersion.version}")
|
||||
)
|
||||
|
||||
dokkaSourceSets {
|
||||
named(commonSourceSet.name) {
|
||||
suppress.set(false)
|
||||
}
|
||||
|
||||
named(variantSourceSet.name) {
|
||||
dependsOn(commonSourceSet)
|
||||
suppress.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Jar>(variantSourceSet.javadocJarTaskName) {
|
||||
from(dokkaTask.flatMap { it.outputDirectory })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withId("java-gradle-plugin") {
|
||||
tasks.named<Copy>(variantSourceSet.processResourcesTaskName) {
|
||||
val copyPluginDescriptors = rootSpec.addChild()
|
||||
copyPluginDescriptors.into("META-INF/gradle-plugins")
|
||||
copyPluginDescriptors.from(tasks.named("pluginDescriptors"))
|
||||
}
|
||||
}
|
||||
|
||||
configurations.configureEach {
|
||||
if (isCanBeConsumed && this@configureEach.name.startsWith(variantSourceSet.name)) {
|
||||
attributes {
|
||||
attribute(
|
||||
GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE,
|
||||
objects.named(variant.minimalSupportedGradleVersion)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
variantSourceSet.compileOnlyConfigurationName(kotlinStdlib())
|
||||
variantSourceSet.compileOnlyConfigurationName("dev.gradleplugins:gradle-api:${variant.gradleApiVersion}")
|
||||
if (this@createGradlePluginVariant.name != "kotlin-gradle-plugin-api" &&
|
||||
this@createGradlePluginVariant.name != "android-test-fixes"
|
||||
) {
|
||||
variantSourceSet.apiConfigurationName(project(":kotlin-gradle-plugin-api")) {
|
||||
capabilities {
|
||||
requireCapability("org.jetbrains.kotlin:kotlin-gradle-plugin-api-${variant.sourceSetName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return variantSourceSet
|
||||
}
|
||||
|
||||
/**
|
||||
* All additional configuration attributes in plugin variant should be the same as in the 'main' variant.
|
||||
* Otherwise, Gradle <7.0 will fail to select plugin variant.
|
||||
*/
|
||||
private fun Project.commonVariantAttributes(): Action<Configuration> = Action<Configuration> {
|
||||
attributes {
|
||||
attribute(
|
||||
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
|
||||
objects.named(TargetJvmEnvironment.STANDARD_JVM)
|
||||
)
|
||||
attribute(
|
||||
Attribute.of(KotlinPlatformTypeAttribute.uniqueName, String::class.java),
|
||||
KotlinPlatformTypeAttribute.JVM
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureKotlinCompileTasksGradleCompatibility() {
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
kotlinOptions.languageVersion = "1.4"
|
||||
@@ -136,7 +435,8 @@ fun Project.configureKotlinCompileTasksGradleCompatibility() {
|
||||
|
||||
// Will allow combining outputs of multiple SourceSets
|
||||
fun Project.publishShadowedJar(
|
||||
sourceSet: SourceSet
|
||||
sourceSet: SourceSet,
|
||||
commonSourceSet: SourceSet
|
||||
) {
|
||||
val jarTask = tasks.named<Jar>(sourceSet.jarTaskName)
|
||||
|
||||
@@ -149,6 +449,7 @@ fun Project.publishShadowedJar(
|
||||
)
|
||||
addEmbeddedRuntime()
|
||||
from(sourceSet.output)
|
||||
from(commonSourceSet.output)
|
||||
|
||||
// When Gradle traverses the inputs, reject the shaded compiler JAR,
|
||||
// which leads to the content of that JAR being excluded as well:
|
||||
|
||||
@@ -23,9 +23,6 @@ configure<PluginBundleExtension> {
|
||||
tags = listOf("kotlin")
|
||||
}
|
||||
|
||||
configureGradlePluginCommonSettings()
|
||||
publishShadowedJar(sourceSets[SourceSet.MAIN_SOURCE_SET_NAME])
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
withType<MavenPublication>().configureEach {
|
||||
@@ -39,3 +36,14 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val commonSourceSet = createGradleCommonSourceSet()
|
||||
reconfigureMainSourcesSetForGradlePlugin(commonSourceSet)
|
||||
publishShadowedJar(sourceSets[SourceSet.MAIN_SOURCE_SET_NAME], commonSourceSet)
|
||||
|
||||
// Used for Gradle 7.0+ versions
|
||||
val gradle70SourceSet = createGradlePluginVariant(
|
||||
GradlePluginVariant.GRADLE_70,
|
||||
commonSourceSet = commonSourceSet
|
||||
)
|
||||
publishShadowedJar(gradle70SourceSet, commonSourceSet)
|
||||
|
||||
@@ -16,12 +16,21 @@ configureCommonPublicationSettingsForGradle()
|
||||
configureKotlinCompileTasksGradleCompatibility()
|
||||
extensions.extraProperties["kotlin.stdlib.default.dependency"] = "false"
|
||||
|
||||
configureGradlePluginCommonSettings()
|
||||
val commonSourceSet = createGradleCommonSourceSet()
|
||||
reconfigureMainSourcesSetForGradlePlugin(commonSourceSet)
|
||||
|
||||
// Used for Gradle 7.0+ versions
|
||||
createGradlePluginVariant(
|
||||
GradlePluginVariant.GRADLE_70,
|
||||
commonSourceSet = commonSourceSet,
|
||||
isGradlePlugin = false
|
||||
)
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
register<MavenPublication>(DEFAULT_MAIN_PUBLICATION_NAME) {
|
||||
from(components["java"])
|
||||
suppressAllPomMetadataWarnings() // Don't warn about additional published variants
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user