IJI-2358 Jewel maven artifacts build

(cherry picked from commit 0e1f8e8533c2342d11b3aff557a26c3c021e63d1)

IJ-MR-159792

GitOrigin-RevId: b6a987273d48ab5b876621121b3550510c733184
This commit is contained in:
Dmitriy.Panov
2025-03-28 15:38:20 +01:00
committed by intellij-monorepo-bot
parent 220aa9e0c6
commit 720aebd79d
6 changed files with 158 additions and 2 deletions

View File

@@ -34,6 +34,7 @@ open class IdeaCommunityProperties(private val communityHomeDir: Path) : BaseIde
"intellij.maven.testFramework",
"intellij.tools.reproducibleBuilds.diff",
"intellij.space.java.jps",
*JewelMavenArtifacts.STANDALONE.keys.toTypedArray(),
)
}
@@ -72,6 +73,23 @@ open class IdeaCommunityProperties(private val communityHomeDir: Path) : BaseIde
"intellij.platform.util.base",
"intellij.platform.util.zip",
))
mavenArtifacts.patchCoordinates = { module, coordinates ->
when {
JewelMavenArtifacts.isJewel(module) -> JewelMavenArtifacts.patchCoordinates(module, coordinates)
else -> coordinates
}
}
mavenArtifacts.addPomMetadata = { module, model ->
when {
JewelMavenArtifacts.isJewel(module) -> JewelMavenArtifacts.addPomMetadata(module, model)
}
}
mavenArtifacts.isJavadocJarRequired = {
JewelMavenArtifacts.isJewel(it)
}
mavenArtifacts.validate = { context, artifacts ->
JewelMavenArtifacts.validate(context, artifacts)
}
versionCheckerConfig = CE_CLASS_VERSIONS
baseDownloadUrl = "https://download.jetbrains.com/idea/"

View File

@@ -0,0 +1,130 @@
// Copyright 2000-2025 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 org.apache.maven.model.Developer
import org.apache.maven.model.License
import org.apache.maven.model.Model
import org.apache.maven.model.Scm
import org.jetbrains.intellij.build.impl.libraries.isLibraryModule
import org.jetbrains.intellij.build.impl.maven.GeneratedMavenArtifacts
import org.jetbrains.intellij.build.impl.maven.MavenCentralPublication
import org.jetbrains.intellij.build.impl.maven.MavenCoordinates
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.module.JpsModuleDependency
import kotlin.io.path.name
internal object JewelMavenArtifacts {
private const val GROUP_ID: String = "org.jetbrains.jewel"
val CORE: Map<String, String> = mapOf(
"intellij.platform.jewel.foundation" to "jewel-foundation",
"intellij.platform.jewel.markdown.core" to "jewel-markdown-core",
"intellij.platform.jewel.ui" to "jewel-ui",
"intellij.platform.jewel.markdown.extension.gfmTables" to "jewel-markdown-extension-gfm-tables",
"intellij.platform.jewel.markdown.extension.gfmAlerts" to "jewel-markdown-extension-gfm-alerts",
)
val STANDALONE: Map<String, String> = mapOf(
"intellij.platform.jewel.markdown.intUiStandaloneStyling" to "jewel-markdown-int-ui-standalone-styling",
"intellij.platform.jewel.intUi.decoratedWindow" to "jewel-int-ui-decorated-window",
"intellij.platform.jewel.intUi.standalone" to "jewel-int-ui-standalone",
"intellij.platform.jewel.decoratedWindow" to "jewel-decorated-window",
)
fun isJewel(module: JpsModule): Boolean {
return module.name.startsWith("intellij.platform.jewel.")
}
fun patchCoordinates(module: JpsModule, coordinates: MavenCoordinates): MavenCoordinates {
check(isJewel(module))
return coordinates.copy(groupId = GROUP_ID)
}
fun addPomMetadata(module: JpsModule, model: Model) {
check(isJewel(module))
model.name = "Jewel"
model.description = "A theme for Compose for Desktop that implements the IntelliJ Platform look and feel."
model.url = "https://github.com/JetBrains/intellij-community"
model.addLicense(License().apply {
name = "Apache License 2.0"
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
})
model.scm = Scm().apply {
connection = "scm:git:https://github.com/JetBrains/intellij-community.git"
developerConnection = "scm:git:https://github.com/JetBrains/intellij-community.git"
url = "https://github.com/JetBrains/intellij-community"
}
model.addDeveloper(Developer().apply {
id = "Google"
name = "Google Team"
organization = "Google"
organizationUrl = "https://developer.android.com"
})
}
private fun JpsModule.modulesTree(): Sequence<JpsModule> {
return sequenceOf(this) + dependenciesList.dependencies.asSequence()
.filterIsInstance<JpsModuleDependency>()
.mapNotNull { it.module }
.flatMap { it.modulesTree() }
}
fun validate(context: BuildContext, mavenArtifacts: Collection<GeneratedMavenArtifacts>) {
val jewelModules = CORE + STANDALONE
jewelModules.keys.asSequence()
.map(context::findRequiredModule)
.flatMap { it.modulesTree() }
.distinct().forEach { module ->
val artifact = mavenArtifacts.singleOrNull { (it) -> it.name == module.name }
if (module.isLibraryModule()) {
check(artifact == null) {
"Maven artifact for the library module ${module.name} is not supposed to be created: $artifact"
}
}
else {
checkNotNull(artifact) {
"No maven artifact is created for the module ${module.name}:\n$mavenArtifacts"
}
check(artifact.coordinates.groupId == GROUP_ID) {
"The module ${module.name} has groupId=${artifact.coordinates.groupId} " +
"but it's expected to have groupId=$GROUP_ID because Maven Central publication credentials are issues per namespace/groupId"
}
validateForMavenCentralPublication(artifact)
}
}
for ((jewelModuleName, artifactId) in jewelModules) {
check(mavenArtifacts.any { (module, mavenCoordinates) ->
module.name == jewelModuleName &&
mavenCoordinates.groupId == GROUP_ID &&
mavenCoordinates.artifactId == artifactId
}) {
"The module $jewelModuleName is expected to have groupId=$GROUP_ID and artifactId=$artifactId: " +
"${mavenArtifacts.filter { (module) -> module.name == jewelModuleName }}"
}
}
}
/**
* See https://central.sonatype.org/publish/requirements
*/
private fun validateForMavenCentralPublication(artifacts: GeneratedMavenArtifacts) {
val sources = artifacts.coordinates.getFileName("sources", "jar")
check(artifacts.files.any { it.name == sources }) {
"No $sources is generated for the module ${artifacts.module.name}"
}
val javadoc = artifacts.coordinates.getFileName("javadoc", "jar")
check(artifacts.files.any { it.name == javadoc }) {
"No $javadoc is generated for the module ${artifacts.module.name}"
}
val pom = artifacts.coordinates.getFileName(packaging = "pom")
val pomXml = artifacts.files.singleOrNull { it.name == pom }
check(pomXml != null) {
"No $pom is generated for the module ${artifacts.module.name}"
}
val coordinates = MavenCentralPublication.loadAndValidatePomXml(pomXml)
check(coordinates == artifacts.coordinates) {
"Maven coordinates ${artifacts.coordinates} generated for the module ${artifacts.module.name} " +
"don't match the coordinates $coordinates from $pomXml"
}
}
}

View File

@@ -21,7 +21,7 @@ class MavenArtifactsProperties {
/**
* If `true` Maven artifacts are generated for all modules included in the IDE distribution.
*/
var forIdeModules = false
var forIdeModules: Boolean = false
/**
* Names of additional modules for which Maven artifacts should be generated.
@@ -59,4 +59,7 @@ class MavenArtifactsProperties {
@ApiStatus.Internal
var isJavadocJarRequired: (JpsModule) -> Boolean = { false }
@ApiStatus.Internal
var validate: (Collection<Pair<JpsModule, MavenCoordinates>>) -> Unit = {}
}

View File

@@ -523,6 +523,7 @@ private fun CoroutineScope.createMavenArtifactJob(context: BuildContext, distrib
outputDir = "proprietary-maven-artifacts"
)
}
mavenArtifacts.validate(builtArtifacts.map { it.module to it.coordinates })
}
}

View File

@@ -276,7 +276,7 @@ open class MavenArtifactsBuilder(protected val context: BuildContext) {
return null
}
val artifactData = MavenArtifactData(generateMavenCoordinatesForModule(module), dependencies)
val artifactData = MavenArtifactData(module, generateMavenCoordinatesForModule(module), dependencies)
results[module] = artifactData
return artifactData
}
@@ -311,6 +311,7 @@ data class MavenCoordinates(
}
internal data class MavenArtifactData(
val module: JpsModule,
val coordinates: MavenCoordinates,
val dependencies: List<MavenArtifactDependency>
)

View File

@@ -20,6 +20,9 @@ internal fun PublishingExtension.configureJewelRepositories(project: Project) {
}
}
/**
* Obsolete, please use https://github.com/JetBrains/intellij-community/blob/master/build/src/org/jetbrains/intellij/build/JewelMavenArtifacts.kt instead
*/
internal fun MavenPom.configureJewelPom() {
name = "Jewel"
description = "A theme for Compose for Desktop that implements the IntelliJ Platform look and feel."