can a pre-compiled script plugin be parameterized?...
# gradle
e
can a pre-compiled script plugin be parameterized? don’t see it mentioned in the docs
v
What do you mean with parameterized? A precompiled script plugin can basically do anything a normal plugin can also do.
It's just a different syntax to get the same result
e
So if I have
kotlin/com/example/gradle/myplugin.gradle.kts
Can I do something like this:
Copy code
plugins {
    id "com.example.myplugin" version "1.0.0-RC02"
}

myplugin {
  someprop1 = 1
  someprop2 = "foo"
}
v
Sure, if you add an extension with that name to the project in your plugin, just like with any other plugin
Copy code
interface MyExtension {
    val someprop1: Property<Int>
    val someprop2: Property<String>
}
val myExtension = extensions.create<MyExtension>("myPlugin")
e
Ahhh… the last line does the registration. Didn’t know how to do that since we aren’t implementing
apply
Thanks
v
Your whole script is the content of an apply method effectively
e
Is there an idiomatic way to establish defaults? I’m trying this and it isn’t quite right.
Copy code
interface ScaffoldExtension {
    @get:Input
    val version: Property<String>

    @get:Input
    val javaVersion: Property<String>

    @get:Input
    val freeCompilerArgs: Property<Array<String>>

    @get:Nested
    val models: LibraryProperties
}

val extension = extensions.create<ScaffoldExtension>("scaffold")
with(extension) {
    version.convention("1.0")
    javaVersion.convention("1.8")
    freeCompilerArgs.convention(arrayOf("-Xjsr305=strict"))

    models.include.convention(true)
    models.version.convention("2.350.0")
}

interface LibraryProperties {
    @get:Input
    val include: Property<Boolean>

    @get:Input
    val version: Property<String>
}
I can’t seem to specify
models.version
in the build that’s using the plugin:
Copy code
scaffold {
    version = "1.1"
    models {
        version = "2.351.0"
    }
}
v
What has the establishing of defaults to do with the inability to set the version?
The setting of defaults is fine I think if the semantics of
convention
is what you want. For setting the version, you thier need to use
models.version = "2.351.0"
, or you need to provide the configuration helper yourself, those are not auto-generated.
Copy code
fun models(block: Action<LibraryProperties>) {
    block.execute(models)
}
👍 1
e
I think my issue is lifecycle related. By the time the project can set that property, the plugin has already been applied.
I’m trying to dynamically add some dependencies.
Copy code
if (extension.gcpStorage.include.getOrElse(false)) {
    implementation("com.google.cloud:google-cloud-storage:${extension.gcpStorage.version.getOrElse(Defaults.gcpStorageVersion)}")
}
I can set
Copy code
scaffold {
    gcpStorage.include = true
}
but the dependency does not get added. I think it is too late.
v
Yes, you can for example instead make a method in your extension that adds the dependency
👍 1
e
The Kotlin compiler is crashing when trying to add a function to the interface. Tried the various
jvm-default
compiler options to no avail. If I make the extension an abstract class instead of an interface, then the consuming project can’t create an instance.
Copy code
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
        at org.gradle.internal.instantiation.generator.DependencyInjectingInstantiator.addServicesToParameters(DependencyInjectingInstantiator.java:167)
Does the abstract extension need a ctor w/ a certain signature?
v
Nah, the problem is probably not that you add a function, but the content of the function accessing something from the outer context and thus getting a constructor Gradle cannot handle.
I don't have in mind right now how to properly do it. Maybe you need to make an explicit constructor and when calling the
create
give as additional parameters what you need as constructor args or something like that iirc
e
ahhh… passing a
DependencyHandler
in to my function, seems to have done it. otherwise it was trying to access it outside some scope
This is now adding GCP’s storage dependency w/ a default version as desired:
Copy code
scaffold {
    gcpStorage {
        include = true
    }
}.addDependencies(dependencies)
thanks so much for your help
v
yw