I am trying to create a Gradle plugin in Java that has property extensions (not conventions, as this is apparently the old , wrong way ). For the record, I work with Gradle 1.6 on a Linux machine (Ubuntu 12.04).
I figured this should be done in the Plugin class definition. Here is a way to add an extension. Create an extension class containing your properties:
public class MyPluginExtensions { File sourceDir; File outputDir; public MyPluginExtensions(Project project) { this.project = project; sourceDir = new File(project.getProjectDir(), "src"); outputDir = new File(project.getBuildDir(), "out"); } }
Now add these extensions to the project in the main class of the plugin:
public class MyPlugin implements Plugin<Project> { @Override public void apply(Project project) { Map<String,Object> taskInfo = new HashMap<String,Object>(); taskInfo.put("type", MyPluginTask.class); taskInfo.put("description", "Generates blah from blah."); taskInfo.put("group", "Blah"); Task myPluginTask = project.task(taskInfo, "myPluginTask");
This approach, however, does not seem to be correct. The project.ext namespace displays the new project property. I expect that I can address the plugin extensions as:
in my build.gradle: myPluginTask.sourceDir = file('the/main/src') myPluginTask.outputDir = file('the/output')
However, when I put such things into a Gradle script that uses my plugin and tries to set this property, Gradle tells me that I cannot install it:
* What went wrong: A problem occurred evaluating script. > There an extension registered with name 'sourceDir'. You should not reassign it via a property setter.
So, what is the right way to add property extensions for a task to a Java-based Gradle plugin?
EDIT:
Based on some other SO posts, I tried to just add an extension object in one snapshot:
// first attempt: //myPluginTask.getExtensions().add("sourceDir", extensions.sourceDir); //myPluginTask.getExtensions().add("outputDir",extensions.outputDir); // second attempt myPluginTask.getExtensions().add("myPluginTask", extensions);
It works. However, Gradle now complains that it has added a dynamic property:
Deprecated dynamic property: "sourceDir" on "task ':myPluginTask'", value: "/Users/jfer...".
So again, what is the right way to add a plugin extension property?
EDIT 2
So, taking another shot, I add the extension to the project object and use the create method instead:
// first attempt: //myPluginTask.getExtensions().add("sourceDir", extensions.sourceDir); //myPluginTask.getExtensions().add("outputDir",extensions.outputDir); // second attempt // myPluginTask.getExtensions().add("myPluginTask", extensions); // third attempt project.getExtensions().create("myPluginTask", MyPluginExtensions.class, project);
However, this fails for two reasons:
- Creating a property extension with the same name ("myPluginTask"), because the task creates a collision between the task name and the extension name, as a result of which the task disappears from the Gradle point of view (and throws oblique errors, such as "No property: dependsOn for the class. .. MyPluginExtensions ").
- If I provide a name that does not interfere with the task name (for example, "myPluginPropExt"), the create () method works, but DOES NOT add the extension to its own namespace as expected (for example,
project.myPluginPropExt.propertyName and instead adds it to the project namespace (for example, project.propertyName ), which is incorrect, and calls Gradle to throw a bunch of warnings about the "outdated dynamic property".