I am trying to move the code from a set of several plugins written in Gradle scripts included with "apply from: " to a jar of Groovy scripts included with "apply plugin: ". I have been mostly successful but I am having trouble creating 'extension objects' for those plugins that have them. I seem to be unable to reference the extension class name within the plugin's apply function. I am missing something basic - what is it?
I have whittled the problem down to a simple example that I hope will serve as a useful template. Here is a plugin named "sample":
PLUGIN: plugin\src\main\groovy\com\company\gradle\sample.groovy:
package com.company.gradle
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.Task
// Configuration object (project may override these values)
class sampleExtension {
String product // product code - 3 alphanumeric characters
String customer // customer id - integer 0-999999
sampleExtension() {
this.product = 'ABC'
this.customer = '123'
}
}
class sample implements Plugin<Project> {
void apply(Project target) {
println "SAMPLE: A"
// create the configuration objects for this plugin
target.extensions.create('sample', sampleExtension)
println "SAMPLE: B"
// This task generates the license.
Task sampleTask = target.task('printProperties') {
doFirst {
println("target.sample.product = '$target.sample.product'")
println("target.sample.customer = '$target.sample.customer'")
}
}
println "SAMPLE: C"
}
}
The printlns are helpful because in the project that uses sample, plugin errors are reported as occurring at some line within the project script, not the plugin script. I'm not sure if the constructor is necessary; I have also tried nesting the extension class inside class 'sample'
plugin\src\main\resources\META-INF\gradle-plugins\sample.properties:
implementation-class=com.company.gradle.sample
plugin\build.gradle
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
group = 'com.company.gradle'
version = '1.0'
uploadArchives {
repositories { mavenDeployer { repository(url: uri('../repo')) }}
}
That is the plugin. Here is the project script, which for the purpose of this example has no code - just execute the task provided by the sample plugin:
project\build.gradle:
buildscript {
repositories{ maven{url uri('../repo')} }
dependencies { classpath 'com.company.gradle:plugin:1.0' }
}
apply plugin: 'sample'
The plugin is built with 'gradle build uploadArchives' and it compiles clean. The project is built with 'gradle printProperties'. It prints the "A" message, and complains that it failed to apply the sample plugin because 'no such property: sampleExtension' for class 'com.company.gradle.sample'.
c:\jdev\project>gradle printProperties
SAMPLE: A
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\jdev\project\build.gradle' line: 9
* What went wrong:
A problem occurred evaluating root project 'project'.
> Failed to apply plugin [id 'sample']
> No such property: sampleExtension for class: com.company.gradle.sample
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.
BUILD FAILED
Total time: 2.13 secs
The plugin code worked when the plugin was written as a 'sample.groovy' script included in the project\build.gradle with 'apply from: sample.groovy'.
When my extension class was nested, the failure was different: 'could not create an instance of type com.company.gradle.sample$sampleExtension_Decorated.'
What is the pattern when you have an extension object and the plugin is written in .groovy for a plugin jar, rather than .gradle for direct inclusion?
Thanks for taking the time to wade through all this...