Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-debug/build.gradle.kts (Kotlin)

Code before:
val shadowJarWithCorrectModuleInfo by tasks.registering(Jar::class) {
    group = "shadow"
    from(zipTree(shadowJar.archiveFile))
    from(tasks.compileModuleInfoJava) {
        // Include **only** file we are interested in as JavaCompile output also contains some tmp files
        include("module-info.class")
        into("META-INF/versions/9/")
    }
    duplicatesStrategy = DuplicatesStrategy.FAIL
    archiveBaseName.set(jar.archiveBaseName)
    archiveVersion.set(jar.archiveVersion)
    archiveClassifier.set(jar.archiveClassifier)
    manifest {
        attributes(mapOf(
            "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain",
            "Can-Redefine-Classes" to "true",
            "Multi-Release" to "true"
        ))
    }
}

tasks.getByName("publishMavenPublicationToMavenLocal") {
    dependsOn(shadowJarWithCorrectModuleInfo)
}

VersionFile.configure(project, shadowJarWithCorrectModuleInfo.get())

configurations.all {
    // we're not interested at all in the output of the shadowJar task; it's just an intermediate stage
    outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(shadowJar) }
    // if something wants a `jar` to be published, we want to publish the `shadowJarWithCorrectModuleInfo` instead
    if (outgoing.artifacts.buildDependencies.getDependencies(null).contains(jar)) {
        outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
        outgoing.artifact(shadowJarWithCorrectModuleInfo)
    }
}

koverReport {
    filters {
        excludes {
            // Never used, safety mechanism
            classes("kotlinx.coroutines.debug.internal.NoOpProbesKt")
        }
    }
}


Review comment (suggestion):
Thank you for going the extra mile with rewriting the build script into kts!

While we are here, would you mind improving it even more?

The current approach breaks [configuration avoidance](https://docs.gradle.org/current/userguide/task_configuration_avoidance.html).

AFAIK, the recommended approach is the following:

0) Generally, avoid materializing tasks during the configuration phase (e.g. when you are receiving the task of a particular type in an arbitrary place of code)

1) This line should be `VersionFile.configure(project, shadowJarWithCorrectModuleInfo)`

2) `VersionFile.configure` should configure the given task provider: `jarProvider.Configure { dependsOn(...) `

3) The other callsite (version file convention) should do the similar trick:

```
tasks.withType<>.configureEach { ... }
```

Code after:
    from the `jar` task is not present when the compilaton finishes, even if the file with this name exists. */
    archiveClassifier.convention(null as String?)
    archiveClassifier.set(null as String?)
    archiveBaseName.set(jar.flatMap { it.archiveBaseName })
    archiveVersion.set(jar.flatMap { it.archiveVersion })
    manifest {
        attributes(
            mapOf(
                "Premain-Class" to "kotlinx.coroutines.debug.AgentPremain",
                "Can-Redefine-Classes" to "true",
                "Multi-Release" to "true"
            )
        )
    }
    // add module-info.class to the META-INF/versions/9/ directory.
    dependsOn(tasks.compileModuleInfoJava)
    doLast {
        // We can't do that directly with the shadowJar task because it doesn't support replacing existing files.
        val zipPath = this@existing.outputs.files.singleFile.toPath()
        val zipUri = URI.create("jar:${zipPath.toUri()}")
        val moduleInfoFilePath = tasks.compileModuleInfoJava.get().outputs.files.asFileTree.matching {
            include("module-info.class")
        }.singleFile.toPath()
        FileSystems.newFileSystem(zipUri, emptyMap<String, String>()).use { fs ->
            val moduleInfoFile = fs.getPath("META-INF/versions/9/module-info.class")
            Files.copy(moduleInfoFilePath, moduleInfoFile, StandardCopyOption.REPLACE_EXISTING)
        }
    }
}

configurations {
    // shadowJar is already part of the `shadowRuntimeElements` and `shadowApiElements`, but the other subprojects
    // that depend on `kotlinx-coroutines-debug` look at `runtimeElements` and `apiElements`.
    artifacts {
        add("apiElements", shadowJar)
        add("runtimeElements", shadowJar)
    }
}

koverReport {
    filters {
        excludes {
            // Never used, safety mechanism
            classes("kotlinx.coroutines.debug.internal.NoOpProbesKt")
        }
    }
}