hello, i'm trying to define custom gradle task tha...
# gradle
d
hello, i'm trying to define custom gradle task that accepts output file name and generates corresponding output file according to some logic, e.g.
Copy code
@Input
@Option(option = "outputFileName", description = "target file name")
val outputFileName: Property<String> = project.objects.property(String::class.java)

@Suppress("UnstableApiUsage")
@Internal
@OutputFile
val outputFile: RegularFileProperty = project.objects.fileProperty()
How do I properly initialize the
outputFile
with the specified
outputFileName
?
d
something like
Copy code
init {
    outputFile = project.objects.fileProperty().fileValue(File(outputFileName.getOrElse("whatever")))
}
?
o
I mean, you can leave the initializer as is
I was specifically suggesting
convention(Provider<RegularFile>)
outputFile.convention { project.layout.projectDirectory.file(outputFileName.getOrElse("whatever")) }
d
getting type mismatch required
File
but got
RegularFile
o
are you sure? I explicitly wrote that to use
RegularFile
d
Copy code
@Internal
    @OutputFile
    val outputFile: RegularFileProperty = project.objects.fileProperty()

    init {
        outputFile.convention { project.layout.projectDirectory.file(outputFileName.getOrElse("whatever")) }
}
intellij complains about it
guess can do regular file as file
o
what part is requiring a File
d
convention
also it looks like this doesn't work with cli
always uses the else
o
that's odd, what version of Gradle are you on?
RegularFileProperty.convention
uses
RegularFile
in 6.1.1
d
6.0.1
o
it's the same
sounds like you have other issues at play
d
let me check if intellij picks the correct one or not
k settings point to gradle wrapper which points to version 6.1
brb
k issue was lambda
{}
vs value set
()
o
oh, right, Provider isn't a functional interface
it won't work properly without the lambda
it initializes too early
d
so the remaining problem is how to get cli working
i.e. when task is evaluated it always goes to the else
o
wrap the lambda in
project.provider()
that should work
d
🤞
you mean
project.provider { convention }
? didn't like it
apologies if i'm asking very basic questions
its pretty confusing to me
o
no, like I had above, but the
{ ... }
wrapped in
project.provider
, e.g.
outputFile.convention(project.provider { ... })
you're converting a lambda to a
Callable
via implicit Single-Abstract-Method (SAM) Conversion, then
project.provider()
converts that to a
Provider
, which
outputFile.convention()
can then take
d
if i wrap that in project provider then i got provider of a provider of a regular file 😞
o
why?
the lambda should be returning a RegularFile
oh, wait, this is way simpler
outputFile.convetion(project.layout.projectDirectory.file(outputFileName))
d
doh
o
and you should the convention for
outputFileName
to "whatever"
then you don't need
getOrElse
d
yeah the problem is the get or else
k gotcha
using convention i can set the default value if it is not specified
awesome
you are the best!
thanks for the help
btw since i don't want to let people mutate the output file I changed it to
Copy code
@OutputFile
val outputFile: Provider<RegularFile> = outputFileName.map { name -> project.layout.projectDirectory.file(name) }
thanks!