Gradle:如何初始化 SourceTask 的 属性 扩展名为 属性 的“源”?

Gradle: How to init SourceTask's property ‘source’ with extension property?

我的插件注册了一个扩展和一些继承自 org.gradle.api.tasks.SourceTask 的自定义任务。

class MyPlugin implements Plugin<Project> {
    private final Instantiator instantiator
    private final FileResolver fileResolver
    @Inject
    MyPlugin (Instantiator instantiator, FileResolver fileResolver) {
        this.instantiator = instantiator
        this.fileResolver = fileResolver
    }
    void apply(Project project) {
        MyPluginExtension extension = project.extensions.create("myPlugin", MyPluginExtension, project, instantiator, fileResolver)
        project.tasks.create('doSomething', MyCustomTask) {}
    }
}

class MyPluginExtension {
    final MySourceSetContainer source
    MyPluginExtension(Project project, Instantiator instantiator, FileResolver fileResolver) {
        source = instantiator.newInstance(ImplMySourceSetContainer, project, instantiator, fileResolver)
    }
    void source(Closure closure) {
        ConfigureUtil.configure(closure, source)
    }
}

class MyCustomTask extends SourceTask {
    @TaskAction
    void act() {
        // something
    }
}

现在,如果我配置构建脚本:

myPlugin {
    source{
        main {
            something {
                srcDirs "src/main/resources"
            }
        }
    }
}
doSomething {
    source = myPlugin.source.main.something.asFileTree
}

- 一切正常。但我想通过 MyPluginExtension 的值初始化任务 属性 source

source = extension.source.findAll().inject(project.files().asFileTree, { result, item -> result + item.html.asFileTree })

我无法在用户指南 (https://docs.gradle.org/4.2.1/userguide/custom_plugins.html#sec:mapping_extension_properties_to_task_properties) 中描述的执行阶段提取扩展 属性,因为 getter 用于在超类中声明的 source org.gradle.api.tasks.SourceTask 标有注解 @org.gradle.api.tasks.SkipWhenEmpty,任务将被跳过。

如何在执行阶段之前使用扩展中的值初始化任务的 属性? 谢谢

我不确定我是否完全理解您在做什么,但您可能会使用闭包来延迟评估。参见 Project.files(Object...)

例如:

doSomething {
    def myClosure = {
        extension.source.findAll().inject(project.files().asFileTree, { result, item -> result + item.html.asFileTree })
    }
    source = files(myClosure)
}

通过将 source init 包装在闭包中解决:

class MyPlugin implements Plugin<Project> {
    // ...
    void apply(Project project) {
        MyPluginExtension extension = project.extensions.create("myPlugin", MyPluginExtension, project, instantiator, fileResolver)
        project.tasks.create('doSomething', MyCustomTask) { task ->
            task.source = { 
                extension.source.findAll().inject(new HashSet<File>(), { result, item -> result + item.html.srcDirs }) 
            }
        }
    }
}