Correct way to define Gradle plugin property extension using Java?

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"); // Define conventions and attach them to tasks MyPluginExtensions extensions = new MyPluginExtensions(project); myPluginTask.getExtensions().add( "sourceDir", extensions.sourceDir); myPluginTask.getExtensions().add( "outputDir", extensions.outputDir); } } 

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".
+4
source share
3 answers

So here is the solution to my problem:

 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"); // Define conventions and attach them to tasks MyPluginExtensions extensions = new MyPluginExtensions(project); // the magic extension code: project.getExtensions().add("myPluginName", extensions); } } 

Now I can set the value for one of the extension properties in my gradle.build file, for example (and I do not receive a warning about adding deprecated dynamic properties):

  myPluginName.sourceDir = file('the/main/src') 

The final trick is to get this value in my Plugin task:

 public class MyPluginTask extends DefaultTask { @TaskAction public void action() { MyPluginExtensions extensions = (MyPluginExtensions) getProject() .getExtensions().findByName("myPluginName"); System.out.println("sourceDir value: " + extensions.sourceDir); } } 

This works, but what annoys me in this solution is that I want to be able to add extension properties in the same namespace as the job (like myPluginTask.sourceDir ) that I saw in plugins based on groovy, but this does not seem to be supported or just not working.

In the meantime, hope this helps someone else.

+3
source

The code adds an extension to the task (and not to the project), which is rarely useful. After that, he tries to set myPluginTask.sourceDir = file('the/main/src') , which is impossible, since the extension was just registered under the same name.

0
source

When your task and your extension have the same name, you can do this in your build.gradle :

 myPluginTask.sourceDir = file('the/main/src') project.tasks.myPluginTask.dependsOn clean 
0
source

Source: https://habr.com/ru/post/1498900/


All Articles