mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
bazel: add debugger-agent as a kotlin test dependency
GitOrigin-RevId: 1244ce715c8039dae45ce29306da890a8e0fcd3b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1513f7024b
commit
1f46eeef22
@@ -17,6 +17,8 @@ local_path_override(
|
||||
path = "build/jvm-rules",
|
||||
)
|
||||
|
||||
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
|
||||
|
||||
bazel_dep(name = "hermetic_cc_toolchain", version = "4.0.1")
|
||||
|
||||
toolchains = use_extension("@hermetic_cc_toolchain//toolchain:ext.bzl", "toolchains")
|
||||
@@ -88,6 +90,13 @@ use_repo(
|
||||
"kotlin_test_deps_parcelize-compiler-plugin-for-ide",
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "debugger_test_deps_debugger_agent",
|
||||
url = "https://cache-redirector.jetbrains.com/packages.jetbrains.team/maven/p/ij/intellij-dependencies/org/jetbrains/intellij/deps/debugger-agent/1.79/debugger-agent-1.79.jar",
|
||||
sha256 = "ba7a0aa7bbb813acab3b0edf36c0a15449f41896993c97e0d133fa4ea0a3e6d9",
|
||||
downloaded_file_path = "debugger-agent.jar"
|
||||
)
|
||||
|
||||
# GraalVM
|
||||
# git_override(
|
||||
# module_name = "rules_graalvm",
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testResources" type="java-test-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
@@ -100,6 +102,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.debugger.impl.rpc" />
|
||||
<orderEntry type="module" module-name="fleet.rpc" />
|
||||
<orderEntry type="module" module-name="intellij.platform.rpc" />
|
||||
<orderEntry type="module" module-name="intellij.platform.testFramework.common" scope="TEST" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -13,10 +13,12 @@ import com.intellij.debugger.memory.utils.StackFrameItem;
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.debugger.settings.CaptureSettingsProvider;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.debugger.testFramework.TestDebuggerAgentArtifactsProvider;
|
||||
import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint;
|
||||
import com.intellij.execution.JavaExecutionUtil;
|
||||
import com.intellij.execution.configurations.JavaParameters;
|
||||
import com.intellij.execution.configurations.ParametersList;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
@@ -353,6 +355,13 @@ public final class AsyncStacksUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if Bazel-test specific env variables are set
|
||||
*/
|
||||
private static Boolean isBazelTestRun() {
|
||||
return System.getenv("TEST_SRCDIR") != null && System.getenv("TEST_UNDECLARED_OUTPUTS_DIR") != null;
|
||||
}
|
||||
|
||||
@NativePath
|
||||
private static @Nullable String getAgentArtifactPath(@Nullable Project project, @Nullable Disposable disposable) {
|
||||
String relevantJarsRoot = PathManager.getArchivedCompliedClassesLocation();
|
||||
@@ -375,13 +384,37 @@ public final class AsyncStacksUtils {
|
||||
try {
|
||||
Path agentArtifactPath = createTemporaryAgentPath(project, disposable);
|
||||
|
||||
Path communityRoot = Path.of(PathManager.getCommunityHomePath());
|
||||
Path iml = BuildDependenciesJps.getProjectModule(communityRoot, "intellij.java.debugger.agent.holder");
|
||||
Path downloadedAgent = BuildDependenciesJps.INSTANCE.getModuleLibrarySingleRootSync(
|
||||
iml,
|
||||
"debugger-agent",
|
||||
"https://cache-redirector.jetbrains.com/intellij-dependencies",
|
||||
new BuildDependenciesCommunityRoot(Path.of(PathManager.getCommunityHomePath())));
|
||||
Path downloadedAgent;
|
||||
// In jps runs we resolve the debugger agent via the standard BuildDependenciesJps path below.
|
||||
// However, when tests are executed under Bazel, they run inside a hermetic sandbox. In this environment:
|
||||
// - Network/downloads and access to arbitrary files are restricted.
|
||||
// - All runtime inputs must come from explicit Bazel-declared dependencies (runfiles).
|
||||
// Therefore, in Bazel unit-test mode we must obtain the agent JAR from the test classpath via a test-only
|
||||
// service. The TestDebuggerAgentArtifactsProvider is implemented in test sources and knows how to locate
|
||||
// the agent artifact provided by Bazel via runfiles, so we use ServiceLoader to find that provider
|
||||
// on the tests classpath and resolve the agent from there. Outside Bazel (regular production/dev runs), we
|
||||
// keep using the standard resolution path that downloads the dependency if needed.
|
||||
if (PluginManagerCore.isUnitTestMode && isBazelTestRun()) {
|
||||
ServiceLoader<TestDebuggerAgentArtifactsProvider> providerClasses = ServiceLoader.load(TestDebuggerAgentArtifactsProvider.class);
|
||||
var iterator = providerClasses.iterator();
|
||||
if (!iterator.hasNext()) {
|
||||
throw new IllegalStateException("TestDebuggerAgentArtifactsProvider service provider not found");
|
||||
}
|
||||
TestDebuggerAgentArtifactsProvider provider = iterator.next();
|
||||
if (iterator.hasNext()) {
|
||||
throw new IllegalStateException("more than one TestDebuggerAgentArtifactsProvider service providers found. Only one is expected");
|
||||
}
|
||||
|
||||
downloadedAgent = provider.getDebuggerAgentJar();
|
||||
} else {
|
||||
Path communityRoot = Path.of(PathManager.getCommunityHomePath());
|
||||
Path iml = BuildDependenciesJps.getProjectModule(communityRoot, "intellij.java.debugger.agent.holder");
|
||||
downloadedAgent = BuildDependenciesJps.INSTANCE.getModuleLibrarySingleRootSync(
|
||||
iml,
|
||||
"debugger-agent",
|
||||
"https://cache-redirector.jetbrains.com/intellij-dependencies",
|
||||
new BuildDependenciesCommunityRoot(Path.of(PathManager.getCommunityHomePath())));
|
||||
}
|
||||
|
||||
// The agent file must have a fixed name (AGENT_JAR_NAME) which is mentioned in MANIFEST.MF inside.
|
||||
// The copy operation is used as the rename operation.
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.testFramework;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Test-only service used to resolve debugger agent artifacts when running tests (especially under Bazel).
|
||||
* <p>
|
||||
* In production and regular dev runs, the agent is resolved via standard mechanisms (e.g., BuildDependenciesJps).
|
||||
* But Bazel tests execute in a hermetic sandbox where downloads and arbitrary file access are restricted and all
|
||||
* inputs must be declared as dependencies (runfiles). To make the agent available in that environment, Bazel wires
|
||||
* the artifact into the test's classpath/runfiles. This service, implemented in test sources, knows how to locate
|
||||
* that artifact and provide its path to the runtime code.
|
||||
* <p>
|
||||
* The implementation must be present on the tests classpath and is discovered via {@link java.util.ServiceLoader}.
|
||||
*/
|
||||
public interface TestDebuggerAgentArtifactsProvider {
|
||||
|
||||
Path getDebuggerAgentJar();
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.artifacts;
|
||||
|
||||
import com.intellij.debugger.testFramework.TestDebuggerAgentArtifactsProvider;
|
||||
import com.intellij.testFramework.common.bazel.BazelLabel;
|
||||
import com.intellij.testFramework.common.BazelTestUtil;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class TestDebuggerAgentArtifactsProviderImpl implements TestDebuggerAgentArtifactsProvider {
|
||||
|
||||
@Override
|
||||
public Path getDebuggerAgentJar() {
|
||||
String debuggerAgentLabel = "@debugger_test_deps_debugger_agent//file:debugger-agent.jar";
|
||||
BazelLabel label = BazelLabel.Companion.fromString(debuggerAgentLabel);
|
||||
|
||||
if (BazelTestUtil.isUnderBazelTest()) {
|
||||
return BazelTestUtil.getFileFromBazelRuntime(label);
|
||||
} else {
|
||||
throw new IllegalStateException("Expected to be used only in bazel-test environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.intellij.debugger.artifacts.TestDebuggerAgentArtifactsProviderImpl
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.testFramework.common
|
||||
|
||||
import com.intellij.testFramework.common.bazel.BazelLabel
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolute
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.isRegularFile
|
||||
import kotlin.io.path.useLines
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@@ -64,6 +66,22 @@ object BazelTestUtil {
|
||||
path
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getFileFromBazelRuntime(label: BazelLabel): Path {
|
||||
val repoEntry = bazelTestRepoMapping.getOrElse(label.repo) {
|
||||
error("Unable to determine dependency path '${label.asLabel}'")
|
||||
}
|
||||
val file = bazelTestRunfilesPath.resolve(
|
||||
repoEntry.runfilesRelativePath + "/${label.packageName}/${label.file}"
|
||||
)
|
||||
return when {
|
||||
file.isRegularFile() || file.isDirectory() -> file.toAbsolutePath()
|
||||
else -> {
|
||||
error("Unable to find test dependency '${label.asLabel}' at $file")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests under community root may run in community (OSS) or in the ultimate monorepo context.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.testFramework.common.bazel
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
// https://bazel.build/rules/lib/builtins/Label.html
|
||||
@ApiStatus.Experimental
|
||||
data class BazelLabel(
|
||||
val repo: String,
|
||||
val packageName: String,
|
||||
val file: String,
|
||||
) {
|
||||
companion object {
|
||||
private val regex = Regex("@([a-zA-Z0-9_-]+)//([a-z0-9_/-]+):([a-zA-Z0-9._-]+)")
|
||||
fun fromString(label: String): BazelLabel {
|
||||
val match = regex.matchEntire(label) ?: error("Bazel label must match '${regex.pattern}': $label")
|
||||
return BazelLabel(
|
||||
repo = match.groupValues[1],
|
||||
packageName = match.groupValues[2],
|
||||
file = match.groupValues[3],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val asLabel: String
|
||||
get() = "@$repo//$packageName:$file"
|
||||
}
|
||||
+2
-38
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.idea.base.plugin.artifacts
|
||||
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.testFramework.common.BazelTestUtil
|
||||
import com.intellij.testFramework.common.bazel.BazelLabel
|
||||
import com.intellij.util.io.createParentDirectories
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -81,43 +82,6 @@ object TestKotlinArtifacts {
|
||||
listOf(getKotlinDepsByLabel("@kotlin_test_deps_kotlin-jps-plugin-classpath//file:kotlin-jps-plugin-classpath.jar").toPath())
|
||||
}
|
||||
|
||||
// https://bazel.build/rules/lib/builtins/Label.html
|
||||
data class BazelLabel(
|
||||
val repo: String,
|
||||
val packageName: String,
|
||||
val file: String,
|
||||
) {
|
||||
companion object {
|
||||
private val regex = Regex("@([a-zA-Z0-9_-]+)//([a-z0-9_/-]+):([a-zA-Z0-9._-]+)")
|
||||
fun fromString(label: String): BazelLabel {
|
||||
val match = regex.matchEntire(label) ?: error("Bazel label must match '${regex.pattern}': $label")
|
||||
return BazelLabel(
|
||||
repo = match.groupValues[1],
|
||||
packageName = match.groupValues[2],
|
||||
file = match.groupValues[3],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val asLabel: String
|
||||
get() = "@$repo//$packageName:$file"
|
||||
}
|
||||
|
||||
private fun getFileFromBazelRuntime(label: BazelLabel): Path {
|
||||
val repoEntry = BazelTestUtil.bazelTestRepoMapping.getOrElse(label.repo) {
|
||||
error("Unable to determine dependency path '${label.asLabel}'")
|
||||
}
|
||||
val file = BazelTestUtil.bazelTestRunfilesPath.resolve(
|
||||
repoEntry.runfilesRelativePath + "/${label.packageName}/${label.file}"
|
||||
)
|
||||
return when {
|
||||
file.exists() -> file.toAbsolutePath()
|
||||
else -> {
|
||||
error("Unable to find test dependency '${label.asLabel}' at $file")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class HttpFile(val downloadFilePath: String, val name: String, val url: String)
|
||||
|
||||
private val kotlinTestDependenciesHttpFiles by lazy {
|
||||
@@ -183,7 +147,7 @@ object TestKotlinArtifacts {
|
||||
private fun getKotlinDepsByLabel(label: BazelLabel): File {
|
||||
// Why it is different
|
||||
val dependency = if (BazelTestUtil.isUnderBazelTest) {
|
||||
getFileFromBazelRuntime(label)
|
||||
BazelTestUtil.getFileFromBazelRuntime(label)
|
||||
} else {
|
||||
downloadFile(label)
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ jps_test(
|
||||
runtime_deps = [
|
||||
":k2_test_lib",
|
||||
"//:main_test_lib",
|
||||
"@lib//:java-debugger-agent-holder-debugger-agent",
|
||||
],
|
||||
data = [
|
||||
"@kotlin_test_deps_org_jetbrains_kotlinx_kotlinx_coroutines_core_1_10_2//file:kotlinx_coroutines_core_1_10_2.jar",
|
||||
"@kotlin_test_deps_org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm_1_10_2//file:kotlinx_coroutines_core_jvm_1_10_2.jar",
|
||||
|
||||
"@debugger_test_deps_debugger_agent//file:debugger-agent.jar",
|
||||
"@community//plugins/kotlin/jvm-debugger/test:testData",
|
||||
"@kotlin_test_deps_annotations//file:annotations.jar",
|
||||
"@kotlin_test_deps_junit//file:junit.jar",
|
||||
@@ -54,7 +54,7 @@ jvm_library(
|
||||
name = "k2_test_lib",
|
||||
module_name = "kotlin.jvm-debugger.test.k2",
|
||||
visibility = ["//visibility:public"],
|
||||
srcs = glob(["test/**/*.kt", "test/**/*.java", "test/**/*.form"], allow_empty = True),
|
||||
srcs = glob(["test/**/*.kt", "test/**/*.java"], allow_empty = True),
|
||||
deps = [
|
||||
"//platform/core-ui",
|
||||
"//plugins/kotlin/plugin/k2",
|
||||
|
||||
Reference in New Issue
Block a user