convert AppServerAndCloudPluginLayouts to kotlin, simplify plugin layout configuration for ultimate

GitOrigin-RevId: c24202bb7616d7d006656a12eee36a63879f56f8
This commit is contained in:
Vladimir Krivosheev
2022-09-19 14:16:18 +00:00
committed by intellij-monorepo-bot
parent c241b222fd
commit ab2f75e335
12 changed files with 99 additions and 88 deletions
+2 -2
View File
@@ -6,14 +6,14 @@ import org.jetbrains.intellij.build.IdeaCommunityProperties
import org.jetbrains.intellij.build.IdeaProjectLoaderUtil
import org.jetbrains.intellij.build.kotlin.KotlinPluginBuilder
object KotlinPluginBuildTarget {
internal object KotlinPluginBuildTarget {
@JvmStatic
fun main(args: Array<String>) {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
runBlocking(Dispatchers.Default) {
KotlinPluginBuilder.build(communityHome = communityHome,
home = communityHome.communityRoot,
properties = IdeaCommunityProperties(communityHome))
properties = IdeaCommunityProperties(communityHome.communityRoot))
}
}
}
@@ -15,11 +15,11 @@ internal fun createCommunityBuildContext(
): BuildContext {
return BuildContextImpl.createContextBlocking(communityHome = communityHome,
projectHome = projectHome,
productProperties = IdeaCommunityProperties(communityHome),
productProperties = IdeaCommunityProperties(communityHome.communityRoot),
options = options)
}
open class IdeaCommunityProperties(private val communityHome: BuildDependenciesCommunityRoot) : BaseIdeaProperties() {
open class IdeaCommunityProperties(private val communityHomeDir: Path) : BaseIdeaProperties() {
companion object {
val MAVEN_ARTIFACTS_ADDITIONAL_MODULES = persistentListOf(
"intellij.tools.jps.build.standalone",
@@ -40,7 +40,7 @@ open class IdeaCommunityProperties(private val communityHome: BuildDependenciesC
init {
platformPrefix = "Idea"
applicationInfoModule = "intellij.idea.community.resources"
additionalIDEPropertiesFilePaths = persistentListOf(communityHome.communityRoot.resolve("build/conf/ideaCE.properties"))
additionalIDEPropertiesFilePaths = persistentListOf(communityHomeDir.resolve("build/conf/ideaCE.properties"))
toolsJarRequired = true
scrambleMainJar = false
useSplash = true
@@ -48,7 +48,10 @@ open class IdeaCommunityProperties(private val communityHome: BuildDependenciesC
productLayout.productImplementationModules = listOf("intellij.platform.main")
productLayout.withAdditionalPlatformJar(BaseLayout.APP_JAR, "intellij.idea.community.resources")
productLayout.bundledPluginModules.addAll(BUNDLED_PLUGIN_MODULES)
productLayout.bundledPluginModules = IDEA_BUNDLED_PLUGINS
.add("intellij.javaFX.community")
.toMutableList()
productLayout.prepareCustomPluginRepositoryForPublishedPlugins = false
productLayout.buildAllCompatiblePlugins = false
productLayout.pluginLayouts = CommunityRepositoryModules.COMMUNITY_REPOSITORY_PLUGINS.addAll(listOf(
@@ -94,9 +97,9 @@ open class IdeaCommunityProperties(private val communityHome: BuildDependenciesC
override fun createWindowsCustomizer(projectHome: String): WindowsDistributionCustomizer {
return object : WindowsDistributionCustomizer() {
init {
icoPath = "${communityHome.communityRoot}/platform/icons/src/idea_CE.ico"
icoPathForEAP = "${communityHome.communityRoot}/build/conf/ideaCE/win/images/idea_CE_EAP.ico"
installerImagesPath = "${communityHome.communityRoot}/build/conf/ideaCE/win/images"
icoPath = "${communityHomeDir}/platform/icons/src/idea_CE.ico"
icoPathForEAP = "${communityHomeDir}/build/conf/ideaCE/win/images/idea_CE_EAP.ico"
installerImagesPath = "${communityHomeDir}/build/conf/ideaCE/win/images"
fileAssociations = listOf("java", "groovy", "kt", "kts")
}
@@ -113,8 +116,8 @@ open class IdeaCommunityProperties(private val communityHome: BuildDependenciesC
override fun createLinuxCustomizer(projectHome: String): LinuxDistributionCustomizer {
return object : LinuxDistributionCustomizer() {
init {
iconPngPath = "${communityHome.communityRoot}/build/conf/ideaCE/linux/images/icon_CE_128.png"
iconPngPathForEAP = "${communityHome.communityRoot}/build/conf/ideaCE/linux/images/icon_CE_EAP_128.png"
iconPngPath = "${communityHomeDir}/build/conf/ideaCE/linux/images/icon_CE_128.png"
iconPngPathForEAP = "${communityHomeDir}/build/conf/ideaCE/linux/images/icon_CE_EAP_128.png"
snapName = "intellij-idea-community"
snapDescription =
"The most intelligent Java IDE. Every aspect of IntelliJ IDEA is specifically designed to maximize developer productivity. " +
@@ -135,13 +138,13 @@ open class IdeaCommunityProperties(private val communityHome: BuildDependenciesC
override fun createMacCustomizer(projectHome: String): MacDistributionCustomizer {
return object : MacDistributionCustomizer() {
init {
icnsPath = "${communityHome.communityRoot}/build/conf/ideaCE/mac/images/idea.icns"
icnsPath = "${communityHomeDir}/build/conf/ideaCE/mac/images/idea.icns"
urlSchemes = listOf("idea")
associateIpr = true
fileAssociations = FileAssociation.from("java", "groovy", "kt", "kts")
bundleIdentifier = "com.jetbrains.intellij.ce"
dmgImagePath = "${communityHome.communityRoot}/build/conf/ideaCE/mac/images/dmg_background.tiff"
icnsPathForEAP = "${communityHome.communityRoot}/build/conf/ideaCE/mac/images/communityEAP.icns"
dmgImagePath = "${communityHomeDir}/build/conf/ideaCE/mac/images/dmg_background.tiff"
icnsPathForEAP = "${communityHomeDir}/build/conf/ideaCE/mac/images/communityEAP.icns"
}
override fun getRootDirectoryName(appInfo: ApplicationInfoProperties, buildNumber: String): String {
@@ -20,7 +20,7 @@ class IdeaCommunityBuildTest {
runTestBuild(
homePath = homePath,
communityHomePath = communityHomePath,
productProperties = IdeaCommunityProperties(communityHomePath),
productProperties = IdeaCommunityProperties(communityHomePath.communityRoot),
) {
it.projectClassesOutputDirectory = System.getProperty(BuildOptions.PROJECT_CLASSES_OUTPUT_DIRECTORY_PROPERTY)
?: "$homePath/out/classes"
@@ -34,7 +34,7 @@ class IdeaCommunityBuildTest {
runBlocking(Dispatchers.Default) {
val context = createBuildContext(
homePath = homePath,
productProperties = IdeaCommunityProperties(communityHome),
productProperties = IdeaCommunityProperties(communityHome.communityRoot),
skipDependencySetup = true,
communityHomePath = communityHome,
)
@@ -4,6 +4,7 @@
package org.jetbrains.intellij.build
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentHashMapOf
import kotlinx.collections.immutable.persistentListOf
@@ -50,8 +51,12 @@ private val BASE_CLASS_VERSIONS = persistentHashMapOf(
"plugins/xslt-debugger/lib/rt/xslt-debugger-impl-rt.jar" to "1.8",
)
/**
* Default bundled plugins for all editions of IntelliJ IDEA.
* See also [JB_BUNDLED_PLUGINS] and [DEFAULT_BUNDLED_PLUGINS].
*/
@Suppress("SpellCheckingInspection")
val BUNDLED_PLUGIN_MODULES: PersistentList<String> = persistentListOf(
val IDEA_BUNDLED_PLUGINS: PersistentList<String> = JB_BUNDLED_PLUGINS + persistentListOf(
"intellij.java.plugin",
"intellij.java.ide.customization",
"intellij.copyright",
@@ -86,7 +91,6 @@ val BUNDLED_PLUGIN_MODULES: PersistentList<String> = persistentListOf(
"intellij.xslt.debugger",
"intellij.android.plugin",
"intellij.android.design-plugin",
"intellij.javaFX.community",
"intellij.java.i18n",
"intellij.ant",
"intellij.java.guiForms.designer",
@@ -132,6 +136,7 @@ abstract class BaseIdeaProperties : ProductProperties() {
init {
@Suppress("LeakingThis")
configureJetBrainsProduct(this)
productLayout.mainJarName = "idea.jar"
productLayout.withAdditionalPlatformJar(BaseLayout.APP_JAR, "intellij.java.ide.resources")
@@ -1,6 +1,7 @@
// Copyright 2000-2022 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 kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.intellij.build.impl.BundledMavenDownloader
import org.jetbrains.intellij.build.impl.LibraryPackMode
@@ -19,8 +20,8 @@ object CommunityRepositoryModules {
/**
* Specifies non-trivial layout for all plugins which sources are located in 'community' and 'contrib' repositories
*/
@JvmStatic
val COMMUNITY_REPOSITORY_PLUGINS = persistentListOf(
@Suppress("SpellCheckingInspection")
val COMMUNITY_REPOSITORY_PLUGINS: PersistentList<PluginLayout> = persistentListOf(
plugin("intellij.ant") { spec ->
spec.mainJarName = "antIntegration.jar"
spec.withModule("intellij.ant.jps", "ant-jps.jar")
@@ -271,8 +272,8 @@ object CommunityRepositoryModules {
},
)
@JvmStatic
val CONTRIB_REPOSITORY_PLUGINS = persistentListOf(
@Suppress("SpellCheckingInspection")
val CONTRIB_REPOSITORY_PLUGINS: PersistentList<PluginLayout> = persistentListOf(
plugin("intellij.errorProne") { spec ->
spec.withModule("intellij.errorProne.jps", "jps/errorProne-jps.jar")
},
@@ -304,6 +305,7 @@ object CommunityRepositoryModules {
// design-tools.jar
spec.withModule("intellij.android.compose-designer", "design-tools.jar")
spec.withModule("intellij.android.design-plugin", "design-tools.jar")
@Suppress("SpellCheckingInspection")
spec.withModule("intellij.android.designer.customview", "design-tools.jar")
spec.withModule("intellij.android.designer", "design-tools.jar")
spec.withModule("intellij.android.layoutlib", "design-tools.jar")
@@ -1,11 +1,21 @@
// Copyright 2000-2022 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.jetbrains.intellij.build.ProductModulesLayout.Companion.DEFAULT_BUNDLED_PLUGINS
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.jps.util.JpsPathUtil
import java.nio.file.Path
import java.util.function.BiPredicate
/**
* Default bundled plugins for all editions of IntelliJ-based IDE.
* See also [IDEA_BUNDLED_PLUGINS] and [DEFAULT_BUNDLED_PLUGINS].
*/
val JB_BUNDLED_PLUGINS: PersistentList<String> = DEFAULT_BUNDLED_PLUGINS.addAll(persistentListOf(
"intellij.laf.macos",
"intellij.laf.win10",
))
/**
* Describes distribution of an in-house IntelliJ-based IDE hosted in IntelliJ repository.
*/
@@ -25,10 +35,6 @@ abstract class JetBrainsProductProperties : ProductProperties() {
internal fun configureJetBrainsProduct(properties: ProductProperties) {
properties.scrambleMainJar = true
properties.productLayout.bundledPluginModules = DEFAULT_BUNDLED_PLUGINS
.add("intellij.laf.macos")
.add("intellij.laf.win10")
.toMutableList()
properties.includeIntoSourcesArchiveFilter = BiPredicate { module, context ->
module.contentRootsList.urls.all { url ->
Path.of(JpsPathUtil.urlToPath(url)).startsWith(context.paths.communityHomeDir)
@@ -11,15 +11,16 @@ import org.jetbrains.intellij.build.impl.PlatformLayout
import org.jetbrains.intellij.build.impl.PluginLayout
import java.util.function.BiConsumer
class ProductModulesLayout {
companion object {
@JvmField
val DEFAULT_BUNDLED_PLUGINS: PersistentList<String> = persistentListOf(
"intellij.platform.images",
"intellij.dev",
)
}
/**
* Default bundled plugins for all products.
* See also [JB_BUNDLED_PLUGINS].
*/
val DEFAULT_BUNDLED_PLUGINS: PersistentList<String> = persistentListOf(
"intellij.platform.images",
"intellij.dev",
)
class ProductModulesLayout {
/**
* Name of the main product JAR file. Outputs of {@link #productImplementationModules} will be packed into it.
*/
@@ -163,7 +164,7 @@ class ProductModulesLayout {
* Map name of JAR to names of the modules; these modules will be packed into these JARs and copied to the product's 'lib' directory.
*/
fun withAdditionalPlatformJar(jarName: String, vararg moduleNames: String) {
additionalPlatformJars.putValues(jarName, moduleNames.toList())
additionalPlatformJars.putValues(jarName, moduleNames.asList())
}
fun withoutAdditionalPlatformJar(jarName: String, moduleName: String) {
@@ -668,16 +668,15 @@ suspend fun buildDistributions(context: BuildContext) {
else {
context.executeStep("build toolbox lite-gen links", BuildOptions.TOOLBOX_LITE_GEN_STEP) {
val toolboxLiteGenVersion = System.getProperty("intellij.build.toolbox.litegen.version")
if (toolboxLiteGenVersion == null) {
context.messages.error("Toolbox Lite-Gen version is not specified!")
}
else {
ToolboxLiteGen.runToolboxLiteGen(context.paths.communityHomeDirRoot, context.messages,
toolboxLiteGenVersion, "/artifacts-dir=" + context.paths.artifacts,
"/product-code=" + context.applicationInfo.productCode,
"/isEAP=" + context.applicationInfo.isEAP.toString(),
"/output-dir=" + context.paths.buildOutputRoot + "/toolbox-lite-gen")
checkNotNull(toolboxLiteGenVersion) {
"Toolbox Lite-Gen version is not specified!"
}
ToolboxLiteGen.runToolboxLiteGen(context.paths.communityHomeDirRoot, context.messages,
toolboxLiteGenVersion, "/artifacts-dir=" + context.paths.artifacts,
"/product-code=" + context.applicationInfo.productCode,
"/isEAP=" + context.applicationInfo.isEAP.toString(),
"/output-dir=" + context.paths.buildOutputRoot + "/toolbox-lite-gen")
}
}
}
@@ -739,31 +738,29 @@ private fun checkProductProperties(context: BuildContextImpl) {
checkProductLayout(context)
val properties = context.productProperties
val messages = context.messages
checkPaths2(properties.brandingResourcePaths, "productProperties.brandingResourcePaths", messages)
checkPaths2(properties.additionalIDEPropertiesFilePaths, "productProperties.additionalIDEPropertiesFilePaths", messages)
checkPaths2(properties.additionalDirectoriesWithLicenses, "productProperties.additionalDirectoriesWithLicenses", messages)
checkPaths2(properties.brandingResourcePaths, "productProperties.brandingResourcePaths")
checkPaths2(properties.additionalIDEPropertiesFilePaths, "productProperties.additionalIDEPropertiesFilePaths")
checkPaths2(properties.additionalDirectoriesWithLicenses, "productProperties.additionalDirectoriesWithLicenses")
checkModules(properties.additionalModulesToCompile, "productProperties.additionalModulesToCompile", context)
checkModules(properties.modulesToCompileTests, "productProperties.modulesToCompileTests", context)
context.windowsDistributionCustomizer?.let { winCustomizer ->
checkPaths(listOfNotNull(winCustomizer.icoPath), "productProperties.windowsCustomizer.icoPath", messages)
checkPaths(listOfNotNull(winCustomizer.icoPathForEAP), "productProperties.windowsCustomizer.icoPathForEAP", messages)
checkPaths(listOfNotNull(winCustomizer.installerImagesPath), "productProperties.windowsCustomizer.installerImagesPath", messages)
checkPaths(listOfNotNull(winCustomizer.icoPath), "productProperties.windowsCustomizer.icoPath")
checkPaths(listOfNotNull(winCustomizer.icoPathForEAP), "productProperties.windowsCustomizer.icoPathForEAP")
checkPaths(listOfNotNull(winCustomizer.installerImagesPath), "productProperties.windowsCustomizer.installerImagesPath")
}
context.linuxDistributionCustomizer?.let { linuxDistributionCustomizer ->
checkPaths(listOfNotNull(linuxDistributionCustomizer.iconPngPath), "productProperties.linuxCustomizer.iconPngPath", messages)
checkPaths(listOfNotNull(linuxDistributionCustomizer.iconPngPathForEAP), "productProperties.linuxCustomizer.iconPngPathForEAP",
messages)
checkPaths(listOfNotNull(linuxDistributionCustomizer.iconPngPath), "productProperties.linuxCustomizer.iconPngPath")
checkPaths(listOfNotNull(linuxDistributionCustomizer.iconPngPathForEAP), "productProperties.linuxCustomizer.iconPngPathForEAP")
}
context.macDistributionCustomizer?.let { macCustomizer ->
checkMandatoryField(macCustomizer.bundleIdentifier, "productProperties.macCustomizer.bundleIdentifier", messages)
checkMandatoryPath(macCustomizer.icnsPath, "productProperties.macCustomizer.icnsPath", messages)
checkPaths(listOfNotNull(macCustomizer.icnsPathForEAP), "productProperties.macCustomizer.icnsPathForEAP", messages)
checkMandatoryPath(macCustomizer.dmgImagePath, "productProperties.macCustomizer.dmgImagePath", messages)
checkPaths(listOfNotNull(macCustomizer.dmgImagePathForEAP), "productProperties.macCustomizer.dmgImagePathForEAP", messages)
checkMandatoryField(macCustomizer.bundleIdentifier, "productProperties.macCustomizer.bundleIdentifier")
checkMandatoryPath(macCustomizer.icnsPath, "productProperties.macCustomizer.icnsPath")
checkPaths(listOfNotNull(macCustomizer.icnsPathForEAP), "productProperties.macCustomizer.icnsPathForEAP")
checkMandatoryPath(macCustomizer.dmgImagePath, "productProperties.macCustomizer.dmgImagePath")
checkPaths(listOfNotNull(macCustomizer.dmgImagePathForEAP), "productProperties.macCustomizer.dmgImagePathForEAP")
}
checkModules(properties.mavenArtifacts.additionalModules, "productProperties.mavenArtifacts.additionalModules", context)
@@ -922,44 +919,41 @@ private fun checkPluginModules(
val unspecifiedLayoutPluginModules = pluginModules.filter { mainModuleName ->
pluginLayoutList.none { it.mainModule == mainModuleName }
}
if (!unspecifiedLayoutPluginModules.isEmpty()) {
context.messages.error("No plugin layout specified in productProperties.productLayout.pluginLayouts for " +
"following plugin main modules (referenced from $fieldName): ${unspecifiedLayoutPluginModules.joinToString(separator = "\n") {
"simplePlugin(\"$it\"),"
}}")
check(unspecifiedLayoutPluginModules.isEmpty()) {
"No plugin layout specified in productProperties.productLayout.pluginLayouts for following plugin main modules " +
"(referenced from $fieldName):\n${unspecifiedLayoutPluginModules.joinToString(separator = "\n") { "simplePlugin(\"$it\")," }}"
}
val unknownBundledPluginModules = pluginModules.filter { context.findFileInModuleSources(it, "META-INF/plugin.xml") == null }
if (!unknownBundledPluginModules.isEmpty()) {
context.messages.error("The following modules from $fieldName don\'t contain META-INF/plugin.xml file and" +
" aren\'t specified as optional plugin modules in productProperties.productLayout.pluginLayouts: " +
"${unknownBundledPluginModules.joinToString()}}. ")
check(unknownBundledPluginModules.isEmpty()) {
"The following modules from $fieldName don\'t contain META-INF/plugin.xml file and aren\'t specified as optional plugin modules" +
"in productProperties.productLayout.pluginLayouts: ${unknownBundledPluginModules.joinToString()}."
}
}
private fun checkPaths(paths: Collection<String>, propertyName: String, messages: BuildMessages) {
private fun checkPaths(paths: Collection<String>, propertyName: String) {
val nonExistingFiles = paths.filter { Files.notExists(Path.of(it)) }
if (!nonExistingFiles.isEmpty()) {
messages.error("$propertyName contains non-existing files: ${nonExistingFiles.joinToString()}")
check(nonExistingFiles.isEmpty()) {
"$propertyName contains non-existing files: ${nonExistingFiles.joinToString()}"
}
}
private fun checkPaths2(paths: Collection<Path>, propertyName: String, messages: BuildMessages) {
private fun checkPaths2(paths: Collection<Path>, propertyName: String) {
val nonExistingFiles = paths.filter { Files.notExists(it) }
if (!nonExistingFiles.isEmpty()) {
messages.error("$propertyName contains non-existing files: ${nonExistingFiles.joinToString()}")
check(nonExistingFiles.isEmpty()) {
"$propertyName contains non-existing files: ${nonExistingFiles.joinToString()}"
}
}
private fun checkMandatoryField(value: String?, fieldName: String, messages: BuildMessages) {
if (value == null) {
messages.error("Mandatory property \'$fieldName\' is not specified")
private fun checkMandatoryField(value: String?, fieldName: String) {
checkNotNull(value) {
"Mandatory property \'$fieldName\' is not specified"
}
}
private fun checkMandatoryPath(path: String, fieldName: String, messages: BuildMessages) {
checkMandatoryField(path, fieldName, messages)
checkPaths(listOf(path), fieldName, messages)
private fun checkMandatoryPath(path: String, fieldName: String) {
checkMandatoryField(path, fieldName)
checkPaths(listOf(path), fieldName)
}
private fun logFreeDiskSpace(phase: String, context: CompilationContext) {
@@ -147,6 +147,10 @@ class PluginLayout private constructor(val mainModule: String, mainJarNameWithou
fun withResourceFromModule(moduleName: String, resourcePath: String, relativeOutputPath: String) {
layout.withResourceFromModule(moduleName, resourcePath, relativeOutputPath)
}
fun withPatch(patcher: BiConsumer<ModuleOutputPatcher, BuildContext>) {
layout.patchers = layout.patchers.add(patcher::accept)
}
}
// as a builder for PluginLayout, that ideally should be immutable
@@ -249,10 +253,6 @@ class PluginLayout private constructor(val mainModule: String, mainJarNameWithou
packToZip = true))
}
fun withPatch(patcher: BiConsumer<ModuleOutputPatcher, BuildContext>) {
layout.patchers = layout.patchers.add(patcher::accept)
}
/**
* By default, version of a plugin is equal to the build number of the IDE it's built with. This method allows to specify custom version evaluator.
*/
@@ -20,7 +20,7 @@ object KotlinPluginBuilder {
/**
* Module which contains META-INF/plugin.xml
*/
const val MAIN_KOTLIN_PLUGIN_MODULE = "kotlin.plugin"
const val MAIN_KOTLIN_PLUGIN_MODULE: String = "kotlin.plugin"
/**
* Version of Kotlin compiler which is used in the cooperative development setup in kt-master && kt-*-master branches
@@ -13,7 +13,7 @@ class DistributionJARsBuilderTest {
@Test
fun verifyStableClasspathOrder() {
val communityHome = IdeaProjectLoaderUtil.guessCommunityHome(javaClass)
val productProperties = IdeaCommunityProperties(communityHome)
val productProperties = IdeaCommunityProperties(communityHome.communityRoot)
runBlocking(Dispatchers.Default) {
val context = BuildContextImpl.createContext(communityHome, communityHome.communityRoot, productProperties)
val ideClasspath1 = DistributionJARsBuilder(DistributionBuilderState(emptySet(), context)).createIdeClassPath(context)
@@ -25,7 +25,7 @@ internal class PythonCommunityPluginBuilder(private val home: Path) {
val communityRoot = BuildDependenciesCommunityRoot(homeDir)
val buildContext = BuildContextImpl.createContextBlocking(communityRoot,
homeDir,
IdeaCommunityProperties(communityRoot),
IdeaCommunityProperties(communityRoot.communityRoot),
ProprietaryBuildTools.DUMMY,
options)
BuildTasks.create(buildContext).blockingBuildNonBundledPlugins(listOf(