IJI-3435 build scripts: bazel: Production Target //build:idea_monorepo_bazel Depends on Test Targets

in dev builds do not depend on test targets, fix defaults in build scripts

Space-RevId: cc5b3fa3019ba02ae6e91ca8ddc2883b26daed1e

GitOrigin-RevId: 55d291ca4cb34dd77ff0a57af43df980b01dc95f
This commit is contained in:
Leonid Shalupov
2026-01-22 03:03:45 +00:00
committed by intellij-monorepo-bot
parent 1d8ec5e529
commit 3f71dfd564
15 changed files with 59 additions and 10 deletions
+5 -1
View File
@@ -1,6 +1,7 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.jetbrains.intellij.build.BuildOptions
import org.jetbrains.intellij.build.BuildPaths.Companion.COMMUNITY_ROOT
import org.jetbrains.intellij.build.TestingOptions
import org.jetbrains.intellij.build.TestingTasks
@@ -21,7 +22,10 @@ object CommunityRunTestsBuildTarget {
runBlocking(Dispatchers.Default) {
val context = createCompilationContext(
projectHome = COMMUNITY_ROOT.communityRoot,
defaultOutputRoot = COMMUNITY_ROOT.communityRoot.resolve("out/tests")
defaultOutputRoot = COMMUNITY_ROOT.communityRoot.resolve("out/tests"),
options = BuildOptions().also {
it.useTestCompilationOutput = true
},
)
val options = TestingOptions()
options.mainModule = options.mainModule ?: "intellij.idea.community.main"
@@ -36,6 +36,7 @@ public final class JUnitDevMainKt {
System.setProperty("idea.vendor.name", "JetBrains");
System.setProperty("idea.use.dev.build.server", "true");
System.setProperty("idea.build.pack.test.source.enabled", "true");
if (jUnitStarterModule != null) System.setProperty("idea.dev.build.unpacked", "true");
// idea.platform.prefix should be set
if (System.getProperty("idea.platform.prefix") == null) {
@@ -6,6 +6,8 @@ import org.jetbrains.jps.model.module.JpsModule
import java.nio.file.Path
interface ModuleOutputProvider {
val useTestCompilationOutput: Boolean
fun readFileContentFromModuleOutput(module: JpsModule, relativePath: String, forTests: Boolean = false): ByteArray?
fun findModule(name: String): JpsModule?
@@ -20,7 +20,6 @@ import java.nio.file.Path
import java.nio.file.attribute.BasicFileAttributes
const val PLUGIN_XML_RELATIVE_PATH: String = "META-INF/plugin.xml"
val useTestSourceEnabled: Boolean = System.getProperty("idea.build.pack.test.source.enabled", "true").toBoolean()
fun getUnprocessedPluginXmlContent(module: JpsModule, outputProvider: ModuleOutputProvider): ByteArray {
return requireNotNull(findUnprocessedDescriptorContent(module = module, path = PLUGIN_XML_RELATIVE_PATH, outputProvider = outputProvider)) {
@@ -31,7 +30,7 @@ fun getUnprocessedPluginXmlContent(module: JpsModule, outputProvider: ModuleOutp
fun findUnprocessedDescriptorContent(module: JpsModule, path: String, outputProvider: ModuleOutputProvider): ByteArray? {
try {
val result = outputProvider.readFileContentFromModuleOutput(module = module, relativePath = path, forTests = false)
if (result == null && useTestSourceEnabled) {
if (result == null && outputProvider.useTestCompilationOutput) {
return outputProvider.readFileContentFromModuleOutput(module = module, relativePath = path, forTests = true)
}
return result
@@ -401,6 +401,9 @@ class ProductModulesContentSpecTest {
* Mock ModuleOutputProvider for testing that doesn't load modules.
*/
private class MockModuleOutputProvider : ModuleOutputProvider {
override val useTestCompilationOutput: Boolean
get() = throw UnsupportedOperationException("Not available in mock")
override fun readFileContentFromModuleOutput(module: JpsModule, relativePath: String, forTests: Boolean): ByteArray? {
throw UnsupportedOperationException("Not available in mock")
}
@@ -506,6 +506,9 @@ private fun createTestModuleOutputProvider(project: JpsProject): ModuleOutputPro
override fun findRequiredModule(name: String): JpsModule =
findModule(name) ?: error("Module not found: $name")
override val useTestCompilationOutput: Boolean
get() = true
override fun readFileContentFromModuleOutput(module: JpsModule, relativePath: String, forTests: Boolean): ByteArray {
throw UnsupportedOperationException("Not needed for this test")
}
@@ -44,6 +44,12 @@ data class BuildOptions(
@JvmField var isInDevelopmentMode: Boolean = getBooleanProperty("intellij.build.dev.mode", System.getenv("TEAMCITY_VERSION") == null && System.getenv("GITHUB_ACTIONS") == null),
@JvmField var useCompiledClassesFromProjectOutput: Boolean = getBooleanProperty(USE_COMPILED_CLASSES_PROPERTY, isInDevelopmentMode),
/**
* In addition to production compilation sources, allow various functions to use and traverse test output.
* It is necessary. e.g., to run tests in a dev-build-provided environment.
*/
var useTestCompilationOutput: Boolean = getBooleanProperty(USE_TEST_COMPILATION_OUTPUT_PROPERTY, defaultValue = USE_TEST_COMPILATION_OUTPUT_DEFAULT_VALUE),
@JvmField val cleanOutDir: Boolean = getBooleanProperty(CLEAN_OUTPUT_DIRECTORY_PROPERTY, true),
@JvmField var classOutDir: String? = System.getProperty(PROJECT_CLASSES_OUTPUT_DIRECTORY_PROPERTY),
@@ -243,6 +249,13 @@ data class BuildOptions(
*/
const val CLEAN_OUTPUT_DIRECTORY_PROPERTY: String = "intellij.build.clean.output.root"
/**
* In addition to production compilation sources, allow various functions to use and traverse test output.
* It is necessary. e.g., to run tests in a dev-build-provided environment.
*/
const val USE_TEST_COMPILATION_OUTPUT_PROPERTY: String = "idea.build.pack.test.source.enabled"
const val USE_TEST_COMPILATION_OUTPUT_DEFAULT_VALUE: Boolean = false
/**
* If `false` build scripts compile project classes to a special output directory (to not interfere with the default project output if
* invoked on a developer machine).
@@ -34,7 +34,7 @@ internal class JarPackagerDependencyHelper(private val outputProvider: ModuleOut
}
fun isTestPluginModule(moduleName: String, module: JpsModule?): Boolean {
if (!useTestSourceEnabled) {
if (!outputProvider.useTestCompilationOutput) {
return false
}
@@ -426,6 +426,7 @@ private suspend fun createBuildContext(
logDir = buildDir.resolve("log"),
isUnpackedDist = request.isUnpackedDist,
useTestCompilationOutput = buildOptionsTemplate?.useTestCompilationOutput ?: BuildOptions().useTestCompilationOutput,
)
options.setTargetOsAndArchToCurrent()
options.buildStepsToSkip += listOf(
@@ -37,7 +37,13 @@ class BazelCompilationContext(
private val scope: CoroutineScope?,
) : CompilationContext {
override val outputProvider: ModuleOutputProvider by lazy {
BazelModuleOutputProvider(modules = delegate.project.modules, projectHome = delegate.paths.projectHome, bazelOutputRoot = bazelOutputRoot!!, scope = scope)
BazelModuleOutputProvider(
modules = delegate.project.modules,
projectHome = delegate.paths.projectHome,
bazelOutputRoot = bazelOutputRoot!!,
scope = scope,
useTestCompilationOutput = options.useTestCompilationOutput,
)
}
override val options: BuildOptions
@@ -5,11 +5,13 @@ package org.jetbrains.intellij.build.impl
import com.intellij.util.io.toByteArray
import kotlinx.coroutines.CoroutineScope
import org.jetbrains.intellij.bazelEnvironment.BazelLabel
import org.jetbrains.intellij.bazelEnvironment.BazelRunfiles
import org.jetbrains.intellij.build.BuildOptions.Companion.USE_TEST_COMPILATION_OUTPUT_DEFAULT_VALUE
import org.jetbrains.intellij.build.BuildOptions.Companion.USE_TEST_COMPILATION_OUTPUT_PROPERTY
import org.jetbrains.intellij.build.ModuleOutputProvider
import org.jetbrains.intellij.build.io.ZipEntryProcessorResult
import org.jetbrains.intellij.build.io.readZipFile
import org.jetbrains.intellij.bazelEnvironment.BazelLabel
import org.jetbrains.intellij.bazelEnvironment.BazelRunfiles
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService
import java.nio.file.Files
@@ -21,6 +23,7 @@ internal class BazelModuleOutputProvider(
private val projectHome: Path,
val bazelOutputRoot: Path,
scope: CoroutineScope?,
override val useTestCompilationOutput: Boolean,
) : ModuleOutputProvider {
private val nameToModule = modules.associateByTo(HashMap(modules.size)) { it.name }
@@ -119,6 +122,15 @@ internal class BazelModuleOutputProvider(
private fun getModuleOutputRootsImpl(module: JpsModule, forTests: Boolean): List<Path> {
val moduleDescription = bazelTargetsMap.modules[module.name] ?: error("Cannot find module '${module.name}' in the project")
if (forTests && !useTestCompilationOutput) {
error(
"Cannot find test sources for module '${module.name}' because 'useTestSourceEnabled' is false.\n" +
"System property '${USE_TEST_COMPILATION_OUTPUT_PROPERTY}' value: ${System.getProperty(USE_TEST_COMPILATION_OUTPUT_PROPERTY)}, " +
"BazelModuleOutputProvider.useTestCompilationOutput (from BuildOptions.useTestCompilationOutput) value: $useTestCompilationOutput, " +
"default value: $USE_TEST_COMPILATION_OUTPUT_DEFAULT_VALUE"
)
}
return if (BazelRunfiles.isRunningFromBazel) {
val targets = if (forTests) moduleDescription.testTargets else moduleDescription.productionTargets
targets.map { BazelRunfiles.getFileByLabel(BazelLabel.fromString(it)) }
@@ -170,7 +170,7 @@ class CompilationContextImpl internal constructor(
val global: JpsGlobal
get() = model.global
override val outputProvider: ModuleOutputProvider = JpsModuleOutputProvider(project)
override val outputProvider: ModuleOutputProvider = JpsModuleOutputProvider(project, useTestCompilationOutput = options.useTestCompilationOutput)
override var classesOutputDirectory: Path
get() = Path.of(JpsPathUtil.urlToPath(JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(project).outputUrl))
@@ -14,7 +14,7 @@ import java.nio.file.NoSuchFileException
import java.nio.file.Path
import kotlin.io.path.isRegularFile
internal class JpsModuleOutputProvider(private val project: JpsProject) : ModuleOutputProvider {
internal class JpsModuleOutputProvider(private val project: JpsProject, override val useTestCompilationOutput: Boolean) : ModuleOutputProvider {
private val modules = project.modules
private val nameToModule = modules.associateByTo(HashMap(modules.size)) { it.name }
@@ -195,16 +195,18 @@ private suspend fun jsonResponse(
}
private fun createModuleOutputProvider(projectRoot: Path, scope: CoroutineScope): ModuleOutputProvider {
val useTestCompilationOutput = true
val project = JpsSerializationManager.getInstance().loadProject(
projectRoot.toString(),
mapOf("MAVEN_REPOSITORY" to JpsMavenSettings.getMavenRepositoryPath()),
false
)
val bazelOutputRoot = bazelOutputRoot ?: return JpsModuleOutputProvider(project)
val bazelOutputRoot = bazelOutputRoot ?: return JpsModuleOutputProvider(project, useTestCompilationOutput = useTestCompilationOutput)
return BazelModuleOutputProvider(
modules = project.modules,
projectHome = projectRoot,
bazelOutputRoot = bazelOutputRoot,
scope = scope,
useTestCompilationOutput = useTestCompilationOutput,
)
}
@@ -33,6 +33,9 @@ object IdeInstance {
fun isStarted(): Boolean = _ide != null
fun startIde(runMode: IdeRunMode): IdeWithLambda = synchronized(this) {
// Allow IDE building to access test modules
System.setProperty("idea.build.pack.test.source.enabled", "true")
try {
if (isStarted() && currentIdeMode == runMode && IdeStartConfig.current == currentIdeConfig) {
LOG.info("IDE is already running in mode: $runMode and there were no requests to change it's config. Reusing the current instance of IDE.")