Access a custom task type from a plugin

I have a build script that’s getting sort of obscenely long and complicated. When I look around for suggestions about how to manage this, one common answer is “use plugins”. Okay, I can imagine moving a lot of the configuration complexity into a plugin.

I can create a plugin, add it to my build script, and call methods on it. Good.

The methods that I call can use project.task() to add tasks to the build. Good.

The task I want to add uses a custom task type. I can’t for the life of me figure out how to expose that custom type in the plugin. I can’t import the class. Adding the plugin and imports to buildSrc/build.gradle doesn’t help.

Am I overlooking the blindingly obvious again?

Can you maybe share what you try?
Because from that description it is very hard to point at the problem. :slight_smile:

I oughta learn, eh? Instead of imposing the tangled mess, I’ll make a small test case :slight_smile:

1 Like

Here’s a small repository that attempts to explain my problem, what I tried, and what I can’t make work about it: GitHub - ndw/gradle-modularity-testing: A test repository for learning about how to modularize Gradle build scripts

Hopefully that will clarify where my ignorance lies. :slight_smile:

There are some quirks in your example, but I try to focus on your actual question.

What your have there is not a plugin, though you call it that.
A plugin would implement Plugin<...> and be applied.
Plugin != Extension.
A plugin often creates tasks and registers an extension, so that a project that applies the plugin can configure some details of the behavior.

But in your case as far as you have shown it, neither a plugin, nor an extension makes sense, registering an extension just to call a method on it. You practically just let Gradle call the constructor for you in your case. You can as well just do new MyTaskCreator(project).toyNumbered().

Regarding accessing the class in your “plugin”, buildSrc is a complete standalone multi-project build that happens to be built before your main build and is automatically added to the classpath of all your main build’s build scripts. So if you want to use a 3rd party dependency like Saxon, you have to declare it as dependency in the build script of the respective project, so in this case buildSrc/build.gradle(.kts). I would also add an explicit settings script. Even though in the case of buildSrc it works without one, it is good practice to always have it for each individual build.

Fair point about “plugin”. It started out as a proper plugin but then I couldn’t see that I was adding any value and I just pared it back. I’ll pare it back further. Not sure I really follow, but I’ll see what I can do when I get back to it.

Apparently, I’m still missing something. I’ve made another commit to the modtest project, attempting to add the dependencies and settings.gradle files to buildSrc. My attempt to import the relevant task type in the my “MyPlugin” (sic) class fails. I got about this far before I gave up the other day.

You apply the Saxon Gradle plugin to buildSrc, why?
You want a dependency on it, not apply it.
So declare a dependency on com.nwalsh.gradle.saxon.saxon-gradle:com.nwalsh.gradle.saxon.saxon-gradle.gradle.plugin:0.10.2 or com.nwalsh.gradle.saxon:saxon-gradle:0.10.2 by defining a repository and declaring the dependency as usual.

Btw. you should test the Saxon Gradle plugin on Windows, it is not working right now.
In your play project it complains when you try to decode the URL D:\.....\hello.xsl at position 2.

Okay. So in addition to publishing it to the Gradle plugin registry, I have to publish it to Maven or somewhere like that so that I can use it as a depedency? That hadn’t occurred to me.

Thanks for pointing out the Windows bug. Fixed now, I think.

No, plugins are published in Maven at #headdesk

1 Like

Exactly, the plugin central is a maven repository. You can reference it using gradlePluginPortal() like you use mavenCentral(), or mavenLocal() ( later of which you really shouldn’t use).

Success! Thank you, Björn!

1 Like