Move to plugins

Our current gradle setup includes a number of pseudo-plugins that we have written in some foo-script.gradle files. How we use these files across multiple separate gradle projects is really gross, and we are now trying to move them to actual gradle plugins published to our shared repository. My first question that I believe the answer to is “yes”, but can we simply re-use our existing foo-script.gradle files and package/publish them as plugins? From what I’ve seen, I just need to move them into src/main/groovy, add the ‘groovy-gradle-plugin’, and I think I’m good. The id of the plugin in this example would just be foo-script. Of course I would need to define the group for publishing as well. Are these called “pre-compiled plugins” as referenced here? Developing Custom Gradle Plugins

I’ve made a bit of progress. The issue I’m now having is in regards to the group and artifactId of the published jar. According to this Plugin Marker Artifacts I need to ensure my artifact matches plugin.id:plugin.id.gradle.plugin:plugin.version, but the docs don’t show how to make that happen in this standalone groovy gradle plugin.

Another update. By introducing a settings.gradle file in my plugin project, I was able to set a meaningful name as follows: rootProject.name = 'com.foo.gradle.simple-plugin'. This allows me to set the group value in my build.gradle like this: group = rootProject.name. Now when I publish locally, I see this:

> tree ~/.m2/repository/com/foo
/Users/me/.m2/repository/com/foo
└── gradle
    └── simple-plugin
        └── com.foo.gradle.simple-plugin
            ├── 0.0.1
            │   ├── com.foo.gradle.simple-plugin-0.0.1.jar
            │   ├── com.foo.gradle.simple-plugin-0.0.1.module
            │   └── com.foo.gradle.simple-plugin-0.0.1.pom
            └── maven-metadata-local.xml

I think this all looks good, but I’m not sure. However, when I try to pull in the plugin in another project, I’m getting this error:

* What went wrong:
Plugin [id: 'com.foo.gradle.simple-plugin', version: '0.0.1'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.foo.gradle.simple-plugin:com.foo.gradle.simple-plugin.gradle.plugin:0.0.1')
  Searched in the following repositories:
    MavenLocal(file:/Users/me/.m2/repository/)
    Gradle Central Plugin Repository

Any thoughts would be appreciated.

The coordinates of the artifact are totally irrelevant and unrelated to the plugin ID. You could have 10 plugins within one code artifact.

The plugin marker artifact is an additional artifact that is published and follows the naming convention you mentioned. It does not have a jar, but just a pom that references the code artifact. That way you have one artifact per plugin ID so that usage in plugins { ... } block can be translated to some coordinates and one artiact per project with the code in it.

So if you want to have com.foo.gradle.simple-plugin as plugin id, you either have to call the file com.foo.gradle.simple-plugin.gradle or add package com.foo.gradle inside the simple-plugin.gradle.

And yes, those are what is called precompiled script plugins.

I think that all makes sense. So do I also need to include a gradlePlugin block inside my plugin build.gradle to have it publish the Plugin Marker artifact? If so what should that look like? Am I supposed to specify the implementationClass and id attributes?

As an FYI, moving the script into a package breaks the build.

Execution failed for task ':extractPluginRequests'.
> Script '/Users/me/dev/gradle-plugins/simple-plugin/src/main/groovy/com/foo/gradle/simple-plugin.gradle' should not contain a package statement.

Oh, ok, then the package statement only works with Kotlin DSL precompiled script plugins, not with Groovy DSL ones.
Then you need to name the file accordingly with the plugin ID.

And no, you do not need the gradlePlugin block for precompiled script plugins.
Everything is setup for you already properly if one of the publish plugins is applied.
You just need to publish all publications.

I guess I assumed that the creation and publishing of the marker artifact would come with using this:

plugins {
    id 'groovy-gradle-plugin'
}

but it appears not so since I’m not seeing that artifact.

Ah ha!

Yeah, also just found that bug.
It’s essentially just an ordering problem.
Apply the publish plugin after the groovy-gradle-plugin and it will work properly.