M.Devan
M.Devan

Reputation: 249

Use TOML vesion file in gradle

I try use version from libs.versions.toml to set composeOptions like this:

android {
 ...
    composeOptions {
        kotlinCompilerExtensionVersion = libs.versions.kotlinCompilerExtensionVersion.get()
    }
}

But I get error with .get() function :

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public inline operator fun <K, V> Map<out TypeVariable(K), TypeVariable(V)>.get(key: TypeVariable(K)): TypeVariable(V)? defined in kotlin.collections public operator fun MatchGroupCollection.get(name: String): MatchGroup? defined in kotlin.text

TOML versioning working well when a use this to apply plugins and implement libraries but not working when I want to get a version with .get()

Gradle version 7.5.1

Upvotes: 4

Views: 8141

Answers (3)

NickUnuchek
NickUnuchek

Reputation: 12857

toml file MyProject/gradle/libs.versions.toml:

[versions]
minSdk = "24"
kotlinVersion = "1.8.21"#https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-gradle-plugin
[libraries]
kotlinStdlibJdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlinVersion" }

In gradle use: libs.versions.kotlinVersion.get(), for example:

minSdk libs.versions.minSdk.get().toInteger()
...
dependencies {
    
    implementation "org.jetbrains.kotlin:kotlin-reflect:${libs.versions.kotlinVersion.get()}"
    implementation libs.kotlinStdlibJdk8

}

See documentation

Upvotes: 7

geek5nan
geek5nan

Reputation: 21

Short answer:

If your libs.versions.toml is like below

[versions]
compose = "1.4.3"
compose-compiler = "1.4.7"

then you should use

composeOptions {
  kotlinCompilerExtensionVersion libs.versions.compose.compiler.get()
}

Long answer:

Gradle will generate a LibrariesForLibs class based on the libs.versions.toml file, which you can find in the .gradle/7.5/dependencies-accessors/sources folder in the project root path.

For example, the toml mentioned above would generate code as follows:

@NonNullApi
public class LibrariesForLibs extends AbstractExternalDependencyFactory {
    @Inject
    public LibrariesForLibs(DefaultVersionCatalog config, ProviderFactory providers) {
        super(config, providers);
    }
    private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config);
    /**
     * Returns the group of versions at versions
     */
    public VersionAccessors getVersions() { return vaccForVersionAccessors; }
    public static class VersionAccessors extends VersionFactory  {
        private final ComposeVersionAccessors vaccForComposeVersionAccessors = new ComposeVersionAccessors(providers, config);
        public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
        /**
         * Returns the group of versions at versions.compose
         */
        public ComposeVersionAccessors getCompose() { return vaccForComposeVersionAccessors; }
    }
    public static class ComposeVersionAccessors extends VersionFactory  implements VersionNotationSupplier {
        public ComposeVersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
        /**
         * Returns the version associated to this alias: compose (1.4.3)
         * If the version is a rich version and that its not expressible as a
         * single version string, then an empty string is returned.
         * This version was declared in catalog libs.versions.toml
         */
        public Provider<String> asProvider() {return getVersion("compose");}

        /**
         * Returns the version associated to this alias: compose.compiler (1.4.7)
         * If the version is a rich version and that its not expressible as a
         * single version string, then an empty string is returned.
         * This version was declared in catalog libs.versions.toml
         */
        public Provider<String> getCompiler() {return getVersion("compose.compiler");}
    }
}

When you use the libs variable in gradle.build, you are actually accessing an instance object of LibrariesForLibs. So if you want to get the version of compose-compiler, you need to call libs.getVersions().getCompose().getCompiler().get() , and groovy has built-in getter syntactic sugar, so we can write more elegant code libs.versions.compose.compiler.get()

sample

Upvotes: 2

Evgeny K
Evgeny K

Reputation: 3167

If you get Unresolved reference. None of the following candidates is applicable receiver type mismatch... when you are trying to get a version of library xxx from your Gradle Version Catalogs via .get() method, in 99% of cases it means that you have library xxx-yyy in your [versions] block, e.g.

[versions]

kotlin = "1.7.20"
kotlin-coroutines = "1.6.4"
kotlin-serialization = "1.4.1"

In that case Gradle won't generate regular Provider for the field libs.versions.kotlin (in the example), it generates more complex object, because it has to generate libs.versions.kotlin.coroutines, libs.versions.kotlin.serialization fields.

That's why if you want to get library version you have to explicitly ask for provider using .asProvider() before getter .get():

libs.versions.kotlin.asProvider().get()

and for library in question it will be:

libs.versions.kotlinCompilerExtensionVersion.asProvider().get()

Upvotes: 2

Related Questions