I'm migrating from groovy to kts. In my root buil...
# community-support
c
I'm migrating from groovy to kts. In my root build.gradle we have
Copy code
subprojects {
  configurations.configureEach {
    resolutionStrategy ...
  }
  afterEvaluate { subproject ->
    subproject.apply from: "$subproject.rootDir/jacocoTask.gradle"  
  }
}
I updated the after evaluate in kts to
Copy code
afterEvaluate {
    apply { from("$rootDir/jacocoTask.gradle") }
  }
but now I get an error in my jacocoTask.gradle file on this line
task coverageReport(type: JacocoReport...
So my questions are: 1. Is my conversion correct? 2. I'm assuming the previous code was not correct since I now get an error in my jacoco Task.gradle file? I guess it wasn't being executed at all before? 😱 I'm new to this project so its been ad adventure trying to modernize some of these things 😅
Maybe the purpose of this script was to only run on subprojects and so changing it from subproject.rootdir to just rootdir actually is the issue?
v
subproject.rootdir
and
rootdir
should be the same. It should always be the project directory of the root project of the build. But that the original little snippet combines at least 4 quite bad practices you know, right? 🙂
But besides that, what you showed makes impossible that you get an error from
jacocoTAsk.gradle
, because the snippet you showed is syntactically not valid Kotlin, so the build script would not even compile 🙂
c
> at least 4 quite bad practices you know, right? The only one I can think of is
subprojects
because I should be using convention plugins I think? 😅 (please let me know what other cardinal rules im breaking here. always learning. And yes sorry about the kts compile issue. I updated the snippet. I dont have gradle slack on my work laptop. sorry for the sloppy copy pasta.
e
I'm not at a computer to check but I'm pretty sure you've converted to the wrong
apply
👀 1
I'd expect
apply(from =)
because
apply {}
is Kotlin's receiver and not Gradle's plugin application
👀 1
c
hm. that didn't work. let me go back to groovy and see if i can make the issue repro with just groovy to get the kts conversion out of the equation.
interesting. back in groovy this (original code) doesn't cause an error downstream
Copy code
afterEvaluate { subproject ->
    subproject.apply from: "$subproject.rootDir/jacocoTask.gradle"  
  }
while (keeping it in groovy)
Copy code
afterEvaluate {
    apply from: "$rootDir/jacocoTask.gradle"  
  }
does cause an error downstream...
so something about subproject it doesn't like
e
it's still bad practice to be doing so across project boundaries as Vampire already brought up though
c
yeah. i fully get that this is bad. (personally id like to delete all the jacoco stuff... i dont think those code coverage reports even show anywhere (does jacoco even work with kotlin? anyway, id like to delete it long term) short term tho... im just trying to convert to kts and failing because of this damn afterEvaluate
v
The only one I can think of is subprojects because I should be using convention plugins I think? 😅 (please let me know what other cardinal rules im breaking here. always learning.
Yes, cross-project configuration is one of the points. Next is
afterEvaluate
which should imho be avoided at almost any cost and die the most part only brings you ordering problems, timing problems, and race conditions. Then using a legacy script plugin (the ones you use with "apply from", they have many works and are discouraged. And number 4 is
task coverageReport(type: JacocoReport...
which is an eager API, directly creating the task, instead of a lazy API leveraging task-configuration avoidance. Regarding the actual question, I think the problem was already started (wrong apply), but I wonder what from is used there then. JaCoCo works fine with Kotlin, yes, I use it every day.
c
hm. i did try the apply approach that ephemient brought up and no dice. i also just stopped trying to convert to kts and tried removing the "subproject" instances ie. before build.gradle doesn't cause an error downstream
Copy code
afterEvaluate { subproject ->
    subproject.apply from: "$subproject.rootDir/jacocoTask.gradle"  
  }
after build.gralde (not kts)
Copy code
afterEvaluate {
    apply from: "$rootDir/jacocoTask.gradle"  
  }
and it does cause an error downstream... so even without moving to kts, I still have the same error so it seems like subproject is actually needed?
okay. very interesting. so if I do (build.gradle, still no kts)
Copy code
afterEvaluate {
    it.apply from: "$rootDir/jacocoTask.gradle"  
  }
then no failure...
and if i convert the above to kts... then i get a failure... until I change
it
to
this
. then no failure again. this hurts my brain.
v
Hm, actually the
apply { from("$rootDir/jacocoTask.gradle") }
that @ephemient and me thought is invalid is fine.
apply
is
void apply(Action<? super ObjectConfigurationAction> action);
. TIL
so even without moving to kts, I still have the same error so it seems like subproject is actually needed?
Without looking, I guess without the
subproject.
you call it on the cross-configuring project when the cross-configured projectg is configued. So you apply that script plugin to the root project or whereever the code is instead of the subproject.
okay. very interesting. so if I do (build.gradle, still no kts)
Yes, what I just said. if you leave out the
subproject ->
, then it is
it
.
and if i convert the above to kts... then i get a failure... until I change
it
to
this
. then no failure again. this hurts my brain.
That's because of the sam-with-receiver plugin, so that in that lambda the argument is available as
this
, so that you can have a nicer DSL. But that is a Kotlin specific and in Groovy it is different.
c
i do wonder if this code never "worked" right to begin with. the fact that i get a error in jacocoTask.gradle about a task name already being used seems like a valid error and i should update it. but it sounds like jacocoTask.gradle was never even being executed in the first place...
v
You might still not have understood what I said. Assume you have a root project with two subprojects. As you do
subprojects { ... }
, you do the closure two times, once for each subproject. And as you call the apply on the root project, you call it twice in the root project. And as it is a legacy script plugin, not a normal plugin, it is indeed done twice, so on second indication the task is already registered and it fails.
c
ah. thank you for re-stating. i think ive got it now. thanks for teaching
👌 1