mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
[devkit] IJPL-158473 attach bundled plugin sources archives located inside the IntelliJ Platform directory
(cherry picked from commit 40481ca23e1ac81d3b3e99b732cdaa49f0fef0a9) IJ-CR-140104 GitOrigin-RevId: 954f4059a02959254c428bc563467acd1d0f778b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5e46db7296
commit
bb40a5e935
@@ -6,7 +6,6 @@ import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.exists
|
||||
@@ -19,11 +18,10 @@ private val json = Json { ignoreUnknownKeys = true }
|
||||
*/
|
||||
fun loadProductInfo(ideaJdkHome: String): ProductInfo? {
|
||||
val ideHomePath = Path.of(ideaJdkHome)
|
||||
val productInfoJsonPath = when {
|
||||
SystemInfo.isMac -> ideHomePath.resolve(ApplicationEx.PRODUCT_INFO_FILE_NAME_MAC)
|
||||
else -> ideHomePath.resolve(ApplicationEx.PRODUCT_INFO_FILE_NAME)
|
||||
}
|
||||
if (Files.notExists(productInfoJsonPath)) return null
|
||||
val productInfoJsonPath = listOf(
|
||||
ApplicationEx.PRODUCT_INFO_FILE_NAME_MAC,
|
||||
ApplicationEx.PRODUCT_INFO_FILE_NAME,
|
||||
).firstNotNullOfOrNull { ideHomePath.resolve(it).takeIf(Path::exists) } ?: return null
|
||||
|
||||
return runCatching { json.decodeFromString<ProductInfo>(productInfoJsonPath.readText()) }
|
||||
.onFailure { logger<ProductInfo>().error("error parsing '$productInfoJsonPath'", it) }
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
module.wizard.gradle.presentable.name=IntelliJ Platform Plugin
|
||||
module.wizard.gradle.learn.title=Learn how to <a>build plugins with Gradle</a>
|
||||
attachSources.action.name=Download IntelliJ Platform sources
|
||||
attachSources.action.busyText=Downloading IntelliJ Platform sources\u2026
|
||||
attachLSPSources.action.name=Attach IntelliJ Platform LSP-API sources
|
||||
attachLSPSources.action.busyText=Attaching IntelliJ Platform LSP-API sources\u2026
|
||||
attachSources.intellijPlatform.action.name=Download IntelliJ Platform sources
|
||||
attachSources.intellijPlatform.action.busyText=Downloading IntelliJ Platform sources\u2026
|
||||
attachSources.lsp.action.name=Attach IntelliJ Platform LSP-API sources
|
||||
attachSources.lsp.action.busyText=Attaching IntelliJ Platform LSP-API sources\u2026
|
||||
attachSources.css.action.name=Attach CSS plugin sources
|
||||
attachSources.css.action.busyText=Attaching CSS plugin sources\u2026
|
||||
attachSources.database.action.name=Attach Database plugin sources
|
||||
attachSources.database.action.busyText=Attaching Database plugin sources\u2026
|
||||
attachSources.java.action.name=Attach Java plugin sources
|
||||
attachSources.java.action.busyText=Attaching Java plugin sources\u2026
|
||||
attachSources.javaee.action.name=Attach JavaEE plugin sources
|
||||
attachSources.javaee.action.busyText=Attaching JavaEE plugin sources\u2026
|
||||
attachSources.persistence.action.name=Attach Persistence plugin sources
|
||||
attachSources.persistence.action.busyText=Attaching Persistence plugin sources\u2026
|
||||
attachSources.spring.action.name=Attach Spring plugin sources
|
||||
attachSources.spring.action.busyText=Attaching Spring plugin sources\u2026
|
||||
attachSources.springBoot.action.name=Attach SpringBoot plugin sources
|
||||
attachSources.springBoot.action.busyText=Attaching SpringBoot plugin sources\u2026
|
||||
attachSources.tomcat.action.name=Attach Tomcat plugin sources
|
||||
attachSources.tomcat.action.busyText=Attaching Tomcat plugin sources\u2026
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.util.ActionCallback
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.findFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.idea.devkit.projectRoots.IntelliJPlatformProduct
|
||||
import org.jetbrains.idea.devkit.run.ProductInfo
|
||||
@@ -18,9 +17,27 @@ import org.jetbrains.idea.devkit.run.loadProductInfo
|
||||
import org.jetbrains.plugins.gradle.execution.build.CachedModuleDataFinder
|
||||
import org.jetbrains.plugins.gradle.util.GradleDependencySourceDownloader
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
internal enum class PluginSourceArchives(
|
||||
val pluginId: String,
|
||||
val archiveName: String,
|
||||
val messageKey: String,
|
||||
) {
|
||||
CSS("com.intellij.css", "src_css-api.zip", "css"),
|
||||
DATABASE("com.intellij.database", "src_database-openapi.zip", "database"),
|
||||
JAVA("com.intellij.java", "src_jam-openapi.zip", "java"),
|
||||
JAVAEE("com.intellij.javaee", "src_javaee-openapi.zip", "javaee"),
|
||||
PERSISTENCE("com.intellij.persistence", "src_persistence-openapi.zip", "persistence"),
|
||||
SPRING("com.intellij.spring", "src_spring-openapi.zip", "spring"),
|
||||
SPRING_BOOT("com.intellij.spring.boot", "src_spring-boot-openapi.zip", "springBoot"),
|
||||
TOMCAT("Tomcat", "src_tomcat.zip", "tomcat"),
|
||||
LSP("LSP", "src_lsp-openapi.zip", "lsp"),
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches sources to the IntelliJ Platform dependencies in projects using IntelliJ Platform Gradle Plugin 2.x.
|
||||
* Some IDEs, like IntelliJ IDEA Ultimate or PhpStorm, don't provide sources for artifacts published to IntelliJ Repository.
|
||||
@@ -91,7 +108,8 @@ internal class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
else -> IntelliJPlatformProduct.IDEA_IC
|
||||
}.mavenCoordinates ?: return null
|
||||
|
||||
// We're checking if the compiled class belongs to the `/com/intellij/platform/lsp/` package, but not `.../impl` as it's not part of the API
|
||||
// When targeting IntelliJ IDEA Ultimate, it is possible to attach LSP module sources.
|
||||
// If the compiled class belongs to `com/intellij/platform/lsp/`, suggest attaching the relevant ZIP archive with LSP sources.
|
||||
val isLspApi = with(psiFile.virtualFile.path.substringAfter('!')) {
|
||||
when {
|
||||
startsWith("/com/intellij/platform/lsp/impl/") -> false
|
||||
@@ -102,7 +120,7 @@ internal class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
|
||||
return when {
|
||||
// We're handing LSP API class, but IU is lower than 242 -> attach a standalone sources file
|
||||
isLspApi && majorVersion < 242 -> createAttachLSPSourcesAction(psiFile)
|
||||
isLspApi && majorVersion < 242 -> createAttachSourcesArchiveAction(psiFile, PluginSourceArchives.LSP)
|
||||
|
||||
// Create the actual IntelliJ Platform sources attaching action
|
||||
else -> createAttachPlatformSourcesAction(psiFile, productCoordinates, version)
|
||||
@@ -133,32 +151,37 @@ internal class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
val product = IntelliJPlatformProduct.fromProductCode(productInfo.productCode) ?: return null
|
||||
val version = coordinates.version.substringBefore('+')
|
||||
|
||||
return resolveIntelliJPlatformAction(psiFile, product, version)
|
||||
val pluginSourceArchive = PluginSourceArchives.entries.firstOrNull { it.pluginId == coordinates.artifactId }
|
||||
return createAttachSourcesArchiveAction(psiFile, pluginSourceArchive)
|
||||
?: resolveIntelliJPlatformAction(psiFile, product, version)
|
||||
}
|
||||
|
||||
/**
|
||||
* When targeting IntelliJ IDEA Ultimate, it is possible to attach LSP module sources.
|
||||
* If the compiled class belongs to `com/intellij/platform/lsp/`, suggest attaching relevant ZIP archive with LSP sources.
|
||||
* Attach the provided sources archive.
|
||||
*
|
||||
* @param psiFile The PSI file that represents the currently handled class.
|
||||
* @param pluginSourceArchive Plugin sources archive metadata.
|
||||
*/
|
||||
private fun createAttachLSPSourcesAction(psiFile: PsiFile): AttachSourcesAction? {
|
||||
val jarFile = VfsUtilCore.getVirtualFileForJar(psiFile.virtualFile) ?: return null
|
||||
val sources = jarFile.parent.findFile("src/src_lsp-openapi.zip") ?: return null
|
||||
private fun createAttachSourcesArchiveAction(psiFile: PsiFile, pluginSourceArchive: PluginSourceArchives?): AttachSourcesAction? {
|
||||
if (pluginSourceArchive == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
return object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachLSPSources.action.name")
|
||||
return resolveSourcesArchive(psiFile, pluginSourceArchive.archiveName)?.let {
|
||||
object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachSources.${pluginSourceArchive.messageKey}.action.name")
|
||||
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachLSPSources.action.busyText")
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachSources.${pluginSourceArchive.messageKey}.action.busyText")
|
||||
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val executionResult = ActionCallback()
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val executionResult = ActionCallback()
|
||||
|
||||
attachSources(sources.toNioPath().toFile(), orderEntries) {
|
||||
executionResult.setDone()
|
||||
attachSources(it.toFile(), orderEntries) {
|
||||
executionResult.setDone()
|
||||
}
|
||||
|
||||
return executionResult
|
||||
}
|
||||
|
||||
return executionResult
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,39 +193,36 @@ internal class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
* @param productCoordinates The Maven coordinates of the IntelliJ Platform whose sources we load.
|
||||
* @param version The version of the product.
|
||||
*/
|
||||
private fun createAttachPlatformSourcesAction(
|
||||
psiFile: PsiFile,
|
||||
productCoordinates: String,
|
||||
version: String,
|
||||
) = object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachSources.action.name")
|
||||
private fun createAttachPlatformSourcesAction(psiFile: PsiFile, productCoordinates: String, version: String) =
|
||||
object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachSources.intellijPlatform.action.name")
|
||||
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachSources.action.busyText")
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachSources.intellijPlatform.action.busyText")
|
||||
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val externalProjectPath = CachedModuleDataFinder.getGradleModuleData(orderEntries.first().ownerModule)?.directoryToRunTask
|
||||
?: return ActionCallback.REJECTED
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val externalProjectPath = CachedModuleDataFinder.getGradleModuleData(orderEntries.first().ownerModule)?.directoryToRunTask
|
||||
?: return ActionCallback.REJECTED
|
||||
|
||||
val executionResult = ActionCallback()
|
||||
val project = psiFile.project
|
||||
val sourceArtifactNotation = "$productCoordinates:$version:sources"
|
||||
val executionResult = ActionCallback()
|
||||
val project = psiFile.project
|
||||
val sourceArtifactNotation = "$productCoordinates:$version:sources"
|
||||
|
||||
GradleDependencySourceDownloader
|
||||
.downloadSources(project, name, sourceArtifactNotation, externalProjectPath)
|
||||
.whenComplete { path, error ->
|
||||
if (error != null) {
|
||||
executionResult.setRejected()
|
||||
}
|
||||
else {
|
||||
attachSources(path, orderEntries) {
|
||||
executionResult.setDone()
|
||||
GradleDependencySourceDownloader
|
||||
.downloadSources(project, name, sourceArtifactNotation, externalProjectPath)
|
||||
.whenComplete { path, error ->
|
||||
if (error != null) {
|
||||
executionResult.setRejected()
|
||||
}
|
||||
else {
|
||||
attachSources(path, orderEntries) {
|
||||
executionResult.setDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return executionResult
|
||||
return executionResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches sources jar to the specified libraries and executes the provided block of code.
|
||||
@@ -218,9 +238,19 @@ internal class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
* Resolve the [ProductInfo] of the current IntelliJ Platform.
|
||||
*/
|
||||
private fun resolveProductInfo(psiFile: PsiFile): ProductInfo? {
|
||||
val jarPath = Path(psiFile.virtualFile.path)
|
||||
val jarPath = Path(psiFile.virtualFile.path.substringBefore('!'))
|
||||
return generateSequence(jarPath) { it.parent }
|
||||
.takeWhile { it != it.root }
|
||||
.firstNotNullOfOrNull { loadProductInfo(it.pathString) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the [ProductInfo] of the current IntelliJ Platform.
|
||||
*/
|
||||
private fun resolveSourcesArchive(psiFile: PsiFile, archiveName: String): Path? {
|
||||
val path = VfsUtilCore.getVirtualFileForJar(psiFile.virtualFile)?.toNioPath() ?: return null
|
||||
return generateSequence(path) { it.parent }
|
||||
.takeWhile { it != it.root }
|
||||
.firstNotNullOfOrNull { it.resolve("lib/src/$archiveName").takeIf(Path::exists) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user