Pill: Introduce pill{} extension to set extended Pill configuration
Also introduce the flavor concept which allows to specify what part of Kotlin project should be imported.
This commit is contained in:
@@ -33,9 +33,9 @@ plugins {
|
||||
|
||||
gradlePlugin {
|
||||
(plugins) {
|
||||
"jps-compatible-base" {
|
||||
id = "jps-compatible-base"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatibleBasePlugin"
|
||||
"pill-configurable" {
|
||||
id = "pill-configurable"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
|
||||
}
|
||||
"jps-compatible" {
|
||||
id = "jps-compatible"
|
||||
|
||||
@@ -33,9 +33,9 @@ plugins {
|
||||
|
||||
gradlePlugin {
|
||||
(plugins) {
|
||||
"jps-compatible-base" {
|
||||
id = "jps-compatible-base"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatibleBasePlugin"
|
||||
"pill-configurable" {
|
||||
id = "pill-configurable"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
|
||||
}
|
||||
"jps-compatible" {
|
||||
id = "jps-compatible"
|
||||
|
||||
@@ -12,4 +12,4 @@ class DependencyMapper(
|
||||
|
||||
class MappedDependency(val main: PDependency, val deferred: List<PDependency> = emptyList())
|
||||
|
||||
class ParserContext(val dependencyMappers: List<DependencyMapper>)
|
||||
class ParserContext(val dependencyMappers: List<DependencyMapper>, val variant: PillExtension.Variant)
|
||||
@@ -0,0 +1,32 @@
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import java.io.File
|
||||
|
||||
open class PillExtension {
|
||||
enum class Variant {
|
||||
// Default variant (./gradlew pill)
|
||||
BASE() { override val includes = setOf(BASE) },
|
||||
|
||||
// Full variant (./gradlew pill -Dpill.variant=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>() },
|
||||
|
||||
// 'BASE' if the "jps-compatible" plugin is applied, 'NONE' otherwise
|
||||
DEFAULT() { override val includes = emptySet<Variant>() };
|
||||
|
||||
abstract val includes: Set<Variant>
|
||||
}
|
||||
|
||||
open var variant: Variant = Variant.DEFAULT
|
||||
|
||||
open var importAsLibrary: Boolean = false
|
||||
|
||||
open var libraryPath: File? = null
|
||||
set(v) {
|
||||
importAsLibrary = true
|
||||
field = v
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ fun generateKotlinPluginArtifactFile(rootProject: Project): PFile {
|
||||
.findByName(EmbeddedComponents.CONFIGURATION_NAME)?.resolvedConfiguration
|
||||
|
||||
if (embeddedComponents != null) {
|
||||
for ((_, _, dependency) in listOf(embeddedComponents to Scope.COMPILE).collectDependencies()) {
|
||||
for ((_, dependency) in listOf(embeddedComponents to Scope.COMPILE).collectDependencies()) {
|
||||
if (dependency.configuration == "runtimeElements") {
|
||||
archiveForJar.add(ModuleOutput(dependency.moduleName + ".src"))
|
||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.internal.HasConvention
|
||||
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
|
||||
|
||||
@@ -43,11 +44,7 @@ data class PSourceRoot(
|
||||
val path: File,
|
||||
val kind: Kind
|
||||
) {
|
||||
enum class Kind {
|
||||
PRODUCTION, TEST, RESOURCES, TEST_RESOURCES;
|
||||
|
||||
val isResources get() = this == RESOURCES || this == TEST_RESOURCES
|
||||
}
|
||||
enum class Kind { PRODUCTION, TEST, RESOURCES, TEST_RESOURCES }
|
||||
}
|
||||
|
||||
data class POrderRoot(
|
||||
@@ -83,8 +80,14 @@ fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext):
|
||||
error("$project is not a root project")
|
||||
}
|
||||
|
||||
fun Project.matchesSelectedVariant(): Boolean {
|
||||
val extension = this.extensions.findByType(PillExtension::class.java) ?: return true
|
||||
val projectVariant = extension.variant.takeUnless { it == Variant.DEFAULT } ?: Variant.BASE
|
||||
return projectVariant in context.variant.includes
|
||||
}
|
||||
|
||||
val modules = project.allprojects
|
||||
.filter { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) }
|
||||
.filter { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) && it.matchesSelectedVariant() }
|
||||
.flatMap { parseModules(it) }
|
||||
|
||||
return PProject("Kotlin", project.projectDir, modules, libraries)
|
||||
@@ -162,8 +165,8 @@ private fun ParserContext.parseModules(project: Project): List<PModule> {
|
||||
}
|
||||
}
|
||||
|
||||
val mainModuleFileRelativePath = when {
|
||||
project == project.rootProject -> File(project.rootProject.projectDir, project.name + ".iml")
|
||||
val mainModuleFileRelativePath = when (project) {
|
||||
project.rootProject -> File(project.rootProject.projectDir, project.name + ".iml")
|
||||
else -> getModuleFile()
|
||||
}
|
||||
|
||||
@@ -268,7 +271,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
return configurations
|
||||
}
|
||||
|
||||
nextDependency@ for ((configuration, scope, dependency) in collectConfigurations().collectDependencies()) {
|
||||
nextDependency@ for ((scope, dependency) in collectConfigurations().collectDependencies()) {
|
||||
for (mapper in dependencyMappers) {
|
||||
if (dependency.moduleGroup == mapper.group
|
||||
&& dependency.moduleName == mapper.module
|
||||
@@ -277,12 +280,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
val mappedDependency = mapper.mapping(dependency)
|
||||
|
||||
if (mappedDependency != null) {
|
||||
val orderRoot = POrderRoot(mappedDependency.main, scope)
|
||||
if (mappedDependency.main is PDependency.Module) {
|
||||
mainRoots += orderRoot
|
||||
} else {
|
||||
mainRoots += orderRoot
|
||||
}
|
||||
mainRoots += POrderRoot(mappedDependency.main, scope)
|
||||
|
||||
for (deferredDep in mappedDependency.deferred) {
|
||||
deferredRoots += POrderRoot(deferredDep, scope)
|
||||
@@ -293,10 +291,10 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
if (dependency.configuration == "runtimeElements" && scope != Scope.TEST) {
|
||||
mainRoots += POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
|
||||
mainRoots += if (dependency.configuration == "runtimeElements" && scope != Scope.TEST) {
|
||||
POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
|
||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
||||
mainRoots += POrderRoot(
|
||||
POrderRoot(
|
||||
PDependency.Module(dependency.moduleName + ".test"),
|
||||
scope,
|
||||
isProductionOnTestDependency = true
|
||||
@@ -304,7 +302,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
} else {
|
||||
val classes = dependency.moduleArtifacts.map { it.file }
|
||||
val library = PLibrary(dependency.moduleName, classes)
|
||||
mainRoots += POrderRoot(PDependency.ModuleLibrary(library), scope)
|
||||
POrderRoot(PDependency.ModuleLibrary(library), scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +312,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
|
||||
private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
|
||||
val dependenciesByScope = roots.groupBy { it.scope }.mapValues { it.value.mapTo(mutableSetOf()) { it.dependency } }
|
||||
fun depenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
|
||||
fun dependenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
|
||||
|
||||
val result = mutableSetOf<POrderRoot>()
|
||||
for (root in roots.distinct()) {
|
||||
@@ -325,16 +323,16 @@ private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
|
||||
continue
|
||||
}
|
||||
|
||||
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in depenciesFor(Scope.COMPILE)) {
|
||||
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in dependenciesFor(Scope.COMPILE)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (scope == Scope.PROVIDED && dependency in depenciesFor(Scope.RUNTIME)) {
|
||||
if (scope == Scope.PROVIDED && dependency in dependenciesFor(Scope.RUNTIME)) {
|
||||
result += POrderRoot(dependency, Scope.COMPILE)
|
||||
continue
|
||||
}
|
||||
|
||||
if (scope == Scope.RUNTIME && dependency in depenciesFor(Scope.PROVIDED)) {
|
||||
if (scope == Scope.RUNTIME && dependency in dependenciesFor(Scope.PROVIDED)) {
|
||||
result += POrderRoot(dependency, Scope.COMPILE)
|
||||
continue
|
||||
}
|
||||
@@ -345,7 +343,7 @@ private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
data class DependencyInfo(val configuration: ResolvedConfiguration, val scope: Scope, val dependency: ResolvedDependency)
|
||||
data class DependencyInfo(val scope: Scope, val dependency: ResolvedDependency)
|
||||
|
||||
fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<DependencyInfo> {
|
||||
val dependencies = mutableListOf<DependencyInfo>()
|
||||
@@ -355,7 +353,7 @@ fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<Depende
|
||||
|
||||
for ((configuration, scope) in this) {
|
||||
for (dependency in configuration.firstLevelModuleDependencies) {
|
||||
unprocessed += DependencyInfo(configuration, scope, dependency)
|
||||
unprocessed += DependencyInfo(scope, dependency)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +369,7 @@ fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<Depende
|
||||
continue
|
||||
}
|
||||
|
||||
unprocessed += DependencyInfo(info.configuration, info.scope, child)
|
||||
unprocessed += DependencyInfo(info.scope, child)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ interface PathContext {
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectContext private constructor(val projectDir: File) : PathContext {
|
||||
class ProjectContext private constructor(private val projectDir: File) : PathContext {
|
||||
constructor(project: PProject) : this(project.rootDirectory)
|
||||
constructor(project: Project) : this(project.projectDir)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
@@ -10,16 +11,15 @@ import shadow.org.jdom2.output.Format
|
||||
import shadow.org.jdom2.output.XMLOutputter
|
||||
import java.io.File
|
||||
|
||||
class JpsCompatibleBasePlugin : Plugin<Project> {
|
||||
class PillConfigurablePlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.configurations.create(EmbeddedComponents.CONFIGURATION_NAME)
|
||||
project.extensions.create("pill", PillExtension::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class JpsCompatiblePlugin : Plugin<Project> {
|
||||
companion object {
|
||||
private const val JPS_LIBRARY_PATH = "jpsLibraryPath"
|
||||
|
||||
private fun mapper(module: String, vararg configurations: String): DependencyMapper {
|
||||
return DependencyMapper("org.jetbrains.kotlin", module, *configurations) { MappedDependency(PDependency.Library(module)) }
|
||||
}
|
||||
@@ -47,21 +47,24 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
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")
|
||||
fun projectFile(path: String) = File(rootProject.projectDir, path)
|
||||
|
||||
val libraries = rootProject.allprojects
|
||||
.filter { it.extra.has(JPS_LIBRARY_PATH) }
|
||||
.map { library ->
|
||||
val libraryPath = library.extra.get(JPS_LIBRARY_PATH).toString()
|
||||
.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()
|
||||
classes = listOf(File(libraryPath, "$archivesBaseName.jar")).filterExisting(),
|
||||
sources = listOf(File(libraryPath, "$archivesBaseName-sources.jar")).filterExisting()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -70,7 +73,7 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
}
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.plugins.apply(JpsCompatibleBasePlugin::class.java)
|
||||
project.plugins.apply(PillConfigurablePlugin::class.java)
|
||||
// 'jpsTest' does not require the 'tests-jar' artifact
|
||||
project.configurations.create("jpsTest")
|
||||
|
||||
@@ -103,8 +106,22 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
private fun pill(rootProject: Project) {
|
||||
initEnvironment(rootProject)
|
||||
|
||||
val variantOptionValue = System.getProperty("pill.variant", "base").toUpperCase()
|
||||
val variant = PillExtension.Variant.values().firstOrNull { it.name == variantOptionValue }
|
||||
?: run {
|
||||
rootProject.logger.error("Invalid variant name: $variantOptionValue")
|
||||
return
|
||||
}
|
||||
|
||||
rootProject.logger.lifecycle("Pill: Setting up project for the '${variant.name.toLowerCase()}' variant...")
|
||||
|
||||
if (variant == PillExtension.Variant.NONE || variant == PillExtension.Variant.DEFAULT) {
|
||||
rootProject.logger.error("'none' and 'default' should not be passed as a Pill variant property value")
|
||||
return
|
||||
}
|
||||
|
||||
val projectLibraries = getProjectLibraries(rootProject)
|
||||
val parserContext = ParserContext(getDependencyMappers(projectLibraries))
|
||||
val parserContext = ParserContext(getDependencyMappers(projectLibraries), variant)
|
||||
|
||||
val jpsProject = parse(rootProject, projectLibraries, parserContext)
|
||||
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
|
||||
|
||||
@@ -98,7 +98,6 @@ private fun renderModule(project: PProject, module: PModule) = PFile(
|
||||
"name" to dependency.name,
|
||||
"level" to "project"
|
||||
)
|
||||
else -> error("Unsupported dependency type: $dependency")
|
||||
}
|
||||
|
||||
if (dependency is PDependency.Module && orderRoot.isProductionOnTestDependency) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import shadow.org.jdom2.Element
|
||||
import shadow.org.jdom2.output.Format
|
||||
import shadow.org.jdom2.output.XMLOutputter
|
||||
|
||||
class xml(val name: String, vararg val args: Pair<String, Any>, block: xml.() -> Unit = {}) {
|
||||
class xml(val name: String, private vararg val args: Pair<String, Any>, block: xml.() -> Unit = {}) {
|
||||
private companion object {
|
||||
fun makeXml(name: String, vararg args: Pair<String, Any>, block: xml.() -> Unit = {}): xml {
|
||||
return xml(name, *args, block = block)
|
||||
|
||||
@@ -3,6 +3,7 @@ import java.io.File
|
||||
|
||||
plugins {
|
||||
base
|
||||
id("pill-configurable")
|
||||
}
|
||||
|
||||
val baseProtobuf by configurations.creating
|
||||
@@ -18,7 +19,9 @@ val renamedSources = "$buildDir/renamedSrc/"
|
||||
val outputJarsPath = "$buildDir/libs"
|
||||
val artifactBaseName = "protobuf-java-relocated"
|
||||
|
||||
val jpsLibraryPath by extra(outputJarsPath)
|
||||
pill {
|
||||
libraryPath = File(outputJarsPath)
|
||||
}
|
||||
|
||||
setProperty("archivesBaseName", "$artifactBaseName-$protobufVersion")
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
description = 'Kotlin Test JUnit'
|
||||
|
||||
apply plugin: 'kotlin-platform-jvm'
|
||||
apply plugin: 'pill-configurable'
|
||||
|
||||
configureJvm6Project(project)
|
||||
configureDist(project)
|
||||
configurePublishing(project)
|
||||
|
||||
project.ext["jpsLibraryPath"] = rootProject.distLibDir
|
||||
pill {
|
||||
importAsLibrary = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
expectedBy project(':kotlin-test:kotlin-test-annotations-common')
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
description = 'Kotlin Test'
|
||||
|
||||
apply plugin: 'kotlin-platform-jvm'
|
||||
apply plugin: 'pill-configurable'
|
||||
|
||||
configureJvm6Project(project)
|
||||
configureDist(project)
|
||||
configurePublishing(project)
|
||||
|
||||
project.ext["jpsLibraryPath"] = rootProject.distLibDir
|
||||
pill {
|
||||
importAsLibrary = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
java9
|
||||
|
||||
@@ -3,6 +3,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf
|
||||
import org.jetbrains.kotlin.pill.PillExtension
|
||||
import proguard.gradle.ProGuardTask
|
||||
import shadow.org.apache.tools.zip.ZipEntry
|
||||
import shadow.org.apache.tools.zip.ZipOutputStream
|
||||
@@ -12,12 +13,17 @@ import java.io.DataOutputStream
|
||||
|
||||
description = "Kotlin Full Reflection Library"
|
||||
|
||||
plugins { java }
|
||||
plugins {
|
||||
java
|
||||
id("pill-configurable")
|
||||
}
|
||||
|
||||
callGroovy("configureJavaOnlyJvm6Project", this)
|
||||
publish()
|
||||
|
||||
val jpsLibraryPath by extra(rootProject.extra["distLibDir"])
|
||||
pill {
|
||||
importAsLibrary = true
|
||||
}
|
||||
|
||||
val core = "$rootDir/core"
|
||||
val annotationsSrc = "$buildDir/annotations"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
description = 'Kotlin Standard Library for JVM'
|
||||
|
||||
apply plugin: 'kotlin-platform-jvm'
|
||||
apply plugin: 'pill-configurable'
|
||||
|
||||
archivesBaseName = 'kotlin-stdlib'
|
||||
|
||||
@@ -8,7 +9,9 @@ configureJvm6Project(project)
|
||||
configureDist(project)
|
||||
configurePublishing(project)
|
||||
|
||||
project.ext["jpsLibraryPath"] = rootProject.distLibDir
|
||||
pill {
|
||||
importAsLibrary = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
annotations {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'jps-compatible'
|
||||
|
||||
configureJvmProject(project)
|
||||
configurePublishing(project)
|
||||
@@ -8,6 +9,10 @@ repositories {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
pill {
|
||||
variant = "FULL"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':kotlin-stdlib')
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ apply plugin: 'java-gradle-plugin'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'org.jetbrains.dokka'
|
||||
apply plugin: 'jps-compatible'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
@@ -26,6 +27,10 @@ configurations {
|
||||
agp25CompileOnly
|
||||
}
|
||||
|
||||
pill {
|
||||
variant = "FULL"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':kotlin-gradle-plugin-api')
|
||||
compileOnly project(':compiler')
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
description 'Kotlin Script Runtime'
|
||||
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'pill-configurable'
|
||||
|
||||
configureJvm6Project(project)
|
||||
configureDist(project)
|
||||
configurePublishing(project)
|
||||
|
||||
project.ext["jpsLibraryPath"] = rootProject.distLibDir
|
||||
pill {
|
||||
importAsLibrary = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly project(path: ':kotlin-stdlib', configuration: 'distJar')
|
||||
|
||||
@@ -4,7 +4,7 @@ description = "Kotlin JPS plugin"
|
||||
|
||||
plugins {
|
||||
`java-base`
|
||||
id("jps-compatible-base")
|
||||
id("pill-configurable")
|
||||
}
|
||||
|
||||
val projectsToShadow = listOf(
|
||||
|
||||
Reference in New Issue
Block a user