From e4ce48d9efd5f4e8d2eba44a62983b21e56ebd32 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 4 Sep 2020 05:01:11 +0900 Subject: [PATCH] Pill: Extract artifact-related components to their own package --- .../src/JpsCompatiblePluginTasks.kt | 4 +- .../src/artifact/ArtifactDependencyMapper.kt | 12 ++ .../src/artifact/ArtifactElement.kt | 72 ++++++++ .../src/artifact/ArtifactGenerator.kt | 94 ++++++++++ .../pill-importer/src/artifact/PArtifact.kt | 22 +++ .../pill-importer/src/kotlinPluginArtifact.kt | 173 ------------------ 6 files changed, 203 insertions(+), 174 deletions(-) create mode 100644 plugins/pill/pill-importer/src/artifact/ArtifactDependencyMapper.kt create mode 100644 plugins/pill/pill-importer/src/artifact/ArtifactElement.kt create mode 100644 plugins/pill/pill-importer/src/artifact/ArtifactGenerator.kt create mode 100644 plugins/pill/pill-importer/src/artifact/PArtifact.kt delete mode 100644 plugins/pill/pill-importer/src/kotlinPluginArtifact.kt diff --git a/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt b/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt index b553fb0fd76..4c17962eca8 100644 --- a/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt +++ b/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt @@ -10,6 +10,8 @@ import org.gradle.api.plugins.BasePluginConvention import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.SourceSet import org.gradle.kotlin.dsl.extra +import org.jetbrains.kotlin.pill.artifact.ArtifactDependencyMapper +import org.jetbrains.kotlin.pill.artifact.ArtifactGenerator import shadow.org.jdom2.input.SAXBuilder import shadow.org.jdom2.* import shadow.org.jdom2.output.Format @@ -122,7 +124,7 @@ class JpsCompatiblePluginTasks(private val rootProject: Project, private val pla } } - generateKotlinPluginArtifactFile(rootProject, artifactDependencyMapper).write() + ArtifactGenerator(artifactDependencyMapper).generateKotlinPluginArtifact(rootProject).write() } copyRunConfigurations() diff --git a/plugins/pill/pill-importer/src/artifact/ArtifactDependencyMapper.kt b/plugins/pill/pill-importer/src/artifact/ArtifactDependencyMapper.kt new file mode 100644 index 00000000000..c71e72b5679 --- /dev/null +++ b/plugins/pill/pill-importer/src/artifact/ArtifactDependencyMapper.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.pill.artifact + +import org.jetbrains.kotlin.pill.PDependency + +interface ArtifactDependencyMapper { + fun map(dependency: PDependency): List +} \ No newline at end of file diff --git a/plugins/pill/pill-importer/src/artifact/ArtifactElement.kt b/plugins/pill/pill-importer/src/artifact/ArtifactElement.kt new file mode 100644 index 00000000000..c6e73ee10e3 --- /dev/null +++ b/plugins/pill/pill-importer/src/artifact/ArtifactElement.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.pill.artifact + +import org.jetbrains.kotlin.pill.PathContext +import org.jetbrains.kotlin.pill.XmlNode +import org.jetbrains.kotlin.pill.xml +import java.io.File + +sealed class ArtifactElement { + private val myChildren = mutableListOf() + private val children get() = myChildren + + fun add(child: ArtifactElement) { + myChildren += child + } + + fun add(children: List) { + myChildren += children + } + + abstract fun render(context: PathContext): XmlNode + + fun renderRecursively(context: PathContext): XmlNode { + return render(context).apply { + children.forEach { add(it.renderRecursively(context)) } + } + } + + class Root : ArtifactElement() { + override fun render(context: PathContext) = xml("root", "id" to "root") + } + + data class Directory(val name: String) : ArtifactElement() { + override fun render(context: PathContext) = xml("element", "id" to "directory", "name" to name) + } + + data class Archive(val name: String) : ArtifactElement() { + override fun render(context: PathContext) = xml("element", "id" to "archive", "name" to name) + } + + data class ModuleOutput(val moduleName: String) : ArtifactElement() { + override fun render(context: PathContext) = xml("element", "id" to "module-output", "name" to moduleName) + } + + data class FileCopy(val source: File, val outputFileName: String? = null) : ArtifactElement() { + override fun render(context: PathContext): XmlNode { + val args = mutableListOf("id" to "file-copy", "path" to context(source)) + if (outputFileName != null) { + args += "output-file-name" to outputFileName + } + + return xml("element", *args.toTypedArray()) + } + } + + data class DirectoryCopy(val source: File) : ArtifactElement() { + override fun render(context: PathContext) = xml("element", "id" to "dir-copy", "path" to context(source)) + } + + data class ProjectLibrary(val name: String) : ArtifactElement() { + override fun render(context: PathContext) = xml("element", "id" to "library", "level" to "project", "name" to name) + } + + data class ExtractedDirectory(val archive: File, val pathInJar: String = "/") : ArtifactElement() { + override fun render(context: PathContext) = + xml("element", "id" to "extracted-dir", "path" to context(archive), "path-in-jar" to pathInJar) + } +} \ No newline at end of file diff --git a/plugins/pill/pill-importer/src/artifact/ArtifactGenerator.kt b/plugins/pill/pill-importer/src/artifact/ArtifactGenerator.kt new file mode 100644 index 00000000000..a17b0530b63 --- /dev/null +++ b/plugins/pill/pill-importer/src/artifact/ArtifactGenerator.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.pill.artifact + +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.kotlin.dsl.extra +import org.jetbrains.kotlin.pill.* +import java.io.File + +class ArtifactGenerator(private val dependencyMapper: ArtifactDependencyMapper) { + fun generateKotlinPluginArtifact(rootProject: Project): PFile { + val root = ArtifactElement.Root() + + fun Project.getProject(name: String) = findProject(name) ?: error("Cannot find project $name") + + val prepareIdeaPluginProject = rootProject.getProject(":prepare:idea-plugin") + + root.add(ArtifactElement.Directory("kotlinc").apply { + val kotlincDirectory = rootProject.extra["distKotlinHomeDir"].toString() + add(ArtifactElement.DirectoryCopy(File(kotlincDirectory))) + }) + + root.add(ArtifactElement.Directory("lib").apply { + val librariesConfiguration = prepareIdeaPluginProject.configurations.getByName("libraries") + add(getArtifactElements(librariesConfiguration, false)) + + add(ArtifactElement.Directory("jps").apply { + val prepareJpsPluginProject = rootProject.getProject(":kotlin-jps-plugin") + add(ArtifactElement.Archive(prepareJpsPluginProject.name + ".jar").apply { + val jpsPluginConfiguration = prepareJpsPluginProject.configurations.getByName(EMBEDDED_CONFIGURATION_NAME) + add(getArtifactElements(jpsPluginConfiguration, true)) + }) + }) + + add(ArtifactElement.Archive("kotlin-plugin.jar").apply { + add(ArtifactElement.FileCopy(File(rootProject.projectDir, "resources/kotlinManifest.properties"))) + + val embeddedConfiguration = prepareIdeaPluginProject.configurations.getByName(EMBEDDED_CONFIGURATION_NAME) + add(getArtifactElements(embeddedConfiguration, true)) + }) + }) + + val artifact = PArtifact("KotlinPlugin", File(rootProject.projectDir, "out/artifacts/Kotlin"), root) + return PFile( + File(rootProject.projectDir, ".idea/artifacts/${artifact.artifactName}.xml"), + artifact.render(ProjectContext(rootProject)) + ) + } + + private fun getArtifactElements(configuration: Configuration, extractDependencies: Boolean): List { + val artifacts = mutableListOf() + + fun process(dependency: PDependency) { + when (dependency) { + is PDependency.Module -> { + val moduleOutput = ArtifactElement.ModuleOutput(dependency.name) + + if (extractDependencies) { + artifacts += moduleOutput + } else { + artifacts += ArtifactElement.Archive(dependency.name + ".jar").apply { + add(moduleOutput) + } + } + } + is PDependency.Library -> artifacts += ArtifactElement.ProjectLibrary(dependency.name) + is PDependency.ModuleLibrary -> { + val files = dependency.library.classes + if (extractDependencies) { + files.mapTo(artifacts) { ArtifactElement.ExtractedDirectory(it) } + } else { + files.mapTo(artifacts) { ArtifactElement.FileCopy(it) } + } + } + } + } + + parseDependencies(configuration).forEach(::process) + return artifacts + } + + private fun parseDependencies(configuration: Configuration): List { + val dependencies = mutableListOf() + for (file in configuration.resolve()) { + val library = PLibrary(file.name, listOf(file)) + dependencies += dependencyMapper.map(PDependency.ModuleLibrary(library)) + } + return dependencies + } +} \ No newline at end of file diff --git a/plugins/pill/pill-importer/src/artifact/PArtifact.kt b/plugins/pill/pill-importer/src/artifact/PArtifact.kt new file mode 100644 index 00000000000..69e332a9a16 --- /dev/null +++ b/plugins/pill/pill-importer/src/artifact/PArtifact.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.pill.artifact + +import org.jetbrains.kotlin.pill.* +import org.jetbrains.kotlin.pill.artifact.ArtifactElement.* +import java.io.File + +class PArtifact(val artifactName: String, private val outputDir: File, private val contents: Root) { + fun render(context: PathContext) = xml("component", "name" to "ArtifactManager") { + xml("artifact", "name" to artifactName) { + xml("output-path") { + raw(context(outputDir)) + } + + add(contents.renderRecursively(context)) + } + } +} \ No newline at end of file diff --git a/plugins/pill/pill-importer/src/kotlinPluginArtifact.kt b/plugins/pill/pill-importer/src/kotlinPluginArtifact.kt deleted file mode 100644 index 0d7c356eb2b..00000000000 --- a/plugins/pill/pill-importer/src/kotlinPluginArtifact.kt +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.pill - -import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration -import org.gradle.kotlin.dsl.extra -import org.jetbrains.kotlin.pill.ArtifactElement.* -import java.io.File - -class PArtifact(val artifactName: String, private val outputDir: File, private val contents: Root) { - fun render(context: PathContext) = xml("component", "name" to "ArtifactManager") { - xml("artifact", "name" to artifactName) { - xml("output-path") { - raw(context(outputDir)) - } - - add(contents.renderRecursively(context)) - } - } -} - -interface ArtifactDependencyMapper { - fun map(dependency: PDependency): List -} - -sealed class ArtifactElement { - private val myChildren = mutableListOf() - private val children get() = myChildren - - fun add(child: ArtifactElement) { - myChildren += child - } - - fun add(children: List) { - myChildren += children - } - - abstract fun render(context: PathContext): XmlNode - - fun renderRecursively(context: PathContext): XmlNode { - return render(context).apply { - children.forEach { add(it.renderRecursively(context)) } - } - } - - class Root : ArtifactElement() { - override fun render(context: PathContext) = xml("root", "id" to "root") - } - - data class Directory(val name: String) : ArtifactElement() { - override fun render(context: PathContext) = xml("element", "id" to "directory", "name" to name) - } - - data class Archive(val name: String) : ArtifactElement() { - override fun render(context: PathContext) = xml("element", "id" to "archive", "name" to name) - } - - data class ModuleOutput(val moduleName: String) : ArtifactElement() { - override fun render(context: PathContext) = xml("element", "id" to "module-output", "name" to moduleName) - } - - data class FileCopy(val source: File, val outputFileName: String? = null) : ArtifactElement() { - override fun render(context: PathContext): XmlNode { - val args = mutableListOf("id" to "file-copy", "path" to context(source)) - if (outputFileName != null) { - args += "output-file-name" to outputFileName - } - - return xml("element", *args.toTypedArray()) - } - } - - data class DirectoryCopy(val source: File) : ArtifactElement() { - override fun render(context: PathContext) = xml("element", "id" to "dir-copy", "path" to context(source)) - } - - data class ProjectLibrary(val name: String) : ArtifactElement() { - override fun render(context: PathContext) = xml("element", "id" to "library", "level" to "project", "name" to name) - } - - data class ExtractedDirectory(val archive: File, val pathInJar: String = "/") : ArtifactElement() { - override fun render(context: PathContext) = - xml("element", "id" to "extracted-dir", "path" to context(archive), "path-in-jar" to pathInJar) - } -} - -fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMapper: ArtifactDependencyMapper): PFile { - val root = Root() - - fun Project.getProject(name: String) = findProject(name) ?: error("Cannot find project $name") - - val prepareIdeaPluginProject = rootProject.getProject(":prepare:idea-plugin") - - root.add(Directory("kotlinc").apply { - val kotlincDirectory = rootProject.extra["distKotlinHomeDir"].toString() - add(DirectoryCopy(File(kotlincDirectory))) - }) - - root.add(Directory("lib").apply { - val librariesConfiguration = prepareIdeaPluginProject.configurations.getByName("libraries") - add(getArtifactElements(librariesConfiguration, dependencyMapper, false)) - - add(Directory("jps").apply { - val prepareJpsPluginProject = rootProject.getProject(":kotlin-jps-plugin") - add(Archive(prepareJpsPluginProject.name + ".jar").apply { - val jpsPluginConfiguration = prepareJpsPluginProject.configurations.getByName(EMBEDDED_CONFIGURATION_NAME) - add(getArtifactElements(jpsPluginConfiguration, dependencyMapper, true)) - }) - }) - - add(Archive("kotlin-plugin.jar").apply { - add(FileCopy(File(rootProject.projectDir, "resources/kotlinManifest.properties"))) - - val embeddedConfiguration = prepareIdeaPluginProject.configurations.getByName(EMBEDDED_CONFIGURATION_NAME) - add(getArtifactElements(embeddedConfiguration, dependencyMapper, true)) - }) - }) - - val artifact = PArtifact("KotlinPlugin", File(rootProject.projectDir, "out/artifacts/Kotlin"), root) - return PFile( - File(rootProject.projectDir, ".idea/artifacts/${artifact.artifactName}.xml"), - artifact.render(ProjectContext(rootProject)) - ) -} - -private fun getArtifactElements( - configuration: Configuration, - dependencyMapper: ArtifactDependencyMapper, - extractDependencies: Boolean -): List { - val artifacts = mutableListOf() - - fun process(dependency: PDependency) { - when (dependency) { - is PDependency.Module -> { - val moduleOutput = ModuleOutput(dependency.name) - - if (extractDependencies) { - artifacts += moduleOutput - } else { - artifacts += Archive(dependency.name + ".jar").apply { - add(moduleOutput) - } - } - } - is PDependency.Library -> artifacts += ProjectLibrary(dependency.name) - is PDependency.ModuleLibrary -> { - val files = dependency.library.classes - if (extractDependencies) { - files.mapTo(artifacts) { ExtractedDirectory(it) } - } else { - files.mapTo(artifacts) { FileCopy(it) } - } - } - } - } - - parseDependencies(configuration, dependencyMapper).forEach(::process) - return artifacts -} - -private fun parseDependencies(configuration: Configuration, dependencyMapper: ArtifactDependencyMapper): List { - val dependencies = mutableListOf() - for (file in configuration.resolve()) { - val library = PLibrary(file.name, listOf(file)) - dependencies += dependencyMapper.map(PDependency.ModuleLibrary(library)) - } - return dependencies -} \ No newline at end of file