Gradle 如何将自定义任务用作工件

Gradle 如何将自定义任务用作工件,gradle,gradle-dependencies,gradle-task,Gradle,Gradle Dependencies,Gradle Task,我在创建文件的项目(我们称之为projectA)构建脚本中有一个简单的自定义任务。任务如下所示: task createFile() { def outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt") outputs.file(outputFile) outputs.upToDateWhen { false } doLast { outputFile.parentFile.mkdirs() o

我在创建文件的项目(我们称之为
projectA
)构建脚本中有一个简单的自定义任务。任务如下所示:

task createFile() {
  def outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
  outputs.file(outputFile)
  outputs.upToDateWhen { false }
  doLast {
    outputFile.parentFile.mkdirs()
    outputFile.text = "Hello World"
  }
}
apply from 'util.gradle'

task createFile(type: CreateFile) {
  outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
}

artifacts {
  myDistConfig createFile.outputFile
}
该项目是多项目构建的一部分,我需要此任务生成的文件作为
projectB
中复制任务的输入。为了实现这一点,我在
projectB
中创建了一个配置和相应的依赖项:

configurations {
  mySourceConfig
}

dependencies {
  mySourceConfig project(path: ':projectA', configuration: 'myDistConfig')
}

task copySourceDependencies(type: Copy) {
   from configurations.mySourceConfig 
   into contextDir
}
projectA
中,我得到了一个
myDistConfig
配置,并希望使用
createFile
任务的输出文件作为此配置的工件:

configurations {
  myDistConfig
}

artifacts {
  myDistConfig createFile
}
如果我这样做,gradle告诉我任务不能转换为
ConfigurablePublishArtifact

在projectA的
build.gradle
中,如下所示:

task createFile() {
  def outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
  outputs.file(outputFile)
  outputs.upToDateWhen { false }
  doLast {
    outputFile.parentFile.mkdirs()
    outputFile.text = "Hello World"
  }
}
apply from 'util.gradle'

task createFile(type: CreateFile) {
  outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
}

artifacts {
  myDistConfig createFile.outputFile
}

现在gradle意识到了正确的依赖关系,它就像一个符咒

当使用任务作为工件符号时,它必须是类型。因此,对于其他类型的任务,您必须执行其他操作

使用
createFile.outputs.files.singleFile
的方法很好,因为它是受支持的类型(从错误输出中可以看到)。但是Gradle没有创建对生产任务的依赖性的原因是
文件
没有携带该信息。为此,它必须是
提供者
。但是解决这个问题的一个快速方法是明确地配置生成工件的任务:

artifacts.add("myDistConfig", createFile.outputs.files.singleFile) {
    builtBy("createFile")
}
或者,您也可以使用ObjectFactory将outputFile更改为
提供程序
RegularFileProperty
,因为其中包含任务生产者信息。我从未将它们作为DSL的一部分使用过,它可能更适合于处理类。(虽然这看起来需要更多的工作,但一旦代码增长到某个级别,它会使代码更具可读性。)下面是Groovy中的一个示例:

class MyFileCreator extends DefaultTask {
  @OutputFile
  RegularFileProperty outputFile = project.objects.fileProperty().convention(project.layout.buildDirectory.file("tmp/outputFile.txt"))

  @TaskAction
  void createFile() {
    File outFile = outputFile.get().asFile
    outFile.parentFile.mkdirs()
    outFile.text = "Hello World"
  }
}

MyFileCreator createFileTask = tasks.create("createFile", MyFileCreator)

configurations {
  myDistConfig
}

artifacts {
  myDistConfig createFileTask.outputFile
}

我可以在gradle文件中定义这个任务吗?它包含在
apply from:“my file ceator.gradle”
中。是的,在gradle脚本文件中一切都应该正常工作(甚至声明类)。另一种选择是使用目录,如果您想更好地组织它的话。