Pill: Fix artifact generation
This commit is contained in:
@@ -5,11 +5,13 @@ package org.jetbrains.kotlin.pill
|
|||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
import org.gradle.api.internal.file.copy.SingleParentCopySpec
|
import org.gradle.api.internal.file.copy.SingleParentCopySpec
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
import org.gradle.api.tasks.Copy
|
import org.gradle.api.tasks.Copy
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.kotlin.dsl.extra
|
import org.gradle.kotlin.dsl.extra
|
||||||
|
import org.jetbrains.kotlin.pill.DependencyInfo.ResolvedDependencyInfo
|
||||||
import org.jetbrains.kotlin.pill.ArtifactElement.*
|
import org.jetbrains.kotlin.pill.ArtifactElement.*
|
||||||
import org.jetbrains.kotlin.pill.POrderRoot.*
|
import org.jetbrains.kotlin.pill.POrderRoot.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -34,6 +36,10 @@ sealed class ArtifactElement {
|
|||||||
myChildren += child
|
myChildren += child
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun add(children: List<ArtifactElement>) {
|
||||||
|
myChildren += children
|
||||||
|
}
|
||||||
|
|
||||||
abstract fun render(context: PathContext): xml
|
abstract fun render(context: PathContext): xml
|
||||||
|
|
||||||
fun renderRecursively(context: PathContext): xml {
|
fun renderRecursively(context: PathContext): xml {
|
||||||
@@ -102,99 +108,37 @@ sealed class ArtifactElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateKotlinPluginArtifactFile(rootProject: Project): PFile {
|
fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMappers: List<DependencyMapper>): PFile {
|
||||||
val mainIdeaPluginTask = rootProject.tasks.getByName("ideaPlugin")
|
|
||||||
val gradleArtifactDir = File(rootProject.extra["ideaPluginDir"] as File, "lib")
|
|
||||||
|
|
||||||
val ideaPluginTasks = mainIdeaPluginTask.taskDependencies
|
|
||||||
.getDependencies(mainIdeaPluginTask)
|
|
||||||
.filter { it.name == "ideaPlugin" }
|
|
||||||
.filterIsInstance<Copy>()
|
|
||||||
|
|
||||||
val root = Root()
|
val root = Root()
|
||||||
|
|
||||||
// Copy kotlinc directory
|
fun Project.getProject(name: String) = findProject(name) ?: error("Cannot find project $name")
|
||||||
|
|
||||||
|
val prepareIdeaPluginProject = rootProject.getProject(":prepare:idea-plugin")
|
||||||
|
val prepareJpsPluginProject = rootProject.getProject(":kotlin-jps-plugin")
|
||||||
|
|
||||||
root.add(Directory("kotlinc").apply {
|
root.add(Directory("kotlinc").apply {
|
||||||
val kotlincDirectory = rootProject.extra["distKotlinHomeDir"].toString()
|
val kotlincDirectory = rootProject.extra["distKotlinHomeDir"].toString()
|
||||||
add(DirectoryCopy(File(kotlincDirectory)))
|
add(DirectoryCopy(File(kotlincDirectory)))
|
||||||
})
|
})
|
||||||
|
|
||||||
for (task in ideaPluginTasks) {
|
root.add(Directory("lib").apply {
|
||||||
val spec = task.rootSpec.children.filterIsInstance<SingleParentCopySpec>().singleOrNull()
|
val librariesConfiguration = prepareIdeaPluginProject.configurations.getByName("libraries")
|
||||||
?: error("Copy spec is not unique in ${rootProject.name}. Available specs: ${task.rootSpec.children}")
|
add(getArtifactElements(librariesConfiguration, dependencyMappers, false))
|
||||||
|
|
||||||
val sourcePaths = spec.sourcePaths
|
add(Directory("jps").apply {
|
||||||
for (sourcePath in sourcePaths) {
|
add(Archive(prepareJpsPluginProject.name).apply {
|
||||||
if (sourcePath is ShadowJar) {
|
val embeddedConfiguration = prepareJpsPluginProject.configurations.getByName(EmbeddedComponents.CONFIGURATION_NAME)
|
||||||
if (sourcePath.project.path == ":prepare:idea-plugin") {
|
add(getArtifactElements(embeddedConfiguration, dependencyMappers, true))
|
||||||
val kotlinPluginJar = Archive(sourcePath.archiveName).also { root.getDirectory("lib").add(it) }
|
})
|
||||||
|
})
|
||||||
|
|
||||||
kotlinPluginJar.add(FileCopy(File(rootProject.projectDir, "resources/kotlinManifest.properties")))
|
add(Archive(prepareIdeaPluginProject.name + ".jar").apply {
|
||||||
|
add(FileCopy(File(rootProject.projectDir, "resources/kotlinManifest.properties")))
|
||||||
|
|
||||||
for (jarFile in sourcePath.project.configurations.getByName(EmbeddedComponents.CONFIGURATION_NAME).resolve()) {
|
val embeddedConfiguration = prepareIdeaPluginProject.configurations.getByName(EmbeddedComponents.CONFIGURATION_NAME)
|
||||||
kotlinPluginJar.add(ExtractedDirectory(jarFile))
|
add(getArtifactElements(embeddedConfiguration, dependencyMappers, true))
|
||||||
}
|
})
|
||||||
|
})
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
for (projectPath in sourcePath.project.extra["projectsToShadow"] as List<String>) {
|
|
||||||
val jpsModuleName = rootProject.findProject(projectPath)!!.name + ".src"
|
|
||||||
kotlinPluginJar.add(ModuleOutput(jpsModuleName))
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fileCopySnapshotAware(file: File): FileCopy {
|
|
||||||
val SHAPSHOT_JAR_SUFFIX = "-SNAPSHOT.jar"
|
|
||||||
if (file.name.endsWith(SHAPSHOT_JAR_SUFFIX)) {
|
|
||||||
return FileCopy(file, file.name.dropLast(SHAPSHOT_JAR_SUFFIX.length).substringBeforeLast("-") + ".jar")
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileCopy(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
when (sourcePath) {
|
|
||||||
is Jar -> {
|
|
||||||
val targetDir = ("lib/" + task.destinationDir.toRelativeString(gradleArtifactDir)).withoutSlash()
|
|
||||||
|
|
||||||
val archiveForJar = Archive(sourcePath.project.name + ".jar").apply {
|
|
||||||
if (task.project.plugins.hasPlugin(JavaPlugin::class.java)) {
|
|
||||||
add(ModuleOutput(sourcePath.project.name + ".src"))
|
|
||||||
}
|
|
||||||
root.getDirectory(targetDir).add(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
val embeddedComponents = sourcePath.project.configurations
|
|
||||||
.findByName(EmbeddedComponents.CONFIGURATION_NAME)?.resolvedConfiguration
|
|
||||||
|
|
||||||
if (embeddedComponents != null) {
|
|
||||||
val configuration = CollectedConfiguration(embeddedComponents, Scope.COMPILE)
|
|
||||||
for (dependencyInfo in listOf(configuration).collectDependencies()) {
|
|
||||||
val dependency = (dependencyInfo as? DependencyInfo.ResolvedDependencyInfo)?.dependency ?: continue
|
|
||||||
|
|
||||||
if (dependency.isModuleDependency) {
|
|
||||||
archiveForJar.add(ModuleOutput(dependency.moduleName + ".src"))
|
|
||||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
|
||||||
error("Test configurations are not allowed here")
|
|
||||||
} else {
|
|
||||||
for (file in dependency.moduleArtifacts.map { it.file }) {
|
|
||||||
archiveForJar.add(ExtractedDirectory(file))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is Configuration -> {
|
|
||||||
require(sourcePath.name == "sideJars") { "Configurations other than 'sideJars' are not supported" }
|
|
||||||
for (file in sourcePath.resolve()) {
|
|
||||||
root.getDirectory("lib").add(fileCopySnapshotAware(file))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> error("${task.name} Unexpected task type ${task.javaClass.name}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val artifact = PArtifact("KotlinPlugin", File(rootProject.projectDir, "out/artifacts/Kotlin"), root)
|
val artifact = PArtifact("KotlinPlugin", File(rootProject.projectDir, "out/artifacts/Kotlin"), root)
|
||||||
return PFile(
|
return PFile(
|
||||||
@@ -203,3 +147,50 @@ fun generateKotlinPluginArtifactFile(rootProject: Project): PFile {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getArtifactElements(
|
||||||
|
configuration: Configuration,
|
||||||
|
dependencyMappers: List<DependencyMapper>,
|
||||||
|
extractDependencies: Boolean
|
||||||
|
): List<ArtifactElement> {
|
||||||
|
val resolved = configuration.resolvedConfiguration
|
||||||
|
val collected = CollectedConfiguration(resolved, Scope.COMPILE)
|
||||||
|
val dependencies = listOf(collected).collectDependencies()
|
||||||
|
|
||||||
|
val mainRoots = mutableListOf<POrderRoot>()
|
||||||
|
val deferredRoots = mutableListOf<POrderRoot>()
|
||||||
|
|
||||||
|
dependencies.forEach { it.processResolvedDependency(mainRoots, deferredRoots, dependencyMappers) }
|
||||||
|
|
||||||
|
val artifacts = mutableListOf<ArtifactElement>()
|
||||||
|
|
||||||
|
for (dependency in configuration.allDependencies) {
|
||||||
|
if (dependency !is ProjectDependency) continue
|
||||||
|
|
||||||
|
val project = dependency.dependencyProject
|
||||||
|
val moduleOutput = ModuleOutput(project.name + ".src")
|
||||||
|
|
||||||
|
if (extractDependencies) {
|
||||||
|
artifacts += moduleOutput
|
||||||
|
} else {
|
||||||
|
artifacts += Archive(project.name + ".jar").apply {
|
||||||
|
add(moduleOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val embeddedConfiguration = project.configurations.findByName(EmbeddedComponents.CONFIGURATION_NAME) ?: continue
|
||||||
|
artifacts += getArtifactElements(embeddedConfiguration, dependencyMappers, extractDependencies)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (orderRoot in listOf(mainRoots, deferredRoots).flatten()) {
|
||||||
|
when (val dependency = orderRoot.dependency) {
|
||||||
|
is PDependency.Module -> {} // already added above
|
||||||
|
is PDependency.Library -> artifacts += ProjectLibrary(dependency.name)
|
||||||
|
is PDependency.ModuleLibrary -> {
|
||||||
|
val files = dependency.library.classes
|
||||||
|
artifacts += files.map(if (extractDependencies) ::ExtractedDirectory else ::FileCopy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return artifacts
|
||||||
|
}
|
||||||
@@ -376,7 +376,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
|||||||
return configurations
|
return configurations
|
||||||
}
|
}
|
||||||
|
|
||||||
nextDependency@ for (dependencyInfo in collectConfigurations().collectDependencies()) {
|
for (dependencyInfo in collectConfigurations().collectDependencies()) {
|
||||||
val scope = dependencyInfo.scope
|
val scope = dependencyInfo.scope
|
||||||
|
|
||||||
if (dependencyInfo is DependencyInfo.CustomDependencyInfo) {
|
if (dependencyInfo is DependencyInfo.CustomDependencyInfo) {
|
||||||
@@ -387,46 +387,54 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val dependency = (dependencyInfo as DependencyInfo.ResolvedDependencyInfo).dependency
|
dependencyInfo.processResolvedDependency(mainRoots, deferredRoots, dependencyMappers)
|
||||||
|
|
||||||
for (mapper in dependencyMappers) {
|
|
||||||
if (dependency.configuration in mapper.configurations && mapper.predicate(dependency)) {
|
|
||||||
val mappedDependency = mapper.mapping(dependency)
|
|
||||||
|
|
||||||
if (mappedDependency != null) {
|
|
||||||
val mainDependency = mappedDependency.main
|
|
||||||
if (mainDependency != null) {
|
|
||||||
mainRoots += POrderRoot(mainDependency, scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (deferredDep in mappedDependency.deferred) {
|
|
||||||
deferredRoots += POrderRoot(deferredDep, scope)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue@nextDependency
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mainRoots += if (dependency.isModuleDependency && scope != Scope.TEST) {
|
|
||||||
POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
|
|
||||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
|
||||||
POrderRoot(
|
|
||||||
PDependency.Module(dependency.moduleName + ".test"),
|
|
||||||
scope,
|
|
||||||
isProductionOnTestDependency = true
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val classes = dependency.moduleArtifacts.map { it.file }
|
|
||||||
val library = PLibrary(dependency.moduleName, classes)
|
|
||||||
POrderRoot(PDependency.ModuleLibrary(library), scope)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeDuplicates(mainRoots + deferredRoots)
|
return removeDuplicates(mainRoots + deferredRoots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DependencyInfo.processResolvedDependency(
|
||||||
|
mainConsumer: MutableList<POrderRoot>,
|
||||||
|
deferredConsumer: MutableList<POrderRoot>,
|
||||||
|
dependencyMappers: List<DependencyMapper>
|
||||||
|
) {
|
||||||
|
val dependency = (this as? DependencyInfo.ResolvedDependencyInfo)?.dependency ?: return
|
||||||
|
|
||||||
|
for (mapper in dependencyMappers) {
|
||||||
|
if (dependency.configuration in mapper.configurations && mapper.predicate(dependency)) {
|
||||||
|
val mappedDependency = mapper.mapping(dependency)
|
||||||
|
|
||||||
|
if (mappedDependency != null) {
|
||||||
|
val mainDependency = mappedDependency.main
|
||||||
|
if (mainDependency != null) {
|
||||||
|
mainConsumer += POrderRoot(mainDependency, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (deferredDep in mappedDependency.deferred) {
|
||||||
|
deferredConsumer += POrderRoot(deferredDep, scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainConsumer += if (dependency.isModuleDependency && scope != Scope.TEST) {
|
||||||
|
POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
|
||||||
|
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
||||||
|
POrderRoot(
|
||||||
|
PDependency.Module(dependency.moduleName + ".test"),
|
||||||
|
scope,
|
||||||
|
isProductionOnTestDependency = true
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val classes = dependency.moduleArtifacts.map { it.file }
|
||||||
|
val library = PLibrary(dependency.moduleName, classes)
|
||||||
|
POrderRoot(PDependency.ModuleLibrary(library), scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveExtraDependencies(configuration: Configuration): List<File> {
|
private fun resolveExtraDependencies(configuration: Configuration): List<File> {
|
||||||
return configuration.dependencies
|
return configuration.dependencies
|
||||||
.filterIsInstance<SelfResolvingDependency>()
|
.filterIsInstance<SelfResolvingDependency>()
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val projectLibraries = getProjectLibraries(rootProject)
|
val projectLibraries = getProjectLibraries(rootProject)
|
||||||
val parserContext = ParserContext(getDependencyMappers(projectLibraries), variant)
|
val dependencyMappers = getDependencyMappers(projectLibraries)
|
||||||
|
|
||||||
|
val parserContext = ParserContext(dependencyMappers, variant)
|
||||||
|
|
||||||
val jpsProject = parse(rootProject, projectLibraries, parserContext)
|
val jpsProject = parse(rootProject, projectLibraries, parserContext)
|
||||||
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
|
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
|
||||||
@@ -152,7 +154,7 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
|||||||
removeJpsAndPillRunConfigurations()
|
removeJpsAndPillRunConfigurations()
|
||||||
removeAllArtifactConfigurations()
|
removeAllArtifactConfigurations()
|
||||||
|
|
||||||
generateKotlinPluginArtifactFile(rootProject).write()
|
generateKotlinPluginArtifactFile(rootProject, dependencyMappers).write()
|
||||||
|
|
||||||
copyRunConfigurations()
|
copyRunConfigurations()
|
||||||
setOptionsForDefaultJunitRunConfiguration(rootProject)
|
setOptionsForDefaultJunitRunConfiguration(rootProject)
|
||||||
|
|||||||
Reference in New Issue
Block a user