I want that my gradle plugin depends on some common code that can be used inside the gradle plugin as well as inside a android library.
Is there a way to share plain java/kotlin code between a gradle plugin and an android library?
When I try to add a module to the gradle plugin I get "could ':...' could not be found in project" error... I tried different combinations of includeBuild
and include
but they don't solve the issue...
Example:
Gradle Plugin:
plugins {
`kotlin-dsl`
`java-gradle-plugin`
`maven-publish`
}
dependencies {
// fails
implementation(project(":Library:Plugin:Shared"))
//implementation(project(":library:plugin:shared"))
}
Library Module:
plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-parcelize")
id("maven-publish")
}
android {
// ...
}
dependencies {
api(project(":Library:Plugin:Shared"))
}
Shared Module:
repositories {
mavenCentral()
}
plugins {
id("org.jetbrains.kotlin.jvm")
`java-library`
`maven-publish`
}
dependencies {
}
settings.gradle.kts:
pluginManagement {
includeBuild(File("library/plugin/gradle"))
}
include(":Library:Plugin:Shared")
project(":Library:Plugin:Shared").projectDir = file("library/plugin/shared")
include(":Library:Plugin:Gradle")
project(":Library:Plugin:Gradle").projectDir = file("library/plugin/gradle")
EXAMPLE SETUP
1) root/gradle-plugin/build.gradle.kts
repositories {
mavenCentral()
}
plugins {
`kotlin-dsl-base`
`java-gradle-plugin`
`maven-publish`
}
dependencies {
//implementation(":gradle-shared")
// following does not work inside a gradle plugin module...
// it works in other modules though
implementation(project(":Library:Plugin:Shared"))
}
gradlePlugin {
plugins {
create("changelog-utils") {
id = "changelog-utils"
implementationClass = "<path>.ClassLoaderPlugin"
}
}
}
2) root/gradle-shared/build.gradle.kts
repositories {
mavenCentral()
}
plugins {
`kotlin-dsl-base`
`java-library`
//`maven-publish`
}
3) root/settings.gradle.kts
// --------------
// Gradle Plugin
// --------------
includeBuild("gradle-plugin")
// --------------
// Shared Code (Plugin + Library)
// --------------
include(":MyLibrary:Plugin:Shared")
project(":MyLibrary:Plugin:Shared").projectDir = file("gradle-shared")
You need an included build to share code between a plugin and the application code of a project.
It's not clear to me where you are writing your plugin code, but the logical place to put it is as a subproject of the included build, which I will describe below. Here are some step-by-step instructions.
Set up your included build project in a new folder under your main project folder. Call it, say, myIncludedBuild
.
Give the included build its own settings.gradle.kts
file in that folder. I suggest you write your plugin and the shared library in this project, so with that in mind, include both of them in what is going to be a multiproject project by writing the following in that file:
include("myPlugin", "myLibrary")
myIncludedBuild/myPlugin
. Give it a build.gradle.kts
file and, assuming you are writing the plugin in Kotlin, apply the kotlin-dsl
plugin1
plugins {
`kotlin-dsl`
}
build.gradle.kts
file to set out the details of your plugin in Java Gradle Plugin syntax. This gives that plugin the information it needs to package your plugin in the prescribed way for other projects to locate it.
gradlePlugin {
plugins {
create("myPlugin") {
id = "myPluginId"
implementationClass = "package.MyPlugin"
}
}
}
myIncludedBuild/myPlugin/src/kotlin/package/MyPlugin.kt
(or whatever package suits you, reflecting it in the build file) in a class called MyPlugin
implementing Plugin<Project>
.For the library, set up a folder at myIncludedBuild/myLibrary
and give it a build.gradle.kts
file. In there apply the Java Library plugin and give the project a group.
plugins {
`java-library`
}
group = "myIncludedBuildGroup"
Write your shared code in myIncludedBuild/myLibrary/src/main/java
build.gradle.kts
, importing it as a sister project:
dependencies {
implementation(project(":myLibrary"))
}
settings.gradle.kts
:
includeBuild("myIncludedBuild")
plugins {
id("myPluginId")
}
dependencies {
implementation("myIncludedBuildGroup:myLibrary")
}
1The Kotlin DSL plugin includes the Kotlin JVM plugin and the Java Gradle plugin; it puts the Kotlin Gradle DSL on the classpath; and it provides a convenient change to the Kotlin syntax to make regular Kotlin code similar to writing a Kotlin DSL build script, in that Gradle Action
parameters are treated with their subject as receivers.