Pill: Support all Gradle source sets, not just main/test

This commit is contained in:
Yan Zhulanow
2020-01-24 22:19:43 +09:00
parent 3acf7a4679
commit 73813aef23
24 changed files with 446 additions and 551 deletions
-4
View File
@@ -46,10 +46,6 @@ plugins {
gradlePlugin {
plugins {
register("pill-configurable") {
id = "pill-configurable"
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
}
register("jps-compatible") {
id = "jps-compatible"
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatiblePlugin"
-33
View File
@@ -1,33 +0,0 @@
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.component.*
class DependencyMapper(val predicate: (ResolvedArtifact) -> Boolean, val mapping: (ResolvedArtifact) -> MappedDependency?) {
companion object {
fun forProject(path: String, mapping: (ResolvedArtifact) -> MappedDependency?): DependencyMapper {
return DependencyMapper(
predicate = { artifact ->
val identifier = artifact.id.componentIdentifier as? ProjectComponentIdentifier
identifier?.projectPath == path
},
mapping = mapping
)
}
fun forModule(group: String, module: String, version: String?, mapping: (ResolvedArtifact) -> MappedDependency?): DependencyMapper {
return DependencyMapper(
predicate = { artifact ->
val identifier = artifact.id.componentIdentifier as? ModuleComponentIdentifier
identifier?.group == group && identifier?.module == module && (version == null || identifier?.version == version)
},
mapping = mapping
)
}
}
}
class MappedDependency(val main: PDependency?, val deferred: List<PDependency> = emptyList())
class ParserContext(val dependencyMappers: List<DependencyMapper>, val variant: PillExtension.Variant)
@@ -1,94 +0,0 @@
/*
* Copyright 2010-2019 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.
*/
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
import java.io.File
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.artifacts.*
import org.gradle.api.artifacts.component.*
data class PDependencies(val main: List<PDependency>, val deferred: List<PDependency>) {
fun join(): List<PDependency> {
return main + deferred
}
}
fun Project.resolveDependencies(
configuration: Configuration,
forTests: Boolean,
dependencyMappers: List<DependencyMapper>,
withEmbedded: Boolean = false
): PDependencies {
val dependencies = mutableListOf<PDependency>()
val deferred = mutableListOf<PDependency>()
nextArtifact@ for (artifact in configuration.resolvedConfiguration.resolvedArtifacts) {
val identifier = artifact.id.componentIdentifier
for (mapper in dependencyMappers) {
if (mapper.predicate(artifact)) {
val mapped = mapper.mapping(artifact)
if (mapped != null) {
mapped.main?.let { dependencies += it }
deferred += mapped.deferred
}
continue@nextArtifact
}
}
fun addProjectDependency(projectPath: String) {
val project = rootProject.findProject(projectPath) ?: error("Cannot find project $projectPath")
fun addSourceSet(name: String, suffix: String): Boolean {
val sourceSet = project.sourceSets?.findByName(name)?.takeIf { !it.allSource.isEmpty() } ?: return false
dependencies += PDependency.Module(project.pillModuleName + '.' + suffix)
return true
}
if (forTests && artifact.classifier == "tests") {
addSourceSet(SourceSet.TEST_SOURCE_SET_NAME, "test") || addSourceSet(SourceSet.MAIN_SOURCE_SET_NAME, "src")
} else {
addSourceSet(SourceSet.MAIN_SOURCE_SET_NAME, "src")
}
if (withEmbedded) {
val embeddedConfiguration = project.configurations.findByName(EmbeddedComponents.CONFIGURATION_NAME)
if (embeddedConfiguration != null) {
dependencies += resolveDependencies(embeddedConfiguration, forTests, dependencyMappers, withEmbedded).join()
}
}
}
when (identifier) {
is ProjectComponentIdentifier -> addProjectDependency(identifier.projectPath)
is LibraryBinaryIdentifier -> addProjectDependency(identifier.projectPath)
is ModuleComponentIdentifier -> {
val file = artifact.file
val library = PLibrary(file.name, classes = listOf(file))
dependencies += PDependency.ModuleLibrary(library)
}
}
}
val existingFiles = mutableSetOf<File>()
for (dependency in configuration.dependencies) {
if (dependency !is SelfResolvingDependency) {
continue
}
val files = dependency.resolve().filter { it !in existingFiles }.takeIf { it.isNotEmpty() } ?: continue
existingFiles.addAll(files)
val library = PLibrary(dependency.name, classes = files.toList())
deferred += PDependency.ModuleLibrary(library)
}
return PDependencies(dependencies, deferred)
}
+18 -12
View File
@@ -1,3 +1,8 @@
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
@@ -7,33 +12,34 @@ import org.gradle.api.Project
open class PillExtension {
enum class Variant {
// Default variant (./gradlew pill)
BASE() { override val includes = setOf(BASE) },
BASE() {
override val includes = setOf(BASE)
},
// Full variant (./gradlew pill -Dpill.variant=full)
FULL() { override val includes = setOf(BASE, FULL) },
FULL() {
override val includes = setOf(BASE, FULL)
},
// Do not import the project to JPS model, but set some options for it
NONE() { override val includes = emptySet<Variant>() },
NONE() {
override val includes = emptySet<Variant>()
},
// 'BASE' if the "jps-compatible" plugin is applied, 'NONE' otherwise
DEFAULT() { override val includes = emptySet<Variant>() };
DEFAULT() {
override val includes = emptySet<Variant>()
};
abstract val includes: Set<Variant>
}
open var variant: Variant = Variant.DEFAULT
open var importAsLibrary: Boolean = false
open var excludedDirs: List<File> = emptyList()
@Suppress("unused")
fun Project.excludedDirs(vararg dirs: String) {
excludedDirs = excludedDirs + dirs.map { File(projectDir, it) }
}
open var libraryPath: File? = null
set(v) {
importAsLibrary = true
field = v
}
}
@@ -1,21 +1,19 @@
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.internal.file.copy.SingleParentCopySpec
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.Copy
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.extra
import org.jetbrains.kotlin.pill.ArtifactElement.*
import org.jetbrains.kotlin.pill.POrderRoot.*
import java.io.File
class PArtifact(val artifactName: String, val outputDir: File, private val contents: ArtifactElement.Root) {
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") {
@@ -27,6 +25,10 @@ class PArtifact(val artifactName: String, val outputDir: File, private val conte
}
}
interface OpaqueDependencyMapper {
fun map(dependency: PDependency): List<PDependency>
}
sealed class ArtifactElement {
private val myChildren = mutableListOf<ArtifactElement>()
val children get() = myChildren
@@ -47,25 +49,6 @@ sealed class ArtifactElement {
}
}
fun getDirectory(path: String): ArtifactElement {
if (path.isEmpty()) {
return this
}
var current: ArtifactElement = this
for (segment in path.split("/")) {
val existing = current.children.firstOrNull { it is Directory && it.name == segment }
if (existing != null) {
current = existing
continue
}
current = Directory(segment).also { current.add(it) }
}
return current
}
class Root : ArtifactElement() {
override fun render(context: PathContext) = xml("root", "id" to "root")
}
@@ -107,7 +90,7 @@ sealed class ArtifactElement {
}
}
fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMappers: List<DependencyMapper>): PFile {
fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMapper: OpaqueDependencyMapper): PFile {
val root = Root()
fun Project.getProject(name: String) = findProject(name) ?: error("Cannot find project $name")
@@ -121,13 +104,13 @@ fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMappers: Li
root.add(Directory("lib").apply {
val librariesConfiguration = prepareIdeaPluginProject.configurations.getByName("libraries")
add(getArtifactElements(rootProject, librariesConfiguration, dependencyMappers, false))
add(getArtifactElements(rootProject, librariesConfiguration, dependencyMapper, false))
add(Directory("jps").apply {
val prepareJpsPluginProject = rootProject.getProject(":kotlin-jps-plugin")
add(Archive(prepareJpsPluginProject.name + ".jar").apply {
val jpsPluginConfiguration = prepareIdeaPluginProject.configurations.getByName("jpsPlugin")
add(getArtifactElements(rootProject, jpsPluginConfiguration, dependencyMappers, true))
add(getArtifactElements(rootProject, jpsPluginConfiguration, dependencyMapper, true))
})
})
@@ -135,7 +118,7 @@ fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMappers: Li
add(FileCopy(File(rootProject.projectDir, "resources/kotlinManifest.properties")))
val embeddedConfiguration = prepareIdeaPluginProject.configurations.getByName(EmbeddedComponents.CONFIGURATION_NAME)
add(getArtifactElements(rootProject, embeddedConfiguration, dependencyMappers, true))
add(getArtifactElements(rootProject, embeddedConfiguration, dependencyMapper, true))
})
})
@@ -149,10 +132,10 @@ fun generateKotlinPluginArtifactFile(rootProject: Project, dependencyMappers: Li
private fun getArtifactElements(
rootProject: Project,
configuration: Configuration,
dependencyMappers: List<DependencyMapper>,
dependencyMapper: OpaqueDependencyMapper,
extractDependencies: Boolean
): List<ArtifactElement> {
val dependencies = rootProject.resolveDependencies(configuration, false, dependencyMappers, withEmbedded = true).join()
val dependencies = parseDependencies(configuration, dependencyMapper)
val artifacts = mutableListOf<ArtifactElement>()
@@ -179,4 +162,13 @@ private fun getArtifactElements(
}
return artifacts
}
private fun parseDependencies(configuration: Configuration, dependencyMapper: OpaqueDependencyMapper): List<PDependency> {
val dependencies = mutableListOf<PDependency>()
for (file in configuration.resolve()) {
val library = PLibrary(file.name, listOf(file))
dependencies += dependencyMapper.map(PDependency.ModuleLibrary(library))
}
return dependencies
}
+196 -212
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -7,51 +7,63 @@
package org.jetbrains.kotlin.pill
import org.gradle.api.Project
import org.gradle.api.artifacts.*
import org.gradle.api.tasks.*
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.kotlin.dsl.configure
import org.gradle.plugins.ide.idea.IdeaPlugin
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.HasConvention
import org.gradle.api.internal.file.copy.CopySpecInternal
import org.gradle.api.internal.file.copy.SingleParentCopySpec
import org.gradle.jvm.tasks.Jar
import org.gradle.language.jvm.tasks.ProcessResources
import org.jetbrains.kotlin.pill.POrderRoot.*
import org.jetbrains.kotlin.pill.PSourceRoot.*
import org.jetbrains.kotlin.pill.PillExtension.*
import java.io.File
import java.util.LinkedList
class ParserContext(val variant: Variant)
typealias OutputDir = String
typealias GradleProjectPath = String
data class PProject(
val name: String,
val rootDirectory: File,
val modules: List<PModule>,
val libraries: List<PLibrary>
val libraries: List<PLibrary>,
val artifacts: Map<OutputDir, List<GradleProjectPath>>
)
data class PModule(
val name: String,
val path: GradleProjectPath,
val forTests: Boolean,
val rootDirectory: File,
val moduleFile: File,
val contentRoots: List<PContentRoot>,
val orderRoots: List<POrderRoot>,
val kotlinOptions: PSourceRootKotlinOptions?,
val moduleForProductionSources: PModule? = null
)
data class PContentRoot(
val path: File,
val forTests: Boolean,
val sourceRoots: List<PSourceRoot>,
val excludedDirectories: List<File>
)
data class PSourceRoot(
val path: File,
val kind: Kind,
val kotlinOptions: PSourceRootKotlinOptions?
) {
data class PSourceSet(
val name: String,
val forTests: Boolean,
val sourceDirectories: List<File>,
val resourceDirectories: List<File>,
val kotlinOptions: PSourceRootKotlinOptions?,
val compileClasspathConfigurationName: String,
val runtimeClasspathConfigurationName: String
)
data class PSourceRoot(val directory: File, val kind: Kind) {
enum class Kind { PRODUCTION, TEST, RESOURCES, TEST_RESOURCES }
}
@@ -63,17 +75,7 @@ data class PSourceRootKotlinOptions(
val languageVersion: String?,
val jvmTarget: String?,
val extraArguments: List<String>
) {
fun intersect(other: PSourceRootKotlinOptions) = PSourceRootKotlinOptions(
if (noStdlib == other.noStdlib) noStdlib else null,
if (noReflect == other.noReflect) noReflect else null,
if (moduleName == other.moduleName) moduleName else null,
if (apiVersion == other.apiVersion) apiVersion else null,
if (languageVersion == other.languageVersion) languageVersion else null,
if (jvmTarget == other.jvmTarget) jvmTarget else null,
extraArguments.intersect(other.extraArguments).toList()
)
}
)
data class POrderRoot(
val dependency: PDependency,
@@ -104,7 +106,7 @@ data class PLibrary(
}
}
fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext): PProject = with (context) {
fun parse(project: Project, context: ParserContext): PProject = with(context) {
if (project != project.rootProject) {
error("$project is not a root project")
}
@@ -119,182 +121,199 @@ fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext):
.partition { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) && it.matchesSelectedVariant() }
val modules = includedProjects.flatMap { parseModules(it, excludedProjects) }
val artifacts = parseArtifacts(project)
return PProject("Kotlin", project.projectDir, modules, libraries)
return PProject("Kotlin", project.projectDir, modules, emptyList(), artifacts)
}
/*
Ordering here and below is significant.
Placing 'runtime' configuration dependencies on the top make 'idea' tests to run normally.
('idea' module has 'intellij-core' as transitive dependency, and we really need to get rid of it.)
*/
private val CONFIGURATION_MAPPING = mapOf(
listOf("runtimeClasspath") to Scope.RUNTIME,
listOf("compileClasspath", "compileOnly") to Scope.PROVIDED,
listOf("embedded") to Scope.COMPILE
)
private fun parseArtifacts(rootProject: Project): Map<String, List<GradleProjectPath>> {
val artifacts = HashMap<OutputDir, List<GradleProjectPath>>()
val additionalOutputs = HashMap<OutputDir, List<OutputDir>>()
private val TEST_CONFIGURATION_MAPPING = mapOf(
listOf("runtimeClasspath", "testRuntimeClasspath") to Scope.RUNTIME,
listOf("compileClasspath", "testCompileClasspath", "compileOnly", "testCompileOnly") to Scope.PROVIDED,
listOf("jpsTest") to Scope.TEST
)
for (project in rootProject.allprojects) {
val sourceSets = project.sourceSets?.toList() ?: emptyList()
private fun ParserContext.parseModules(project: Project, excludedProjects: List<Project>): List<PModule> {
val (productionContentRoots, testContentRoots) = parseContentRoots(project).partition { !it.forTests }
for (sourceSet in sourceSets) {
val path = makePath(project, sourceSet.name)
for (output in sourceSet.output.toList()) {
artifacts[output.absolutePath] = listOf(path)
}
val jarTask = project.tasks.findByName(sourceSet.jarTaskName) as? Jar ?: continue
val embeddedTask = findEmbeddableTask(project, sourceSet)
for (task in listOfNotNull(jarTask, embeddedTask)) {
val archiveFile = task.archiveFile.get().asFile
artifacts[archiveFile.absolutePath] = listOf(path)
val additionalOutputsForSourceSet = mutableListOf<File>()
fun process(spec: CopySpecInternal) {
spec.children.forEach { process(it) }
if (spec is SingleParentCopySpec) {
for (sourcePath in spec.sourcePaths) {
if (sourcePath is SourceSetOutput) {
additionalOutputsForSourceSet += sourcePath.classesDirs
sourcePath.resourcesDir?.let { additionalOutputsForSourceSet += it }
}
}
}
}
process(task.rootSpec)
additionalOutputs[archiveFile.absolutePath] = additionalOutputsForSourceSet.map { it.absolutePath }
}
}
}
for ((sourceSetOutputDir, additionalOutputsForSourceSet) in additionalOutputs) {
val projectPaths = artifacts[sourceSetOutputDir] ?: error("Unknown artifact $sourceSetOutputDir")
val newPaths = projectPaths + additionalOutputsForSourceSet.mapNotNull { artifacts[it] }.flatten()
artifacts[sourceSetOutputDir] = newPaths.distinct()
}
return artifacts
}
private fun findEmbeddableTask(project: Project, sourceSet: SourceSet): Jar? {
val jarName = sourceSet.jarTaskName
val embeddable = "embeddable"
val embeddedName = if (jarName == "jar") embeddable else jarName.dropLast("jar".length) + embeddable.capitalize()
return project.tasks.findByName(embeddedName) as? Jar
}
private fun makePath(project: Project, sourceSetName: String): GradleProjectPath {
return project.path + "/" + sourceSetName
}
private fun parseModules(project: Project, excludedProjects: List<Project>): List<PModule> {
val modules = mutableListOf<PModule>()
fun getJavaExcludedDirs() = project.plugins.findPlugin(IdeaPlugin::class.java)
?.model?.module?.excludeDirs?.toList() ?: emptyList()
fun getPillExcludedDirs() = project.extensions.getByType(PillExtension::class.java).excludedDirs
val allExcludedDirs = getPillExcludedDirs() + getJavaExcludedDirs() + project.buildDir +
(if (project == project.rootProject) excludedProjects.map { it.buildDir } else emptyList())
var productionSourcesModule: PModule? = null
fun getModuleFile(suffix: String = ""): File {
val relativePath = File(project.projectDir, project.pillModuleName + suffix + ".iml")
.toRelativeString(project.rootProject.projectDir)
fun getModuleFile(name: String): File {
val relativePath = File(project.projectDir, "$name.iml").toRelativeString(project.rootProject.projectDir)
return File(project.rootProject.projectDir, ".idea/modules/$relativePath")
}
for ((nameSuffix, roots) in mapOf(".src" to productionContentRoots, ".test" to testContentRoots)) {
if (roots.isEmpty()) {
val sourceSets = parseSourceSets(project).sortedBy { it.forTests }
for (sourceSet in sourceSets) {
val sourceRoots = mutableListOf<PSourceRoot>()
for (dir in sourceSet.sourceDirectories) {
sourceRoots += PSourceRoot(dir, if (sourceSet.forTests) Kind.TEST else Kind.PRODUCTION)
}
for (dir in sourceSet.resourceDirectories) {
sourceRoots += PSourceRoot(dir, if (sourceSet.forTests) Kind.TEST_RESOURCES else Kind.RESOURCES)
}
if (sourceRoots.isEmpty()) {
continue
}
val mainRoot = roots.first()
val productionModule = if (sourceSet.forTests) modules.firstOrNull { !it.forTests } else null
var dependencies = parseDependencies(project, mainRoot.forTests)
if (productionContentRoots.isNotEmpty() && mainRoot.forTests) {
val productionModuleDependency = PDependency.Module(project.pillModuleName + ".src")
dependencies += POrderRoot(productionModuleDependency, Scope.COMPILE, true)
val contentRoots = sourceRoots.map { PContentRoot(it.directory, listOf(it), emptyList()) }
var orderRoots = parseDependencies(project, sourceSet)
if (productionModule != null) {
val productionModuleDependency = PDependency.Module(productionModule.name)
orderRoots = listOf(POrderRoot(productionModuleDependency, Scope.COMPILE, true)) + orderRoots
}
val module = PModule(
project.pillModuleName + nameSuffix,
mainRoot.path,
getModuleFile(nameSuffix),
roots,
dependencies,
productionSourcesModule
val name = project.pillModuleName + "." + sourceSet.name
modules += PModule(
name = name,
path = makePath(project, sourceSet.name),
forTests = sourceSet.forTests,
rootDirectory = sourceRoots.first().directory,
moduleFile = getModuleFile(name),
contentRoots = contentRoots,
orderRoots = orderRoots,
kotlinOptions = sourceSet.kotlinOptions,
moduleForProductionSources = productionModule
)
modules += module
if (!mainRoot.forTests) {
productionSourcesModule = module
}
}
val mainModuleFileRelativePath = when (project) {
project.rootProject -> File(project.rootProject.projectDir, project.rootProject.name + ".iml")
else -> getModuleFile()
else -> getModuleFile(project.pillModuleName)
}
modules += PModule(
project.pillModuleName,
project.projectDir,
mainModuleFileRelativePath,
listOf(PContentRoot(project.projectDir, false, emptyList(), allExcludedDirs)),
if (modules.isEmpty()) parseDependencies(project, false) else emptyList()
name = project.pillModuleName,
path = project.path,
forTests = false,
rootDirectory = project.projectDir,
moduleFile = mainModuleFileRelativePath,
contentRoots = listOf(PContentRoot(project.projectDir, listOf(), getExcludedDirs(project, excludedProjects))),
orderRoots = emptyList(),
kotlinOptions = null,
moduleForProductionSources = null
)
return modules
}
private fun parseContentRoots(project: Project): List<PContentRoot> {
val sourceRoots = parseSourceRoots(project).groupBy { it.kind }
fun getRoots(kind: PSourceRoot.Kind) = sourceRoots[kind] ?: emptyList()
private fun getExcludedDirs(project: Project, excludedProjects: List<Project>): List<File> {
fun getJavaExcludedDirs() = project.plugins.findPlugin(IdeaPlugin::class.java)
?.model?.module?.excludeDirs?.toList() ?: emptyList()
val productionSourceRoots = getRoots(Kind.PRODUCTION) + getRoots(Kind.RESOURCES)
val testSourceRoots = getRoots(Kind.TEST) + getRoots(Kind.TEST_RESOURCES)
fun getPillExcludedDirs() = project.extensions.getByType(PillExtension::class.java).excludedDirs
fun createContentRoots(sourceRoots: List<PSourceRoot>, forTests: Boolean): List<PContentRoot> {
return sourceRoots.map { PContentRoot(it.path, forTests, listOf(it), emptyList()) }
}
return createContentRoots(productionSourceRoots, forTests = false) +
createContentRoots(testSourceRoots, forTests = true)
return getPillExcludedDirs() + getJavaExcludedDirs() + project.buildDir +
(if (project == project.rootProject) excludedProjects.map { it.buildDir } else emptyList())
}
private fun parseSourceRoots(project: Project): List<PSourceRoot> {
private fun parseSourceSets(project: Project): List<PSourceSet> {
if (!project.plugins.hasPlugin(JavaPlugin::class.java)) {
return emptyList()
}
val kotlinTasksBySourceSet = project.tasks.names
.filter { it.startsWith("compile") && it.endsWith("Kotlin") }
.map { project.tasks.getByName(it) }
.associateBy { it.invokeInternal("getSourceSetName") }
.filter { it.startsWith("compile") && it.endsWith("Kotlin") }
.map { project.tasks.getByName(it) }
.associateBy { it.invokeInternal("getSourceSetName") }
val sourceRoots = mutableListOf<PSourceRoot>()
val gradleSourceSets = project.sourceSets?.toList() ?: emptyList()
val sourceSets = mutableListOf<PSourceSet>()
val sourceSets = project.sourceSets
if (sourceSets != null) {
for (sourceSet in sourceSets) {
val kotlinCompileTask = kotlinTasksBySourceSet[sourceSet.name]
val kind = if (sourceSet.isTestSourceSet) Kind.TEST else Kind.PRODUCTION
for (sourceSet in gradleSourceSets) {
val kotlinCompileTask = kotlinTasksBySourceSet[sourceSet.name]
fun Any.getKotlin(): SourceDirectorySet {
val kotlinMethod = javaClass.getMethod("getKotlin")
val oldIsAccessible = kotlinMethod.isAccessible
try {
kotlinMethod.isAccessible = true
return kotlinMethod(this) as SourceDirectorySet
} finally {
kotlinMethod.isAccessible = oldIsAccessible
}
}
val kotlinSourceDirectories = (sourceSet as HasConvention).convention
.plugins["kotlin"]?.getKotlin()?.srcDirs
?: emptySet()
val directories = (sourceSet.java.sourceDirectories.files + kotlinSourceDirectories).toList()
.filter { it.exists() }
.takeIf { it.isNotEmpty() }
?: continue
val kotlinOptions = kotlinCompileTask?.let { getKotlinOptions(it) }
for (resourceRoot in sourceSet.resources.sourceDirectories.files) {
if (!resourceRoot.exists() || resourceRoot in directories) {
continue
}
val resourceRootKind = when (kind) {
Kind.PRODUCTION -> Kind.RESOURCES
Kind.TEST -> Kind.TEST_RESOURCES
else -> error("Invalid source root kind $kind")
}
sourceRoots += PSourceRoot(resourceRoot, resourceRootKind, kotlinOptions)
}
for (directory in directories) {
sourceRoots += PSourceRoot(directory, kind, kotlinOptions)
}
for (root in parseResourceRootsProcessedByProcessResourcesTask(project, sourceSet)) {
if (sourceRoots.none { it.path == root.path }) {
sourceRoots += root
}
}
fun Any.getKotlin(): SourceDirectorySet {
val kotlinMethod = javaClass.getMethod("getKotlin")
kotlinMethod.isAccessible = true
return kotlinMethod(this) as SourceDirectorySet
}
val kotlinSourceDirectories = (sourceSet as HasConvention).convention
.plugins["kotlin"]?.getKotlin()?.srcDirs ?: emptySet()
val sourceDirectories = (sourceSet.java.sourceDirectories.files + kotlinSourceDirectories).toList()
val resourceDirectoriesFromSourceSet = sourceSet.resources.sourceDirectories.files
val resourceDirectoriesFromTask = parseResourceRootsProcessedByProcessResourcesTask(project, sourceSet)
val resourceDirectories = (resourceDirectoriesFromSourceSet + resourceDirectoriesFromTask)
.distinct().filter { it !in sourceDirectories }
sourceSets += PSourceSet(
name = sourceSet.name,
forTests = sourceSet.isTestSourceSet,
sourceDirectories = sourceDirectories,
resourceDirectories = resourceDirectories,
kotlinOptions = kotlinCompileTask?.let { getKotlinOptions(it) },
compileClasspathConfigurationName = sourceSet.compileClasspathConfigurationName,
runtimeClasspathConfigurationName = sourceSet.runtimeClasspathConfigurationName
)
}
return sourceRoots
return sourceSets
}
private fun parseResourceRootsProcessedByProcessResourcesTask(project: Project, sourceSet: SourceSet): List<PSourceRoot> {
private fun parseResourceRootsProcessedByProcessResourcesTask(project: Project, sourceSet: SourceSet): List<File> {
val isMainSourceSet = sourceSet.name == SourceSet.MAIN_SOURCE_SET_NAME
val resourceRootKind = if (sourceSet.isTestSourceSet) PSourceRoot.Kind.TEST_RESOURCES else PSourceRoot.Kind.RESOURCES
val taskNameBase = "processResources"
val taskName = if (isMainSourceSet) taskNameBase else sourceSet.name + taskNameBase.capitalize()
val task = project.tasks.findByName(taskName) as? ProcessResources ?: return emptyList()
@@ -309,8 +328,7 @@ private fun parseResourceRootsProcessedByProcessResourcesTask(project: Project,
spec.children.forEach(::collectRoots)
}
collectRoots(task.rootSpec)
return roots.map { PSourceRoot(it, resourceRootKind, null) }
return roots
}
private val SourceSet.isTestSourceSet: Boolean
@@ -322,92 +340,58 @@ private fun getKotlinOptions(kotlinCompileTask: Any): PSourceRootKotlinOptions?
val compileArguments = run {
val method = kotlinCompileTask::class.java.getMethod("getSerializedCompilerArguments")
method.isAccessible = true
@Suppress("UNCHECKED_CAST")
method.invoke(kotlinCompileTask) as List<String>
}
fun parseBoolean(name: String) = compileArguments.contains("-$name")
fun parseString(name: String) = compileArguments.dropWhile { it != "-$name" }.drop(1).firstOrNull()
fun isOptionForScriptingCompilerPlugin(option: String)
= option.startsWith("-Xplugin=") && option.contains("kotlin-scripting-compiler")
fun isOptionForScriptingCompilerPlugin(option: String): Boolean {
return option.startsWith("-Xplugin=") && option.contains("kotlin-scripting-compiler")
}
val extraArguments = compileArguments.filter {
it.startsWith("-X") && !isOptionForScriptingCompilerPlugin(it)
}
return PSourceRootKotlinOptions(
parseBoolean("no-stdlib"),
parseBoolean("no-reflect"),
parseString("module-name"),
parseString("api-version"),
parseString("language-version"),
parseString("jvm-target"),
extraArguments
parseBoolean("no-stdlib"),
parseBoolean("no-reflect"),
parseString("module-name"),
parseString("api-version"),
parseString("language-version"),
parseString("jvm-target"),
extraArguments
)
}
private fun Any.invokeInternal(name: String, instance: Any = this): Any? {
val method = javaClass.methods.single { it.name.startsWith(name) && it.parameterTypes.isEmpty() }
val oldIsAccessible = method.isAccessible
try {
method.isAccessible = true
return method.invoke(instance)
} finally {
method.isAccessible = oldIsAccessible
}
method.isAccessible = true
return method.invoke(instance)
}
private fun ParserContext.parseDependencies(project: Project, forTests: Boolean): List<POrderRoot> {
val configurations = project.configurations
val configurationMapping = if (forTests) TEST_CONFIGURATION_MAPPING else CONFIGURATION_MAPPING
private fun parseDependencies(project: Project, sourceSet: PSourceSet): List<POrderRoot> {
val roots = mutableListOf<POrderRoot>()
val mainRoots = mutableListOf<POrderRoot>()
val deferredRoots = mutableListOf<POrderRoot>()
for ((configurationNames, scope) in configurationMapping) {
for (configurationName in configurationNames) {
val configuration = configurations.findByName(configurationName) ?: continue
val (main, deferred) = project.resolveDependencies(configuration, forTests, dependencyMappers)
mainRoots += main.map { POrderRoot(it, scope) }
deferredRoots += deferred.map { POrderRoot(it, scope) }
fun process(name: String, scope: Scope) {
val configuration = project.configurations.findByName(name) ?: return
for (file in configuration.resolve()) {
val library = PLibrary(file.name, listOf(file))
val dependency = PDependency.ModuleLibrary(library)
roots += POrderRoot(dependency, scope)
}
}
return removeDuplicates(mainRoots + deferredRoots)
}
process(sourceSet.compileClasspathConfigurationName, Scope.PROVIDED)
process(sourceSet.runtimeClasspathConfigurationName, Scope.RUNTIME)
fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
val dependenciesByScope = roots.groupBy { it.scope }.mapValues { it.value.mapTo(mutableSetOf()) { it.dependency } }
fun dependenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
val result = mutableSetOf<POrderRoot>()
for (root in roots.distinct()) {
val scope = root.scope
val dependency = root.dependency
if (root in result) {
continue
}
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in dependenciesFor(Scope.COMPILE)) {
continue
}
if (scope == Scope.PROVIDED && dependency in dependenciesFor(Scope.RUNTIME)) {
result += POrderRoot(dependency, Scope.COMPILE)
continue
}
if (scope == Scope.RUNTIME && dependency in dependenciesFor(Scope.PROVIDED)) {
result += POrderRoot(dependency, Scope.COMPILE)
continue
}
result += root
if (sourceSet.forTests) {
process("jpsTest", Scope.TEST)
}
return result.toList()
return roots
}
val Project.pillModuleName: String
+6 -2
View File
@@ -1,3 +1,8 @@
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
@@ -50,5 +55,4 @@ class ModuleContext(val project: PProject, val module: PModule) : PathContext {
}
}
fun String.withSlash() = if (this.endsWith("/")) this else (this + "/")
fun String.withoutSlash() = this.trimEnd('/')
fun String.withSlash() = if (this.endsWith("/")) this else ("$this/")
+184 -94
View File
@@ -1,3 +1,8 @@
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
@@ -10,71 +15,50 @@ import shadow.org.jdom2.*
import shadow.org.jdom2.output.Format
import shadow.org.jdom2.output.XMLOutputter
import java.io.File
class PillConfigurablePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.configurations.maybeCreate(EmbeddedComponents.CONFIGURATION_NAME)
project.extensions.create("pill", PillExtension::class.java)
}
}
import java.util.*
import kotlin.collections.HashMap
class JpsCompatiblePlugin : Plugin<Project> {
companion object {
private fun getDependencyMappers(projectLibraries: List<PLibrary>): List<DependencyMapper> {
val mappersForKotlinLibrariesExeptStdlib = projectLibraries
.filter { it.name != "kotlin-stdlib" }
.map { DependencyMapper.forProject(it.originalName) { MappedDependency(PDependency.Library(it.name)) } }
private val DIST_LIBRARIES = listOf(
":kotlin-annotations-jvm",
":kotlin-stdlib",
":kotlin-stdlib-jdk7",
":kotlin-stdlib-jdk8",
":kotlin-reflect",
":kotlin-test:kotlin-test-jvm",
":kotlin-test:kotlin-test-junit",
":kotlin-script-runtime",
":kotlin-serialization"
)
val disabledModuleMappers = listOf(
":kotlin-stdlib-common",
":core:builtins",
":kotlin-compiler",
":kotlin-compiler-embeddable",
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-annotations-common"
).map { DependencyMapper.forProject(it) { null } }
private val IGNORED_LIBRARIES = listOf(
// Libraries
":kotlin-stdlib-common",
":kotlin-reflect-api",
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-annotations-common",
// Other
":kotlin-compiler",
":kotlin-daemon-embeddable",
":kotlin-compiler-embeddable",
":kotlin-android-extensions",
":kotlin-scripting-compiler-embeddable",
":kotlin-scripting-compiler-impl-embeddable",
":kotlin-scripting-jvm-host-embeddable"
)
return listOf(
DependencyMapper.forProject(":kotlin-stdlib") {
MappedDependency(
PDependency.Library("kotlin-stdlib"),
listOf(PDependency.Library("annotations-13.0"))
)
},
DependencyMapper.forProject(":kotlin-test:kotlin-test-jvm") { MappedDependency(PDependency.Library("kotlin-test-jvm")) },
DependencyMapper.forProject(":kotlin-reflect-api") { MappedDependency(PDependency.Library("kotlin-reflect")) }
) + mappersForKotlinLibrariesExeptStdlib + disabledModuleMappers
}
private val MAPPED_LIBRARIES = mapOf(
":kotlin-reflect-api/java9" to ":kotlin-reflect/main"
)
fun getProjectLibraries(rootProject: Project): List<PLibrary> {
val distLibDir = File(rootProject.extra["distLibDir"].toString())
fun distJar(name: String) = File(rootProject.projectDir, "dist/kotlinc/lib/$name.jar")
val libraries = rootProject.allprojects
.mapNotNull { library ->
val libraryExtension = library.extensions.findByType(PillExtension::class.java)
?.takeIf { it.importAsLibrary }
?: return@mapNotNull null
val libraryPath = libraryExtension.libraryPath ?: distLibDir
val archivesBaseName = library.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName ?: library.name
fun List<File>.filterExisting() = filter { it.exists() }
PLibrary(
library.name,
classes = listOf(File(libraryPath, "$archivesBaseName.jar")).filterExisting(),
sources = listOf(File(libraryPath, "$archivesBaseName-sources.jar")).filterExisting(),
originalName = library.path
)
}
return libraries + PLibrary("annotations-13.0", classes = listOf(distJar("annotations-13.0")))
}
private val LIB_DIRECTORIES = listOf("dependencies", "dist")
}
override fun apply(project: Project) {
project.plugins.apply(PillConfigurablePlugin::class.java)
project.configurations.maybeCreate(EmbeddedComponents.CONFIGURATION_NAME)
project.extensions.create("pill", PillExtension::class.java)
// 'jpsTest' does not require the 'tests-jar' artifact
project.configurations.create("jpsTest")
@@ -129,13 +113,14 @@ class JpsCompatiblePlugin : Plugin<Project> {
return
}
val projectLibraries = getProjectLibraries(rootProject)
val dependencyMappers = getDependencyMappers(projectLibraries)
val parserContext = ParserContext(variant)
val parserContext = ParserContext(dependencyMappers, variant)
val dependencyPatcher = DependencyPatcher(rootProject)
val dependencyMappers = listOf(dependencyPatcher, ::attachPlatformSources, ::attachAsmSources)
val jpsProject = parse(rootProject, projectLibraries, parserContext)
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
val jpsProject = parse(rootProject, parserContext)
.mapDependencies(dependencyMappers)
.copy(libraries = dependencyPatcher.libraries)
val files = render(jpsProject)
@@ -143,7 +128,13 @@ class JpsCompatiblePlugin : Plugin<Project> {
removeJpsAndPillRunConfigurations()
removeAllArtifactConfigurations()
generateKotlinPluginArtifactFile(rootProject, dependencyMappers).write()
val artifactDependencyMapper = object : OpaqueDependencyMapper {
override fun map(dependency: PDependency): List<PDependency> {
return jpsProject.mapDependency(dependency, dependencyMappers)
}
}
generateKotlinPluginArtifactFile(rootProject, artifactDependencyMapper).write()
copyRunConfigurations()
setOptionsForDefaultJunitRunConfiguration(rootProject)
@@ -192,7 +183,7 @@ class JpsCompatiblePlugin : Plugin<Project> {
.replace("\$ADDITIONAL_IDEA_ARGS\$", additionalIdeaArgs)
}
runConfigurationsDir.listFiles()
(runConfigurationsDir.listFiles() ?: emptyArray())
.filter { it.extension == "xml" }
.map { it.name to substitute(it.readText()) }
.forEach { File(targetDir, it.first).writeText(it.second) }
@@ -260,11 +251,11 @@ class JpsCompatiblePlugin : Plugin<Project> {
}
if (options.none { it == "-ea" }) {
options += "-ea"
options = options + "-ea"
}
addOrReplaceOptionValue("idea.home.path", platformDirProjectRelative)
addOrReplaceOptionValue("ideaSdk.androidPlugin.path", platformDirProjectRelative + "/plugins/android/lib")
addOrReplaceOptionValue("ideaSdk.androidPlugin.path", "$platformDirProjectRelative/plugins/android/lib")
addOrReplaceOptionValue("use.jps", "true")
addOrReplaceOptionValue("kotlinVersion", project.rootProject.extra["kotlinVersion"].toString())
@@ -287,8 +278,9 @@ class JpsCompatiblePlugin : Plugin<Project> {
kotlinJunitConfiguration.applyJUnitTemplate()
val output = XMLOutputter().also {
@Suppress("UsePropertyAccessSyntax")
it.format = Format.getPrettyFormat().apply {
setEscapeStrategy { Verifier.isHighSurrogate(it) || it == '"' }
setEscapeStrategy { c -> Verifier.isHighSurrogate(c) || c == '"' }
setIndent(" ")
setTextMode(Format.TextMode.TRIM)
setOmitEncoding(false)
@@ -304,40 +296,138 @@ class JpsCompatiblePlugin : Plugin<Project> {
workspaceFile.writeText(postProcessedXml)
}
private fun attachPlatformSources(library: PLibrary): PLibrary {
val platformSourcesJar = File(platformDir, "../../../sources/intellij-$platformVersion-sources.jar")
private class DependencyPatcher(private val rootProject: Project): Function2<PProject, PDependency, List<PDependency>> {
private val mappings: Map<String, Optional<PLibrary>> = run {
val distLibDir = File(rootProject.extra["distLibDir"].toString())
val result = HashMap<String, Optional<PLibrary>>()
if (library.classes.any { it.startsWith(platformDir) || it.startsWith(intellijCoreDir) }) {
return library.attachSource(platformSourcesJar)
}
fun List<File>.filterExisting() = filter { it.exists() }
return library
}
private fun attachAsmSources(library: PLibrary): PLibrary {
val asmSourcesJar = File(platformDir, "../asm-shaded-sources/asm-src-$platformBaseNumber.jar")
val asmAllJar = File(platformDir, "lib/asm-all.jar")
if (library.classes.any { it == asmAllJar }) {
return library.attachSource(asmSourcesJar)
}
return library
}
private fun PProject.mapLibraries(vararg mappers: (PLibrary) -> PLibrary): PProject {
fun mapLibrary(root: POrderRoot): POrderRoot {
val dependency = root.dependency
if (dependency is PDependency.ModuleLibrary) {
val newLibrary = mappers.fold(dependency.library) { lib, mapper -> mapper(lib) }
return root.copy(dependency = dependency.copy(library = newLibrary))
for (path in DIST_LIBRARIES) {
val project = rootProject.findProject(path) ?: error("Project not found")
val archiveName = project.convention.findPlugin(BasePluginConvention::class.java)!!.archivesBaseName
val classesJars = listOf(File(distLibDir, "$archiveName.jar")).filterExisting()
val sourcesJars = listOf(File(distLibDir, "$archiveName-sources.jar")).filterExisting()
result["$path/main"] = Optional.of(PLibrary(archiveName, classesJars, sourcesJars, originalName = path))
}
return root
for (path in IGNORED_LIBRARIES) {
result["$path/main"] = Optional.empty<PLibrary>()
}
for ((old, new) in MAPPED_LIBRARIES) {
result[old] = result[new] ?: error("Mapped library $old -> $new not found")
}
return@run result
}
val libraries: List<PLibrary> = mappings.values.filter { it.isPresent }.map { it.get() }
override fun invoke(project: PProject, dependency: PDependency): List<PDependency> {
if (dependency !is PDependency.ModuleLibrary) {
return listOf(dependency)
}
val root = dependency.library.classes.singleOrNull() ?: return listOf(dependency)
val paths = project.artifacts[root.absolutePath]
if (paths == null) {
val projectDir = rootProject.projectDir
if (projectDir.isParent(root) && LIB_DIRECTORIES.none { File(projectDir, it).isParent(root) }) {
rootProject.logger.warn("Paths not found for root: ${root.absolutePath}")
return emptyList()
}
return listOf(dependency)
}
val result = mutableListOf<PDependency>()
for (path in paths) {
val module = project.modules.find { it.path == path }
if (module != null) {
result += PDependency.Module(module.name)
continue
}
val maybeLibrary = mappings[path]
if (maybeLibrary == null) {
rootProject.logger.warn("Library not found for root: ${root.absolutePath} ($path)")
continue
}
if (maybeLibrary.isPresent) {
result += PDependency.Library(maybeLibrary.get().name)
}
}
return result
}
private fun File.isParent(child: File): Boolean {
var parent = child.parentFile ?: return false
while (true) {
if (parent == this) {
return true
}
parent = parent.parentFile ?: return false
}
}
}
private fun attachPlatformSources(@Suppress("UNUSED_PARAMETER") project: PProject, dependency: PDependency): List<PDependency> {
if (dependency is PDependency.ModuleLibrary) {
val library = dependency.library
val platformSourcesJar = File(platformDir, "../../../sources/intellij-$platformVersion-sources.jar")
if (library.classes.any { it.startsWith(platformDir) || it.startsWith(intellijCoreDir) }) {
return listOf(dependency.copy(library = library.attachSource(platformSourcesJar)))
}
}
return listOf(dependency)
}
private fun attachAsmSources(@Suppress("UNUSED_PARAMETER") project: PProject, dependency: PDependency): List<PDependency> {
if (dependency is PDependency.ModuleLibrary) {
val library = dependency.library
val asmSourcesJar = File(platformDir, "../asm-shaded-sources/asm-src-$platformBaseNumber.jar")
val asmAllJar = File(platformDir, "lib/asm-all.jar")
if (library.classes.any { it == asmAllJar }) {
return listOf(dependency.copy(library = library.attachSource(asmSourcesJar)))
}
}
return listOf(dependency)
}
private fun PProject.mapDependencies(mappers: List<(PProject, PDependency) -> List<PDependency>>): PProject {
fun mapRoot(root: POrderRoot): List<POrderRoot> {
val dependencies = mapDependency(root.dependency, mappers)
return dependencies.map { root.copy(dependency = it) }
}
val modules = this.modules.map { module ->
val newOrderRoots = module.orderRoots.flatMap(::mapRoot).distinct()
module.copy(orderRoots = newOrderRoots)
}
val modules = this.modules.map { it.copy(orderRoots = it.orderRoots.map(::mapLibrary)) }
return this.copy(modules = modules)
}
private fun PProject.mapDependency(
dependency: PDependency,
mappers: List<(PProject, PDependency) -> List<PDependency>>
): List<PDependency> {
var dependencies = listOf(dependency)
for (mapper in mappers) {
val newDependencies = mutableListOf<PDependency>()
for (dep in dependencies) {
newDependencies += mapper(this, dep)
}
dependencies = newDependencies
}
return dependencies
}
}
+9 -9
View File
@@ -1,4 +1,9 @@
@file:Suppress("PackageDirectoryMismatch")
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch", "FunctionName")
package org.jetbrains.kotlin.pill
import java.io.File
@@ -49,12 +54,7 @@ private fun renderModule(project: PProject, module: PModule) = PFile(
xml("component", "name" to "TestModuleProperties", "production-module" to moduleForProductionSources.name)
}
val kotlinCompileOptionsList = module.contentRoots.flatMap { it.sourceRoots }.mapNotNull { it.kotlinOptions }
var kotlinCompileOptions = kotlinCompileOptionsList.firstOrNull()
for (otherOptions in kotlinCompileOptionsList.drop(1)) {
kotlinCompileOptions = kotlinCompileOptions?.intersect(otherOptions)
}
val kotlinCompileOptions = module.kotlinOptions
val pathContext = ModuleContext(project, module)
val platformVersion = (kotlinCompileOptions?.jvmTarget ?: "1.8")
@@ -100,10 +100,10 @@ private fun renderModule(project: PProject, module: PModule) = PFile(
) {
xml("exclude-output")
for (contentRoot in module.contentRoots) {
for (contentRoot in module.contentRoots.filter { it.path.exists() }) {
xml("content", pathContext.url(contentRoot.path)) {
for (sourceRoot in contentRoot.sourceRoots) {
var args = arrayOf(pathContext.url(sourceRoot.path))
var args = arrayOf(pathContext.url(sourceRoot.directory))
args += when (sourceRoot.kind) {
PSourceRoot.Kind.PRODUCTION -> ("isTestSource" to "false")
+6 -1
View File
@@ -1,4 +1,9 @@
@file:Suppress("PackageDirectoryMismatch")
/*
* 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.
*/
@file:Suppress("PackageDirectoryMismatch", "ClassName")
package org.jetbrains.kotlin.pill
import shadow.org.jdom2.Document
@@ -90,7 +90,7 @@ public class JUnit3RunnerWithInnersForJPS extends Runner implements Filterable,
String compilerXmlSourcePath = "compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml";
String jpsTargetDirectory = "out/production/kotlin.idea.main";
String pillTargetDirectory = "out/production/idea.src";
String pillTargetDirectory = "out/production/idea.main";
String baseDir = Files.exists(Paths.get(jpsTargetDirectory)) ? jpsTargetDirectory : pillTargetDirectory;
String compilerXmlTargetPath = baseDir + "/META-INF/extensions/compiler.xml";
@@ -1,7 +1,6 @@
description = 'Kotlin Test Annotations Common'
apply plugin: 'kotlin-platform-common'
apply plugin: 'pill-configurable'
configurePublishing(project)
@@ -10,10 +9,6 @@ dependencies {
testCompile project(":kotlin-test:kotlin-test-common")
}
pill {
importAsLibrary = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinCompile) {
kotlinOptions.freeCompilerArgs += "-Xallow-kotlin-package"
}
@@ -1,7 +1,6 @@
description = 'Kotlin Test Common'
apply plugin: 'kotlin-platform-common'
apply plugin: 'pill-configurable'
configurePublishing(project)
@@ -10,10 +9,6 @@ dependencies {
testCompile project(":kotlin-test:kotlin-test-annotations-common")
}
pill {
importAsLibrary = true
}
jar {
manifestAttributes(manifest, project, 'Test')
}
-5
View File
@@ -1,15 +1,10 @@
description = 'Kotlin Test JUnit'
apply plugin: 'kotlin-platform-jvm'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
pill {
importAsLibrary = true
}
dependencies {
expectedBy project(':kotlin-test:kotlin-test-annotations-common')
compile project(':kotlin-test:kotlin-test-jvm')
-5
View File
@@ -1,15 +1,10 @@
description = 'Kotlin Test'
apply plugin: 'kotlin-platform-jvm'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
pill {
importAsLibrary = true
}
def includeJava9 = BuildPropertiesKt.getKotlinBuildProperties(project).includeJava9
sourceSets {
-5
View File
@@ -19,17 +19,12 @@ buildscript {
plugins {
java
id("pill-configurable")
}
callGroovy("configureJavaOnlyJvm6Project", project)
publish()
pill {
importAsLibrary = true
}
val core = "$rootDir/core"
val relocatedCoreSrc = "$buildDir/core-relocated"
val libsDir = property("libsDir")
-5
View File
@@ -1,17 +1,12 @@
description = 'Kotlin Common Standard Library'
apply plugin: 'kotlin-platform-common'
apply plugin: 'pill-configurable'
configurePublishing(project)
def commonSrcDir = "../src"
def commonTestSrcDir = "../test"
pill {
importAsLibrary = true
}
sourceSets {
main {
kotlin {
-5
View File
@@ -1,16 +1,11 @@
description = 'Kotlin Standard Library JDK 7 extension'
apply plugin: 'kotlin'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
ext.javaHome = JDK_17
pill {
importAsLibrary = true
}
sourceSets {
main {
kotlin {
-5
View File
@@ -1,17 +1,12 @@
description = 'Kotlin Standard Library JDK 8 extension'
apply plugin: 'kotlin'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
ext.javaHome = JDK_18
ext.jvmTarget = "1.8"
pill {
importAsLibrary = true
}
dependencies {
compile project(':kotlin-stdlib')
compile project(':kotlin-stdlib-jdk7')
-5
View File
@@ -1,7 +1,6 @@
description = 'Kotlin Standard Library for JVM'
apply plugin: 'kotlin-platform-jvm'
apply plugin: 'pill-configurable'
archivesBaseName = 'kotlin-stdlib'
@@ -12,10 +11,6 @@ configurations {
distSources
}
pill {
importAsLibrary = true
}
sourceSets {
main {
java {
@@ -1,15 +1,10 @@
description = 'Kotlin annotations for JVM'
apply plugin: 'kotlin'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
pill {
importAsLibrary = true
}
sourceSets {
main {
java {
@@ -2,6 +2,7 @@ description = "kotlin-gradle-statistics"
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
@@ -1,15 +1,10 @@
description 'Kotlin Script Runtime'
apply plugin: 'kotlin'
apply plugin: 'pill-configurable'
configureJvm6Project(project)
configurePublishing(project)
pill {
importAsLibrary = true
}
dependencies {
compileOnly kotlinStdlib()
}
-1
View File
@@ -2,7 +2,6 @@ description = "Kotlin JPS plugin"
plugins {
java
id("pill-configurable")
}
val projectsToShadow = listOf(