Title
m

mgrzechocinski

10/09/2018, 2:41 PM
Hey guys. I’m trying to migrate my project from Gradle to kotlin-dsl. One issue I’m struggling with is the usage of Gradle’s
apply from:
directive. Simplifying, when my
build.gradle.kts
file looks like this:
plugins {
   id("kotlin-android-extensions")
}

androidExtensions {
  isExperimental = true
}
it’s works fine. However, when I try to extract plugin definition to a separated file and apply it from my `build.gradle.kts`:
apply{
  from("$rootDir/kotlin_shared.gradle.kts") //contains plugins { id("kotlin-android-extensions") }
}

androidExtensions {
  isExperimental = true
}
it fails on
"Unresolved reference: androidExtensions"
. In Groovy version I had
apply from:
directive on top of my
build.gradle
file and it worked pretty well. Seems like kotlin’s
apply { from () }
doesn’t work like Gradle’s
apply from:
version, or am I missing sth?
r

ribesg

10/09/2018, 2:57 PM
The second block of code you're showing no longer uses the
plugins
block, and you should use it for it to work better
m

mkobit

10/09/2018, 3:03 PM
yup, the top level accessors (
androidExtensions
in this case) are only generated when they are applied in the
plugins {}
block gradle does like a 2 phase compilation, and since the
apply(from = "...")
is executed and not handled in the same way, gradle doesnt know about it so you either use
plugins {}
block to get accessors or need to know the type and do something like
configure<org.android.AndroidExtension> {}
you can use the
./gradlew kotlinDslAccessorsReport
to see what is generated by the
kotlin-dal
m

mgrzechocinski

10/09/2018, 3:10 PM
fine, I get it. Then why something like this doesn’t work either: https://github.com/mgrzechocinski/kstarter/pull/5/files
what I want to achieve is to have a “common”
.kts
file which I can include in my Android Gradle modules
in the pull request above, I get:
Script compilation errors:

  Line 7: androidExtensions {
          ^ Unresolved reference: androidExtensions

  Line 8:     isExperimental = true
              ^ Unresolved reference: isExperimental

2 errors
m

mkobit

10/09/2018, 3:12 PM
static accessors for script plugins are not yet implemented: https://github.com/gradle/kotlin-dsl/issues/427 / https://github.com/gradle/kotlin-dsl/issues/432
for the common KTS using
apply(from = "...")
there is ... something (cant find it ATM) for how you can do it using
buildSrc
precompiled script plugins or something like that?
m

mgrzechocinski

10/09/2018, 3:18 PM
I’m just wondering what’s the best way of sharing some common configuration code between different gradle modules. Currently, I have around 20 of them and they all need to access certain piece of shared configuration
m

mkobit

10/09/2018, 3:37 PM
yeah i hear ya the most common way ive seen it is using
buildSrc
for example, https://github.com/gradle/kotlin-dsl/blob/master/buildSrc/build.gradle.kts#L21 and using https://github.com/gradle/kotlin-dsl/tree/master/buildSrc/src/main/kotlin/plugins then the plugin ids can be consumed from the main build in a multi-project build
m

mgrzechocinski

10/09/2018, 3:47 PM
yup, I already use
buildSrc
for my dependencies catalog which I refer to from different modules
I guess my problem is Android specific as well. I have many modules which needs to access some shared piece of information like allowed build types. I can’t imagine duplicating this code across all modules. I’ll try to find some examples of open source Android multi-module projects which have migrated to kotlin-dsl
thanks for help!
g

gildor

10/09/2018, 4:51 PM
Use buildSrc for that, you can share any piece of config there as plugin or extension function
and check official migration guide, which also recommends to use buildSrc https://guides.gradle.org/migrating-build-logic-from-groovy-to-kotlin/
In your example with androidExtensions you have a few ways to do that. I would just applied this config every time when android-extensions plugin applied. You can easily do that in root build.gradle using
plugins.withId("kotlin-android-extensions") { /* your config */ }
function
The only problem that you don’t have type safe configuration for this, but you can use
configure<YourPluginExtension>
function instead
As I understand in your case you need this in your root project:
allprojects {
  plugins.withId("kotlin-android-extensions") {
      configure<AndroidExtensionsExtension> {
          isExperimental = true
      }
  }
}
m

mgrzechocinski

10/09/2018, 5:59 PM
cool, thanks!
j

Javier

07/23/2019, 12:34 PM
@gildor I am having problem with this too
g

gildor

07/23/2019, 12:35 PM
What kind problem?
j

Javier

07/23/2019, 12:35 PM
when I try to apply from a file
for example to add dependencies
I got this error:
implementation(Dependencies.kotlin) ^ Unresolved reference: implementation
g

gildor

07/23/2019, 12:37 PM
not sure that it’s related to this thread.
tho quite similar reason
j

Javier

07/23/2019, 12:38 PM
yep, I think it is the same problem really, when you use apply from + buildSrc
g

gildor

07/23/2019, 12:38 PM
Most probably you have this problem because you use allprojects/subprojects block on a project that doesn’t apply plugin with this configuration (java/kotlin/android)
j

Javier

07/23/2019, 12:38 PM
I am gonna try
g

gildor

07/23/2019, 12:38 PM
so or you have to apply plugin (it’s possible in buildSrc only with precompiled script plugins) or just use dynamic syntax:
"implementation"(Dependencies.kotlin)
you have static accessors for configurations (and other plugin things like tasks, extensions) only if apply plugin using plugins block which available only in build.gradle.kts or in precompiled script plugins
j

Javier

07/23/2019, 12:40 PM
if I change implementation for "implementation" the old error dissapear but I got
Configuration with name 'implementation' not found.
g

gildor

07/23/2019, 12:41 PM
so, plugin where you apply this dependency doesn’t have implementation configuraion
j

Javier

07/23/2019, 12:42 PM
so I need to add the plugin there?
g

gildor

07/23/2019, 12:43 PM
see,
implementation
is a configuration that provided by java plugin (also implicitly used by java), check that this project where you apply this dependency have it
also you said that it’s apply from and buildSrc, which not clear for me, what exactly you do
j

Javier

07/23/2019, 12:46 PM
I am trying to port build.gradle files to kts
in a similar project to that project
g

gildor

07/23/2019, 12:48 PM
yes, I understand, but where do you see this error, how buildSrc related to apply (because usually no reason to use apply with any buildSrc code)
j

Javier

07/23/2019, 12:50 PM
maybe it is not a problem of buildSrc
g

gildor

07/23/2019, 12:52 PM
this plugin applies com.android.application plugin, so it sould work (and probably works in this project)
j

Javier

07/23/2019, 12:58 PM
I am gonna try to convert directly this project
@gildor I just renamed the file and I wrote it in Kotlin. It is not working.
Script compilation errors:

  Line 09: android {
           ^ Unresolved reference: android
g

gildor

07/23/2019, 1:17 PM
Yes, because you need static accessors or use dynamic plugin application syntax
Please, check official guide from link above (Kotlin DSL primer and Groovy to Kotlin migration guides), it explains how to migrate such logic and provides alternative to script application (which really not good choice in case of Kotlin DSL, because completely dynamic)
j

Javier

07/23/2019, 1:21 PM
really I got it working when I don't try to use from another files
g

gildor

07/23/2019, 1:22 PM
Yes, that what I'm saying apply scripts is dynamic feature, you cannot use almost anything in script plugin, official guide explains this and provide solutions
Or just share some example, it hard to follow what are exactly doing by looking on different code that actually works
j

Javier

07/23/2019, 1:23 PM
Check this project
I am trying to migrate all gradle files to kts. The snippet I shared it is the android_commons.gradle