Gradle 为什么需要PropertyState
假设我正在开发一个Gradle插件,插件配置的一些任务的输入取决于通过扩展配置的方式。例如:Gradle 为什么需要PropertyState,gradle,Gradle,假设我正在开发一个Gradle插件,插件配置的一些任务的输入取决于通过扩展配置的方式。例如: class MyTask extends DefaultTask { @InputFile File toTrack @TaskAction def run() { println("The file now contains ${toTrack.text}") } } class MyConfig { File toTrack = n
class MyTask extends DefaultTask {
@InputFile
File toTrack
@TaskAction
def run() {
println("The file now contains ${toTrack.text}")
}
}
class MyConfig {
File toTrack = new File('bad-default.txt')
}
class MyPlugin implements Plugin<Project> {
@Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
如果我指定了要跟踪的文件,Gradle将在运行config
块之前,对我的任务上的@InputFile
进行评估,因此它将通过查看bad default.txt
而不是file to track.txt
来决定任务是否最新
对此建议的修复方法似乎是这样使用:
通过一些实验,这似乎确实达到了预期的效果。我错过了什么?是否有必要使用
PropertyState
的时候?问题不在于计算@InputFile
的时间@InputFile
是在任务执行之前进行评估的,因此在配置阶段完成之后和gradles执行阶段。PropertyState
正在解决的问题是扩展和任务之间的连接
让我们再看看您的应用方法:
def应用(项目){
计划{
extensions.create('config',MyConfig)
任务('printChanges',类型:MyTask){
toTrack=config.toTrack
}
}
}
给你:
1) 使用MyConfig
类中提供的默认值创建自定义扩展名
2) 将当前在MyConfig
中设置的值链接到MyTask
toTrack属性
现在看看插件的使用情况:
apply plugin: my-plugin
config {
toTrack = file('file-to-track.txt')
}
给你:
1) 应用插件(基本上执行插件的Apply方法)
2) 重新配置MyConfig#toTrack
扩展属性
但是这里没有发生的是更新
printChanges
任务中的值。这就是PropertyState
正在解决的问题。它与任务输入和输出评估无关。Doh!是的,这绝对有道理。在某个时候,我有一个设置,用于最新检查的文件是错误的,但是如果我强制任务运行,正确的文件就会被处理。这使我的思想混乱不堪。那是几次代码更改之前的事,我不确定我是如何设置的。谢谢你的澄清。
class MyTask extends DefaultTask {
PropertyState<File> toTrack = project.property(File)
@InputFile
File getToTrack { return toTrack.get() }
@TaskAction
def run() {
println("The file now contains ${toTrack.get().text}")
}
}
class MyConfig {
private PropertyState<File> toTrack
MyConfig(Project project) {
toTrack = = project.property(File)
toTrack.set('bad-default.txt')
}
void setToTrack(File fileToTrack) { toTrack.set(fileToTrack) }
}
class MyPlugin implements Plugin<Project> {
@Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
class MyTask extends DefaultTask {
File toTrack
// This is the only change: put the annotation on a getter
@InputFile
File getToTrack() { return toTrack }
@TaskAction
def run() {
println("The file now contains ${toTrack.text}")
}
}
class MyConfig {
File toTrack = new File('bad-default.txt')
}
class MyPlugin implements Plugin<Project> {
@Override
def apply(Project project) {
project.with {
extensions.create('config', MyConfig)
task('printChanges', type: MyTask) {
toTrack = config.toTrack
}
}
}
}
apply plugin: my-plugin
config {
toTrack = file('file-to-track.txt')
}