Precompiled script plugin : accessing another precompiled script plugin extension

In my buildSrc, I have one precompiled script plugin used to configure the feature name of my module (in a multi module project) like so :

buildSrc/src/main/kotlin/myFeature.gradle.kts:

interface MyFeaturePluginExtension {
    val name: Property<String>
}

val extension = extension.create<MyFeaturePluginExtension>("myFeature")
extension.name.convention(project.name.substringBefore("-"))

So in my modules, I can override the default name like so :
awesomeFeature/build.gradle.kts:

plugins {
    `my-feature`
}

myFeature {
    name.set("awesome-feature")
}

I would like to use this name in another precompiled script plugin but can’t find how.

I tried this :
buildSrc/src/main/kotlin/baseDeps.gradle.kts :

plugins {
    id("my-feature")
}

val featureName = the<MyFeaturePluginExtension>().name.get()

dependencies {
   "implementation"(project(":$featureName-domain"))
}

I get the following error : Unresolved reference: MyFeaturePluginExtension

How can I do something like this ?

Imagine the contents of a Kotlin as body of a class, that’s close to reality.
So your extension interface is not available to the other script.
Move it out into its own .kt file where both scripts can access it, then it should work like you tried.

Except that you get the name before giving the consumer a chance to set it by using an early get().

You have to delay the dependency adding.

Ok, I will try that. Thanks for your answer

So, I have not the error anymore if I put the interface in a separate file. Thanks a lot.

You told me to delay the dependency adding. How can I do this ?

I thought doing this would work :

buildSrc/src/main/kotlin/baseDeps.gradle.kts :

plugins {
    id("my-feature")
}

val featureName = the<MyFeaturePluginExtension>().name

dependencies {
   "implementation"(project(":${featureName.get()}-domain"))
}

But it seems dependencies block is ran before my configuration.

Any idea ?

That variant has exactly the same problem that you immediately evaluate it.
Iirc, should be something like

val implementation by configurations
implementation.dependencies.addLater(featureName.map { dependencies.project(":$it-domain") })

Works like a charm. Thanks a lot.

In case someone will check later, I had to change a bit to :

implementation.dependencies.addLater(project.provider {featureName.let { dependencies.project(":${it.get()}-domain") }})

Can you elaborate why that was necessary?
What I gave you at least compiled and I think should work, though I didn’t test it.
Why did you need to uglify it?

Ok, my bad.
It was a misunderstanding on my part.

I went back to your solution.

Thanks a lot.

1 Like