Only check ExternalDependency when customizing kotlin dependencies

This commit fixes the issue where kgp checks group/version of project
dependencies which is uncompatible with project isolation. With this
change, kgp will only check ExternalDependency which should be enough
for setting up kotlin dependencies.

This change also changes the way we apply cache redirector gradle
files to all projects when setting up test projects. To make it
compatible with project isolation, we should move away from using
project.getAllProjects() function.

^KT-47792 Fixed
Test: existing + SimpleKotlinGradleIT.testProjectIsolation
This commit is contained in:
Bingran
2021-07-19 19:05:56 +01:00
committed by Yahor Berdnikau
parent 1338675833
commit c57302abba
11 changed files with 85 additions and 50 deletions
@@ -30,7 +30,7 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
group = "com.example"
version = "1.0"
publishing.repositories {
maven {
maven {
url = "${'$'}buildDir/repo"
}
}
@@ -72,9 +72,11 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
}
@Test
fun testInstantExecution() = with(Project("instantExecution")) {
testConfigurationCacheOf("assemble", executedTaskNames = asList(":lib-project:compileKotlin"))
}
fun testInstantExecution() =
// Set min Gradle version to 6.8 because of using DependencyResolutionManagement API to add repositories.
with(Project("instantExecution", gradleVersionRequirement = GradleVersionRequired.AtLeast("6.8"))) {
testConfigurationCacheOf("assemble", executedTaskNames = asList(":lib-project:compileKotlin"))
}
// KT-43605
@Test
@@ -177,7 +177,7 @@ class NewMultiplatformIT : BaseGradleIT() {
it.replace(Regex("""\.version\(.*\)"""), "")
}
gradleBuildScript(subproject = libProject.projectDir.name).modify {
it.lines().dropLast(4).joinToString(separator = "\n")
it.lines().dropLast(5).joinToString(separator = "\n")
}
build(
@@ -386,7 +386,7 @@ class NewMultiplatformIT : BaseGradleIT() {
it.replace(Regex("""\.version\(.*\)"""), "")
}
gradleBuildScript(subproject = libProject.projectDir.name).modify {
it.lines().dropLast(4).joinToString(separator = "\n")
it.lines().dropLast(5).joinToString(separator = "\n")
}
build(
@@ -989,7 +989,7 @@ class NewMultiplatformIT : BaseGradleIT() {
libProject.projectDir.copyRecursively(projectDir.resolve(libProject.projectDir.name))
gradleBuildScript(libProject.projectDir.name).modify {
it.lines().dropLast(4).joinToString(separator = "\n")
it.lines().dropLast(5).joinToString(separator = "\n")
}
projectDir.resolve("settings.gradle").appendText("\ninclude '${libProject.projectDir.name}'")
gradleBuildScript().modify {
@@ -1199,7 +1199,7 @@ class NewMultiplatformIT : BaseGradleIT() {
appProject.setupWorkingDir(false)
appProject.projectDir.copyRecursively(projectDir.resolve("sample-app"))
gradleBuildScript("sample-app").modify {
it.lines().dropLast(4).joinToString(separator = "\n")
it.lines().dropLast(5).joinToString(separator = "\n")
}
gradleSettingsScript().writeText("include 'sample-app'") // disables feature preview 'GRADLE_METADATA', resets rootProject name
@@ -1509,9 +1509,14 @@ class NewMultiplatformIT : BaseGradleIT() {
testDependencies()
// Then run with Gradle Kotlin DSL; the build script needs only one correction to be a valid GK DSL script:
// Then run with Gradle Kotlin DSL; the build script needs some correction to be a valid GK DSL script:
gradleBuildScript("app").run {
modify { originalBuildscriptContent.replace(": ", " = ") }
modify {
originalBuildscriptContent
.replace(": ", " = ")
.replace("def ", " val ")
.replace("new File(cacheRedirectorFile)", "File(cacheRedirectorFile)")
}
renameTo(projectDir.resolve("app/build.gradle.kts"))
}
@@ -219,4 +219,17 @@ class SimpleKotlinGradleIT : KGPBaseTest() {
}
}
}
@GradleTest
@DisplayName("Should be compatible with project isolation")
@GradleTestVersions(minVersion = "7.1.1", maxVersion = "7.1.1")
fun testProjectIsolation(gradleVersion: GradleVersion) {
project(
projectName = "instantExecution",
gradleVersion = gradleVersion,
buildOptions = defaultBuildOptions.copy(configurationCache = true, projectIsolation = true),
) {
build(":main-project:compileKotlin")
}
}
}
@@ -395,10 +395,12 @@ internal fun BaseGradleIT.Project.embedProject(other: BaseGradleIT.Project, rena
}
if (projectName == other.projectName) {
val embeddedModuleDir = projectDir.resolve(embeddedModuleName)
val buildFile = embeddedModuleDir.resolve("build.gradle").takeIf { it.exists() }
?: embeddedModuleDir.resolve("build.gradle.kts")
buildFile.modify {
it.lines().dropLast(4).joinToString(separator = "\n")
embeddedModuleDir.walk().forEach {
if (it.name.contains("build.gradle")) {
it.modify { string ->
string.lines().dropLast(5).joinToString(separator = "\n")
}
}
}
}
testCase.apply {
@@ -38,6 +38,7 @@ abstract class KGPBaseTest {
val kotlinVersion: String = TestVersions.Kotlin.CURRENT,
val warningMode: WarningMode = WarningMode.Fail,
val configurationCache: Boolean = false,
val projectIsolation: Boolean = false,
val configurationCacheProblems: BaseGradleIT.ConfigurationCacheProblems = BaseGradleIT.ConfigurationCacheProblems.FAIL,
val parallel: Boolean = true,
val maxWorkers: Int = (Runtime.getRuntime().availableProcessors() / 4 - 1).coerceAtLeast(2),
@@ -76,6 +77,9 @@ abstract class KGPBaseTest {
arguments.add("-Dorg.gradle.unsafe.configuration-cache=$configurationCache")
arguments.add("-Dorg.gradle.unsafe.configuration-cache-problems=${configurationCacheProblems.name.toLowerCase()}")
}
if (gradleVersion >= GradleVersion.version("7.1")) {
arguments.add("-Dorg.gradle.unsafe.isolated-projects=$projectIsolation")
}
if (parallel) {
arguments.add("--parallel")
arguments.add("--max-workers=$maxWorkers")
@@ -303,30 +303,33 @@ internal fun Path.enableCacheRedirector() {
""".trimIndent()
)
when {
resolve("build.gradle").exists() -> {
//language=Groovy
resolve("build.gradle").appendText(
"""
allprojects {
apply from: "${'$'}rootDir/gradle/cacheRedirector.gradle.kts"
}
""".trimIndent()
)
}
resolve("build.gradle.kts").exists() -> {
//language=Groovy
resolve("build.gradle.kts").appendText(
"""
allprojects {
apply(from = "${'$'}rootDir/gradle/cacheRedirector.gradle.kts")
}
""".trimIndent()
)
val projectDir = toFile()
projectDir.walk().forEach {
when (it.name) {
"build.gradle" -> {
it.appendText(
"""
def cacheRedirectorFile = "${'$'}rootDir/gradle/cacheRedirector.gradle.kts"
if (new File(cacheRedirectorFile).exists()) {
apply(from: cacheRedirectorFile)
}
""".trimIndent()
)
}
"build.gradle.kts" -> {
it.appendText(
"""
val cacheRedirectorFile = "${'$'}rootDir/gradle/cacheRedirector.gradle.kts"
if (File(cacheRedirectorFile).exists()) {
apply(from = cacheRedirectorFile)
}
""".trimIndent()
)
}
}
}
}
@@ -6,11 +6,4 @@ buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
subprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
@@ -1,4 +1,4 @@
import libProject.Util
import libproject.Util
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
@@ -6,5 +6,5 @@ import libProject.Util
*/
fun main(args: Array<String>) {
println(Util.projectName)
println(Util().projectName)
}
@@ -1 +1,9 @@
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenLocal()
mavenCentral()
}
}
include ':main-project', ':lib-project'
@@ -15,6 +15,7 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencySet
import org.gradle.api.artifacts.ExternalDependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.tasks.testing.AbstractTestTask
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.junit.JUnitOptions
@@ -185,7 +186,7 @@ private fun chooseAndAddStdlibDependency(
}
val isStdlibAddedByUser = sourceSetDependencyConfigurations
.flatMap { it.allDependencies }
.flatMap { it.allNonProjectDependencies() }
.any { dependency -> dependency.group == KOTLIN_MODULE_GROUP && dependency.name in stdlibModules }
if (!isStdlibAddedByUser) {
@@ -201,7 +202,7 @@ private fun chooseAndAddStdlibDependency(
// If the exact same module is added in the source sets hierarchy, possibly even with a different scope, we don't add it
val moduleAddedInHierarchy = hierarchySourceSetsDependencyConfigurations.any {
it.allDependencies.any { dependency -> dependency.group == KOTLIN_MODULE_GROUP && dependency.name == stdlibModuleName }
it.allNonProjectDependencies().any { dependency -> dependency.group == KOTLIN_MODULE_GROUP && dependency.name == stdlibModuleName }
}
if (stdlibModuleName != null && !moduleAddedInHierarchy)
@@ -274,7 +275,7 @@ internal fun configureKotlinTestDependency(project: Project) {
val configuration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope)
var finalizingDependencies = false
configuration.dependencies.matching(::isKotlinTestRootDependency).apply {
configuration.nonProjectDependencies().matching(::isKotlinTestRootDependency).apply {
firstOrNull()?.let { versionOrNullBySourceSet[kotlinSourceSet] = it.version }
whenObjectRemoved {
if (!finalizingDependencies && !any())
@@ -400,3 +401,7 @@ private fun Project.tryWithDependenciesIfUnresolved(configuration: Configuration
reportAlreadyResolved()
}
}
private fun Configuration.allNonProjectDependencies() = allDependencies.matching { it !is ProjectDependency }
private fun Configuration.nonProjectDependencies() = dependencies.matching { it !is ProjectDependency }