[Gradle] Migrate MppCInteropDependencyTransformationIT to new test DSL

^KT-65528 In Progress
This commit is contained in:
Yahor Berdnikau
2024-02-12 23:37:23 +01:00
committed by Space Team
parent f22688c4c8
commit 53d42df76b
7 changed files with 309 additions and 269 deletions
@@ -5,12 +5,20 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.gradle.testkit.runner.BuildResult
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.commonizer.CommonizerTarget import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.WithSourceSetCommonizerDependencies import org.jetbrains.kotlin.gradle.util.WithSourceSetCommonizerDependencies
import org.jetbrains.kotlin.gradle.util.reportSourceSetCommonizerDependencies import org.jetbrains.kotlin.gradle.util.reportSourceSetCommonizerDependencies
import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.target.KonanTarget
import org.junit.Test import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import kotlin.io.path.readText
import kotlin.io.path.writeText
import kotlin.test.assertTrue
/** /**
* Runs Tests on a Gradle project with three subprojects * Runs Tests on a Gradle project with three subprojects
@@ -23,51 +31,82 @@ import org.junit.Test
* - dependency-mode=project: In this case p2 will just declare a regular project dependency on p1 * - dependency-mode=project: In this case p2 will just declare a regular project dependency on p1
* - dependency-mode=repository: In this case p2 will rely on a previously published version of p1 * - dependency-mode=repository: In this case p2 will rely on a previously published version of p1
*/ */
abstract class MppCInteropDependencyTransformationIT : BaseGradleIT() { @DisplayName("CInterop dependency transformation")
override val defaultGradleVersion: GradleVersionRequired = GradleVersionRequired.FOR_MPP_SUPPORT @NativeGradlePluginTests
class MppCInteropDependencyTransformationIT : KGPBaseTest() {
override fun defaultBuildOptions(): BuildOptions = super.defaultBuildOptions().run { private val projectDependencyMode = "-PdependencyMode=project"
copy(
forceOutputToStdout = true, private val repositoryDependencyMode = "-PdependencyMode=repository"
parallelTasksInProject = true,
freeCommandLineArgs = freeCommandLineArgs + "-s" private fun BuildResult.assertProjectDependencyMode() {
) assertOutputContains("dependencyMode = 'project'")
} }
protected val projectDependencyOptions private fun BuildResult.assertRepositoryDependencyMode() {
get() = defaultBuildOptions().copy( assertOutputContains("dependencyMode = 'repository'")
freeCommandLineArgs = defaultBuildOptions().freeCommandLineArgs + "-PdependencyMode=project" }
)
protected val repositoryDependencyOptions private fun BuildResult.assertNoCompileTasksExecuted() {
get() = defaultBuildOptions().copy( val compileTaskRegex = ".*[cC]ompile.*".toRegex()
freeCommandLineArgs = defaultBuildOptions().freeCommandLineArgs + "-PdependencyMode=repository" val taskPaths = tasks.map { it.path }
) assertTrue(taskPaths.none { it.contains(compileTaskRegex) })
}
class ComplexProject : MppCInteropDependencyTransformationIT() { private fun TestProject.publishP1ToBuildRepository() {
build(":p1:publishAllPublicationsToMavenRepository", repositoryDependencyMode)
}
private val project by lazy { Project("cinterop-MetadataDependencyTransformation") } private val cinteropProjectName = "cinterop-MetadataDependencyTransformation"
@Test @DisplayName("Compile project with project mode")
fun `test - compile project - dependencyMode=project`() { @GradleTest
testCompileProject(projectDependencyOptions) { fun compileDependencyModeProject(
assertProjectDependencyMode() gradleVersion: GradleVersion,
assertTasksExecuted(":p1:commonizeCInterop") @TempDir localRepo: Path,
} ) {
testCompileProject(
gradleVersion,
projectDependencyMode,
localRepo,
) {
assertProjectDependencyMode()
assertTasksExecuted(":p1:commonizeCInterop")
} }
}
@Test @DisplayName("Compile project with repository mode")
fun `test - compile project - dependencyMode=repository`() { @GradleTest
publishP1ToBuildRepository() fun compileDependencyModeRepository(
testCompileProject(repositoryDependencyOptions) { gradleVersion: GradleVersion,
assertRepositoryDependencyMode() @TempDir localRepo: Path,
} ) {
testCompileProject(
gradleVersion,
repositoryDependencyMode,
localRepo,
additionalBuildStep = { publishP1ToBuildRepository() }
) {
assertRepositoryDependencyMode()
} }
}
private fun testCompileProject(options: BuildOptions, check: CompiledProject.() -> Unit = {}) { private fun testCompileProject(
project.build("compileAll", options = options) { gradleVersion: GradleVersion,
repositoryMode: String,
localRepo: Path,
additionalBuildStep: TestProject.() -> Unit = {},
check: BuildResult.() -> Unit = {},
) {
project(
projectName = cinteropProjectName,
gradleVersion = gradleVersion,
localRepoDir = localRepo
) {
additionalBuildStep()
build("compileAll", repositoryMode) {
check() check()
assertSuccessful()
/* Assert p2 & p3 compiled metadata */ /* Assert p2 & p3 compiled metadata */
assertTasksExecuted(":p2:compileNativeMainKotlinMetadata") assertTasksExecuted(":p2:compileNativeMainKotlinMetadata")
@@ -94,143 +133,210 @@ abstract class MppCInteropDependencyTransformationIT : BaseGradleIT() {
assertTasksExecuted(":p3:compileTestKotlinLinuxX64") assertTasksExecuted(":p3:compileTestKotlinLinuxX64")
/* Configurations should not be resolved during configuration phase */ /* Configurations should not be resolved during configuration phase */
assertNotContains("Configuration resolved before Task Graph is ready") assertOutputDoesNotContain("Configuration resolved before Task Graph is ready")
} }
} }
}
@Test @DisplayName("Source set dependency in project mode")
fun `test - source set dependencies - dependencyMode=project`() { @GradleTest
reportSourceSetCommonizerDependencies(project, "p2", projectDependencyOptions) { fun sourceSetDependencyProjectMode(gradleVersion: GradleVersion) {
project(cinteropProjectName, gradleVersion) {
reportSourceSetCommonizerDependencies(
subproject = "p2",
options = defaultBuildOptions.copy(freeArgs = listOf(projectDependencyMode))
) {
it.assertProjectDependencyMode() it.assertProjectDependencyMode()
it.assertTasksExecuted(":p2:transformNativeMainCInteropDependenciesMetadataForIde") it.assertTasksExecuted(":p2:transformNativeMainCInteropDependenciesMetadataForIde")
it.assertTasksNotExecuted(".*[cC]ompile.*") it.assertNoCompileTasksExecuted()
assertP2SourceSetDependencies() assertP2SourceSetDependencies()
} }
reportSourceSetCommonizerDependencies(project, "p3", projectDependencyOptions) { reportSourceSetCommonizerDependencies(
subproject = "p3",
options = defaultBuildOptions.copy(freeArgs = listOf(projectDependencyMode))
) {
it.assertProjectDependencyMode() it.assertProjectDependencyMode()
it.assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadataForIde") it.assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadataForIde")
it.assertTasksNotExecuted(".*[cC]ompile.*") it.assertNoCompileTasksExecuted()
assertP3SourceSetDependencies() assertP3SourceSetDependencies()
} }
} }
}
@Test @DisplayName("Source set dependency in repository mode")
fun `test - source set dependencies - dependencyMode=repository`() { @GradleTest
fun sourceSetDependencyRepositoryMode(
gradleVersion: GradleVersion,
@TempDir localRepo: Path,
) {
project(cinteropProjectName, gradleVersion, localRepoDir = localRepo) {
publishP1ToBuildRepository() publishP1ToBuildRepository()
reportSourceSetCommonizerDependencies(project, "p2", repositoryDependencyOptions) { reportSourceSetCommonizerDependencies(
subproject = "p2",
options = defaultBuildOptions.copy(freeArgs = listOf(repositoryDependencyMode))
) {
it.assertRepositoryDependencyMode() it.assertRepositoryDependencyMode()
it.assertTasksExecuted(":p2:transformNativeMainCInteropDependenciesMetadataForIde") it.assertTasksExecuted(":p2:transformNativeMainCInteropDependenciesMetadataForIde")
it.assertTasksNotExecuted(".*[cC]ompile.*") it.assertNoCompileTasksExecuted()
assertP2SourceSetDependencies() assertP2SourceSetDependencies()
} }
reportSourceSetCommonizerDependencies(project, "p3", repositoryDependencyOptions) { reportSourceSetCommonizerDependencies(
subproject = "p3",
options = defaultBuildOptions.copy(freeArgs = listOf(repositoryDependencyMode))
) {
it.assertRepositoryDependencyMode() it.assertRepositoryDependencyMode()
it.assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadataForIde") it.assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadataForIde")
it.assertTasksNotExecuted(".*[cC]ompile.*") it.assertNoCompileTasksExecuted()
assertP3SourceSetDependencies() assertP3SourceSetDependencies()
} }
} }
}
private fun WithSourceSetCommonizerDependencies.assertP2SourceSetDependencies() { private fun WithSourceSetCommonizerDependencies.assertP2SourceSetDependencies() {
listOf("nativeMain", "nativeTest").forEach { sourceSetName -> listOf("nativeMain", "nativeTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir) getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(
CommonizerTarget(
KonanTarget.LINUX_ARM64,
KonanTarget.LINUX_X64,
KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64,
KonanTarget.MACOS_X64,
KonanTarget.MINGW_X64
)
)
}
if (HostManager.hostIsMac) {
listOf("appleAndLinuxMain", "appleAndLinuxTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*") .assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies( .assertTargetOnAllDependencies(
CommonizerTarget(LINUX_ARM64, LINUX_X64, IOS_ARM64, IOS_X64, MACOS_X64, MINGW_X64) CommonizerTarget(
KonanTarget.LINUX_ARM64,
KonanTarget.LINUX_X64,
KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64,
KonanTarget.MACOS_X64
)
) )
} }
if (HostManager.hostIsMac) { listOf("appleMain", "appleTest").forEach { sourceSetName ->
listOf("appleAndLinuxMain", "appleAndLinuxTest").forEach { sourceSetName -> getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(LINUX_ARM64, LINUX_X64, IOS_ARM64, IOS_X64, MACOS_X64))
}
listOf("appleMain", "appleTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(IOS_ARM64, IOS_X64, MACOS_X64))
}
listOf("iosMain", "iosTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(IOS_ARM64, IOS_X64))
}
}
listOf("linuxMain", "linuxTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(LINUX_ARM64, LINUX_X64))
}
}
private fun WithSourceSetCommonizerDependencies.assertP3SourceSetDependencies() {
/*
windowsAndLinuxMain / windowsAndLinuxTest will not have a 'perfect target match' in p1.
They will choose cinterops associated with 'nativeMain'
*/
listOf("nativeMain", "nativeTest", "windowsAndLinuxMain", "windowsAndLinuxTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*") .assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies( .assertTargetOnAllDependencies(
CommonizerTarget(LINUX_ARM64, LINUX_X64, IOS_ARM64, IOS_X64, MACOS_X64, MINGW_X64) CommonizerTarget(
KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64,
KonanTarget.MACOS_X64
)
) )
} }
if (HostManager.hostIsMac) { listOf("iosMain", "iosTest").forEach { sourceSetName ->
listOf("appleAndLinuxMain", "appleAndLinuxTest").forEach { sourceSetName -> getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir) .assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*") .assertTargetOnAllDependencies(
.assertTargetOnAllDependencies(CommonizerTarget(LINUX_ARM64, LINUX_X64, IOS_ARM64, IOS_X64, MACOS_X64)) CommonizerTarget(
} KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64
listOf("iosMain", "iosTest").forEach { sourceSetName -> )
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions().konanDataDir) )
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(IOS_ARM64, IOS_X64))
}
} }
} }
@Test listOf("linuxMain", "linuxTest").forEach { sourceSetName ->
fun `test - transformation - UP-TO-DATE behaviour - on p3`() { getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(
CommonizerTarget(KonanTarget.LINUX_ARM64, KonanTarget.LINUX_X64)
)
}
}
private fun WithSourceSetCommonizerDependencies.assertP3SourceSetDependencies() {
/*
windowsAndLinuxMain / windowsAndLinuxTest will not have a 'perfect target match' in p1.
They will choose cinterops associated with 'nativeMain'
*/
listOf("nativeMain", "nativeTest", "windowsAndLinuxMain", "windowsAndLinuxTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(
CommonizerTarget(
KonanTarget.LINUX_ARM64,
KonanTarget.LINUX_X64,
KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64,
KonanTarget.MACOS_X64,
KonanTarget.MINGW_X64
)
)
}
if (HostManager.hostIsMac) {
listOf("appleAndLinuxMain", "appleAndLinuxTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(
CommonizerTarget(
KonanTarget.LINUX_ARM64,
KonanTarget.LINUX_X64,
KonanTarget.IOS_ARM64,
KonanTarget.IOS_X64,
KonanTarget.MACOS_X64,
)
)
}
listOf("iosMain", "iosTest").forEach { sourceSetName ->
getCommonizerDependencies(sourceSetName).withoutNativeDistributionDependencies(defaultBuildOptions.konanDataDir!!)
.assertDependencyFilesMatches(".*cinterop-simple.*", ".*cinterop-withPosix.*")
.assertTargetOnAllDependencies(CommonizerTarget(KonanTarget.IOS_ARM64, KonanTarget.IOS_X64))
}
}
}
@DisplayName("UP-TO-DATE transformations for P3 subproject")
@GradleTest
fun transformationsUpToDateOnP3(
gradleVersion: GradleVersion,
@TempDir localRepo: Path,
) {
project(cinteropProjectName, gradleVersion, localRepoDir = localRepo) {
publishP1ToBuildRepository() publishP1ToBuildRepository()
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) {
assertSuccessful() build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) { build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertSuccessful()
assertTasksNotExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
val p3BuildGradleKts = project.projectDir.resolve("p3/build.gradle.kts") val p3BuildGradleKts = subProject("p3").buildGradleKts
val p3BuildGradleKtsContent = p3BuildGradleKts.readText() val p3BuildGradleKtsContent = p3BuildGradleKts.readText()
// Remove dependency on p2 | Task should re-run // Remove dependency on p2 | Task should re-run
p3BuildGradleKts.writeText(p3BuildGradleKtsContent.replace("""implementation(project(":p2"))""", "")) p3BuildGradleKts.writeText(
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) { p3BuildGradleKtsContent.replace("""implementation(project(":p2"))""", "")
assertSuccessful() )
build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
// Re-add dependency on p3 | Task should re-run for the next invocation // Re-add dependency on p3 | Task should re-run for the next invocation
p3BuildGradleKts.writeText(p3BuildGradleKtsContent) p3BuildGradleKts.writeText(p3BuildGradleKtsContent)
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) { build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertSuccessful()
assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) {
assertSuccessful() build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertTasksNotExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
@@ -238,100 +344,98 @@ abstract class MppCInteropDependencyTransformationIT : BaseGradleIT() {
p3BuildGradleKts.writeText( p3BuildGradleKts.writeText(
p3BuildGradleKtsContent.replace("""project(":p2")""", """"kotlin-multiplatform-projects:p1:1.0.0-SNAPSHOT"""") p3BuildGradleKtsContent.replace("""project(":p2")""", """"kotlin-multiplatform-projects:p1:1.0.0-SNAPSHOT"""")
) )
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = repositoryDependencyOptions) { build(":p3:transformNativeMainCInteropDependenciesMetadata", repositoryDependencyMode) {
assertSuccessful()
/* Same binaries to transform; but project(":p2") is excluded from Task Inputs now */ /* Same binaries to transform; but project(":p2") is excluded from Task Inputs now */
assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata") assertTasksExecuted(":p3:transformNativeMainCInteropDependenciesMetadata")
} }
} }
}
@DisplayName("UP-TO-DATE transformations on adding/removing targets in repositories mode")
@Test @GradleTest
fun `test - transformation - UP-TO-DATE behaviour - on removing and adding targets - on p2 - dependencyMode=repository`() { fun upToDateTransformationsAddingRemovingTargetRepositoriesMode(
gradleVersion: GradleVersion,
@TempDir localRepo: Path,
) {
project(cinteropProjectName, gradleVersion, localRepoDir = localRepo) {
publishP1ToBuildRepository() publishP1ToBuildRepository()
`test - transformation - UP-TO-DATE behaviour - on removing and adding targets - on p2`(repositoryDependencyOptions) testUpToDateTransformationOnRemovingOrAddingTargets(repositoryDependencyMode)
}
@Test
fun `test - transformation - UP-TO-DATE behaviour - on removing and adding targets - on p2 - dependencyMode=project`() {
`test - transformation - UP-TO-DATE behaviour - on removing and adding targets - on p2`(projectDependencyOptions)
}
private fun `test - transformation - UP-TO-DATE behaviour - on removing and adding targets - on p2`(options: BuildOptions) {
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = options) {
assertSuccessful()
}
project.build(":p3:transformNativeMainCInteropDependenciesMetadata", options = options) {
assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata")
}
}
private fun publishP1ToBuildRepository() = project.publishP1ToBuildRepository()
}
class KT50952 : MppCInteropDependencyTransformationIT() {
private val project by lazy { Project("cinterop-MetadataDependencyTransformation-kt-50952") }
@Test
fun `test UP-TO-DATE - when changing consumer targets - dependencyMode=repository`() {
project.publishP1ToBuildRepository()
`test UP-TO-DATE - when changing consumer targets`(repositoryDependencyOptions)
}
@Test
fun `test UP-TO-DATE - when changing consumer targets - dependencyMode=project`() {
`test UP-TO-DATE - when changing consumer targets`(projectDependencyOptions)
}
private fun `test UP-TO-DATE - when changing consumer targets`(options: BuildOptions) {
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = options) {
assertSuccessful()
}
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = options) {
assertSuccessful()
assertTasksNotExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
}
val optionsWithAdditionalTargetEnabled = options.withFreeCommandLineArgument("-Pp2.enableAdditionalTarget")
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = optionsWithAdditionalTargetEnabled) {
assertSuccessful()
assertTasksExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
}
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = optionsWithAdditionalTargetEnabled) {
assertSuccessful()
assertTasksNotExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
}
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = options) {
assertSuccessful()
assertTasksExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
}
project.build(":p2:transformCommonMainCInteropDependenciesMetadata", options = options) {
assertSuccessful()
assertTasksNotExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
}
} }
} }
protected fun CompiledProject.assertProjectDependencyMode() { @DisplayName("UP-TO-DATE transformations on adding/removing targets in project mode")
assertContains("dependencyMode = 'project'") @GradleTest
fun upToDateTransformationsAddingRemovingTargetRepositoriesMode(gradleVersion: GradleVersion) {
project(cinteropProjectName, gradleVersion) {
testUpToDateTransformationOnRemovingOrAddingTargets(projectDependencyMode)
}
} }
protected fun CompiledProject.assertRepositoryDependencyMode() { private fun TestProject.testUpToDateTransformationOnRemovingOrAddingTargets(
assertContains("dependencyMode = 'repository'") dependencyMode: String,
) {
build(":p3:transformNativeMainCInteropDependenciesMetadata", dependencyMode)
build(":p3:transformNativeMainCInteropDependenciesMetadata", dependencyMode) {
assertTasksUpToDate(":p3:transformNativeMainCInteropDependenciesMetadata")
}
} }
protected fun Project.publishP1ToBuildRepository() { private val cinteropProjectNameForKt50952 = "cinterop-MetadataDependencyTransformation-kt-50952"
build(":p1:publishAllPublicationsToBuildRepository", options = repositoryDependencyOptions) {
assertSuccessful() @DisplayName("KT-50952: UP-TO-DATE on changing consumer targets in repository mode")
@GradleTest
fun kt50952UpToDateChangingConsumerTargetsRepositoryMode(
gradleVersion: GradleVersion,
@TempDir localRepo: Path,
) {
project(cinteropProjectNameForKt50952, gradleVersion, localRepoDir = localRepo) {
publishP1ToBuildRepository()
testUpToDateOnChangingConsumerTargets(repositoryDependencyMode)
}
}
@DisplayName("KT-50952: UP-TO-DATE on changing consumer targets in project mode")
@GradleTest
fun kt50952UpToDateChangingConsumerTargetsRepositoryMode(gradleVersion: GradleVersion) {
project(cinteropProjectNameForKt50952, gradleVersion) {
testUpToDateOnChangingConsumerTargets(projectDependencyMode)
}
}
private fun TestProject.testUpToDateOnChangingConsumerTargets(
dependencyMode: String
) {
build(":p2:transformCommonMainCInteropDependenciesMetadata", dependencyMode)
build(":p2:transformCommonMainCInteropDependenciesMetadata", dependencyMode) {
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
}
val optionToEnableAdditionalTarget = "-Pp2.enableAdditionalTarget"
build(
":p2:transformCommonMainCInteropDependenciesMetadata",
optionToEnableAdditionalTarget,
dependencyMode
) {
assertTasksExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
}
build(
":p2:transformCommonMainCInteropDependenciesMetadata",
optionToEnableAdditionalTarget,
dependencyMode
) {
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
}
build(":p2:transformCommonMainCInteropDependenciesMetadata", dependencyMode) {
assertTasksExecuted(":p2:transformCommonMainCInteropDependenciesMetadata")
}
build(":p2:transformCommonMainCInteropDependenciesMetadata", dependencyMode) {
assertTasksUpToDate(":p2:transformCommonMainCInteropDependenciesMetadata")
} }
} }
} }
@@ -11,7 +11,6 @@ import org.intellij.lang.annotations.RegExp
import org.jetbrains.kotlin.commonizer.CommonizerTarget import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
import org.jetbrains.kotlin.commonizer.parseCommonizerTarget import org.jetbrains.kotlin.commonizer.parseCommonizerTarget
import org.jetbrains.kotlin.gradle.BaseGradleIT
import org.jetbrains.kotlin.gradle.testbase.BuildOptions import org.jetbrains.kotlin.gradle.testbase.BuildOptions
import org.jetbrains.kotlin.gradle.testbase.TestProject import org.jetbrains.kotlin.gradle.testbase.TestProject
import org.jetbrains.kotlin.gradle.testbase.build import org.jetbrains.kotlin.gradle.testbase.build
@@ -117,57 +116,16 @@ fun interface WithSourceSetCommonizerDependencies {
fun getCommonizerDependencies(sourceSetName: String): SourceSetCommonizerDependencies fun getCommonizerDependencies(sourceSetName: String): SourceSetCommonizerDependencies
} }
fun BaseGradleIT.reportSourceSetCommonizerDependencies(
project: BaseGradleIT.Project,
subproject: String? = null,
options: BaseGradleIT.BuildOptions = defaultBuildOptions(),
test: WithSourceSetCommonizerDependencies.(compiledProject: BaseGradleIT.CompiledProject) -> Unit
) = with(project) {
if (!projectDir.exists()) {
setupWorkingDir()
}
gradleBuildScript(subproject).apply {
appendText("\n\n")
appendText(taskSourceCode)
appendText("\n\n")
}
val taskName = buildString {
if (subproject != null) append(":$subproject")
append(":reportCommonizerSourceSetDependencies")
}
build(taskName, options = options) {
assertSuccessful()
val dependencyReports = output.lineSequence().filter { line -> line.contains("SourceSetCommonizerDependencyReport") }.toList()
val withSourceSetCommonizerDependencies = WithSourceSetCommonizerDependencies { sourceSetName ->
val reportMarker = "Report[$sourceSetName]"
val reportForSourceSet = dependencyReports.firstOrNull { line -> line.contains(reportMarker) }
?: fail("Missing dependency report for $sourceSetName")
val files = reportForSourceSet.split(reportMarker, limit = 2).last().split("|#+#|")
.map(String::trim).filter(String::isNotEmpty).map(::File)
val dependencies = files.mapNotNull { file -> createSourceSetCommonizerDependencyOrNull(sourceSetName, file) }.toSet()
SourceSetCommonizerDependencies(sourceSetName, dependencies)
}
withSourceSetCommonizerDependencies.test(this)
}
}
fun TestProject.reportSourceSetCommonizerDependencies( fun TestProject.reportSourceSetCommonizerDependencies(
subproject: String? = null, subproject: String? = null,
options: BuildOptions = this.buildOptions, options: BuildOptions = this.buildOptions,
test: WithSourceSetCommonizerDependencies.(compiledProject: BuildResult) -> Unit, test: WithSourceSetCommonizerDependencies.(compiledProject: BuildResult) -> Unit,
) { ) {
if (subproject != null) {
buildGradleKts.appendText("\n\n$taskSourceCode\n\n") subProject(subproject).buildGradleKts.appendText(taskSourceCode)
} else {
buildGradleKts.appendText(taskSourceCode)
}
val taskName = buildString { val taskName = buildString {
if (subproject != null) append(":$subproject") if (subproject != null) append(":$subproject")
@@ -213,6 +171,7 @@ private val File.parentsClosure: Set<File> get() = this.linearClosure { it.paren
private const val dollar = "\$" private const val dollar = "\$"
private val taskSourceCode = """ private val taskSourceCode = """
tasks.register("reportCommonizerSourceSetDependencies") { tasks.register("reportCommonizerSourceSetDependencies") {
kotlin.sourceSets.withType(org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet::class).all { kotlin.sourceSets.withType(org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet::class).all {
inputs.files(configurations.getByName(intransitiveMetadataConfigurationName)) inputs.files(configurations.getByName(intransitiveMetadataConfigurationName))
@@ -229,4 +188,5 @@ tasks.register("reportCommonizerSourceSetDependencies") {
} }
} }
} }
""".trimIndent() """.trimIndent()
@@ -11,10 +11,7 @@ version = "1.0.0-SNAPSHOT"
publishing { publishing {
repositories { repositories {
maven { maven("<localRepo>")
name = "build"
url = rootProject.buildDir.resolve("repo").toURI()
}
} }
} }
@@ -1,12 +1,6 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.HostManager
repositories {
maven {
url = rootProject.buildDir.resolve("repo").toURI()
}
}
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
} }
@@ -19,10 +19,7 @@ version = "1.0.0-SNAPSHOT"
publishing { publishing {
repositories { repositories {
this.maven { maven("<localRepo>")
this.name = "build"
this.url = rootProject.buildDir.resolve("repo").toURI()
}
} }
} }
@@ -9,12 +9,6 @@ class SourceSetHierarchyBuilder(private val node: KotlinSourceSet) {
operator fun KotlinSourceSet.unaryMinus() = this.dependsOn(node) operator fun KotlinSourceSet.unaryMinus() = this.dependsOn(node)
} }
repositories {
maven {
url = rootProject.buildDir.resolve("repo").toURI()
}
}
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
} }
@@ -9,12 +9,6 @@ class SourceSetHierarchyBuilder(private val node: KotlinSourceSet) {
operator fun KotlinSourceSet.unaryMinus() = this.dependsOn(node) operator fun KotlinSourceSet.unaryMinus() = this.dependsOn(node)
} }
repositories {
maven {
url = rootProject.buildDir.resolve("repo").toURI()
}
}
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
} }