Plugin project with samples in one repository

Is there any official way how to create the Gradle plugin project together with samples that allows testing plugin directly without publishing it.

When I put plugin to buildSrc it is very easy to use it directly in the sample project inside of one repo without any additional step. But then it is not possible to publish it to the artifactory.

When I create a normal module, which is possible to publish to artifactory, there is no way how to use it inside of the sample project without publishing it to local maven artifactory after every change. Maybe composite build can help here?

Currently, I’m using a little bit hacky way. I have the plugin module and then buildSrc where is inside of settings.gradle this

include ':plugin'
project(':plugin').projectDir = new File(rootDir, '../plugin')

And inside of build.gradle this

rootProject.dependencies {
    implementation project(':plugin')
}

So I basically use the plugin module as the dependency of buildSrc, which is without real source code.
It works great from a command line, but it causes sync issue in IDEA as I described here https://youtrack.jetbrains.com/issue/IDEA-224846

You can do it with a composite build.
See an example here, I use a version.txt file to share the version amongst the composite

1 Like

It looks that your solution really works with buildscript.dependencies.classpath and then apply, but I’m not able to make it working via plugins {}, which is almost mandatory when you switch to Kotlin :frowning:

There is probably necessary to somehow use pluginManagement and tell to Gradle that plugin in part of composite build.

I’ve found the plugins {...} block inadequate in a few scenarios. I seem to remember I couldn’t do TestKit testing with plugins {...} block either.

I’ve not used kotlin but I would have assumed it could do the same as groovy since it’s all java byte code under the hood. If kotlin forces plugins {...} block that sucks, because its inadequate

Problems with Kotlin is that it will not create extension functions if you will not use plugins {}. So it means, that you can’t use extensions defined by the plugin in a direct way like in Groovy.

For example in Android world, you cannot use
android {

}
I don’t know why the do it in this way :frowning:

But you can use plugins, but prevent them to apply and then later apply them manually.

Btw. I found a solution. Composite works with plugins, but you need to have plugin id declared in gradle file by

gradlePlugin {
    plugins.create("...") {
      ....
    }
}

I found another issue, since I’m using includeBuild instead include I cannot run any task directly from this module, like ./gradlew plugin:publishToMavenLocal

It fail with
Project 'plugin' not found in root project 'gradle-plugin-avast-build'.

Oh no, it looks that it is a design limitation of composite builds :cry:
https://docs.gradle.org/current/userguide/composite_builds.html#composite_build_executing_tasks

There is not (yet) any means to directly execute a task from an included build via the command line.

You can create tasks in the main build that wrap tasks in the composite build which you can then call from command line

Eg

task pluginPublishToMavenLocal {
   dependsOn gradle.includedBuild('plugin').task('foo:publishToMavenLocal') 
} 
1 Like