用Java定义Gradle插件属性扩展的正确方法?
我正在尝试用Java创建一个Gradle插件,它具有属性扩展(而不是约定,因为这显然是一种方式)。作为记录,我正在Linux机器上使用Gradle1.6(Ubuntu 12.04) 我已经弄清楚了,这应该在插件类定义中完成。下面是一种添加扩展的方法。创建包含属性的扩展类:用Java定义Gradle插件属性扩展的正确方法?,java,gradle,Java,Gradle,我正在尝试用Java创建一个Gradle插件,它具有属性扩展(而不是约定,因为这显然是一种方式)。作为记录,我正在Linux机器上使用Gradle1.6(Ubuntu 12.04) 我已经弄清楚了,这应该在插件类定义中完成。下面是一种添加扩展的方法。创建包含属性的扩展类: public class MyPluginExtensions { File sourceDir; File outputDir; public MyPluginExtensions(Project
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");
}
}
myPluginName.sourceDir = file('the/main/src')
现在将这些扩展添加到主插件类中的项目中:
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);
}
}
但是,当我将这些内容放入使用我的插件的gradle脚本并尝试设置此属性时,gradle告诉我无法设置它:
* What went wrong:
A problem occurred evaluating script.
> There's an extension registered with name 'sourceDir'. You should not reassign it via a property setter.
那么,在基于Java的Gradle插件中为任务添加属性扩展的正确方法是什么
编辑:
基于其他一些SO帖子,我尝试在一个快照中添加我的extensions对象:
// first attempt:
//myPluginTask.getExtensions().add("sourceDir", extensions.sourceDir);
//myPluginTask.getExtensions().add("outputDir",extensions.outputDir);
// second attempt
myPluginTask.getExtensions().add("myPluginTask", extensions);
这似乎有效。但是,Gradle现在抱怨我添加了一个动态属性:
Deprecated dynamic property: "sourceDir" on "task ':myPluginTask'", value: "/Users/jfer...".
那么,添加插件扩展属性的正确方法是什么
编辑2
因此,再次尝试一下,我将扩展添加到项目对象中,并使用create方法:
// 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);
然而,这失败的原因有两个:
project.myPluginPropExt.propertyName
,而是将其添加到项目命名空间中(例如,project.propertyName
)这是不正确的,并导致Gradle抛出一堆“不推荐使用的动态属性”警告代码正在向任务(而不是项目)添加一个扩展名,这很少有用。之后,它尝试设置
myPluginTask.sourceDir=file('The/main/src')
,这是不可能的,因为扩展名刚刚以相同的名称注册。因此,我的问题有一个解决方案:
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);
}
}
最后一个技巧是在我的插件任务中获得这个值:
public class MyPluginTask extends DefaultTask {
@TaskAction
public void action() {
MyPluginExtensions extensions = (MyPluginExtensions) getProject()
.getExtensions().findByName("myPluginName");
System.out.println("sourceDir value: " + extensions.sourceDir);
}
}
这是可行的,但这个解决方案让我恼火的是,我希望能够将扩展属性与我在基于groovy的插件中看到的任务(例如,myPluginTask.sourceDir
)放在相同的命名空间中,但这显然不受支持或根本不起作用
同时,希望这对其他人有所帮助。当您的任务和扩展名同名时,您可以在构建中执行此操作。gradle:
myPluginTask.sourceDir = file('the/main/src')
project.tasks.myPluginTask.dependsOn clean
感谢第一个关于不将扩展添加到任务中的建议。现在,通过向项目对象添加扩展,我已经做了一些工作。但是,您误解了第二个要点:
myPluginTask.sourceDir=file(/main/src')
是我的gradle构建脚本的一部分,我试图为特定构建设置扩展值。我理解,但扩展不是这样工作的。客户端构建脚本配置扩展的属性,而不是扩展本身。仍然不太清楚:代码段(myPluginTask.sourceDir=file(/main/src')
)来自使用我的插件的客户端/消费者生成脚本,该脚本正在尝试为特定生成设置该值。插件未正确使用扩展。扩展是一个对象,其属性将由客户端生成脚本配置。因此,它需要具有自定义类型,而不是不可变类型,如字符串或 例如,您可以执行project.getExtensions().create(“foo”,MyPluginExtensions.class)
。然后构建脚本可以设置foo.sourceDir
和foo.outputDir
。重要的是要理解扩展在其目标下创建了一个新的命名空间(在我的示例中是project.foo
)。它不能“融入”就像一个惯例。啊哈!我骗你回答了我原来的问题!:)我认为project.getExtensions().create()
方法看起来是正确的方法,但我尝试这样做的尝试到目前为止都失败了(请参阅我问题的编辑2)。我将再次尝试,并根据需要更新我的Q和a。
myPluginTask.sourceDir = file('the/main/src')
project.tasks.myPluginTask.dependsOn clean