IJI-1571 Extract ultimate and community home folder lockup into static properties.

GitOrigin-RevId: 3dda1f49e57b0e0b23deb5fe5b7fa4f670255b34
This commit is contained in:
Mikhail Filippov
2024-02-12 12:43:43 +04:00
committed by intellij-monorepo-bot
parent 4d41a0c5b5
commit 56c46e4945
15 changed files with 80 additions and 82 deletions

View File

@@ -20,7 +20,6 @@ object CommunityRunTestsBuildTarget {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
runBlocking(Dispatchers.Default) {
val context = createCompilationContext(
communityHome = communityHome,
projectHome = communityHome.communityRoot,
defaultOutputRoot = communityHome.communityRoot.resolve("out/tests")
)

View File

@@ -11,8 +11,7 @@ internal object KotlinPluginBuildTarget {
fun main(args: Array<String>) {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
runBlocking(Dispatchers.Default) {
KotlinPluginBuilder.build(communityHome = communityHome,
home = communityHome.communityRoot,
KotlinPluginBuilder.build(home = communityHome.communityRoot,
properties = IdeaCommunityProperties(communityHome.communityRoot))
}
}

View File

@@ -16,8 +16,7 @@ internal suspend fun createCommunityBuildContext(
options: BuildOptions = BuildOptions(),
projectHome: Path = communityHome.communityRoot,
): BuildContext {
return BuildContextImpl.createContext(communityHome = communityHome,
projectHome = projectHome,
return BuildContextImpl.createContext(projectHome = projectHome,
productProperties = IdeaCommunityProperties(communityHome.communityRoot),
setupTracer = true,
options = options)

View File

@@ -35,7 +35,6 @@ class IdeaCommunityBuildTest {
val productProperties = IdeaCommunityProperties(communityHome.communityRoot)
val options = createBuildOptionsForTest(productProperties = productProperties, skipDependencySetup = true)
val context = BuildContextImpl.createContext(
communityHome = communityHome,
projectHome = homePath,
productProperties = productProperties,
setupTracer = false,

View File

@@ -21,7 +21,6 @@ import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.protobuf.ProtoBuf
import org.jetbrains.intellij.build.*
import org.jetbrains.intellij.build.TraceManager.spanBuilder
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
import org.jetbrains.intellij.build.impl.*
import org.jetbrains.intellij.build.impl.projectStructureMapping.DistributionFileEntry
import org.jetbrains.intellij.build.impl.projectStructureMapping.ModuleOutputEntry
@@ -373,7 +372,6 @@ private suspend fun createBuildContext(
options.generateRuntimeModuleRepository = options.generateRuntimeModuleRepository && request.generateRuntimeModuleRepository
CompilationContextImpl.createCompilationContext(
communityHome = getCommunityHomePath(request.homePath),
projectHome = request.homePath,
buildOutputRootEvaluator = { _ -> runDir },
setupTracer = false,
@@ -442,7 +440,7 @@ private suspend fun createProductProperties(productConfiguration: ProductConfigu
catch (_: NoSuchMethodException) {
lookup
.findConstructor(productPropertiesClass, MethodType.methodType(Void.TYPE, Path::class.java))
.invoke(if (request.platformPrefix == "Idea") getCommunityHomePath(request.homePath).communityRoot else request.homePath)
.invoke(if (request.platformPrefix == "Idea") getCommunityHomePath(request.homePath) else request.homePath)
} as ProductProperties
}
}
@@ -512,14 +510,10 @@ fun computeAdditionalModulesFingerprint(additionalModules: List<String>): String
}
}
private fun getCommunityHomePath(homePath: Path): BuildDependenciesCommunityRoot {
var communityDotIdea = homePath.resolve("community/.idea")
// Handle Rider repository layout
if (Files.notExists(communityDotIdea)) {
val riderSpecificCommunityDotIdea = homePath.parent.resolve("ultimate/community/.idea")
if (Files.exists(riderSpecificCommunityDotIdea)) {
communityDotIdea = riderSpecificCommunityDotIdea
}
private fun getCommunityHomePath(homePath: Path): Path {
return if (Files.isDirectory(homePath.resolve("community"))) {
homePath.resolve("community")
} else {
homePath
}
return BuildDependenciesCommunityRoot(if (Files.isDirectory(communityDotIdea)) communityDotIdea.parent else homePath)
}

View File

@@ -27,6 +27,20 @@ class BuildPaths(
*/
val artifactDir: Path = buildOutputDir.resolve("artifacts"),
) {
companion object {
@JvmStatic
val ULTIMATE_HOME: Path by lazy {
IdeaProjectLoaderUtil.guessUltimateHome(javaClass) ?: error(
"Could not detect ultimate home folder from class: ${BuildPaths.javaClass.name}")
}
@JvmStatic
val COMMUNITY_ROOT: BuildDependenciesCommunityRoot by lazy {
IdeaProjectLoaderUtil.guessCommunityHome(javaClass) ?: error(
"Could not detect community home folder from class: ${BuildPaths.javaClass.name}")
}
}
/**
* Path to a directory where idea/community Git repository is checked out
*/

View File

@@ -2,32 +2,42 @@
package org.jetbrains.intellij.build;
import com.intellij.util.lang.UrlClassLoader;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public final class IdeaProjectLoaderUtil {
private static final String JPS_BOOTSTRAP_COMMUNITY_HOME_ENV_NAME = "JPS_BOOTSTRAP_COMMUNITY_HOME";
private static final String ULTIMATE_REPO_MARKER_FILE = ".ultimate.root.marker";
private static final String COMMUNITY_REPO_MARKER_FILE = "intellij.idea.community.main.iml";
private static final String INTELLIJ_BUILD_COMMUNITY_HOME_PATH = "intellij.build.community.home.path";
private static final String INTELLIJ_BUILD_ULTIMATE_HOME_PATH = "intellij.build.ultimate.home.path";
/**
* @param klass must be a class inside of idea home directory, the one with <code>file</code> protocol. Jar files in maven directory aren't accepted.
* This method only for internal usage. Instead of use: org.jetbrains.intellij.build.BuildPaths.Companion#getULTIMATE_HOME().
* @param klass must be a class inside idea home directory, the one with <code>file</code> protocol. Jar files in maven directory aren't accepted.
*/
@ApiStatus.Internal
public static Path guessUltimateHome(Class<?> klass) {
String ultimateHomePathOverride = System.getProperty(INTELLIJ_BUILD_ULTIMATE_HOME_PATH);
if (ultimateHomePathOverride != null) {
Path path = Paths.get(ultimateHomePathOverride);
if (!path.toFile().exists()) {
throw new IllegalArgumentException("Ultimate home path: '" + path
+ "' passed via system property: '" + INTELLIJ_BUILD_ULTIMATE_HOME_PATH + " not exists");
}
return path;
}
final Path start = getSomeRoot(klass);
Path home = start;
while (home != null) {
if (Files.exists(home.resolve(ULTIMATE_REPO_MARKER_FILE))) {
return home;
}
// Handle Rider layout case
if (Files.exists(home.resolve("ultimate").resolve(ULTIMATE_REPO_MARKER_FILE))) {
return home.resolve("ultimate");
}
home = home.getParent();
}
@@ -36,9 +46,20 @@ public final class IdeaProjectLoaderUtil {
}
/**
* @param klass must be a class inside of idea home directory, the one with <code>file</code> protocol. Jar files in maven directory aren't accepted.
* This method only for internal usage. Instead of use: org.jetbrains.intellij.build.BuildPaths.Companion#getCOMMUNITY_ROOT().
* @param klass must be a class inside idea home directory, the one with <code>file</code> protocol. Jar files in maven directory aren't accepted.
*/
@ApiStatus.Internal
public static BuildDependenciesCommunityRoot guessCommunityHome(Class<?> klass) {
String communityHomePathOverride = System.getProperty(INTELLIJ_BUILD_COMMUNITY_HOME_PATH);
if (communityHomePathOverride != null) {
Path path = Paths.get(communityHomePathOverride);
if (!path.toFile().exists()) {
throw new IllegalArgumentException("Community home path: '" + path
+ "' passed via system property: '" + INTELLIJ_BUILD_COMMUNITY_HOME_PATH + " not exists");
}
return new BuildDependenciesCommunityRoot(path);
}
final Path start = getSomeRoot(klass);
Path home = start;
@@ -51,11 +72,6 @@ public final class IdeaProjectLoaderUtil {
return new BuildDependenciesCommunityRoot(home.resolve("community"));
}
// Handle Rider layout case
if (Files.exists(home.resolve("ultimate").resolve("community").resolve(COMMUNITY_REPO_MARKER_FILE))) {
return new BuildDependenciesCommunityRoot(home.resolve("ultimate").resolve("community"));
}
home = home.getParent();
}
@@ -80,7 +96,8 @@ public final class IdeaProjectLoaderUtil {
}
private static Path getPathFromClass(Class<?> klass) {
final URL classFileURL = klass.getResource(klass.getSimpleName() + ".class");
String klassFileName = klass.getName().replace(klass.getPackageName() + ".", "");
final URL classFileURL = klass.getResource(klassFileName + ".class");
if (classFileURL == null) {
throw new IllegalStateException("Could not get .class file location from class " + klass.getName());
}

View File

@@ -96,15 +96,13 @@ class BuildContextImpl(
companion object {
suspend fun createContext(
communityHome: BuildDependenciesCommunityRoot,
projectHome: Path,
productProperties: ProductProperties,
setupTracer: Boolean = true,
proprietaryBuildTools: ProprietaryBuildTools = ProprietaryBuildTools.DUMMY,
options: BuildOptions = BuildOptions(),
productProperties: ProductProperties,
setupTracer: Boolean = true,
proprietaryBuildTools: ProprietaryBuildTools = ProprietaryBuildTools.DUMMY,
options: BuildOptions = BuildOptions(),
): BuildContext {
val compilationContext = CompilationContextImpl.createCompilationContext(
communityHome = communityHome,
projectHome = projectHome,
setupTracer = setupTracer,
buildOutputRootEvaluator = createBuildOutputRootEvaluator(projectHome = projectHome,
@@ -243,7 +241,6 @@ class BuildContextImpl(
paths = computeBuildPaths(
options = options,
project = project,
communityHome = paths.communityHomeDirRoot,
buildOutputRootEvaluator = createBuildOutputRootEvaluator(
projectHome = paths.projectHome,
productProperties = productProperties,

View File

@@ -22,8 +22,8 @@ import kotlinx.coroutines.withContext
import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.annotations.ApiStatus.Obsolete
import org.jetbrains.intellij.build.*
import org.jetbrains.intellij.build.BuildPaths.Companion.COMMUNITY_ROOT
import org.jetbrains.intellij.build.TraceManager.spanBuilder
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
import org.jetbrains.intellij.build.dependencies.DependenciesProperties
import org.jetbrains.intellij.build.dependencies.JdkDownloader
import org.jetbrains.intellij.build.impl.JdkUtils.defineJdk
@@ -52,44 +52,38 @@ import kotlin.io.path.invariantSeparatorsPathString
import kotlin.io.path.relativeToOrNull
@Obsolete
fun createCompilationContextBlocking(communityHome: BuildDependenciesCommunityRoot,
projectHome: Path,
fun createCompilationContextBlocking(projectHome: Path,
defaultOutputRoot: Path,
options: BuildOptions = BuildOptions()): CompilationContextImpl {
return runBlocking(Dispatchers.Default) {
createCompilationContext(communityHome = communityHome,
projectHome = projectHome,
createCompilationContext(projectHome = projectHome,
defaultOutputRoot = defaultOutputRoot,
options = options)
}
}
suspend fun createCompilationContext(communityHome: BuildDependenciesCommunityRoot,
projectHome: Path,
suspend fun createCompilationContext(projectHome: Path,
defaultOutputRoot: Path,
options: BuildOptions = BuildOptions()): CompilationContextImpl {
val logDir = options.logPath?.let { Path.of(it) }
?: (options.outRootDir ?: defaultOutputRoot).resolve("log")
JaegerJsonSpanExporterManager.setOutput(logDir.toAbsolutePath().normalize().resolve("trace.json"))
return CompilationContextImpl.createCompilationContext(communityHome = communityHome,
projectHome = projectHome,
return CompilationContextImpl.createCompilationContext(projectHome = projectHome,
setupTracer = false,
buildOutputRootEvaluator = { defaultOutputRoot },
options = options)
}
internal fun computeBuildPaths(
options: BuildOptions,
project: JpsProject,
communityHome: BuildDependenciesCommunityRoot,
buildOutputRootEvaluator: (JpsProject) -> Path,
internal fun computeBuildPaths(options: BuildOptions,
project: JpsProject,
buildOutputRootEvaluator: (JpsProject) -> Path,
artifactPathSupplier: (() -> Path)?,
projectHome: Path,
): BuildPaths {
val buildOut = options.outRootDir ?: buildOutputRootEvaluator(project)
val logDir = options.logPath?.let { Path.of(it).toAbsolutePath().normalize() } ?: buildOut.resolve("log")
val result = BuildPaths(
communityHomeDirRoot = communityHome,
communityHomeDirRoot = COMMUNITY_ROOT,
buildOutputDir = buildOut,
logDir = logDir,
projectHome = projectHome,
@@ -102,7 +96,6 @@ internal fun computeBuildPaths(
@Internal
class CompilationContextImpl private constructor(
model: JpsModel,
private val communityHome: BuildDependenciesCommunityRoot,
override val messages: BuildMessages,
override val paths: BuildPaths,
override val options: BuildOptions,
@@ -140,7 +133,7 @@ class CompilationContextImpl private constructor(
override suspend fun getStableJdkHome(): Path {
var jdkHome = cachedJdkHome
if (jdkHome == null) {
jdkHome = JdkDownloader.getJdkHome(communityHome, Span.current()::addEvent)
jdkHome = JdkDownloader.getJdkHome(COMMUNITY_ROOT, Span.current()::addEvent)
cachedJdkHome = jdkHome
}
return jdkHome
@@ -150,7 +143,7 @@ class CompilationContextImpl private constructor(
var jdkHome = cachedJdkHome
if (jdkHome == null) {
// blocking doesn't matter, getStableJdkHome is mostly always called before
jdkHome = JdkDownloader.blockingGetJdkHome(communityHome, Span.current()::addEvent)
jdkHome = JdkDownloader.blockingGetJdkHome(COMMUNITY_ROOT, Span.current()::addEvent)
cachedJdkHome = jdkHome
}
JdkDownloader.getJavaExecutable(jdkHome)
@@ -165,7 +158,6 @@ class CompilationContextImpl private constructor(
companion object {
suspend fun createCompilationContext(
communityHome: BuildDependenciesCommunityRoot,
projectHome: Path,
buildOutputRootEvaluator: (JpsProject) -> Path,
options: BuildOptions,
@@ -173,15 +165,15 @@ class CompilationContextImpl private constructor(
enableCoroutinesDump: Boolean = true,
): CompilationContextImpl {
check(sequenceOf("platform/build-scripts", "bin/idea.properties", "build.txt").all {
Files.exists(communityHome.communityRoot.resolve(it))
Files.exists(COMMUNITY_ROOT.communityRoot.resolve(it))
}) {
"communityHome ($communityHome) doesn\'t point to a directory containing IntelliJ Community sources"
"communityHome ($COMMUNITY_ROOT) doesn\'t point to a directory containing IntelliJ Community sources"
}
val messages = BuildMessagesImpl.create()
if (options.printEnvironmentInfo) {
Span.current().addEvent("environment info", Attributes.of(
AttributeKey.stringKey("community home"), communityHome.communityRoot.toString(),
AttributeKey.stringKey("community home"), COMMUNITY_ROOT.communityRoot.toString(),
AttributeKey.stringKey("project home"), projectHome.toString(),
))
printEnvironmentDebugInfo()
@@ -193,16 +185,14 @@ class CompilationContextImpl private constructor(
val model = loadProject(
projectHome = projectHome,
kotlinBinaries = KotlinBinaries(communityHome),
kotlinBinaries = KotlinBinaries(COMMUNITY_ROOT),
isCompilationRequired = CompiledClasses.isCompilationRequired(options),
)
val buildPaths = computeBuildPaths(
project = model.project,
communityHome = communityHome,
options = options,
buildOutputRootEvaluator = buildOutputRootEvaluator,
projectHome = projectHome,
val buildPaths = computeBuildPaths(project = model.project,
options = options,
buildOutputRootEvaluator = buildOutputRootEvaluator,
projectHome = projectHome,
artifactPathSupplier = null,
)
@@ -213,7 +203,6 @@ class CompilationContextImpl private constructor(
}
val context = CompilationContextImpl(model = model,
communityHome = communityHome,
messages = messages,
paths = buildPaths,
options = options)
@@ -247,7 +236,6 @@ class CompilationContextImpl private constructor(
): CompilationContextImpl {
val copy = CompilationContextImpl(
model = projectModel,
communityHome = paths.communityHomeDirRoot,
messages = messages,
paths = paths,
options = options,

View File

@@ -8,7 +8,6 @@ import org.jetbrains.intellij.build.BuildContext
import org.jetbrains.intellij.build.BuildOptions
import org.jetbrains.intellij.build.ProductProperties
import org.jetbrains.intellij.build.createBuildTasks
import org.jetbrains.intellij.build.dependencies.BuildDependenciesCommunityRoot
import org.jetbrains.intellij.build.dependencies.TeamCityHelper
import org.jetbrains.intellij.build.impl.BuildContextImpl
import org.jetbrains.intellij.build.impl.LibraryPackMode
@@ -427,12 +426,11 @@ object KotlinPluginBuilder {
return result
}
suspend fun build(communityHome: BuildDependenciesCommunityRoot, home: Path, properties: ProductProperties) {
suspend fun build(home: Path, properties: ProductProperties) {
val context = BuildContextImpl.createContext(
communityHome = communityHome,
setupTracer = true,
projectHome = home,
productProperties = properties,
projectHome = home,
productProperties = properties,
options = BuildOptions(enableEmbeddedJetBrainsClient = false),
)
createBuildTasks(context).buildNonBundledPlugins(listOf(MAIN_KOTLIN_PLUGIN_MODULE))

View File

@@ -77,7 +77,6 @@ suspend inline fun createBuildContext(
val options = createBuildOptionsForTest(productProperties)
buildOptionsCustomizer(options)
return BuildContextImpl.createContext(
communityHome = communityHomePath,
projectHome = homePath,
productProperties = productProperties,
proprietaryBuildTools = buildTools,
@@ -119,7 +118,6 @@ fun runTestBuild(
repeat(reproducibilityTest.iterations) { iterationNumber ->
launch {
val buildContext = BuildContextImpl.createContext(
communityHome = communityHomePath,
projectHome = homePath,
productProperties = productProperties,
proprietaryBuildTools = buildTools,
@@ -144,7 +142,6 @@ fun runTestBuild(
else {
doRunTestBuild(
context = BuildContextImpl.createContext(
communityHome = communityHomePath,
projectHome = homePath,
productProperties = productProperties,
proprietaryBuildTools = buildTools,

View File

@@ -15,7 +15,7 @@ class PluginDistributionJARsBuilderTest {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
val productProperties = IdeaCommunityProperties(communityHome.communityRoot)
runBlocking(Dispatchers.Default) {
val context = BuildContextImpl.createContext(communityHome, communityHome.communityRoot, productProperties)
val context = BuildContextImpl.createContext(communityHome.communityRoot, productProperties)
val ideClasspath1 = createIdeClassPath(createPlatformLayout(pluginsToPublish = emptySet(), context = context), context)
val ideClasspath2 = createIdeClassPath(createPlatformLayout(pluginsToPublish = emptySet(), context = context), context)
assertThat(ideClasspath1).isEqualTo(ideClasspath2)

View File

@@ -68,7 +68,6 @@ class BundledRuntimeTest {
try {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
val context = createCompilationContextBlocking(
communityHome = communityHome,
projectHome = communityHome.communityRoot,
defaultOutputRoot = tempDir,
)

View File

@@ -31,7 +31,6 @@ object PyCharmCommunityInstallersBuildTarget {
}
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(PyCharmCommunityInstallersBuildTarget::class.java)
val context = BuildContextImpl.createContext(
communityHome = communityHome,
projectHome = communityHome.communityRoot,
productProperties = PyCharmCommunityProperties(communityHome.communityRoot),
options = options,

View File

@@ -26,8 +26,7 @@ internal class PythonCommunityPluginBuilder(private val home: Path) {
options.outRootDir = homeDir.resolve("out/pycharmCE")
val communityRoot = BuildDependenciesCommunityRoot(homeDir)
val buildContext = BuildContextImpl.createContext(communityHome = communityRoot,
projectHome = homeDir,
val buildContext = BuildContextImpl.createContext(projectHome = homeDir,
productProperties = IdeaCommunityProperties(communityRoot.communityRoot),
options = options)
createBuildTasks(buildContext).buildNonBundledPlugins(listOf(