I don't really understand lazy APIs: what's the di...
# community-support
b
I don't really understand lazy APIs: what's the difference between a RegularFile and a Provider<RegularFile> and which one should I use?
✅ 1
t
When declaring task inputs/outputs, you should use a
RegularFileProperty
https://docs.gradle.org/current/userguide/lazy_configuration.html#working_with_files_in_lazy_properties
b
should everything be lazy?
I want to pass a project version into the task, should I use Property<String>?
âž• 1
also looking at
layout.buildDirectory.file("release.zip")
this returns a Provider<RegularFile> not a RegularFileProperty
not sure how to convert here or if I'm using the wrong APIs
are the docs wrong?
Copy code
greeting.set("Hi") 
greeting = "Hi"
these are mentioned as equivalent but the latter throws a Type mismatch: inferred type is String but Property<String> was expected
./gradlew --version gives me Gradle 8.10
getting this warning btw, not sure if that's the cause though The
embedded-kotlin
and
kotlin-dsl
plugins rely on features of Kotlin
1.9.24
that might work differently than in the requested version
2.0.20
.
t
Are you declaring a task? or configuring one? A
RegularFileProperty
is for declaration; and the property can then be given a
RegularFile
, a
Provider<RegularFile>
, or even a
File
or
Provider<File>
(using the
fileValue()
and
fileProvider()
methods
b
using tasks.register
Copy code
tasks.register<Release>("release") {
    dependsOn("package")
    releaseZip = layout.buildDirectory.file("release.zip")
    version.set(project.version.toString())
}
t
…so configuring a task (that you happen to register yourself)
b
yes
that's the task class btw
Copy code
abstract class Release : DefaultTask() {
    @get:InputFile
    abstract var releaseZip: RegularFileProperty

    @get:Input
    abstract var version: Property<String>

    @TaskAction
    fun action() {
        val zipFile = releaseZip.asFile.orNull
        if (zipFile == null || !zipFile.exists()) {
            throw IllegalStateException("Need an archive file")
        }
        println(version.get())
        println(zipFile.absolutePath)
    }
}
placed that one in buildSrc
t
And here declaring it. Everything looks OK.
âž– 1
Being the provider (buildSrc) and consumer of the task, you could very well use non-lazy properties, but I must say I can't find a compelling reason
b
looking at the type definitions: layout.buildDirectory.file returns a Provider<RegularFile!> which is a supertype of RegularFileProperty
that obviously can't work
could also be that there are some kotlin DSL issues when using Kotlin 2.0 but from what I've seen, the gradle dsl is not yet ported to 2.0
I think I'm gonna ask in the Kotlin Slack
t
Kotlin 2 might indeed be a problem. Use the
.value()
or
.set()
rather than
=
then.
b
the Kotlin docs mention that assignment is fine though, is that a mistake?
although looking at the java interop docs, I don't see a way how this can work
t
Ha, your
Release
task should use
val
, not
var
!
b
what the hell
t
The
=
syntactic sugar is then added by Gradle
b
thanks
is that compiler magic?
t
I don't know the details, but some kind of "magic" yes
v
Actually, it is not Gradle magic in this case, just hooking in Kotlin magic.
It is the
org.jetbrains.kotlin.assignment
compiler plugin (mainly developed for this use-case though as far as I know 😄)
b
code generation, right?
based on some kind of AST introspection
v
Gradle configures it to use the
SupportsKotlinAssignmentOverloading
, so any class annotated with that annotation can use this assignment overloading on
val
properties of that type.
Code generation, no
As I said, it is a compiler plugin
If you want to know the gory details, you can look at the sources at https://github.com/JetBrains/kotlin/tree/master/plugins/assign-plugin
b
I see, thank you, that makes it clearer
👌 1
j
Is that plugin working outside of Gradle scripts?
v
Sure, it is usable in any Kotlin project I think. Just use that compiler plugin and configure it accordingly by giving it the annotations that mark such cases. For example apply the Gradle plugin https://plugins.gradle.org/plugin/org.jetbrains.kotlin.plugin.assignment developed at https://github.com/JetBrains/kotlin/tree/master/libraries/tools/kotlin-assignment. It registers a project extension of type
AssignmentExtension
called
assignment
with which you can configure the annotations that mark supported types in your project.
For types in Gradle plugins you can probably just use the
SupportsKotlinAssignmentOverloading
annotation, it is part of the Gradle public API as it is
org.gradle.api.SupportsKotlinAssignmentOverloading
.
If you did mean not own types, but with the Gradle types, then just with the other compiler plugins like
sam-with-receiver
and so on, simply apply the
kotlin-dsl
plugin which configures this compiler plugin, or configure the plugin yourself if you don't like to use the
kotlin-dsl
plugin for some reason.
j
Sure, it is usable in any Kotlin project I think.
I mean, it is applied on simple kt files in buildSrc by default? I doubt it is applied so the equals overload will not work there
v
As I said, depends on whether you either apply the
kotlin-dsl
plugin or manually configure the compiler plugin. As I usually use included builds instead of
buildSrc
I don't remember the details, but it could even be that the
kotlin-dsl
plugin is applied automatically in
buildSrc
build.