mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 22:09:38 +07:00
[kotlin] Migrate Kotlin plugin build from custom made groovy scripts to common IDEA scripts
KTIJ-11539 Note that those artifacts are being preserved: ``` .idea/artifacts/AppCodeKotlinPlugin.xml .idea/artifacts/KotlinPluginCommunity.xml .idea/artifacts/MobilePlugin.xml .idea/artifacts/kotlin_ocswift.xml ``` because otherwise we would block MobileIde/AppCode development GitOrigin-RevId: 53acc627ed58962c104971ec6260704614c58218
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2e77376916
commit
cb44f4e8f0
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.intellij.build.impl.BaseLayout
|
||||
import org.jetbrains.intellij.build.impl.BuildHelper
|
||||
import org.jetbrains.intellij.build.impl.PlatformLayout
|
||||
import org.jetbrains.intellij.build.kotlin.KotlinPluginBuilder
|
||||
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@@ -88,6 +89,7 @@ abstract class BaseIdeaProperties extends JetBrainsProductProperties {
|
||||
"intellij.vcs.git.featuresTrainer",
|
||||
"intellij.lombok",
|
||||
"intellij.searchEverywhereMl",
|
||||
KotlinPluginBuilder.MAIN_KOTLIN_PLUGIN_MODULE,
|
||||
]
|
||||
|
||||
protected static final Map<String, String> CE_CLASS_VERSIONS = [
|
||||
@@ -160,7 +162,6 @@ abstract class BaseIdeaProperties extends JetBrainsProductProperties {
|
||||
|
||||
productLayout.compatiblePluginsToIgnore = [
|
||||
"intellij.java.plugin",
|
||||
"kotlin.plugin"
|
||||
]
|
||||
additionalModulesToCompile = ["intellij.tools.jps.build.standalone"]
|
||||
modulesToCompileTests = ["intellij.platform.jps.build"]
|
||||
@@ -168,11 +169,6 @@ abstract class BaseIdeaProperties extends JetBrainsProductProperties {
|
||||
isAntRequired = true
|
||||
}
|
||||
|
||||
@Override
|
||||
List<Path> getAdditionalPluginPaths(@NotNull BuildContext context) {
|
||||
return [context.kotlinBinaries.setUpPlugin(context)]
|
||||
}
|
||||
|
||||
@Override
|
||||
@CompileStatic(TypeCheckingMode.SKIP)
|
||||
void copyAdditionalFiles(BuildContext context, String targetDirectory) {
|
||||
|
||||
12
build/scripts/kotlin.gant
Normal file
12
build/scripts/kotlin.gant
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
import org.jetbrains.intellij.build.IdeaCommunityProperties
|
||||
import org.jetbrains.intellij.build.impl.BuildUtils
|
||||
import org.jetbrains.intellij.build.kotlin.KotlinPluginBuilder
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoader
|
||||
|
||||
target("artifact": "Build Kotlin IDE Artifacts") {
|
||||
String home = new File(IdeaProjectLoader.guessHome(this)).absolutePath
|
||||
BuildUtils.addUltimateBuildScriptsToClassPath(home, ant)
|
||||
new KotlinPluginBuilder(home, home, new IdeaCommunityProperties(home)).build()
|
||||
}
|
||||
@@ -244,14 +244,6 @@ class BuildOptions {
|
||||
static final String VALIDATE_MODULES_STRUCTURE = "intellij.build.module.structure"
|
||||
boolean validateModuleStructure = System.getProperty(VALIDATE_MODULES_STRUCTURE, "false").toBoolean()
|
||||
|
||||
/**
|
||||
* Path to prebuilt Kotlin plugin (not zipped).
|
||||
* Currently fully-fledged Kotlin plugin distribution is being on TeamCity only via kombo.gant script.
|
||||
* If this path is not specified then distribution without LLDB debugger is going to be built locally (for tests only).
|
||||
*/
|
||||
static final String PREBUILT_KOTLIN_PLUGIN_PATH = "intellij.build.kotlin.plugin.path"
|
||||
String prebuiltKotlinPluginPath = System.getProperty(PREBUILT_KOTLIN_PLUGIN_PATH)
|
||||
|
||||
static final String TARGET_OS = "intellij.build.target.os"
|
||||
|
||||
BuildOptions() {
|
||||
|
||||
@@ -4,6 +4,7 @@ package org.jetbrains.intellij.build
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.impl.PluginLayout
|
||||
import org.jetbrains.intellij.build.kotlin.KotlinPluginBuilder
|
||||
import org.jetbrains.intellij.build.python.PythonCommunityPluginModules
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
|
||||
@@ -37,6 +38,7 @@ final class CommunityRepositoryModules {
|
||||
mainJarName = "uiDesigner.jar"
|
||||
withModule("intellij.java.guiForms.jps", "jps/java-guiForms-jps.jar")
|
||||
},
|
||||
KotlinPluginBuilder.kotlinPlugin(),
|
||||
plugin("intellij.properties") {
|
||||
withModule("intellij.properties.psi", "properties.jar")
|
||||
withModule("intellij.properties.psi.impl", "properties.jar")
|
||||
@@ -219,10 +221,10 @@ final class CommunityRepositoryModules {
|
||||
plugin("intellij.android.plugin") {
|
||||
directoryName = "android"
|
||||
mainJarName = "android.jar"
|
||||
withCustomVersion({pluginXmlFile, ideVersion ->
|
||||
withCustomVersion({pluginXmlFile, ideVersion, _ ->
|
||||
String text = Files.readString(pluginXmlFile)
|
||||
def declaredVersion = text.substring(text.indexOf("<version>") + "<version>".length(), text.indexOf("</version>"))
|
||||
return "$declaredVersion.$ideVersion"
|
||||
return "$declaredVersion.$ideVersion".toString()
|
||||
})
|
||||
|
||||
withModule("intellij.android.common", "android-common.jar")
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.jetbrains.intellij.build
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.impl.JpsCompilationData
|
||||
import org.jetbrains.intellij.build.kotlin.KotlinBinaries
|
||||
import org.jetbrains.jps.model.JpsModel
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
@@ -21,7 +20,6 @@ interface CompilationContext {
|
||||
JpsModel getProjectModel()
|
||||
|
||||
JpsCompilationData getCompilationData()
|
||||
KotlinBinaries getKotlinBinaries()
|
||||
|
||||
/**
|
||||
* @return directory with compiled project classes, url attribute value of output tag from .idea/misc.xml by default
|
||||
|
||||
@@ -56,11 +56,6 @@ abstract class DelegatingCompilationContext implements CompilationContext {
|
||||
return delegate.getCompilationData()
|
||||
}
|
||||
|
||||
@Override
|
||||
KotlinBinaries getKotlinBinaries() {
|
||||
return delegate.getKotlinBinaries()
|
||||
}
|
||||
|
||||
@Override
|
||||
File getProjectOutputDirectory() {
|
||||
return delegate.getProjectOutputDirectory()
|
||||
|
||||
@@ -160,11 +160,6 @@ final class BuildContextImpl extends BuildContext {
|
||||
compilationContext.compilationData
|
||||
}
|
||||
|
||||
@Override
|
||||
KotlinBinaries getKotlinBinaries() {
|
||||
return compilationContext.kotlinBinaries
|
||||
}
|
||||
|
||||
@Override
|
||||
File getProjectOutputDirectory() {
|
||||
return compilationContext.projectOutputDirectory
|
||||
|
||||
@@ -224,14 +224,6 @@ final class BuildTasksImpl extends BuildTasks {
|
||||
}
|
||||
}
|
||||
|
||||
//todo remove this when KTIJ-11539 is fixed; currently if we add kotlin.idea module to the classpath as a transitive dependency of some other module,
|
||||
// it'll cause conflicts with Kotlin plugin loaded from JAR
|
||||
String pathToIgnore = new File(context.projectOutputDirectory, "production/kotlin.idea").absolutePath
|
||||
if (ideClasspath.remove(pathToIgnore)) {
|
||||
context.messages.debug(" remove $pathToIgnore from classpath to avoid conflicts")
|
||||
}
|
||||
|
||||
|
||||
List<String> jvmArgs = new ArrayList<>(BuildUtils.propertiesToJvmArgs(new HashMap<String, Object>([
|
||||
"idea.home.path" : context.paths.projectHome,
|
||||
"idea.system.path" : "${FileUtilRt.toSystemIndependentName(tempDir.toString())}/system",
|
||||
|
||||
@@ -45,7 +45,6 @@ final class CompilationContextImpl implements CompilationContext {
|
||||
final Map<String, String> oldToNewModuleName
|
||||
final Map<String, String> newToOldModuleName
|
||||
JpsCompilationData compilationData
|
||||
KotlinBinaries kotlinBinaries
|
||||
|
||||
@SuppressWarnings("GrUnresolvedAccess")
|
||||
@CompileDynamic
|
||||
@@ -69,12 +68,12 @@ final class CompilationContextImpl implements CompilationContext {
|
||||
def gradleJdk = toCanonicalPath(JdkUtils.computeJdkHome(messages, '1.8', null, "JDK_18_x64"))
|
||||
GradleRunner gradle = new GradleRunner(dependenciesProjectDir, projectHome, messages, gradleJdk)
|
||||
projectHome = toCanonicalPath(projectHome)
|
||||
def kotlinBinaries = new KotlinBinaries(projectHome, communityHome, options, messages)
|
||||
def kotlinBinaries = new KotlinBinaries(communityHome, options, messages)
|
||||
kotlinBinaries.setUpCompilerIfRequired(gradle, ant)
|
||||
def model = loadProject(projectHome, kotlinBinaries, messages)
|
||||
def jdkHome = defineJavaSdk(model, projectHome, options, messages)
|
||||
def oldToNewModuleName = loadModuleRenamingHistory(projectHome, messages) + loadModuleRenamingHistory(communityHome, messages)
|
||||
def context = new CompilationContextImpl(ant, gradle, model, communityHome, projectHome, jdkHome, kotlinBinaries, messages, oldToNewModuleName,
|
||||
def context = new CompilationContextImpl(ant, gradle, model, communityHome, projectHome, jdkHome, messages, oldToNewModuleName,
|
||||
buildOutputRootEvaluator, options)
|
||||
context.prepareForBuild()
|
||||
messages.debugLogPath = context.paths.logDir.resolve("debug.log")
|
||||
@@ -146,7 +145,7 @@ final class CompilationContextImpl implements CompilationContext {
|
||||
}
|
||||
|
||||
private CompilationContextImpl(AntBuilder ant, GradleRunner gradle, JpsModel model, String communityHome,
|
||||
String projectHome, String jdkHome, KotlinBinaries kotlinBinaries, BuildMessages messages,
|
||||
String projectHome, String jdkHome, BuildMessages messages,
|
||||
Map<String, String> oldToNewModuleName,
|
||||
BiFunction<JpsProject, BuildMessages, String> buildOutputRootEvaluator, BuildOptions options) {
|
||||
this.ant = ant
|
||||
@@ -161,13 +160,12 @@ final class CompilationContextImpl implements CompilationContext {
|
||||
String buildOutputRoot = options.outputRootPath ?: buildOutputRootEvaluator.apply(project, messages)
|
||||
Path logDir = options.logPath != null ? Path.of(options.logPath) : Path.of(buildOutputRoot, "log")
|
||||
this.paths = new BuildPathsImpl(communityHome, projectHome, buildOutputRoot, jdkHome, logDir)
|
||||
this.kotlinBinaries = kotlinBinaries
|
||||
}
|
||||
|
||||
CompilationContextImpl createCopy(AntBuilder ant, BuildMessages messages, BuildOptions options,
|
||||
BiFunction<JpsProject, BuildMessages, String> buildOutputRootEvaluator) {
|
||||
def copy = new CompilationContextImpl(ant, gradle, projectModel, paths.communityHome, paths.projectHome, paths.jdkHome,
|
||||
kotlinBinaries, messages, oldToNewModuleName, buildOutputRootEvaluator, options)
|
||||
messages, oldToNewModuleName, buildOutputRootEvaluator, options)
|
||||
copy.compilationData = compilationData
|
||||
return copy
|
||||
}
|
||||
|
||||
@@ -735,6 +735,13 @@ final class DistributionJARsBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<String, ResourcesGenerator> item : plugin.moduleOutputPatches) {
|
||||
File resources = item.second.generateResources(buildContext)
|
||||
if (resources != null) {
|
||||
layoutBuilder.patchModuleOutput(item.first, resources.toPath())
|
||||
}
|
||||
}
|
||||
|
||||
Path pluginDir = targetDirectory.resolve(getActualPluginDirectoryName(plugin, buildContext))
|
||||
processPluginLayout(plugin, layoutBuilder, pluginDir, generatedResources, parentMapping, true)
|
||||
if (!plugin.pathsToScramble.isEmpty()) {
|
||||
@@ -798,7 +805,7 @@ final class DistributionJARsBuilder {
|
||||
? buildContext.buildNumber + ".${new SimpleDateFormat('yyyyMMdd').format(new Date())}"
|
||||
: buildContext.buildNumber
|
||||
|
||||
def pluginVersion = plugin.versionEvaluator.apply(patchedPluginXmlFile, defaultPluginVersion)
|
||||
def pluginVersion = plugin.versionEvaluator.evaluate(patchedPluginXmlFile, defaultPluginVersion, buildContext)
|
||||
|
||||
Pair<String, String> sinceUntil = getCompatiblePlatformVersionRange(compatibleBuildRange, buildContext.buildNumber)
|
||||
|
||||
@@ -811,6 +818,7 @@ final class DistributionJARsBuilder {
|
||||
pluginsToPublish.contains(plugin),
|
||||
plugin.retainProductDescriptorForBundledPlugin,
|
||||
)
|
||||
plugin.pluginXmlPatcher.accept(patchedPluginXmlFile)
|
||||
}
|
||||
catch (Throwable t) {
|
||||
throw new RuntimeException("Could not patch $pluginXmlPath: ${t.message}", t)
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.intellij.build.ResourcesGenerator
|
||||
import java.nio.file.Path
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.BiPredicate
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
* Describes layout of a plugin in the product distribution
|
||||
@@ -19,7 +20,9 @@ import java.util.function.BiPredicate
|
||||
final class PluginLayout extends BaseLayout {
|
||||
final String mainModule
|
||||
String directoryName
|
||||
BiFunction<Path, String, String> versionEvaluator = { pluginXmlFile, ideVersion -> ideVersion } as BiFunction<Path, String, String>
|
||||
VersionEvaluator versionEvaluator = { pluginXmlFile, ideVersion, context -> ideVersion } as VersionEvaluator
|
||||
Consumer<Path> pluginXmlPatcher = { } as Consumer<Path>
|
||||
List<Pair<String, ResourcesGenerator>> moduleOutputPatches = []
|
||||
boolean directoryNameSetExplicitly
|
||||
PluginBundlingRestrictions bundlingRestrictions
|
||||
final List<String> pathsToScramble = new ArrayList<>()
|
||||
@@ -138,6 +141,23 @@ final class PluginLayout extends BaseLayout {
|
||||
return bundlingRestrictions
|
||||
}
|
||||
|
||||
/**
|
||||
* @param binPathRelativeToCommunity path to resource file or directory relative to the intellij-community repo root
|
||||
* @param outputPath target path relative to the plugin root directory
|
||||
*/
|
||||
def withBin(String binPathRelativeToCommunity, String outputPath, boolean skipIfDoesntExist = false) {
|
||||
withGeneratedResources(new ResourcesGenerator() {
|
||||
@Override
|
||||
File generateResources(BuildContext context) {
|
||||
def file = context.paths.communityHomeDir.resolve(binPathRelativeToCommunity).toFile()
|
||||
if (!skipIfDoesntExist && !file.exists()) {
|
||||
throw new IllegalStateException("'$file' doesn't exist")
|
||||
}
|
||||
return file.exists() ? file : null
|
||||
}
|
||||
}, outputPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resourcePath path to resource file or directory relative to the plugin's main module content root
|
||||
* @param relativeOutputPath target path relative to the plugin root directory
|
||||
@@ -170,17 +190,23 @@ final class PluginLayout extends BaseLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* In {@linkplain BiFunction}:
|
||||
* <ol>
|
||||
* <li> the first {@linkplain File} argument is the plugin.xml file.
|
||||
* <li> the second {@linkplain String} argument is the default version (build number of the IDE).
|
||||
* </ol>
|
||||
* Patches module output with content produced {@code generator}
|
||||
*/
|
||||
void withCustomVersion(BiFunction<Path, String, String> versionEvaluator) {
|
||||
void withModuleOutputPatches(String moduleName, ResourcesGenerator generator) {
|
||||
layout.moduleOutputPatches.add(Pair.create(moduleName, generator))
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void withCustomVersion(VersionEvaluator versionEvaluator) {
|
||||
layout.versionEvaluator = versionEvaluator
|
||||
}
|
||||
|
||||
void withPluginXmlPatcher(Consumer<Path> pluginXmlPatcher) {
|
||||
layout.pluginXmlPatcher = pluginXmlPatcher
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated localizable resources are always put to the module JAR, so there is no need to call this method anymore
|
||||
*/
|
||||
@@ -255,4 +281,8 @@ final class PluginLayout extends BaseLayout {
|
||||
layout.scrambleClasspathFilter = filter
|
||||
}
|
||||
}
|
||||
|
||||
interface VersionEvaluator {
|
||||
String evaluate(Path pluginXml, String ideBuildVersion, BuildContext context)
|
||||
}
|
||||
}
|
||||
@@ -659,7 +659,6 @@ class TestingTasksImpl extends TestingTasks {
|
||||
if (!dependenciesInstalled) {
|
||||
dependenciesInstalled = true
|
||||
context.gradle.run('Setting up testing dependencies', 'setupBundledMaven')
|
||||
context.kotlinBinaries.setUpPlugin(context, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +1,30 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.intellij.build.kotlin
|
||||
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.util.xmlb.XmlSerializer
|
||||
import groovy.transform.CompileStatic
|
||||
import org.apache.tools.ant.BuildException
|
||||
import org.jetbrains.intellij.build.BuildMessages
|
||||
import org.jetbrains.intellij.build.BuildOptions
|
||||
import org.jetbrains.intellij.build.CompilationContext
|
||||
import org.jetbrains.intellij.build.GradleRunner
|
||||
import org.jetbrains.intellij.build.impl.BuildUtils
|
||||
import org.jetbrains.intellij.build.impl.CompilationContextImpl
|
||||
import org.jetbrains.intellij.build.impl.CompilationTasksImpl
|
||||
import org.jetbrains.jps.model.serialization.JpsLoaderBase
|
||||
import org.jetbrains.jps.model.serialization.JpsMacroExpander
|
||||
import org.jetbrains.jps.model.serialization.PathMacroUtil
|
||||
import org.jetbrains.jps.model.serialization.artifact.ArtifactState
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
/**
|
||||
* Sets up both Kotlin compiler (downloaded from Marketplace) and Kotlin plugin (built from source) binaries
|
||||
* Sets up Kotlin compiler (downloaded from Marketplace) which is required for JPS to compile the repository
|
||||
*/
|
||||
@CompileStatic
|
||||
final class KotlinBinaries {
|
||||
static final String SET_UP_COMPILER_GRADLE_TASK = 'setupKotlinCompiler'
|
||||
private static final String PLUGIN_ARTIFACT_NAME = 'KotlinPlugin'
|
||||
private final String projectHome
|
||||
private final String communityHome
|
||||
private final BuildMessages messages
|
||||
private final BuildOptions options
|
||||
final String compilerHome
|
||||
|
||||
KotlinBinaries(String projectHome, String communityHome, BuildOptions options, BuildMessages messages) {
|
||||
KotlinBinaries(String communityHome, BuildOptions options, BuildMessages messages) {
|
||||
this.options = options
|
||||
this.messages = messages
|
||||
this.communityHome = communityHome
|
||||
this.projectHome = projectHome
|
||||
def compilerHome = "$communityHome/build/dependencies/build/kotlin-compiler/Kotlin"
|
||||
this.compilerHome = FileUtil.toSystemIndependentName(new File(compilerHome).canonicalPath)
|
||||
}
|
||||
@@ -59,12 +42,17 @@ final class KotlinBinaries {
|
||||
if (new File(kotlinPluginLibPath).exists() && new File(kotlincLibPath).exists()) {
|
||||
["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-reflect.jar", "kotlin-common.jar"].each {
|
||||
def completePath = "$kotlinPluginLibPath/$it"
|
||||
if (new File(completePath).exists()) {
|
||||
BuildUtils.addToJpsClassPath(completePath, ant)
|
||||
if (!new File(completePath).exists()) {
|
||||
throw new IllegalStateException("KotlinBinaries: '$completePath' doesn't exist")
|
||||
}
|
||||
BuildUtils.addToJpsClassPath(completePath, ant)
|
||||
}
|
||||
["kotlin-stdlib.jar"].each {
|
||||
BuildUtils.addToJpsClassPath("$kotlincLibPath/$it", ant)
|
||||
def completePath = "$kotlincLibPath/$it"
|
||||
if (!new File(completePath).exists()) {
|
||||
throw new IllegalStateException("KotlinBinaries: '$completePath' doesn't exist")
|
||||
}
|
||||
BuildUtils.addToJpsClassPath(completePath, ant)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -92,83 +80,4 @@ final class KotlinBinaries {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private volatile Path pluginArtifact
|
||||
|
||||
Path setUpPlugin(CompilationContext context, boolean isTestBuild = context.options.isTestBuild) {
|
||||
if (pluginArtifact == null) {
|
||||
synchronized (this) {
|
||||
if (pluginArtifact != null) return pluginArtifact
|
||||
if (context.options.prebuiltKotlinPluginPath != null) {
|
||||
pluginArtifact = Paths.get(context.options.prebuiltKotlinPluginPath)
|
||||
}
|
||||
else {
|
||||
pluginArtifact = buildPluginForTests(context)
|
||||
if (!isTestBuild) {
|
||||
def problem = "Prebuilt Kotlin plugin artifact is required to build an installer, " +
|
||||
"please specify it in $BuildOptions.PREBUILT_KOTLIN_PLUGIN_PATH"
|
||||
println("##teamcity[buildProblem description='$problem']")
|
||||
}
|
||||
}
|
||||
copyPluginArtifactToProjectOutput()
|
||||
}
|
||||
}
|
||||
return pluginArtifact
|
||||
}
|
||||
|
||||
private static Path buildPluginForTests(CompilationContext context) {
|
||||
context.messages.block("Building Kotlin plugin for tests") {
|
||||
buildPluginForTests(context, KotlinPluginKind.IJ, PLUGIN_ARTIFACT_NAME)
|
||||
?: buildPluginForTests(context, KotlinPluginKind.IJ_CE, "${PLUGIN_ARTIFACT_NAME}Community")
|
||||
}
|
||||
}
|
||||
|
||||
private static Path buildPluginForTests(CompilationContext context, KotlinPluginKind kind, String unzippedPath) {
|
||||
def pluginZip = kind.build(context)
|
||||
if (pluginZip == null) return null
|
||||
def pluginUnzipped = Paths.get(pluginZip.outputPath)
|
||||
.parent.resolve(unzippedPath)
|
||||
.toAbsolutePath().normalize()
|
||||
return pluginUnzipped
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy artifact to path expected at least by:
|
||||
* * .idea/libraries/KotlinPlugin.xml;
|
||||
* * startup performance tests;
|
||||
* * Code With Me tests;
|
||||
* * Fleet tests.
|
||||
*/
|
||||
private void copyPluginArtifactToProjectOutput() {
|
||||
def stream = Files.walk(pluginArtifact)
|
||||
try {
|
||||
stream.forEach {
|
||||
if (Files.isRegularFile(it)) {
|
||||
def destination = projectOutputPath().resolve(pluginArtifact.relativize(it))
|
||||
Files.createDirectories(destination.parent)
|
||||
Files.copy(it, destination, StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stream.close()
|
||||
}
|
||||
}
|
||||
|
||||
private Path projectOutputPath() {
|
||||
def projectPath = Paths.get(projectHome)
|
||||
def pluginArtifactXml = projectPath.resolve(".idea/artifacts/${PLUGIN_ARTIFACT_NAME}.xml")
|
||||
if (!Files.exists(pluginArtifactXml)) {
|
||||
pluginArtifactXml = projectPath.resolve(".idea/artifacts/${PLUGIN_ARTIFACT_NAME}Community.xml")
|
||||
}
|
||||
if (!Files.exists(pluginArtifactXml)) {
|
||||
throw new BuildException("$pluginArtifactXml doesn't exist")
|
||||
}
|
||||
def rootElement = JpsLoaderBase.tryLoadRootElement(pluginArtifactXml)
|
||||
def artifactElement = JDOMUtil.getChildren(rootElement, "artifact").first()
|
||||
def state = XmlSerializer.deserialize(artifactElement, ArtifactState.class)
|
||||
def macroExpander = new JpsMacroExpander([:])
|
||||
macroExpander.addFileHierarchyReplacements(PathMacroUtil.PROJECT_DIR_MACRO_NAME, projectPath.toFile())
|
||||
return Paths.get(macroExpander.substitute(state.outputPath, SystemInfo.isFileSystemCaseSensitive))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.intellij.build.kotlin
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.CompilationContext
|
||||
import org.jetbrains.intellij.build.CompilationTasks
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifactService
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
@CompileStatic
|
||||
final class KotlinPluginArtifact {
|
||||
private final CompilationContext context
|
||||
|
||||
KotlinPluginArtifact(CompilationContext context) {
|
||||
this.context = context
|
||||
}
|
||||
|
||||
JpsArtifact build(KotlinPluginKind kind,
|
||||
String sinceBuild, String untilBuild,
|
||||
String version = kind.version) {
|
||||
def tasks = CompilationTasks.create(context)
|
||||
patchPluginXml(version, sinceBuild, untilBuild, kind)
|
||||
tasks.buildProjectArtifacts([kind.jpsArtifactIdentifier])
|
||||
return JpsArtifactService.instance.getArtifacts(context.project).find {
|
||||
it.name == kind.jpsArtifactIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
private static String replace(String oldText, String regex, String newText) {
|
||||
String result = oldText.replaceFirst(regex, newText)
|
||||
if (result == oldText && !oldText.contains(newText)) {
|
||||
throw new IllegalStateException("Cannot find '$regex' in '$oldText'")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Path jpsOutPluginXml(KotlinPluginKind kind) {
|
||||
CompilationTasks.create(context).compileModules([kind.pluginXmlModuleName])
|
||||
def pluginXml = "production/${kind.pluginXmlModuleName}/META-INF/plugin.xml"
|
||||
Path jpsOutPluginXml = Paths.get("$context.projectOutputDirectory/$pluginXml")
|
||||
if (!Files.exists(jpsOutPluginXml)) {
|
||||
throw new IllegalStateException("jpsOutPluginXml=$jpsOutPluginXml doesn't exist!")
|
||||
}
|
||||
return jpsOutPluginXml
|
||||
}
|
||||
|
||||
Path srcPluginXml(KotlinPluginKind kind) {
|
||||
Path srcPluginXml = Paths.get("$context.paths.projectHome/${kind.pluginXmlContentRoot}/META-INF/plugin.xml")
|
||||
if (!Files.exists(srcPluginXml)) {
|
||||
def pluginXmlContentRoot = kind.pluginXmlContentRoot
|
||||
if (pluginXmlContentRoot.startsWith('community/')) {
|
||||
pluginXmlContentRoot = kind.pluginXmlContentRoot.replaceFirst('community', '')
|
||||
}
|
||||
srcPluginXml = context.paths.communityHomeDir.resolve("$pluginXmlContentRoot/META-INF/plugin.xml")
|
||||
}
|
||||
if (!Files.exists(srcPluginXml)) {
|
||||
throw new IllegalStateException("srcPluginXml=$srcPluginXml doesn't exist!")
|
||||
}
|
||||
return srcPluginXml
|
||||
}
|
||||
|
||||
private void patchPluginXml(String kotlinPluginVersion, String sinceBuild, String untilBuild, KotlinPluginKind kind) {
|
||||
def jpsOutPluginXml = jpsOutPluginXml(kind)
|
||||
|
||||
switch (kind) {
|
||||
case KotlinPluginKind.AC_KMM:
|
||||
def extendedBuild = sinceBuild.substring(0, sinceBuild.lastIndexOf('.'))
|
||||
if (!sinceBuild.matches("\\d+\\.\\d+")) {
|
||||
sinceBuild = extendedBuild
|
||||
}
|
||||
untilBuild = extendedBuild + ".*"
|
||||
break
|
||||
}
|
||||
|
||||
String versionText = "<version>${kotlinPluginVersion}</version>"
|
||||
|
||||
String replaceText
|
||||
switch (kind) {
|
||||
case KotlinPluginKind.ROBOSCOPE:
|
||||
replaceText = versionText
|
||||
break
|
||||
default:
|
||||
replaceText = """
|
||||
${versionText}
|
||||
<idea-version since-build="${sinceBuild}" until-build="${untilBuild}"/>
|
||||
""".stripIndent().trim()
|
||||
break
|
||||
}
|
||||
|
||||
def newText = replace(Files.readString(jpsOutPluginXml), "<version>.*?</version>", replaceText)
|
||||
|
||||
switch (kind) {
|
||||
case KotlinPluginKind.IJ:
|
||||
case KotlinPluginKind.IJ_CE:
|
||||
newText = replace(
|
||||
newText,
|
||||
"<!-- IJ/AS-INCOMPATIBLE-PLACEHOLDER -->",
|
||||
"<incompatible-with>com.intellij.modules.androidstudio</incompatible-with>"
|
||||
)
|
||||
break
|
||||
case KotlinPluginKind.AS:
|
||||
newText = replace(
|
||||
newText,
|
||||
"<!-- IJ/AS-DEPENDENCY-PLACEHOLDER -->",
|
||||
"<plugin id=\"com.intellij.modules.androidstudio\"/>"
|
||||
)
|
||||
break
|
||||
case KotlinPluginKind.MI:
|
||||
case KotlinPluginKind.AC_KMM:
|
||||
case KotlinPluginKind.ROBOSCOPE:
|
||||
break
|
||||
default:
|
||||
throw new IllegalStateException("Unknown kind = $kind")
|
||||
}
|
||||
Files.writeString(jpsOutPluginXml, newText)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.intellij.build.kotlin
|
||||
|
||||
import com.intellij.util.io.Decompressor
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.BuildContext
|
||||
import org.jetbrains.intellij.build.BuildTasks
|
||||
import org.jetbrains.intellij.build.ProductProperties
|
||||
import org.jetbrains.intellij.build.ResourcesGenerator
|
||||
import org.jetbrains.intellij.build.impl.PluginLayout
|
||||
import org.jetbrains.jps.model.library.JpsLibrary
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType
|
||||
import org.jetbrains.jps.model.library.JpsRepositoryLibraryType
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.function.Consumer
|
||||
|
||||
@CompileStatic
|
||||
class KotlinPluginBuilder {
|
||||
/**
|
||||
* Module which contains META-INF/plugin.xml
|
||||
*/
|
||||
public static String MAIN_KOTLIN_PLUGIN_MODULE = "kotlin.plugin"
|
||||
|
||||
private final String communityHome
|
||||
private final String home
|
||||
private final ProductProperties properties
|
||||
private static List<String> MODULES = [
|
||||
"kotlin.core",
|
||||
"kotlin.idea",
|
||||
"kotlin.fir.frontend-independent",
|
||||
"kotlin.line-indent-provider",
|
||||
"kotlin.jvm",
|
||||
"kotlin.refIndex",
|
||||
"kotlin.compiler-plugins.scripting-ide-services",
|
||||
"kotlin.compiler-plugins.parcelize.common",
|
||||
"kotlin.compiler-plugins.parcelize.gradle",
|
||||
"kotlin.compiler-plugins.allopen.common",
|
||||
"kotlin.compiler-plugins.allopen.gradle",
|
||||
"kotlin.compiler-plugins.allopen.maven",
|
||||
"kotlin.compiler-plugins.annotation-based-compiler-support.common",
|
||||
"kotlin.compiler-plugins.annotation-based-compiler-support.gradle",
|
||||
"kotlin.compiler-plugins.annotation-based-compiler-support.maven",
|
||||
"kotlin.compiler-plugins.kapt",
|
||||
"kotlin.compiler-plugins.kotlinx-serialization.common",
|
||||
"kotlin.compiler-plugins.kotlinx-serialization.gradle",
|
||||
"kotlin.compiler-plugins.kotlinx-serialization.maven",
|
||||
"kotlin.compiler-plugins.noarg.common",
|
||||
"kotlin.compiler-plugins.noarg.gradle",
|
||||
"kotlin.compiler-plugins.noarg.maven",
|
||||
"kotlin.compiler-plugins.sam-with-receiver.common",
|
||||
"kotlin.compiler-plugins.sam-with-receiver.gradle",
|
||||
"kotlin.compiler-plugins.sam-with-receiver.maven",
|
||||
"kotlin.compiler-plugins.scripting",
|
||||
"kotlin.maven",
|
||||
"kotlin.gradle.gradle-tooling",
|
||||
"kotlin.gradle.gradle-idea",
|
||||
"kotlin.gradle.gradle-java",
|
||||
"kotlin.gradle.gradle-native",
|
||||
"kotlin.native",
|
||||
"kotlin.grazie",
|
||||
"kotlin.junit",
|
||||
"kotlin.testng",
|
||||
"kotlin.formatter",
|
||||
"kotlin.repl",
|
||||
"kotlin.git",
|
||||
"kotlin.injection",
|
||||
"kotlin.scripting",
|
||||
"kotlin.coverage",
|
||||
"kotlin.ml-completion",
|
||||
"kotlin.groovy",
|
||||
"kotlin.copyright",
|
||||
"kotlin.spellchecker",
|
||||
"kotlin.jvm-decompiler",
|
||||
"kotlin.properties",
|
||||
"kotlin.j2k.services",
|
||||
"kotlin.j2k.idea",
|
||||
"kotlin.j2k.old",
|
||||
"kotlin.j2k.new",
|
||||
"kotlin.project-wizard.cli",
|
||||
"kotlin.project-wizard.core",
|
||||
"kotlin.project-wizard.idea",
|
||||
"kotlin.project-wizard.maven",
|
||||
"kotlin.project-wizard.gradle",
|
||||
"kotlin.jvm-debugger.util",
|
||||
"kotlin.jvm-debugger.core",
|
||||
"kotlin.jvm-debugger.evaluation",
|
||||
"kotlin.jvm-debugger.coroutines",
|
||||
"kotlin.jvm-debugger.sequence",
|
||||
"kotlin.jvm-debugger.eval4j",
|
||||
"kotlin.uast.uast-kotlin",
|
||||
"kotlin.uast.uast-kotlin-idea",
|
||||
"kotlin.i18n",
|
||||
"kotlin.project-model",
|
||||
]
|
||||
private static List<String> LIBRARIES = [
|
||||
"kotlinc.android-extensions-compiler-plugin",
|
||||
"kotlinc.allopen-compiler-plugin",
|
||||
"kotlinc.noarg-compiler-plugin",
|
||||
"kotlinc.sam-with-receiver-compiler-plugin",
|
||||
"kotlinc.kotlinx-serialization-compiler-plugin",
|
||||
"kotlinc.parcelize-compiler-plugin",
|
||||
"kotlinc.kotlin-script-util",
|
||||
"kotlin-script-runtime",
|
||||
"kotlinc.kotlin-scripting-compiler",
|
||||
"kotlinc.kotlin-gradle-statistics",
|
||||
]
|
||||
|
||||
KotlinPluginBuilder(String communityHome, String home, ProductProperties properties) {
|
||||
this.communityHome = communityHome
|
||||
this.home = home
|
||||
this.properties = properties
|
||||
}
|
||||
|
||||
static PluginLayout kotlinPlugin() {
|
||||
return PluginLayout.plugin(MAIN_KOTLIN_PLUGIN_MODULE) {
|
||||
directoryName = "Kotlin"
|
||||
mainJarName = "kotlin-plugin.jar"
|
||||
boolean isUltimate
|
||||
try {
|
||||
Class.forName("org.jetbrains.intellij.build.IdeaUltimateProperties")
|
||||
isUltimate = true
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
isUltimate = false
|
||||
}
|
||||
|
||||
KotlinPluginKind kind = KotlinPluginKind.valueOf(Objects.requireNonNullElse(System.getProperty("kotlin.plugin.kind"), "IJ"))
|
||||
|
||||
for (String moduleName : MODULES) {
|
||||
withModule(moduleName)
|
||||
}
|
||||
for (String library : LIBRARIES) {
|
||||
withProjectLibraryUnpackedIntoJar(library, mainJarName)
|
||||
}
|
||||
|
||||
if (isUltimate && kind == KotlinPluginKind.IJ) {
|
||||
withModule("kotlin-ultimate.common-native")
|
||||
withModule("kotlin-ultimate.common-noncidr-native")
|
||||
withModule("kotlin-ultimate.javascript.debugger")
|
||||
withModule("kotlin-ultimate.javascript.nodeJs")
|
||||
withModule("kotlin-ultimate.ultimate-plugin")
|
||||
withModule("kotlin-ultimate.ultimate-native")
|
||||
}
|
||||
|
||||
String jpsPluginJar = "jps/kotlin-jps-plugin.jar"
|
||||
withModule("kotlin.jps-plugin", jpsPluginJar)
|
||||
withProjectLibraryUnpackedIntoJar("kotlinc.compiler-components-for-jps", jpsPluginJar)
|
||||
|
||||
String kotlincKotlinCompiler = "kotlinc.kotlin-compiler"
|
||||
withProjectLibrary(kotlincKotlinCompiler, "", true)
|
||||
|
||||
withModuleOutputPatches(MAIN_KOTLIN_PLUGIN_MODULE, new ResourcesGenerator() {
|
||||
@Override
|
||||
File generateResources(BuildContext context) {
|
||||
JpsLibrary library = context.project.libraryCollection.findLibrary(kotlincKotlinCompiler)
|
||||
List<File> jars = library.getFiles(JpsOrderRootType.COMPILED)
|
||||
if (jars.size() != 1) {
|
||||
throw new IllegalStateException("$kotlincKotlinCompiler is expected to have only one jar")
|
||||
}
|
||||
def extractedDir = context.paths.tempDir.resolve("$kotlincKotlinCompiler-extracted")
|
||||
new Decompressor.Zip(jars[0]).extract(extractedDir)
|
||||
def compilerExtensions = context.paths.tempDir.resolve("$kotlincKotlinCompiler-compiler-extensions")
|
||||
def prefix = "META-INF/extensions"
|
||||
compilerExtensions.resolve(prefix).toFile().mkdirs()
|
||||
for (File file : extractedDir.resolve(prefix).toFile().listFiles()) {
|
||||
Files.copy(file.toPath(), compilerExtensions.resolve(prefix).resolve(file.name))
|
||||
}
|
||||
return compilerExtensions.toFile()
|
||||
}
|
||||
})
|
||||
|
||||
withModule("kotlin.jps-common", "kotlin-jps-common.jar")
|
||||
withModule("kotlin.common", "kotlin-common.jar")
|
||||
|
||||
withProjectLibrary("kotlin-reflect", "", true)
|
||||
withProjectLibrary("kotlin-stdlib-jdk8", "", true)
|
||||
withProjectLibrary("javaslang")
|
||||
withProjectLibrary("kotlinx-collections-immutable-jvm")
|
||||
withProjectLibrary("javax-inject")
|
||||
withProjectLibrary("kotlinx-coroutines-jdk8")
|
||||
withProjectLibrary("completion-ranking-kotlin")
|
||||
|
||||
withGeneratedResources(new ResourcesGenerator() {
|
||||
@Override
|
||||
File generateResources(BuildContext context) {
|
||||
def distLibName = "kotlinc.kotlin-dist"
|
||||
JpsLibrary library = context.project.libraryCollection.findLibrary(distLibName)
|
||||
List<File> jars = library.getFiles(JpsOrderRootType.COMPILED)
|
||||
if (jars.size() != 1) {
|
||||
throw new IllegalStateException("$distLibName is expected to have only one jar")
|
||||
}
|
||||
def extractedDist = context.paths.tempDir.resolve("kotlinc-dist")
|
||||
new Decompressor.Zip(jars[0]).extract(extractedDist)
|
||||
return extractedDist.toFile()
|
||||
}
|
||||
}, "kotlinc")
|
||||
|
||||
withCustomVersion(new PluginLayout.VersionEvaluator() {
|
||||
@Override
|
||||
String evaluate(Path pluginXml, String ideBuildVersion, BuildContext context) {
|
||||
def index = ideBuildVersion.indexOf(".")
|
||||
assert index > 0
|
||||
def major = ideBuildVersion.substring(0, index)
|
||||
def minor = ideBuildVersion.substring(index + 1)
|
||||
def kotlinVersion = context.project.libraryCollection.libraries
|
||||
.find { it.name.startsWith("kotlinc.") && it.type instanceof JpsRepositoryLibraryType }
|
||||
?.asTyped(JpsRepositoryLibraryType.INSTANCE)
|
||||
?.properties?.data?.version
|
||||
assert kotlinVersion != null
|
||||
return "${major}-${kotlinVersion}-${kind}${minor}"
|
||||
}
|
||||
})
|
||||
|
||||
withPluginXmlPatcher(new Consumer<Path>() {
|
||||
@Override
|
||||
void accept(Path path) {
|
||||
String sinceBuild = System.getProperty("kotlin.plugin.since")
|
||||
String untilBuild = System.getProperty("kotlin.plugin.until")
|
||||
|
||||
String text = Files.readString(path)
|
||||
|
||||
if (sinceBuild != null && untilBuild != null) {
|
||||
// In kt-branches we have own since and until versions
|
||||
text = replace(text, "<idea-version.*?\\/>", "<idea-version since-build=\"${sinceBuild}\" until-build=\"${untilBuild}\"/>")
|
||||
}
|
||||
|
||||
switch (kind) {
|
||||
case KotlinPluginKind.IJ:
|
||||
case KotlinPluginKind.MI:
|
||||
text = replace(
|
||||
text,
|
||||
"<!-- IJ/AS-INCOMPATIBLE-PLACEHOLDER -->",
|
||||
"<incompatible-with>com.intellij.modules.androidstudio</incompatible-with>"
|
||||
)
|
||||
break
|
||||
case KotlinPluginKind.AS:
|
||||
text = replace(
|
||||
text,
|
||||
"<!-- IJ/AS-DEPENDENCY-PLACEHOLDER -->",
|
||||
"<plugin id=\"com.intellij.modules.androidstudio\"/>"
|
||||
)
|
||||
break
|
||||
case KotlinPluginKind.AC_KMM:
|
||||
break
|
||||
default:
|
||||
throw new IllegalStateException("Unknown kind = $kind")
|
||||
}
|
||||
|
||||
Files.writeString(path, text)
|
||||
}
|
||||
})
|
||||
|
||||
if (kind == KotlinPluginKind.IJ && isUltimate) {
|
||||
// TODO KTIJ-11539 change to `System.getenv("TEAMCITY_VERSION") == null` later but make sure
|
||||
// that `IdeaUltimateBuildTest.testBuild` passes on TeamCity
|
||||
boolean skipIfDoesntExist = true
|
||||
|
||||
// Use 'DownloadAppCodeDependencies' run configuration to download LLDBFrontend
|
||||
withBin("../CIDR/cidr-debugger/bin/lldb/linux/bin/LLDBFrontend", "bin/linux", skipIfDoesntExist)
|
||||
withBin("../CIDR/cidr-debugger/bin/lldb/mac/LLDBFrontend", "bin/macos", skipIfDoesntExist)
|
||||
withBin("../CIDR/cidr-debugger/bin/lldb/win/x64/bin/LLDBFrontend", "bin/windows", skipIfDoesntExist)
|
||||
|
||||
withBin("../mobile-ide/common-native/scripts", "scripts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String replace(String oldText, String regex, String newText) {
|
||||
String result = oldText.replaceFirst(regex, newText)
|
||||
if (result == oldText) {
|
||||
throw new IllegalStateException("Cannot find '$regex' in '$oldText'")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
def build() {
|
||||
BuildContext buildContext = BuildContext.createContext(communityHome, home, properties)
|
||||
BuildTasks.create(buildContext).buildNonBundledPlugins([MAIN_KOTLIN_PLUGIN_MODULE])
|
||||
}
|
||||
|
||||
enum KotlinPluginKind {
|
||||
IJ, AS, MI,
|
||||
AC_KMM{ // AppCode KMM plugin
|
||||
@Override
|
||||
String toString() {
|
||||
return "AC"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.intellij.build.kotlin
|
||||
|
||||
import com.intellij.openapi.util.Couple
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.intellij.build.CompilationContext
|
||||
import org.jetbrains.intellij.build.impl.BuildContextImpl
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact
|
||||
import org.jetbrains.jps.model.library.JpsRepositoryLibraryType
|
||||
|
||||
@CompileStatic
|
||||
enum KotlinPluginKind {
|
||||
IJ("KotlinPlugin", "kotlin.plugin.version"),
|
||||
AS("KotlinPluginCommunity", "kotlin.plugin.version.as"),
|
||||
IJ_CE("KotlinPluginCommunity", "kotlin.plugin.version"),
|
||||
MI("MobilePlugin",
|
||||
"kotlin.plugin.version",
|
||||
"intellij.mobile.ide",
|
||||
"mobile-ide/resources",
|
||||
[
|
||||
Couple.of("artifacts/kotlin-ocswift", "kotlin-ocswift"),
|
||||
Couple.of("artifacts/MobilePlugin", "Mobile")
|
||||
]),
|
||||
AC_KMM(
|
||||
"AppCodeKMMPlugin",
|
||||
"kotlin.plugin.version",
|
||||
"kotlin-ultimate.appcode-kmm",
|
||||
"CIDR-appcode/appcode-kmm/resources"
|
||||
),
|
||||
ROBOSCOPE(
|
||||
"RoboscopePlugin.zip", "kotlin.plugin.version",
|
||||
"util.android-studio.android-studio-roboscope-plugin",
|
||||
"plugins/kotlin/tools/android-studio/android-studio-roboscope-plugin/resources",
|
||||
[
|
||||
Couple.of("RoboscopePlugin_zip/RoboscopePlugin.zip", "roboscope-plugin.zip")
|
||||
]),
|
||||
|
||||
final String jpsArtifactIdentifier
|
||||
final String pluginXmlModuleName
|
||||
final String pluginXmlContentRoot
|
||||
final List<Couple<String>> artifactCopyRules
|
||||
private final String versionPropertyName
|
||||
final String version
|
||||
|
||||
private KotlinPluginKind(String jpsArtifactIdentifier,
|
||||
String pluginXmlModuleName,
|
||||
String pluginXmlContentRoot,
|
||||
List<Couple<String>> artifactCopyRules,
|
||||
String versionPropertyName) {
|
||||
this.jpsArtifactIdentifier = jpsArtifactIdentifier
|
||||
this.pluginXmlModuleName = pluginXmlModuleName
|
||||
this.pluginXmlContentRoot = pluginXmlContentRoot
|
||||
this.versionPropertyName = versionPropertyName
|
||||
this.version = getVersionFromProperty(versionPropertyName)
|
||||
this.artifactCopyRules = artifactCopyRules
|
||||
}
|
||||
|
||||
KotlinPluginKind(String name, String versionPropertyName) {
|
||||
this(name + ".zip", "kotlin.plugin", "community/plugins/kotlin/plugin/resources",
|
||||
[Couple.of("${name}_zip/${name}.zip" as String, "kotlin-plugin-${getVersionFromProperty(versionPropertyName)}.zip" as String)],
|
||||
versionPropertyName
|
||||
)
|
||||
}
|
||||
|
||||
KotlinPluginKind(String name, String versionPropertyName, String pluginXmlModuleName, String pluginXmlContentRoot, List<Couple<String>> artifactCopyRules) {
|
||||
this(name, pluginXmlModuleName, pluginXmlContentRoot, artifactCopyRules, versionPropertyName)
|
||||
}
|
||||
|
||||
KotlinPluginKind(String name, String versionPropertyName, String pluginXmlModuleName, String pluginXmlContentRoot) {
|
||||
this(name, pluginXmlModuleName, pluginXmlContentRoot, [Couple.of(name, name)], versionPropertyName)
|
||||
}
|
||||
|
||||
JpsArtifact build(CompilationContext context) {
|
||||
def buildNumber = buildNumber(context)
|
||||
def version = System.getProperty(versionPropertyName, version(context, buildNumber))
|
||||
def sinceBuild = System.getProperty("build.since", buildNumber)
|
||||
def untilBuild = System.getProperty("build.until", buildNumber)
|
||||
return new KotlinPluginArtifact(context).build(this, sinceBuild, untilBuild, version)
|
||||
}
|
||||
|
||||
private static String buildNumber(CompilationContext context) {
|
||||
def buildNumber = context.options.buildNumber
|
||||
if (buildNumber == null || !buildNumber.contains('.')) {
|
||||
buildNumber = BuildContextImpl.readSnapshotBuildNumber(context.paths.communityHomeDir)
|
||||
}
|
||||
return buildNumber
|
||||
}
|
||||
|
||||
private static String version(CompilationContext context, String rawBuildNumber) {
|
||||
def index = rawBuildNumber.indexOf('.')
|
||||
assert index > 0
|
||||
def intellijMajorVersion = rawBuildNumber.substring(0, index)
|
||||
def buildNumber = rawBuildNumber.substring(++index)
|
||||
def kotlinVersion = context.project.libraryCollection.libraries
|
||||
.find { it.name.startsWith("kotlinc.") && it.type instanceof JpsRepositoryLibraryType }
|
||||
?.asTyped(JpsRepositoryLibraryType.INSTANCE)
|
||||
?.properties?.data?.version ?: "UNKNOWN"
|
||||
return "$intellijMajorVersion-$kotlinVersion-IJ$buildNumber"
|
||||
}
|
||||
|
||||
private static String getVersionFromProperty(String versionPropertyName) {
|
||||
return System.getProperty(versionPropertyName) ?: "TC must specify '$versionPropertyName' property"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user