This message was deleted.
# community-support
s
This message was deleted.
v
"requires" is wrong. "does" is correct. And "doing it" is wrong. 🙂 Just remove the import
The hash changes everytime the classpath of those accessors changes
Sometimes IntelliJ is adding these imports when copying around things within such scripts, but they are just non-sense.
You showed that you use the string-y API to access the verison catalog. But could it be that you are also using my hack-around for using the static accessors for version catalogs in precompiled script plugins? Because I believe that such inserted imports might be a side-effect of using that hack-around.
l
In my case it is indeed required. When I remove it, I neither can build nor sync it. > But could it be that you are also using my hack-around for using the static accessors for version catalogs in precompiled script plugins? I'm using
val libs: VersionCatalog = versionCatalogs.named("libs")
in all scripts.
v
Oh, yes, now I see the problem
You only get static accessors generated for things that are added by plugins unconditionally that you add within the same script in a
plugins { ... }
block.
You are using the accessor that is generated for something else and if the classpath of that "else" changes the accessor package changes
One way to solve this by properly using type-safe accessors is, to apply the necessary plugin in the
plugins { ... }
block of that script, as the pure presence of the accessor is already a guarantee, that the configuration you try to use there is present at runtime.
By using such imports you are voiding the type-safety and could as well not use type-safe accessors at all
Which would be the other possible solution, for example by replacing
implementation(platform(it))
by
"implementation"(platform(it))
Or by adding before a
val implementation by configurations
, that would also work but also not have the "it exists" compile-time guarantee, but fail at runtime if it does not.
So summarized, if you ever use such imports anywhere, you are definitely doing something wrong and should change it. 🙂
❤️ 1
l
I understand. I would like to try solution 1 (apply plugin) or solution 3 (val implementation by configurations). Do you know which plugin I could apply. I tried with kotlin("android") but this didn't help.
v
I think Android is very special as always. I'm not into Android dev, but afair the variants like "debug" can be configured and the AGP then adds the configurations and so on for it depending on that configuration. This does not fulfill the "unconditionally" requirement I mentioned above, so it would probably be sufficient to use
implementation
but not
debugImplementation
I guess.
l
ok and which plugin can I add to provide accessor for
implementation
?
v
You should apply that plugin that does do register those configurations that are then also used. Applying any plugin just because it adds that configuration, then you can also just use "solution 3".
But actually,
kotlin("android")
is fine.
I just tried and it adds both,
implementation
and
debugImplementation
❤️ 1
l
You should apply that plugin that does do register those configurations that are then also used. Applying any plugin just because it adds that configuration, then you can also just use "solution 3".
Makes sense. Solution 3 is clean. I like it and it works
v
Solution 1 is cleaner and as I said
kotlin("android")
is sufficient. But whatever works for you
🙂
l
Unfortunately, it does not work. Any ideas?
v
Did you sync?
Does it also not build from commandline?
l
Sync fails, and .\gradlew configuration pluginbuild in terminal fails too
v
And the concrete error message is?
l
configuration-plugin/src/main/kotlin/de/test/configuration/compose-deps.gradle.kts1149 Unresolved reference: implementation
v
Hm, very strange. Is that something you can share, or maybe you can knit an MCVE?
l
Should be possible. Give me some time to prepare. Can I drop a zip here with the project or should I dm you?
v
What you prefer
l
Thanks for your investigation
v
Ah, sorry, I'm stupid. Applying
kotlin("android")
is of course useless. But to apply it I had to apply one of the android plugins or it fails. And those are adding these configurations, so you would need to apply one of the Android plugins
Unfortunately, as far as I know there is no common base plugin that does this work that you could use, and as you use that plugin in the other two convention plugins you can apply neither or you get an error when you build the respective other convention plugin that uses it. So the "correct" solution for your case is probably indeed "3", with reacting to the Android plugins. Otherwise - i.e. currently - your plugin depends on ordering and fails if you apply it before applying one of the Android plugins and that is again bad practice. Should be something like this:
Copy code
package de.test.configuration

val libs: VersionCatalog = versionCatalogs.named("libs")

listOf(
    "com.android.application",
    "com.android.library"
).forEach {
    pluginManager.withPlugin(it) {
        val implementation by configurations
        val debugImplementation by configurations

        dependencies {
            libs.findLibrary("compose-bom").ifPresent { implementation(platform(it)) }
            libs.findLibrary("core-ktx").ifPresent { implementation(it) }
            libs.findLibrary("coroutines-android").ifPresent { implementation(it) }
            libs.findBundle("compose").ifPresent { implementation(it) }
            libs.findLibrary("compose-ui-tooling-core").ifPresent { debugImplementation(it) }
            libs.findLibrary("compose-ui-test-manifest").ifPresent { debugImplementation(it) }
        }
    }
}
l
Good job, thank you. Wouldn't it be sufficient to just write
Copy code
val implementation by configurations
val debugImplementation by configurations

dependencies {
    libs.findLibrary("compose-bom").ifPresent { implementation(platform(it)) }
    libs.findLibrary("core-ktx").ifPresent { implementation(it) }
    libs.findLibrary("coroutines-android").ifPresent { implementation(it) }
    libs.findBundle("compose").ifPresent { implementation(it) }
    libs.findLibrary("compose-ui-tooling-core").ifPresent { debugImplementation(it) }
    libs.findLibrary("compose-ui-test-manifest").ifPresent { debugImplementation(it) }
}
v
No, for the reason I just explained
Well, you don't make it worse, but you keep the bad-practice state
l
But why does it work with the simple version?
v
Because you apply your plugin after having one of the Android plugins applied. Apply your plugin first and it will fail. And that is the bad-practice. Either apply what you need in your plugin, or react to the plugin you need being applied, then the order becomes irrelevant.
l
Ahh ok, now I understand what's going on. You are still the best ❤️
You helped me a lot
👌 1