JPS: don't consider that production target of module "B" is depends on test target of module "A" when "B" depends on "A"
#KT-12595 Fixed
This commit is contained in:
committed by
Zalim Bashorov
parent
a17b0dd1b5
commit
0e428ca10c
@@ -26,6 +26,7 @@ import com.intellij.testFramework.UsefulTestCase
|
|||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import com.intellij.util.io.ZipUtil
|
import com.intellij.util.io.ZipUtil
|
||||||
|
import org.jetbrains.jps.ModuleChunk
|
||||||
import org.jetbrains.jps.api.CanceledStatus
|
import org.jetbrains.jps.api.CanceledStatus
|
||||||
import org.jetbrains.jps.builders.BuildResult
|
import org.jetbrains.jps.builders.BuildResult
|
||||||
import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
||||||
@@ -33,16 +34,23 @@ import org.jetbrains.jps.builders.JpsBuildTestCase
|
|||||||
import org.jetbrains.jps.builders.TestProjectBuilderLogger
|
import org.jetbrains.jps.builders.TestProjectBuilderLogger
|
||||||
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
||||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||||
|
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||||
import org.jetbrains.jps.incremental.BuilderRegistry
|
import org.jetbrains.jps.incremental.BuilderRegistry
|
||||||
|
import org.jetbrains.jps.incremental.CompileContext
|
||||||
import org.jetbrains.jps.incremental.IncProjectBuilder
|
import org.jetbrains.jps.incremental.IncProjectBuilder
|
||||||
|
import org.jetbrains.jps.incremental.ModuleLevelBuilder
|
||||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||||
|
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||||
|
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||||
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
||||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||||
import org.jetbrains.jps.model.module.JpsModule
|
import org.jetbrains.jps.model.module.JpsModule
|
||||||
import org.jetbrains.jps.util.JpsPathUtil
|
import org.jetbrains.jps.util.JpsPathUtil
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
|
import org.jetbrains.kotlin.incremental.CacheVersion
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
@@ -754,18 +762,66 @@ class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
|||||||
doTest()
|
doTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testGetDependentTargets() {
|
||||||
|
fun addModuleWithSourceAndTestRoot(name: String): JpsModule {
|
||||||
|
return addModule(name, "src/").apply {
|
||||||
|
contentRootsList.addUrl(JpsPathUtil.pathToUrl("test/"))
|
||||||
|
addSourceRoot(JpsPathUtil.pathToUrl("test/"), JavaSourceRootType.TEST_SOURCE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val a = addModuleWithSourceAndTestRoot("a")
|
||||||
|
val b = addModuleWithSourceAndTestRoot("b")
|
||||||
|
val c = addModuleWithSourceAndTestRoot("c")
|
||||||
|
val b2 = addModuleWithSourceAndTestRoot("b2")
|
||||||
|
val c2 = addModuleWithSourceAndTestRoot("c2")
|
||||||
|
|
||||||
|
JpsModuleRootModificationUtil.addDependency(b, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ true)
|
||||||
|
JpsModuleRootModificationUtil.addDependency(c, b, JpsJavaDependencyScope.COMPILE, /*exported =*/ false)
|
||||||
|
JpsModuleRootModificationUtil.addDependency(b2, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ false)
|
||||||
|
JpsModuleRootModificationUtil.addDependency(c2, b2, JpsJavaDependencyScope.COMPILE, /*exported =*/ false)
|
||||||
|
|
||||||
|
val actual = StringBuilder()
|
||||||
|
buildCustom(CanceledStatus.NULL, TestProjectBuilderLogger(), BuildResult()) {
|
||||||
|
project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object: BuildLogger {
|
||||||
|
override fun buildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||||
|
actual.append("Targets dependent on ${chunk.targets.joinToString() }:\n")
|
||||||
|
actual.append(getDependentTargets(chunk, context).map { it.toString() }.sorted().joinToString("\n"))
|
||||||
|
actual.append("\n---------\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun actionsOnCacheVersionChanged(actions: List<CacheVersion.Action>) {}
|
||||||
|
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {}
|
||||||
|
override fun markedAsDirty(files: Iterable<File>) {}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedFile = File(getCurrentTestDataRoot(), "expected.txt")
|
||||||
|
|
||||||
|
KotlinTestUtils.assertEqualsToFile(expectedFile, actual.toString())
|
||||||
|
}
|
||||||
|
|
||||||
private fun BuildResult.checkErrors() {
|
private fun BuildResult.checkErrors() {
|
||||||
val actualErrors = getMessages(BuildMessage.Kind.ERROR)
|
val actualErrors = getMessages(BuildMessage.Kind.ERROR)
|
||||||
.map { it as CompilerMessage }
|
.map { it as CompilerMessage }
|
||||||
.map { "${it.messageText} at line ${it.line}, column ${it.column}" }.sorted().joinToString("\n")
|
.map { "${it.messageText} at line ${it.line}, column ${it.column}" }.sorted().joinToString("\n")
|
||||||
val projectRoot = File(AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/" + getTestName(false))
|
val expectedFile = File(getCurrentTestDataRoot(), "errors.txt")
|
||||||
val expectedFile = File(projectRoot, "errors.txt")
|
|
||||||
KotlinTestUtils.assertEqualsToFile(expectedFile, actualErrors)
|
KotlinTestUtils.assertEqualsToFile(expectedFile, actualErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCustom(canceledStatus: CanceledStatus, logger: TestProjectBuilderLogger,buildResult: BuildResult) {
|
private fun getCurrentTestDataRoot() = File(AbstractKotlinJpsBuildTestCase.TEST_DATA_PATH + "general/" + getTestName(false))
|
||||||
|
|
||||||
|
private fun buildCustom(
|
||||||
|
canceledStatus: CanceledStatus,
|
||||||
|
logger: TestProjectBuilderLogger,
|
||||||
|
buildResult: BuildResult,
|
||||||
|
setupProject: ProjectDescriptor.() -> Unit = {}
|
||||||
|
) {
|
||||||
val scopeBuilder = CompileScopeTestBuilder.make().all()
|
val scopeBuilder = CompileScopeTestBuilder.make().all()
|
||||||
val descriptor = this.createProjectDescriptor(BuildLoggingManager(logger))
|
val descriptor = this.createProjectDescriptor(BuildLoggingManager(logger))
|
||||||
|
|
||||||
|
descriptor.setupProject()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val builder = IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), this.myBuildParams, canceledStatus, null, true)
|
val builder = IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), this.myBuildParams, canceledStatus, null, true)
|
||||||
builder.addMessageHandler(buildResult)
|
builder.addMessageHandler(buildResult)
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
|
|
||||||
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
|
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
|
||||||
|
|
||||||
LOG.info("Build result: " + actualExitCode)
|
LOG.debug("Build result: " + actualExitCode)
|
||||||
|
|
||||||
context.testingContext?.buildLogger?.buildFinished(actualExitCode)
|
context.testingContext?.buildLogger?.buildFinished(actualExitCode)
|
||||||
|
|
||||||
@@ -820,14 +820,15 @@ private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): M
|
|||||||
return chunkCaches
|
return chunkCaches
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDependentTargets(
|
fun getDependentTargets(
|
||||||
compilingChunk: ModuleChunk,
|
compilingChunk: ModuleChunk,
|
||||||
context: CompileContext
|
context: CompileContext
|
||||||
): Set<ModuleBuildTarget> {
|
): Set<ModuleBuildTarget> {
|
||||||
val classpathKind = JpsJavaClasspathKind.compile(compilingChunk.targets.any { it.isTests })
|
val compilingChunkIsTests = compilingChunk.targets.any { it.isTests }
|
||||||
|
val classpathKind = JpsJavaClasspathKind.compile(compilingChunkIsTests)
|
||||||
|
|
||||||
fun dependsOnCompilingChunk(target: BuildTarget<*>): Boolean {
|
fun dependsOnCompilingChunk(target: BuildTarget<*>): Boolean {
|
||||||
if (target !is ModuleBuildTarget) return false
|
if (target !is ModuleBuildTarget || compilingChunkIsTests && !target.isTests) return false
|
||||||
|
|
||||||
val dependencies = getDependenciesRecursively(target.module, classpathKind)
|
val dependencies = getDependenciesRecursively(target.module, classpathKind)
|
||||||
return ContainerUtil.intersects(dependencies, compilingChunk.modules)
|
return ContainerUtil.intersects(dependencies, compilingChunk.modules)
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
Targets dependent on Module 'a' production:
|
||||||
|
Module 'a' tests
|
||||||
|
Module 'b' production
|
||||||
|
Module 'b' tests
|
||||||
|
Module 'b2' production
|
||||||
|
Module 'b2' tests
|
||||||
|
Module 'c' production
|
||||||
|
Module 'c' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'a' tests:
|
||||||
|
Module 'b' tests
|
||||||
|
Module 'b2' tests
|
||||||
|
Module 'c' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'b2' production:
|
||||||
|
Module 'b2' tests
|
||||||
|
Module 'c2' production
|
||||||
|
Module 'c2' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'b2' tests:
|
||||||
|
Module 'c2' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'c2' production:
|
||||||
|
Module 'c2' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'c2' tests:
|
||||||
|
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'b' production:
|
||||||
|
Module 'b' tests
|
||||||
|
Module 'c' production
|
||||||
|
Module 'c' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'b' tests:
|
||||||
|
Module 'c' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'c' production:
|
||||||
|
Module 'c' tests
|
||||||
|
---------
|
||||||
|
Targets dependent on Module 'c' tests:
|
||||||
|
|
||||||
|
---------
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo() {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user