Kotlin-dsl-samples: Getting project properties via delegation is not working in buildscript block.

Created on 10 Oct 2017  路  12Comments  路  Source: gradle/kotlin-dsl-samples

In the buildscript block, getting properties via project delegation is not working as the other scope works.

Expected Behavior


In buildscript block, project properties can be accessed via project delegation.

Current Behavior


If we use project delegation in buildscript block, it fails to compile script.

Context


Managing project's dependencies in gradle.properties in multiple project, because of avoiding redundant description in each project scripts.

Steps to Reproduce (for bugs)


Given the script,

buildscript {
  dependencies {
    val junitGradlePlugin by project
    classpath("$junitGradlePlugin")
  }
}

and got

e: /Users/my/case/build.gradle.kts:14:34: Property delegate must have a 'getValue(Nothing?, KProperty<*>)' method. None of the following functions is suitable:
public operator fun Project.getValue(any: Any, property: KProperty<*>): Any? defined in org.gradle.kotlin.dsl

Your Environment

------------------------------------------------------------
Gradle 4.2.1
------------------------------------------------------------

Build time:   2017-10-02 15:36:21 UTC
Revision:     a88ebd6be7840c2e59ae4782eb0f27fbe3405ddf

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_141 (Oracle Corporation 25.141-b15)
OS:           Mac OS X 10.12.6 x86_64
bug kotlin-dsl-api

All 12 comments

Thanks for the report @mike-neck!

About your use case. You can manage versions of plugins applied to your multiple projects in a central place using the pluginManagement {} block in settings.gradle where gradle.properties can be used. See https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management.

This will also allow you to apply the plugins to your projects using the plugins {} block and then benefit from more Kotlin DSL goodness. See doc/getting-started/Configuring-Plugins.md.

Thanks @eskatos

For getting properties, I resolved this by using property function.

BTW I wonder that the extension function getValue(Any, KProperty) is not applied in buildscript block, and that declaring variable outside of buildscript using it in buildscript becomes compile error(I think it may because of gradle's build phases). I think it should be documented that project properties via delegation is not available at the buildscript block if it is difficult to fix this.

val foo by project
buildscript {
  repositories {
    maven {
      url(foo)  // <- error
    }
  }
  dependencies {
    val bar by project // <- error
    classpath("$bar")
  }
}

@mike-neck You can do something like this: https://github.com/jaredsburrows/android-gif-example/blob/master/build.gradle.kts#L5.

Apply your extra properties in your buildscript so they are ready to be used by your entire build:

buildscript {
  rootProject.apply { from(rootProject.file("gradle/dependencies.gradle.kts")) }

  repositories {
    jcenter()
  }

  dependencies {
    classpath(extra["gradle"] as String)
  }
}

Resolved in 09828a0.

@bamboo Does mean I can do classpath(extra["gradle"]) instead of classpath(extra["gradle"] as String)?

@jaredsburrows this about accessing project properties via delegated properties within the buildscript block:

buildscript {
  dependencies {
    val junitGradlePlugin by project
    classpath("$junitGradlePlugin")
  }
}

@bamboo Thanks! I still think it would be awesome to be able to get this all on 1 line!

Is this supposed to be working in the settings.gradle.kts file with Gradle 4.7? I can't get it to work

^ Missing 'getValue(Nothing?, KProperty<*>)' method on delegate of type 'Dependency'

@NikolayMetchev since 4.7 it should be:

buildscript {
    dependencies {
        val junitGradlePlugin: String by project
        classpath(junitGradlePlugin)
    }
}

Note that the delegated property type must now be declared.
See the "Potential breaking changes" section of gradle-kotlin-dsl-0.16.3 release notes.

@eskatos Thanks, but is it supposed to work in settings.gradle.kts?

@NikolayMetchev it does, but then you need to use by settings:

buildscript {
    dependencies {
        val junitGradlePlugin: String by settings
        classpath(junitGradlePlugin)
    }
}

@eskatos perfect thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mkobit picture mkobit  路  3Comments

cbeams picture cbeams  路  5Comments

jaredsburrows picture jaredsburrows  路  3Comments

wuchengithub picture wuchengithub  路  4Comments

jaredsburrows picture jaredsburrows  路  3Comments