Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/nikolay.chashnikov/frontend-plug…
Browse files Browse the repository at this point in the history
…ins'
  • Loading branch information
hsz committed Apr 29, 2024
2 parents 411e6af + 99217d2 commit 0c6867a
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [next]

### Added
- `targetProductPart` property is added to allow installing plugin on the frontend part when running in Split Mode [#1563](../../issues/1563)

### Fixed

- Fix for: `coroutinesJavaAgentPath` specifies file `.../build/tmp/initializeIntelliJPlugin/coroutines-javaagent.jar` which doesn't exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
package org.jetbrains.intellij.platform.gradle.argumentProviders

import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.PathSensitivity.RELATIVE
import org.gradle.process.CommandLineArgumentProvider
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
import org.jetbrains.intellij.platform.gradle.utils.asPath
import java.io.File
import java.nio.file.Path
Expand Down Expand Up @@ -39,6 +38,14 @@ class SandboxArgumentProvider(

@OutputDirectory
val sandboxLogDirectory: DirectoryProperty,

@Optional
@Input
val splitMode: Provider<Boolean>,

@Optional
@Input
val targetProductPart: Provider<SplitModeAware.SplitModeTarget>,
) : CommandLineArgumentProvider {

/**
Expand All @@ -51,13 +58,24 @@ class SandboxArgumentProvider(
it.listDirectoryEntries().joinToString("${File.pathSeparator},")
}

private fun computePluginPathProperties(): List<String> {
if (splitMode.get() && targetProductPart.get() == SplitModeAware.SplitModeTarget.FRONTEND) {
return listOfNotNull(
// Specifies an empty directory to ensure that the plugin won't be loaded by the backend process.
sandboxPluginsDirectory.ifExists { "-Didea.plugins.path=$it/backend" },
)
}
return listOfNotNull(
sandboxPluginsDirectory.ifExists { "-Didea.plugins.path=$it" },
pluginPath?.let { "-Dplugin.path=$it" },
)
}

override fun asArguments() = listOfNotNull(
sandboxConfigDirectory.ifExists { "-Didea.config.path=$it" },
sandboxSystemDirectory.ifExists { "-Didea.system.path=$it" },
sandboxLogDirectory.ifExists { "-Didea.log.path=$it" },
sandboxPluginsDirectory.ifExists { "-Didea.plugins.path=$it" },
pluginPath?.let { "-Dplugin.path=$it" },
)
sandboxLogDirectory.ifExists { "-Didea.log.path=$it" }
) + computePluginPathProperties()

private fun <T> DirectoryProperty.ifExists(block: (Path) -> T) = orNull?.asPath?.takeIf { it.exists() }?.run(block)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ import org.jetbrains.intellij.platform.gradle.models.productInfo
import org.jetbrains.intellij.platform.gradle.models.toPublication
import org.jetbrains.intellij.platform.gradle.models.validateSupportedVersion
import org.jetbrains.intellij.platform.gradle.providers.ProductReleasesValueSource
import org.jetbrains.intellij.platform.gradle.tasks.BuildSearchableOptionsTask
import org.jetbrains.intellij.platform.gradle.tasks.PatchPluginXmlTask
import org.jetbrains.intellij.platform.gradle.tasks.PublishPluginTask
import org.jetbrains.intellij.platform.gradle.tasks.SignPluginTask
import org.jetbrains.intellij.platform.gradle.tasks.*
import org.jetbrains.intellij.platform.gradle.tasks.VerifyPluginTask.*
import org.jetbrains.intellij.platform.gradle.tasks.aware.PluginVerifierAware
import org.jetbrains.intellij.platform.gradle.tasks.aware.SigningAware
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
import org.jetbrains.intellij.platform.gradle.toIntelliJPlatformType
import org.jetbrains.intellij.platform.gradle.utils.asLenient
import org.jetbrains.intellij.platform.gradle.utils.asPath
Expand Down Expand Up @@ -127,12 +125,20 @@ abstract class IntelliJPlatformExtension @Inject constructor(
* is running a frontend part (JetBrains Client) which connects to the backend.
*
* This property allows running the IDE with backend and frontend parts running in separate processes.
* The developed plugin is installed in the backend part.
* The developed plugin is installed in the backend part by default, this can be changed via [splitModeTarget].
*
* Default value: `false`
*/
abstract val splitMode: Property<Boolean>

/**
* Taken into account only if [splitMode] is set to `true` and specifies in which part of the IDE the plugin
* should be installed when `runIde` task is executed: the backend process, the frontend process, or both.
*
* Default value: [SplitModeAware.SplitModeTarget.BACKEND]
*/
abstract val splitModeTarget: Property<SplitModeAware.SplitModeTarget>

val pluginConfiguration
get() = extensions.getByName<PluginConfiguration>(Extensions.PLUGIN_CONFIGURATION)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ abstract class IntelliJPlatformBasePlugin : Plugin<Project> {
projectName.convention(project.name)
sandboxContainer.convention(project.layout.buildDirectory.dir(Sandbox.CONTAINER))
splitMode.convention(false)
splitModeTarget.convention(SplitModeAware.SplitModeTarget.BACKEND)

configureExtension<IntelliJPlatformExtension.PluginConfiguration>(Extensions.PLUGIN_CONFIGURATION) {
version.convention(project.provider { project.version.toString() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ abstract class CustomTestIdeTask : Test(), TestableAware, CustomIntelliJPlatform
sourceTask.sandboxPluginsDirectory,
sourceTask.sandboxSystemDirectory,
sourceTask.sandboxLogDirectory,
project.provider { false },
project.provider { null },
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformDepende
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformExtension
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformPluginsExtension
import org.jetbrains.intellij.platform.gradle.models.transformXml
import org.jetbrains.intellij.platform.gradle.tasks.aware.CustomIntelliJPlatformVersionAware
import org.jetbrains.intellij.platform.gradle.tasks.aware.SandboxAware
import org.jetbrains.intellij.platform.gradle.tasks.aware.SandboxProducerAware
import org.jetbrains.intellij.platform.gradle.tasks.aware.*
import org.jetbrains.intellij.platform.gradle.utils.asPath
import java.nio.file.Path
import kotlin.io.path.*
Expand All @@ -45,7 +43,7 @@ import kotlin.io.path.*
* @see Constants.Sandbox
*/
@CacheableTask
abstract class PrepareSandboxTask : Sync(), SandboxProducerAware {
abstract class PrepareSandboxTask : Sync(), SandboxProducerAware, SplitModeAware {

/**
* Default sandbox destination directory to where the plugin files will be copied into.
Expand Down Expand Up @@ -112,7 +110,7 @@ abstract class PrepareSandboxTask : Sync(), SandboxProducerAware {
override fun copy() {
disableIdeUpdate()
disabledPlugins()

createSplitModeFrontendPropertiesFile()
super.copy()
}

Expand Down Expand Up @@ -175,6 +173,33 @@ abstract class PrepareSandboxTask : Sync(), SandboxProducerAware {
.writeLines(disabledPlugins.get())
}

/**
* Creates a properties file which will be passed to the frontend process when the IDE is started in Split Mode.
*/
private fun createSplitModeFrontendPropertiesFile() {
if (!splitMode.get()) {
return
}

val pluginsPath = when (splitModeTarget.get()) {
SplitModeAware.SplitModeTarget.FRONTEND, SplitModeAware.SplitModeTarget.BACKEND_AND_FRONTEND ->
sandboxPluginsDirectory.asPath

SplitModeAware.SplitModeTarget.BACKEND ->
// Specifies an empty directory to ensure that the plugin won't be loaded.
sandboxPluginsDirectory.asPath.resolve("frontend")
}

frontendPropertiesFile.asPath.writeText(
"""
idea.config.path=${sandboxConfigDirectory.asPath.resolve("frontend")}
idea.system.path=${sandboxSystemDirectory.asPath.resolve("frontend")}
idea.log.path=${sandboxLogDirectory.asPath.resolve("frontend")}
idea.plugins.path=$pluginsPath
""".trimIndent()
)
}

fun ensureName(path: Path): String {
var name = path.name
var index = 1
Expand Down Expand Up @@ -215,6 +240,8 @@ abstract class PrepareSandboxTask : Sync(), SandboxProducerAware {
from(pluginsClasspath)

inputs.property("intellijPlatform.instrumentCode", extension.instrumentCode)
inputs.property("intellijPlatform.splitMode", extension.splitMode)
inputs.property("intellijPlatform.targetProductPart", extension.splitModeTarget)
inputs.files(runtimeConfiguration)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ abstract class RunIdeTask : JavaExec(), RunnableIdeAware, IntelliJPlatformVersio

if (splitMode.get()) {
environment("JETBRAINS_CLIENT_JDK", runtimeDirectory.asPath.pathString)
environment("JETBRAINS_CLIENT_PROPERTIES", frontendPropertiesFile.asPath.pathString)

if (args.orEmpty().isNotEmpty()) {
throw InvalidUserDataException("Passing arguments directly is not supported in Split Mode. Use `argumentProviders` instead.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
package org.jetbrains.intellij.platform.gradle.tasks.aware

import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Internal
import org.jetbrains.intellij.platform.gradle.Constants
import org.jetbrains.intellij.platform.gradle.extensions.IntelliJPlatformExtension
Expand Down Expand Up @@ -63,4 +65,11 @@ interface SandboxAware : IntelliJPlatformVersionAware {
*/
@get:Internal
val sandboxLogDirectory: DirectoryProperty

/**
* Path to a properties file which will be used to configure the frontend process if the IDE is started in Split Mode.
*/
@get:Internal
val frontendPropertiesFile: Provider<RegularFile>
get() = sandboxContainerDirectory.file("frontend.properties")
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ interface SplitModeAware : IntelliJPlatformVersionAware {
@get:Internal
val splitMode: Property<Boolean>

/**
* Specifies in which part of the product the developed plugin should be installed.
*
* Default value: [SplitModeTarget.BACKEND]
*/
@get:Internal
val splitModeTarget: Property<SplitModeTarget>

/**
* Validates that the resolved IntelliJ Platform supports Split Mode.
*
Expand All @@ -41,4 +49,15 @@ interface SplitModeAware : IntelliJPlatformVersionAware {
throw IllegalArgumentException("Split Mode requires the IntelliJ Platform in version '${Constraints.MINIMAL_SPLIT_MODE_BUILD_NUMBER}' or later, but '$currentBuildNumber' was provided.")
}
}

/**
* Describes a part of the product where the developed plugin can be installed when running in [splitMode].
*/
enum class SplitModeTarget {
BACKEND,
FRONTEND,
BACKEND_AND_FRONTEND;

override fun toString() = name.lowercase().replace('_', '-')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ internal fun <T : Task> Project.preconfigureTask(task: T) {
*/
if (this is SplitModeAware) {
splitMode.convention(extension.splitMode)
splitModeTarget.convention(extension.splitModeTarget)
}

/**
Expand Down Expand Up @@ -418,6 +419,8 @@ internal fun <T : Task> Project.preconfigureTask(task: T) {
sandboxPluginsDirectory,
sandboxSystemDirectory,
sandboxLogDirectory,
splitMode,
splitModeTarget,
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package org.jetbrains.intellij.platform.gradle.tasks
import org.jetbrains.intellij.platform.gradle.*
import org.jetbrains.intellij.platform.gradle.Constants.Sandbox
import org.jetbrains.intellij.platform.gradle.Constants.Tasks
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
import java.nio.file.Path
import kotlin.io.path.*
import kotlin.test.Ignore
import kotlin.test.Test
Expand Down Expand Up @@ -361,6 +363,61 @@ class PrepareSandboxTaskTest : IntelliJPluginTestBase() {
)
}

@Test
fun `prepare sandbox for splitMode with plugin installed on frontend`() {
buildSandboxForSplitMode(SplitModeAware.SplitModeTarget.FRONTEND)
checkFrontendProperties(sandbox.resolve("plugins"))
}

@Test
fun `prepare sandbox for splitMode with plugin installed on backend`() {
buildSandboxForSplitMode(SplitModeAware.SplitModeTarget.BACKEND)
checkFrontendProperties(sandbox.resolve("plugins").resolve("frontend"))
}

@Test
fun `prepare sandbox for splitMode with plugin installed on backend and frontend`() {
buildSandboxForSplitMode(SplitModeAware.SplitModeTarget.BACKEND_AND_FRONTEND)
checkFrontendProperties(sandbox.resolve("plugins"))
}

private fun checkFrontendProperties(pluginsPath: Path) {
assertFileContent(
sandbox.resolve("frontend.properties"),
"""
idea.config.path=${sandbox.resolve("config").resolve("frontend")}
idea.system.path=${sandbox.resolve("system").resolve("frontend")}
idea.log.path=${sandbox.resolve("log").resolve("frontend")}
idea.plugins.path=$pluginsPath
""".trimIndent()
)
}

private fun buildSandboxForSplitMode(splitModeTarget: SplitModeAware.SplitModeTarget) {
writeJavaFile()

pluginXml write //language=xml
"""
<idea-plugin />
""".trimIndent()

buildFile prepend // language=kotlin
"""
import org.jetbrains.intellij.platform.gradle.tasks.aware.SplitModeAware
""".trimIndent()

buildFile write //language=kotlin
"""
intellijPlatform {
sandboxContainer = file("${buildDirectory.resolve(Sandbox.CONTAINER)}")
splitMode = true
splitModeTarget = SplitModeAware.SplitModeTarget.${splitModeTarget.name}
}
""".trimIndent()

build(Tasks.PREPARE_SANDBOX)
}

@Test
fun `prepare sandbox with external jar-type plugin`() {
writeJavaFile()
Expand Down

0 comments on commit 0c6867a

Please sign in to comment.