I have a simple custom task in a project's (lets call it projectA
) build script that creates a file. The task looks like this:
task createFile() {
def outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
outputs.file(outputFile)
outputs.upToDateWhen { false }
doLast {
outputFile.parentFile.mkdirs()
outputFile.text = "Hello World"
}
}
The project is part of a multiproject build and I need the file generated by this task as input for a Copy task in projectB
. To achieve this I created a configuration in projectB
and a corresponding dependency:
configurations {
mySourceConfig
}
dependencies {
mySourceConfig project(path: ':projectA', configuration: 'myDistConfig')
}
task copySourceDependencies(type: Copy) {
from configurations.mySourceConfig
into contextDir
}
In projectA
I got a myDistConfig
configuration and want to use the output file of the createFile
task as artifact for this configruation:
configurations {
myDistConfig
}
artifacts {
myDistConfig createFile
}
If I do this, gradle tells me that a task cannot be converted to a ConfigurablePublishArtifact
:
> Cannot convert the provided notation to an object of type ConfigurablePublishArtifact: task ':projectA:createFile'. The following types/formats are supported: - Instances of ConfigurablePublishArtifact. - Instances of PublishArtifact. - Instances of AbstractArchiveTask, for example jar. - Instances of Provider<RegularFile>. - Instances of Provider<Directory>. - Instances of Provider<File>. - Instances of RegularFile. - Instances of Directory. - Instances of File. - Maps with 'file' key
So I tried createFile.outputs.files.singleFile
as artifact. This stops gradle from complaining, but fails to setup the dependency between :projectB:copySourceDependencies
and :projectA:createFile
and if projectB:copySourceDependencies
is executed on a clean workspace it is simply skipped with status NO-SOURCE
.
Is it somehow possible to use a custom task as artifact similar to a Zip task, to make gradle aware of the dependency?!
Update 2020-02-28:
Based on the very good answer by @BjørnVester I implemented the following task in a separate gradle file util.gradle
:
class CreateFile extends DefaultTask {
@OutputFile
RegularFileProperty outputFile = project.objects.fileProperty()
@TaskAction
void createFile() {
def tOutFile = outputFile.get().asFile
tOutFile.parentFile.mkdirs()
tOutFile.text = "Hello World"
}
}
rootProject.ext.CreateFile = CreateFile
In projectA's build.gradle
this looks like this:
apply from 'util.gradle'
task createFile(type: CreateFile) {
outputFile = rootProject.file("${buildDir}/tmp/outputFile.txt")
}
artifacts {
myDistConfig createFile.outputFile
}
Now gradle is aware of the correct dependencies and it works like a charm!