IJPL-149028 extract inferModuleSources

GitOrigin-RevId: 20a0896eb1ec0599957e1299d7411d4ebf4540ad
This commit is contained in:
Vladimir Krivosheev
2024-04-30 11:04:35 +02:00
committed by intellij-monorepo-bot
parent bb38ce369b
commit a29ac8baf7
4 changed files with 109 additions and 102 deletions

View File

@@ -3,6 +3,7 @@
package org.jetbrains.intellij.build
import com.intellij.util.xml.dom.readXmlAsModel
import org.jetbrains.intellij.build.impl.ModuleItem
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
@@ -22,6 +23,18 @@ internal class JarPackagerDependencyHelper(private val context: BuildContext) {
return getModuleDependencies(context.findRequiredModule(moduleName)).map { it.moduleReference.moduleName }
}
fun readPluginContentFromDescriptor(context: BuildContext, pluginModule: JpsModule): Sequence<String> {
val pluginXml = context.findFileInModuleSources(pluginModule, "META-INF/plugin.xml") ?: return emptySequence()
return sequence {
for (content in readXmlAsModel(pluginXml).children("content")) {
for (module in content.children("module")) {
val moduleName = module.attributes.get("name")?.takeIf { !it.contains('/') } ?: continue
yield(moduleName)
}
}
}
}
private fun getModuleDependencies(module: JpsModule): Sequence<JpsModuleDependency> {
return sequence {
for (element in module.dependenciesList.dependencies) {
@@ -53,9 +66,7 @@ internal class JarPackagerDependencyHelper(private val context: BuildContext) {
// And it is a plugin that depends on cool.module.core.
//
// We should include cool-library only to cool.module.core (same group).
fun hasLibraryInDependencyChainOfModuleDependencies(dependentModule: JpsModule,
libraryName: String,
siblings: Collection<ModuleItem>): Boolean {
fun hasLibraryInDependencyChainOfModuleDependencies(dependentModule: JpsModule, libraryName: String, siblings: Collection<ModuleItem>): Boolean {
val prefix = dependentModule.name.let { it.substring(0, it.lastIndexOf('.') + 1) }
for (dependency in getModuleDependencies(dependentModule)) {
val moduleName = dependency.moduleReference.moduleName

View File

@@ -0,0 +1,77 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.intellij.build
import com.intellij.util.xml.dom.readXmlAsModel
import org.jetbrains.intellij.build.impl.*
internal suspend fun inferModuleSources(
layout: PluginLayout,
addedModules: MutableSet<String>,
platformLayout: PlatformLayout,
helper: JarPackagerDependencyHelper,
jarPackager: JarPackager,
moduleOutputPatcher: ModuleOutputPatcher,
jarsWithSearchableOptions: Set<String>,
context: BuildContext,
) {
// for now, check only direct dependencies of the main plugin module
val childPrefix = "${layout.mainModule}."
for (name in helper.getModuleDependencies(layout.mainModule)) {
if ((!name.startsWith(childPrefix) && name != "intellij.platform.commercial.verifier") || addedModules.contains(name)) {
continue
}
val moduleItem = ModuleItem(moduleName = name, relativeOutputFile = layout.getMainJarName(), reason = "<- ${layout.mainModule}")
addedModules.add(name)
if (platformLayout.includedModules.contains(moduleItem)) {
continue
}
jarPackager.computeSourcesForModule(item = moduleItem, moduleOutputPatcher = moduleOutputPatcher, layout = layout, jarsWithSearchableOptions = jarsWithSearchableOptions)
}
if (layout.mainModule == "intellij.pycharm.ds.remoteInterpreter") {
// todo PyCharm team why this module is being incorrectly published
return
}
// check content
helper.readPluginContentFromDescriptor(context, context.findRequiredModule(layout.mainModule))
.filterNot { !addedModules.add(it) }
.forEach { moduleName ->
val descriptor = readXmlAsModel(context.findFileInModuleSources(moduleName, "$moduleName.xml")!!)
jarPackager.computeSourcesForModule(
item = ModuleItem(
moduleName = moduleName,
// relative path with `/` is always packed by dev-mode, so, we don't need to fix resolving for now and can improve it later
relativeOutputFile = if (descriptor.getAttributeValue("package") == null) "modules/$moduleName.jar" else layout.getMainJarName(),
reason = "<- ${layout.mainModule} (plugin content)",
),
moduleOutputPatcher = moduleOutputPatcher,
layout = layout,
jarsWithSearchableOptions = jarsWithSearchableOptions,
)
}
// check verifier in all included modules
val effectiveIncludedNonMainModules = LinkedHashSet<String>(layout.includedModules.size + addedModules.size)
layout.includedModules.mapTo(effectiveIncludedNonMainModules) { it.moduleName }
effectiveIncludedNonMainModules.remove(layout.mainModule)
effectiveIncludedNonMainModules.addAll(addedModules)
for (moduleName in effectiveIncludedNonMainModules) {
for (name in helper.getModuleDependencies(moduleName)) {
if (name != "intellij.platform.commercial.verifier" || addedModules.contains(name)) {
continue
}
val moduleItem = ModuleItem(moduleName = name, relativeOutputFile = layout.getMainJarName(), reason = "<- ${layout.mainModule}")
addedModules.add(name)
jarPackager.computeSourcesForModule(
item = moduleItem,
moduleOutputPatcher = moduleOutputPatcher,
layout = layout,
jarsWithSearchableOptions = jarsWithSearchableOptions,
)
}
}
}

View File

@@ -1,4 +1,6 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("ReplaceGetOrSet")
package org.jetbrains.intellij.build.impl
import com.intellij.openapi.util.JDOMUtil
@@ -10,7 +12,6 @@ import com.intellij.platform.diagnostic.telemetry.helpers.useWithScope
import com.intellij.platform.diagnostic.telemetry.helpers.useWithoutActiveScope
import com.intellij.util.io.Decompressor
import com.intellij.util.system.CpuArch
import com.intellij.util.xml.dom.readXmlAsModel
import com.jetbrains.plugin.structure.base.utils.toList
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.api.common.Attributes
@@ -186,10 +187,11 @@ private suspend fun localizeModules(context: BuildContext, moduleNames: Collecti
val modules = if (moduleNames.isEmpty()) {
context.project.modules
} else {
}
else {
moduleNames.asSequence().mapNotNull { context.findModule(it) }
.flatMap { m ->
readPluginDependenciesFromXml(context, m).mapNotNull { context.findModule(it) } + sequenceOf(m)
(context as BuildContextImpl).jarPackagerDependencyHelper.readPluginContentFromDescriptor(context, m).mapNotNull { context.findModule(it) } + sequenceOf(m)
}.flatMap { m ->
m.dependenciesList.dependencies.asSequence().filterIsInstance<JpsModuleDependency>().mapNotNull { it.module } + sequenceOf(m)
}.distinctBy { m -> m.name }.toList()
@@ -1447,11 +1449,7 @@ internal suspend fun setLastModifiedTime(directory: Path, context: BuildContext)
/**
* @return list of all modules which output is included in the plugin's JARs
*/
internal fun collectIncludedPluginModules(
enabledPluginModules: Collection<String>,
product: ProductModulesLayout,
result: MutableSet<String>
) {
internal fun collectIncludedPluginModules(enabledPluginModules: Collection<String>, product: ProductModulesLayout, result: MutableSet<String>) {
result.addAll(enabledPluginModules)
val enabledPluginModuleSet = if (enabledPluginModules is Set<String> || enabledPluginModules.size < 2) {
enabledPluginModules
@@ -1464,24 +1462,6 @@ internal fun collectIncludedPluginModules(
.flatMapTo(result) { layout -> layout.includedModules.asSequence().map { it.moduleName } }
}
internal fun readPluginDependenciesFromXml(context: BuildContext, module: JpsModule) : Sequence<String> {
return sequence {
context.findFileInModuleSources(module, "META-INF/plugin.xml")?.let { pluginXml ->
readXmlAsModel(pluginXml).children("content").let { contents ->
contents.forEach { content ->
for (depModule in content.children("module")) {
val moduleName = depModule.attributes["name"]
if (moduleName == null || moduleName.contains('/')) {
continue
}
yield(moduleName)
}
}
}
}
}
}
fun copyDistFiles(context: BuildContext, newDir: Path, os: OsFamily, arch: JvmArchitecture) {
for (item in context.getDistFiles(os, arch)) {
val targetFile = newDir.resolve(item.relativePath)

View File

@@ -10,7 +10,6 @@ import com.intellij.util.PathUtilRt
import com.intellij.util.io.URLUtil
import com.intellij.util.io.sanitizeFileName
import com.intellij.util.lang.ImmutableZipFile
import com.intellij.util.xml.dom.readXmlAsModel
import com.jetbrains.util.filetype.FileType
import com.jetbrains.util.filetype.FileTypeDetector.DetectFileType
import io.opentelemetry.api.common.AttributeKey
@@ -252,75 +251,19 @@ class JarPackager private constructor(
return
}
// for now, check only direct dependencies of the main plugin module
val childPrefix = "${layout.mainModule}."
for (name in helper.getModuleDependencies(layout.mainModule)) {
if ((!name.startsWith(childPrefix) && name != "intellij.platform.commercial.verifier") || addedModules.contains(name)) {
continue
}
val moduleItem = ModuleItem(moduleName = name, relativeOutputFile = layout.getMainJarName(), reason = "<- ${layout.mainModule}")
addedModules.add(name)
if (platformLayout!!.includedModules.contains(moduleItem)) {
continue
}
computeSourcesForModule(
item = moduleItem,
moduleOutputPatcher = moduleOutputPatcher,
layout = layout,
jarsWithSearchableOptions = jarsWithSearchableOptions,
)
}
if (layout.mainModule == "intellij.pycharm.ds.remoteInterpreter") {
// todo PyCharm team why this module is being incorrectly published
return
}
// check content
readPluginDependenciesFromXml(context, context.findRequiredModule(layout.mainModule))
.filterNot { d -> !addedModules.add(d) }
.forEach { moduleName ->
val descriptor = readXmlAsModel(context.findFileInModuleSources(moduleName, "$moduleName.xml")!!)
computeSourcesForModule(
item = ModuleItem(
moduleName = moduleName,
// relative path with `/` is always packed by dev-mode, so, we don't need to fix resolving for now and can improve it later
relativeOutputFile = if (descriptor.getAttributeValue("package") == null) "modules/$moduleName.jar" else layout.getMainJarName(),
reason = "<- ${layout.mainModule} (plugin content)",
),
moduleOutputPatcher = moduleOutputPatcher,
layout = layout,
jarsWithSearchableOptions = jarsWithSearchableOptions,
)
}
// check verifier in all included modules
val effectiveIncludedNonMainModules = LinkedHashSet<String>(layout.includedModules.size + addedModules.size)
layout.includedModules.mapTo(effectiveIncludedNonMainModules) { it.moduleName }
effectiveIncludedNonMainModules.remove(layout.mainModule)
effectiveIncludedNonMainModules.addAll(addedModules)
for (moduleName in effectiveIncludedNonMainModules) {
for (name in helper.getModuleDependencies(moduleName)) {
if (name != "intellij.platform.commercial.verifier" || addedModules.contains(name)) {
continue
}
val moduleItem = ModuleItem(moduleName = name, relativeOutputFile = layout.getMainJarName(), reason = "<- ${layout.mainModule}")
addedModules.add(name)
computeSourcesForModule(
item = moduleItem,
moduleOutputPatcher = moduleOutputPatcher,
layout = layout,
jarsWithSearchableOptions = jarsWithSearchableOptions,
)
}
}
inferModuleSources(
layout = layout,
platformLayout = platformLayout!!,
addedModules = addedModules,
helper = helper,
moduleOutputPatcher = moduleOutputPatcher,
jarsWithSearchableOptions = jarsWithSearchableOptions,
jarPackager = this,
context = context,
)
}
private suspend fun computeSourcesForModule(
internal suspend fun computeSourcesForModule(
item: ModuleItem,
moduleOutputPatcher: ModuleOutputPatcher,
layout: BaseLayout?,
@@ -431,11 +374,7 @@ class JarPackager private constructor(
continue
}
if (helper.hasLibraryInDependencyChainOfModuleDependencies(
dependentModule = module,
libraryName = libName,
siblings = layout.includedModules,
)) {
if (helper.hasLibraryInDependencyChainOfModuleDependencies(dependentModule = module, libraryName = libName, siblings = layout.includedModules)) {
continue
}