Gradle自定义任务指定输入

时间:2019-04-18 13:05:12

标签: gradle-plugin gradle-kotlin-dsl

我正在为我们的发布方法创建一个插件。我需要执行的任务之一是收集此任务所依赖的每个子项目的distZip输出,并将它们打包到一个带有一些静态文件的zip文件中。

这是我的插件(为简单起见,删除了所有其他任务和扩展名):

open class SemanticVersionPlugin : Plugin<Project> {

    override fun apply(project: Project) {
        project.tasks.create("release", ReleaseTask::class.java) {
            group = "releasing"
        }
    }
}

这是我的任务:

open class ReleaseTask : Zip() {

    // This fuction copies the content of the distZip output into this task    
    private fun addProjectResultToRelease(zip: Zip, projectPath: String) {
        logger.quiet("   Adding $projectPath")
        with(zip) {
            val distTaskName = "$projectPath:distZip"
            val task = project.tasks.findByPath(distTaskName) ?: throw GradleException("Task not found: $distTaskName")
            task.outputs.files.filter { it.extension == "zip" }.forEach {
                val srcZip = project.zipTree(it)
                //includeEmptyDirs = false
                from(srcZip) {
                    eachFile {
                        this.path = (this.path.replaceBefore(delimiter = "/", replacement = ""))
                    }
                }
            }
        }
    }

    // Some default value overrides
    init {
        outputs.upToDateWhen { false }
        destinationDir = File("_release")
        baseName = project.name
    }


    @Suppress("unused")
    @TaskAction
    fun action() {
        val ext = project.extensions["semanticVersion"] as SemanticVersionExtension

        println(dependsOn.joinToString { it.toString() })

        // Iterating through dependencies
        dependsOn.forEach {
            it as String
            println("DEP: $it")
            addProjectResultToRelease(this, it.substringBeforeLast(":"))
        }

        from(project.file("version.txt"))

        super.copy()
    }
}

在我使用它的构建脚本中:

tasks.withType<ReleaseTask> {
    dependsOn(":core:distZip")
}

第一个问题:init块是设置或覆盖默认值的正确位置吗?

运行此任务时,收到“ NO-SOURCE”消息:

> ...
> Task :core:distZip UP-TO-DATE
> Task :release NO-SOURCE

如何指定相应distZip的输出是此任务的输入?

1 个答案:

答案 0 :(得分:0)

经过几十种不同的方法,我找到了解决方案。我与覆盖dependsOn函数的正确实现相距不远。

首先,我切换到5.4版。它使ZipTask的某些属性被弃用,但否则升级非常简单。

open class ReleaseTask : Zip() {

    // This function zips out the zip files and removes the root directory    
    private fun addProjectResultToRelease(task: Task) {
        logger.quiet("   Adding ${task.path}")
        task.outputs.files.apply { println(this) }.filter { it.extension == "zip" }.forEach {
            val srcZip = project.zipTree(it)
            includeEmptyDirs = false
            from(srcZip) {
                eachFile {
                    this.path = (this.path.replaceBefore(delimiter = "/", replacement = ""))
                }
            }
        }
    }

    // This overrides calls the unzip function for each dependancy
    override fun dependsOn(vararg paths: Any?): Task {
        super.dependsOn(*paths)

        paths.forEach {
            val t = project.tasks.getByPath(it.toString())
            addProjectResultToRelease(t)
        }

        return this
    }

    // Some refactor was needed for upgrade
    init {
        println("Init")
        outputs.upToDateWhen { false }
        from(project.file("version.txt"))
        destinationDirectory.set(project.file("_release"))
        archiveBaseName.set(project.name)
    }

    // At the moment this function override is needless, but here will come some other 
    // activities later
    override fun copy() {
        val ext = project.extensions["semanticVersion"] as SemanticVersionExtension

        println(archiveFile.get())

        super.copy()
    }
}

我仍然不完全满意init块中的设置。可能有一个生命周期函数可以替代,但是我错过了。