https://kotlinlang.org logo
Title
d

Dariusz Kuc

02/07/2020, 2:57 AM
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.
@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

Dariusz Kuc

02/07/2020, 3:02 AM
something like
init {
    outputFile = project.objects.fileProperty().fileValue(File(outputFileName.getOrElse("whatever")))
}
?
o

octylFractal

02/07/2020, 3:02 AM
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

Dariusz Kuc

02/07/2020, 3:06 AM
getting type mismatch required
File
but got
RegularFile
o

octylFractal

02/07/2020, 3:06 AM
are you sure? I explicitly wrote that to use
RegularFile
d

Dariusz Kuc

02/07/2020, 3:07 AM
@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

octylFractal

02/07/2020, 3:08 AM
what part is requiring a File
d

Dariusz Kuc

02/07/2020, 3:08 AM
convention
also it looks like this doesn't work with cli
always uses the else
o

octylFractal

02/07/2020, 3:09 AM
that's odd, what version of Gradle are you on?
RegularFileProperty.convention
uses
RegularFile
in 6.1.1
d

Dariusz Kuc

02/07/2020, 3:09 AM
6.0.1
o

octylFractal

02/07/2020, 3:09 AM
it's the same
sounds like you have other issues at play
d

Dariusz Kuc

02/07/2020, 3:10 AM
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

octylFractal

02/07/2020, 3:46 AM
oh, right, Provider isn't a functional interface
it won't work properly without the lambda
it initializes too early
d

Dariusz Kuc

02/07/2020, 3:46 AM
so the remaining problem is how to get cli working
i.e. when task is evaluated it always goes to the else
o

octylFractal

02/07/2020, 3:47 AM
wrap the lambda in
project.provider()
that should work
d

Dariusz Kuc

02/07/2020, 3:47 AM
🤞
you mean
project.provider { convention }
? didn't like it
apologies if i'm asking very basic questions
its pretty confusing to me
o

octylFractal

02/07/2020, 3:50 AM
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

Dariusz Kuc

02/07/2020, 3:56 AM
if i wrap that in project provider then i got provider of a provider of a regular file 😞
o

octylFractal

02/07/2020, 3:57 AM
why?
the lambda should be returning a RegularFile
oh, wait, this is way simpler
outputFile.convetion(project.layout.projectDirectory.file(outputFileName))
d

Dariusz Kuc

02/07/2020, 3:58 AM
doh
o

octylFractal

02/07/2020, 3:58 AM
and you should the convention for
outputFileName
to "whatever"
then you don't need
getOrElse
d

Dariusz Kuc

02/07/2020, 3:58 AM
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
@OutputFile
val outputFile: Provider<RegularFile> = outputFileName.map { name -> project.layout.projectDirectory.file(name) }
thanks!