diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c559f..cc955e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,17 +6,59 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security + +## [0.7.0] + +### Added +- Changelog plugin automatically applied to `project`. +- Feature matrix and Readme generation task for a `project` plugin. +- Add `binary-compatibility-validator` to the `project` plugin. +- Separate `yamlKt` serialization target +- Moved all logic to a common plugin, leaving only proxies for platform plugins + +### Changed +- Remove node plugin. Node binaries should be turned on manually. +- Use default webpack distribution path. +- `ru.mipt.npm.base` -> `ru.mipt.npm.project`. +- Move publishing out of general extension and apply it to project plugin instead. +- Platform plugins are now simple references to common plugin +- FX configuration moved to extension +- Moved internals to internals + +### Deprecated +- Support of `kaml` and `snake-yaml` in favor of `yamlKt` +- Publish plugin + +### Removed +- `useDokka` method. Documentation jar should be added manually if needed. + + +### Fixed + +### Security +## [0.6.0] ### Added - Migrate to kotlin 1.4.0 -- Separate Native (current platform) and nodeJs plugins +- Separate Native (current platform) and nodeJs plugins. - Add `application()` toggle in plugin configuration to produce binaries on JS and applicaion plugin on jvm. -- Add `publish` to expose publishing configuration +- Add `publish` to expose publishing configuration. ### Changed --Publishing in bintray now is automatic +-Publishing in bintray now is automatic. ## [0.5.2] ### Added -- Copy resources for jvm modules and jvm source sets in mpp \ No newline at end of file +- Copy resources for jvm modules and jvm source sets in mpp. \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 07fa8c6..1a5dbd4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,11 +2,11 @@ plugins { `java-gradle-plugin` `kotlin-dsl` `maven-publish` - id("org.jetbrains.changelog") version "0.4.0" + id("org.jetbrains.changelog") version "0.6.2" } group = "ru.mipt.npm" -version = "0.6.0" +version = "0.7.1" repositories { gradlePluginPortal() @@ -16,7 +16,7 @@ repositories { maven("https://dl.bintray.com/kotlin/kotlin-dev") } -val kotlinVersion = "1.4.10" +val kotlinVersion = "1.4.21" java { targetCompatibility = JavaVersion.VERSION_1_8 @@ -26,18 +26,27 @@ java { dependencies { implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion") - implementation("org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.14.4") - implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.4.0") - implementation("org.jetbrains.dokka:dokka-base:1.4.0") + implementation("org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.15.0") + implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.4.20") + implementation("org.jetbrains.dokka:dokka-base:1.4.20") + implementation("org.jetbrains.intellij.plugins:gradle-changelog-plugin:0.6.2") + implementation("org.jetbrains.kotlinx:binary-compatibility-validator:0.2.4") } gradlePlugin { plugins { - create("kscience.base"){ - id = "ru.mipt.npm.base" - description = "The basic plugin that does not do anything but loading classpath, versions and extensions" - implementationClass = "ru.mipt.npm.gradle.KScienceBasePlugin" + create("kscience.common"){ + id = "ru.mipt.npm.kscience" + description = "The generalized kscience plugin that works in conjunction with any kotlin plugin" + implementationClass = "ru.mipt.npm.gradle.KScienceCommonPlugin" } + + create("kscience.project"){ + id = "ru.mipt.npm.project" + description = "The root plugin for multimodule project infrastructure" + implementationClass = "ru.mipt.npm.gradle.KScienceProjectPlugin" + } + create("kscience.publish") { id = "ru.mipt.npm.publish" description = "The publication plugin for bintray and github" @@ -70,7 +79,7 @@ gradlePlugin { create("kscience.node") { id = "ru.mipt.npm.node" - description = "NodeJS target for kotlin-mpp and kotlin-js" + description = "Additional nodejs target to be use alongside mpp" implementationClass = "ru.mipt.npm.gradle.KScienceNodePlugin" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 12d38de..4d9ca16 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceBasePlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceBasePlugin.kt deleted file mode 100644 index 341be36..0000000 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceBasePlugin.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ru.mipt.npm.gradle - -import org.gradle.api.Plugin -import org.gradle.api.Project - -/** - * Apply extension and repositories - */ -open class KScienceBasePlugin : Plugin { - override fun apply(target: Project): Unit = target.run{ - registerKScienceExtension() - } -} \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceCommonPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceCommonPlugin.kt new file mode 100644 index 0000000..405b3a5 --- /dev/null +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceCommonPlugin.kt @@ -0,0 +1,147 @@ +package ru.mipt.npm.gradle + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import ru.mipt.npm.gradle.internal.applyRepos +import ru.mipt.npm.gradle.internal.applySettings +import ru.mipt.npm.gradle.internal.fromDependencies + +open class KScienceCommonPlugin : Plugin { + override fun apply(project: Project): Unit = project.run { + //Common configuration + registerKScienceExtension() + repositories.applyRepos() + + // apply dokka for all projects + if (!plugins.hasPlugin("org.jetbrains.dokka")) { + plugins.apply("org.jetbrains.dokka") + } + + //Configuration for K-JVM plugin + pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { + //logger.info("Applying KScience configuration for JVM project") + configure { + explicitApiWarning() + + sourceSets["main"].apply { + languageSettings.applySettings() + } + + sourceSets["test"].apply { + languageSettings.applySettings() + dependencies { + implementation(kotlin("test-junit5")) + implementation("org.junit.jupiter:junit-jupiter:5.6.1") + } + } + } + } + + pluginManager.withPlugin("org.jetbrains.kotlin.js") { + //logger.info("Applying KScience configuration for JS project") + configure { + explicitApiWarning() + + js(IR) { + browser() + } + + sourceSets["main"].apply { + languageSettings.applySettings() + } + + sourceSets["test"].apply { + languageSettings.applySettings() + dependencies { + implementation(kotlin("test-js")) + } + } + } + + (tasks.findByName("processResources") as? Copy)?.apply { + fromDependencies("runtimeClasspath") + } + + } + + pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { + configure { + explicitApiWarning() + + jvm { + compilations.all { + kotlinOptions { +// useIR = true + jvmTarget = KScienceVersions.JVM_TARGET.toString() + } + } + } + + js(IR) { + browser() + } + + sourceSets.invoke { + val commonMain by getting + val commonTest by getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val jvmMain by getting + val jvmTest by getting { + dependencies { + implementation(kotlin("test-junit5")) + implementation("org.junit.jupiter:junit-jupiter:5.6.1") + } + } + val jsMain by getting + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } + + afterEvaluate { + targets.all { + sourceSets.all { + languageSettings.applySettings() + } + } + } + + (tasks.findByName("jsProcessResources") as? Copy)?.apply { + fromDependencies("jsRuntimeClasspath") + } + } + } + + afterEvaluate { + extensions.findByType()?.apply { + targetCompatibility = KScienceVersions.JVM_TARGET + } + + tasks.apply { + withType { + kotlinOptions { + // useIR = true + jvmTarget = KScienceVersions.JVM_TARGET.toString() + } + } + withType { + useJUnitPlatform() + } + } + } + } +} diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceExtension.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceExtension.kt index 0a19219..e7e3d59 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceExtension.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceExtension.kt @@ -1,11 +1,44 @@ package ru.mipt.npm.gradle import org.gradle.api.Project -import org.gradle.kotlin.dsl.* +import org.gradle.api.plugins.ApplicationPlugin +import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import ru.mipt.npm.gradle.internal.configurePublishing +import ru.mipt.npm.gradle.internal.defaultPlatform +import ru.mipt.npm.gradle.internal.useCommonDependency +import ru.mipt.npm.gradle.internal.useFx + +enum class FXModule(val artifact: String, vararg val dependencies: FXModule) { + BASE("javafx-base"), + GRAPHICS("javafx-graphics", BASE), + CONTROLS("javafx-controls", GRAPHICS, BASE), + FXML("javafx-fxml", BASE), + MEDIA("javafx-media", GRAPHICS, BASE), + SWING("javafx-swing", GRAPHICS, BASE), + WEB("javafx-web", CONTROLS, GRAPHICS, BASE) +} + +enum class FXPlatform(val id: String) { + WINDOWS("win"), + LINUX("linux"), + MAC("mac") +} + +enum class DependencyConfiguration { + API, + IMPLEMENTATION, + COMPILE_ONLY +} + +enum class DependencySourceSet(val setName: String, val suffix: String) { + MAIN("main", "Main"), + TEST("test", "Test") +} + class KScienceExtension(val project: Project) { @@ -59,9 +92,12 @@ class KScienceExtension(val project: Project) { ) } - fun useDokka(): Unit = project.run { - plugins.apply("org.jetbrains.dokka") - } + fun useFx( + vararg modules: FXModule, + configuration: DependencyConfiguration = DependencyConfiguration.COMPILE_ONLY, + version: String = "14", + platform: FXPlatform = defaultPlatform + ) = project.useFx(modules.toList(), configuration, version, platform) /** * Mark this module as an application module. JVM application should be enabled separately @@ -70,46 +106,29 @@ class KScienceExtension(val project: Project) { project.extensions.findByType()?.apply { explicitApi = null } + project.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { - project.plugins.apply("org.gradle.application") + project.plugins.apply(ApplicationPlugin::class.java) } + project.extensions.findByType()?.apply { js { binaries.executable() } } + project.extensions.findByType()?.apply { js { binaries.executable() } - (targets.findByName("native") as? KotlinNativeTarget)?.apply { - binaries.executable() + targets.filterIsInstance().forEach { + it.binaries.executable() } } - } - /** - * Activate publishing and configure it - */ - fun publish(block: Publishing.() -> Unit = {}) = Publishing().apply(block) - - inner class Publishing { - init { - if (project.plugins.findPlugin(KSciencePublishPlugin::class) == null) { - project.plugins.apply(KSciencePublishPlugin::class) - } - } - - var githubOrg: String? by project.extra - var githubProject: String? by project.extra - var spaceRepo: String? by project.extra - var spaceUser: String? by project.extra - var spaceToken: String? by project.extra - var bintrayOrg: String? by project.extra - var bintrayUser: String? by project.extra - var bintrayApiKey: String? by project.extra - var bintrayRepo: String? by project.extra + fun publish() { + project.configurePublishing() } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceJSPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceJSPlugin.kt index aa1a822..75de0f4 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceJSPlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceJSPlugin.kt @@ -2,62 +2,15 @@ package ru.mipt.npm.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.tasks.Copy -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.get -import org.gradle.kotlin.dsl.getValue -import org.gradle.kotlin.dsl.getting -import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.gradle.kotlin.dsl.apply open class KScienceJSPlugin : Plugin { override fun apply(project: Project): Unit = project.run { - plugins.apply("org.jetbrains.kotlin.js") - registerKScienceExtension() - - repositories.applyRepos() - - configure { - explicitApiWarning() - js(IR) { - browser { - webpackTask { - outputFileName = "main.bundle.js" - } - distribution { - directory = project.jsDistDirectory - } - } - } - sourceSets["main"].apply { - languageSettings.applySettings() - - dependencies { - api(kotlin("stdlib-js")) - } - } - - sourceSets["test"].apply { - languageSettings.applySettings() - dependencies { - implementation(kotlin("test-js")) - } - } - } - - tasks.apply { - - val processResources by getting(Copy::class) - processResources.copyJSResources(configurations["runtimeClasspath"]) - - findByName("jsBrowserDistribution")?.apply { - doLast { - val indexFile = project.jsDistDirectory.resolve("index.html") - if (indexFile.exists()) { - println("Run JS distribution at: ${indexFile.canonicalPath}") - } - } - } + if (plugins.findPlugin("org.jetbrains.kotlin.js") == null) { + pluginManager.apply("org.jetbrains.kotlin.js") + } else { + logger.info("Kotlin JS plugin is already present") } + plugins.apply(KScienceCommonPlugin::class) } - } \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceJVMPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceJVMPlugin.kt index 0c6d26e..f496817 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceJVMPlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceJVMPlugin.kt @@ -2,86 +2,15 @@ package ru.mipt.npm.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.tasks.Copy -import org.gradle.api.tasks.bundling.Jar -import org.gradle.api.tasks.testing.Test -import org.gradle.kotlin.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.gradle.kotlin.dsl.apply open class KScienceJVMPlugin : Plugin { override fun apply(project: Project): Unit = project.run { - plugins.apply("org.jetbrains.kotlin.jvm") - registerKScienceExtension() - - repositories.applyRepos() - - extensions.findByType()?.apply { - targetCompatibility = KScienceVersions.JVM_TARGET - } - - tasks.withType { - kotlinOptions { -// useIR = true - jvmTarget = KScienceVersions.JVM_TARGET.toString() - } - } - - configure { - explicitApiWarning() - val sourceSet = sourceSets["main"].apply { - languageSettings.applySettings() - } - - sourceSets["test"].apply { - languageSettings.applySettings() - dependencies { - implementation(kotlin("test-junit5")) - implementation("org.junit.jupiter:junit-jupiter:5.6.1") - } - } - - val sourcesJar by tasks.registering(Jar::class) { - archiveClassifier.set("sources") - from(sourceSet.kotlin.srcDirs.first()) - } - - pluginManager.withPlugin("maven-publish") { - - configure { - publications { - register("jvm", MavenPublication::class) { - from(components["java"]) - artifact(sourcesJar.get()) - } - } - } - -// pluginManager.withPlugin("org.jetbrains.dokka") { -// logger.info("Adding dokka functionality to project ${project.name}") - -// val dokkaHtml by tasks.getting(DokkaTask::class){ -// dokkaSourceSets { -// configureEach { -// jdkVersion.set(11) -// } -// } -// } -// } - } - } - - tasks.apply { - withType() { - useJUnitPlatform() - } - - val processResources by getting(Copy::class) - processResources.copyJVMResources(configurations["runtimeClasspath"]) + if (plugins.findPlugin("org.jetbrains.kotlin.jvm") == null) { + pluginManager.apply("org.jetbrains.kotlin.jvm") + } else { + logger.info("Kotlin JVM plugin is already present") } + plugins.apply(KScienceCommonPlugin::class) } - } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceMPPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceMPPlugin.kt index 85baece..167d9b9 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceMPPlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceMPPlugin.kt @@ -2,116 +2,15 @@ package ru.mipt.npm.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.tasks.Copy -import org.gradle.api.tasks.testing.Test -import org.gradle.kotlin.dsl.* -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.gradle.kotlin.dsl.apply open class KScienceMPPlugin : Plugin { override fun apply(project: Project): Unit = project.run { - plugins.apply("org.jetbrains.kotlin.multiplatform") - registerKScienceExtension() - repositories.applyRepos() - - configure { - explicitApiWarning() - - jvm { - compilations.all { - kotlinOptions { -// useIR = true - jvmTarget = KScienceVersions.JVM_TARGET.toString() - } - } - } - - js(IR) { - browser { - webpackTask { - outputFileName = "main.bundle.js" - } - distribution { - directory = project.jsDistDirectory - } - } - } - - sourceSets.invoke { - val commonMain by getting - val commonTest by getting { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } - } - val jvmMain by getting - val jvmTest by getting { - dependencies { - implementation(kotlin("test-junit5")) - implementation("org.junit.jupiter:junit-jupiter:5.6.1") - } - } - val jsMain by getting - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - } - - afterEvaluate { - targets.all { - sourceSets.all { - languageSettings.applySettings() - } - } - } - -// pluginManager.withPlugin("org.jetbrains.dokka") { -// logger.info("Adding dokka functionality to project ${this@run.name}") -// -// val dokkaHtml by tasks.getting(DokkaTask::class) { -// dokkaSourceSets { -// register("commonMain") { -// displayName = "common" -// platform = "common" -// } -// register("jvmMain") { -// displayName = "jvm" -// platform = "jvm" -// } -// register("jsMain") { -// displayName = "js" -// platform = "js" -// } -// configureEach { -// jdkVersion = 11 -// } -// } -// } -// } - - tasks.apply { - withType() { - useJUnitPlatform() - } - - val jsProcessResources by getting(Copy::class) - jsProcessResources.copyJSResources(configurations["jsRuntimeClasspath"]) - - val jvmProcessResources by getting(Copy::class) - jvmProcessResources.copyJVMResources(configurations["jvmRuntimeClasspath"]) - - findByName("jsBrowserDistribution")?.apply { - doLast { - val indexFile = project.jsDistDirectory.resolve("index.html") - if (indexFile.exists()) { - println("Run JS distribution at: ${indexFile.canonicalPath}") - } - } - } - } - + if (plugins.findPlugin("org.jetbrains.kotlin.multiplatform") == null) { + pluginManager.apply("org.jetbrains.kotlin.multiplatform") + } else { + logger.info("Kotlin MPP plugin is already present") } - } + plugins.apply(KScienceCommonPlugin::class) + } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceNativePlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceNativePlugin.kt index c0d659c..c507d49 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceNativePlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceNativePlugin.kt @@ -9,30 +9,71 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class KScienceNativePlugin : Plugin { override fun apply(target: Project) = target.run { //Apply multiplatform plugin is not applied, apply it - if (plugins.findPlugin(KScienceMPPlugin::class) == null) { - logger.info("Multiplatform KScience plugin is not resolved. Adding it automatically") - pluginManager.apply(KScienceMPPlugin::class) + if (plugins.findPlugin("org.jetbrains.kotlin.multiplatform") == null) { + logger.info("Kotlin multiplatform plugin is not resolved. Adding it automatically") + pluginManager.apply("org.jetbrains.kotlin.multiplatform") + } + if (plugins.findPlugin(KScienceCommonPlugin::class) == null) { + logger.info("KScience plugin is not resolved. Adding it automatically") + pluginManager.apply(KScienceCommonPlugin::class) } configure { - val hostOs = System.getProperty("os.name") - val isMingwX64 = hostOs.startsWith("Windows") + val ideaActive = System.getProperty("idea.active") == "true" - val nativeTarget = when { - hostOs == "Mac OS X" -> macosX64("native") - hostOs == "Linux" -> linuxX64("native") - isMingwX64 -> { - mingwX64("native") - linuxX64() + if (ideaActive) { + //development mode + val hostOs = System.getProperty("os.name") + + when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + hostOs.startsWith("Windows") -> mingwX64("native") + else -> throw GradleException("Host OS is not supported in Kotlin/Native.") } - else -> throw GradleException("Host OS is not supported in Kotlin/Native.") - } + } else { + //deploy mode + linuxX64() + mingwX64() + macosX64() - sourceSets.invoke { - val nativeMain by getting - findByName("linuxX64Main")?.dependsOn(nativeMain) - val nativeTest by getting - findByName("linuxX64Test")?.dependsOn(nativeTest) + sourceSets{ + val commonMain by getting + val nativeMain by creating{ + dependsOn(commonMain) + } + + val commonTest by getting + + val nativeTest by creating{ + dependsOn(nativeMain) + dependsOn(commonTest) + } + + val linuxX64Main by getting{ + dependsOn(nativeMain) + } + + val mingwX64Main by getting{ + dependsOn(nativeMain) + } + + val macosX64Main by getting{ + dependsOn(nativeMain) + } + + val linuxX64Test by getting{ + dependsOn(nativeTest) + } + + val mingwX64Test by getting{ + dependsOn(nativeTest) + } + + val macosX64Test by getting{ + dependsOn(nativeTest) + } + } } } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceNodePlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceNodePlugin.kt index bba5346..473424e 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceNodePlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceNodePlugin.kt @@ -2,27 +2,45 @@ package ru.mipt.npm.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.kotlin.dsl.configure -import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.gradle.kotlin.dsl.* import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +/** + * Create a separate target for node + */ class KScienceNodePlugin : Plugin { - override fun apply(target: Project) = target.run{ - pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { - configure { - js { - nodejs() + override fun apply(target: Project) = target.run { + //Apply multiplatform plugin is not applied, apply it + if (plugins.findPlugin("org.jetbrains.kotlin.multiplatform") == null) { + logger.info("Kotlin multiplatform plugin is not resolved. Adding it automatically") + pluginManager.apply("org.jetbrains.kotlin.multiplatform") + } + if (plugins.findPlugin(KScienceCommonPlugin::class) == null) { + logger.info("KScience plugin is not resolved. Adding it automatically") + pluginManager.apply(KScienceCommonPlugin::class) + } + + configure { + js(name = "node", compiler = IR) { + nodejs() + } + sourceSets { + val commonMain by getting + val nodeMain by creating { + dependsOn(commonMain) + dependencies{ + api("org.jetbrains.kotlinx:kotlinx-nodejs:${KScienceVersions.kotlinxNodeVersion}") + } + } + + val commonTest by getting + + val nodeTest by creating { + dependsOn(nodeMain) + dependsOn(commonTest) } } } - pluginManager.withPlugin("org.jetbrains.kotlin.js") { - configure { - js { - nodejs() - } - } - } } - } \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceProjectPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceProjectPlugin.kt new file mode 100644 index 0000000..942334a --- /dev/null +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceProjectPlugin.kt @@ -0,0 +1,223 @@ +package ru.mipt.npm.gradle + +import groovy.text.SimpleTemplateEngine +import kotlinx.validation.BinaryCompatibilityValidatorPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.* +import org.jetbrains.changelog.ChangelogPlugin +import org.jetbrains.dokka.gradle.DokkaPlugin +import org.jetbrains.dokka.gradle.DokkaTask +import java.io.File +import kotlin.collections.component1 +import kotlin.collections.component2 + +class KSciencePublishingExtension(val project: Project) { + var githubOrg: String? by project.extra + var githubProject: String? by project.extra + var spaceRepo: String? by project.extra + var spaceUser: String? by project.extra + var spaceToken: String? by project.extra + var bintrayOrg: String? by project.extra + var bintrayUser: String? by project.extra + var bintrayApiKey: String? by project.extra + var bintrayRepo: String? by project.extra +} + +enum class Maturity { + PROTOTYPE, + EXPERIMENTAL, + DEVELOPMENT, + PRODUCTION +} + +class KScienceReadmeExtension(val project: Project) { + var description: String = "" + var maturity: Maturity = Maturity.EXPERIMENTAL + + var readmeTemplate: File = project.file("docs/README-TEMPLATE.md") + + data class Feature(val id: String, val ref: String, val description: String, val name: String = id) + + val features = ArrayList() + + fun feature(id: String, ref: String, description: String, name: String = id) { + features.add(Feature(id, ref, description, name)) + } + + val properties: MutableMap Any?> = mutableMapOf( + "name" to { project.name }, + "group" to { project.group }, + "version" to { project.version }, + "features" to { featuresString() } + ) + + private fun getActualizedProperties() = properties.mapValues { (_, value) -> + value.invoke() + } + + fun property(key: String, value: Any?) { + properties[key] = {value} + } + + fun propertyByTemplate(key: String, template: String) { + val actual = getActualizedProperties() + properties[key] = {SimpleTemplateEngine().createTemplate(template).make(actual).toString()} + } + + internal val additionalFiles = ArrayList() + + fun propertyByTemplate(key: String, template: File) { + val actual = getActualizedProperties() + properties[key] = {SimpleTemplateEngine().createTemplate(template).make(actual).toString()} + additionalFiles.add(template) + } + + /** + * Generate a markdown string listing features + */ + fun featuresString(itemPrefix: String = " - ", pathPrefix: String = "") = buildString { + features.forEach { + appendln("$itemPrefix[${it.id}]($pathPrefix${it.ref}) : ${it.description}") + } + } + + /** + * Generate a readme string from the stub + */ + fun readmeString(): String? { + return if (readmeTemplate.exists()) { + val actual = getActualizedProperties() + SimpleTemplateEngine().createTemplate(readmeTemplate).make(actual).toString() + } else { + null + } + } +} + +/** + * Apply extension and repositories + */ +open class KScienceProjectPlugin : Plugin { + override fun apply(target: Project): Unit = target.run { + apply() + apply() + apply() + + val rootReadmeExtension = KScienceReadmeExtension(this) + extensions.add("ksciencePublish", KSciencePublishingExtension(this)) + extensions.add("readme", rootReadmeExtension) + + //Add readme generators to individual subprojects + subprojects { + val readmeExtension = KScienceReadmeExtension(this) + extensions.add("readme", readmeExtension) + val generateReadme by tasks.creating { + group = "documentation" + description = "Generate a README file if stub is present" + + if(readmeExtension.readmeTemplate.exists()) { + inputs.file(readmeExtension.readmeTemplate) + } + readmeExtension.additionalFiles.forEach { + if(it.exists()){ + inputs.file(it) + } + } + + val readmeFile = this@subprojects.file("README.md") + outputs.file(readmeFile) + + doLast { + val readmeString = readmeExtension.readmeString() + if (readmeString != null) { + readmeFile.writeText(readmeString) + } + } + } + tasks.withType{ + dependsOn(generateReadme) + } + } + + val generateReadme by tasks.creating { + group = "documentation" + description = "Generate a README file and a feature matrix if stub is present" + + subprojects { + tasks.findByName("generateReadme")?.let { + dependsOn(it) + } + } + + if(rootReadmeExtension.readmeTemplate.exists()) { + inputs.file(rootReadmeExtension.readmeTemplate) + } + rootReadmeExtension.additionalFiles.forEach { + if(it.exists()){ + inputs.file(it) + } + } + + val readmeFile = project.file("README.md") + outputs.file(readmeFile) + + doLast { + val projects = subprojects.associate { + it.name to it.extensions.findByType() + } + + if (rootReadmeExtension.readmeTemplate.exists()) { + + val modulesString = buildString { + projects.entries.forEach { (name, ext) -> + appendln("
") + appendln("\n* ### [$name]($name)") + if (ext != null) { + appendln("> ${ext.description}") + appendln(">\n> **Maturity**: ${ext.maturity}") + val featureString = ext.featuresString(itemPrefix = "> - ", pathPrefix = "$name/") + if(featureString.isNotBlank()) { + appendln(">\n> **Features:**") + appendln(featureString) + } + } + } + appendln("
") + } + + val rootReadmeProperties: Map = mapOf( + "name" to project.name, + "group" to project.group, + "version" to project.version, + "modules" to modulesString + ) + + readmeFile.writeText( + SimpleTemplateEngine().createTemplate(rootReadmeExtension.readmeTemplate) + .make(rootReadmeProperties).toString() + ) + } + + } + } + + tasks.withType{ + dependsOn(generateReadme) + } + + val patchChangelog by tasks.getting + + val release by tasks.creating{ + group = RELEASE_GROUP + description = "Publish development or production release based on version suffix" + dependsOn(generateReadme, patchChangelog) + tasks.findByName("publishAllPublicationsToBintrayRepository")?.let { + dependsOn(it) + } + } + } + companion object{ + const val RELEASE_GROUP = "release" + } +} \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KSciencePublishPlugin.kt b/src/main/kotlin/ru/mipt/npm/gradle/KSciencePublishPlugin.kt index e45ea06..c45e556 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KSciencePublishPlugin.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KSciencePublishPlugin.kt @@ -2,129 +2,12 @@ package ru.mipt.npm.gradle import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.provideDelegate -import org.gradle.kotlin.dsl.withType +import ru.mipt.npm.gradle.internal.configurePublishing open class KSciencePublishPlugin : Plugin { - override fun apply(project: Project): Unit = project.run{ - plugins.apply("maven-publish") - registerKScienceExtension() - - afterEvaluate { - val githubOrg: String = project.findProperty("githubOrg") as? String ?: "mipt-npm" - val githubProject: String? by project - val vcs = findProperty("vcs") as? String - ?: githubProject?.let { "https://github.com/$githubOrg/$it" } - - if (vcs == null) { - project.logger.warn("[${project.name}] Missing deployment configuration. Skipping publish.") - return@afterEvaluate - } - - project.configure { - // Process each publication we have in this project - publications.withType().forEach { publication -> - @Suppress("UnstableApiUsage") - publication.pom { - name.set(project.name) - description.set(project.description) - url.set(vcs) - - licenses { - license { - name.set("The Apache Software License, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - distribution.set("repo") - } - } - developers { - developer { - id.set("MIPT-NPM") - name.set("MIPT nuclear physics methods laboratory") - organization.set("MIPT") - organizationUrl.set("http://npm.mipt.ru") - } - - } - scm { - url.set(vcs) - tag.set(project.version.toString()) - } - } - } - - val githubUser: String? by project - val githubToken: String? by project - - if (githubProject != null && githubUser != null && githubToken != null) { - project.logger.info("Adding github publishing to project [${project.name}]") - repositories { - maven { - name = "github" - url = uri("https://maven.pkg.github.com/mipt-npm/$githubProject/") - credentials { - username = githubUser - password = githubToken - } - } - } - } - - val spaceRepo: String? by project - val spaceUser: String? by project - val spaceToken: String? by project - - if (spaceRepo != null && spaceUser != null && spaceToken != null) { - project.logger.info("Adding mipt-npm Space publishing to project [${project.name}]") - repositories { - maven { - name = "space" - url = uri(spaceRepo!!) - credentials { - username = spaceUser - password = spaceToken - } - - } - } - } - - val bintrayOrg = project.findProperty("bintrayOrg") as? String ?: "mipt-npm" - val bintrayUser: String? by project - val bintrayApiKey: String? by project - - - val bintrayRepo = if (project.version.toString().contains("dev")) { - "dev" - } else { - findProperty("bintrayRepo") as? String - } - - val projectName = project.name - - if (bintrayRepo != null && bintrayUser != null && bintrayApiKey != null) { - project.logger.info("Adding bintray publishing to project [$projectName]") - - repositories { - maven { - name = "bintray" - url = uri( - "https://api.bintray.com/maven/$bintrayOrg/$bintrayRepo/$projectName/;publish=1;override=1" - ) - credentials { - username = bintrayUser - password = bintrayApiKey - } - } - } - - } - } - } + override fun apply(project: Project): Unit = project.plugins.withId("ru.mipt.npm.kscience") { + project.configurePublishing() } } \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/KScienceVersions.kt b/src/main/kotlin/ru/mipt/npm/gradle/KScienceVersions.kt index 5016871..7849dda 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/KScienceVersions.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/KScienceVersions.kt @@ -6,15 +6,19 @@ import org.gradle.api.JavaVersion * Build constants */ object KScienceVersions { - const val coroutinesVersion = "1.3.9" - const val serializationVersion = "1.0.0-RC" + const val kotlinVersion = "1.4.21" + const val kotlinxNodeVersion = "0.0.7" + const val coroutinesVersion = "1.4.2" + const val serializationVersion = "1.0.1" const val atomicVersion = "0.14.4" val JVM_TARGET = JavaVersion.VERSION_11 object Serialization{ - const val xmlVersion = "0.80.0-RC"//to be fixed + const val xmlVersion = "0.80.1" + @Deprecated("Use yamlKt instead") const val yamlVersion = "0.21.0" - const val bsonVersion = "0.4.1-rc" + const val bsonVersion = "0.4.4" + const val yamlKtVersion = "0.7.5" } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/serialization.kt b/src/main/kotlin/ru/mipt/npm/gradle/SerializationTargets.kt similarity index 67% rename from src/main/kotlin/ru/mipt/npm/gradle/serialization.kt rename to src/main/kotlin/ru/mipt/npm/gradle/SerializationTargets.kt index a5eb039..1f66db2 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/serialization.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/SerializationTargets.kt @@ -3,11 +3,24 @@ package ru.mipt.npm.gradle import org.gradle.api.Project import org.gradle.kotlin.dsl.maven import org.gradle.kotlin.dsl.repositories +import ru.mipt.npm.gradle.internal.useCommonDependency +import ru.mipt.npm.gradle.internal.useDependency class SerializationTargets( val sourceSet: DependencySourceSet, val configuration: DependencyConfiguration ) { + + fun Project.json( + version: String = KScienceVersions.serializationVersion + ) { + useCommonDependency( + "org.jetbrains.kotlinx:kotlinx-serialization-json:$version", + dependencySourceSet = sourceSet, + dependencyConfiguration = configuration + ) + } + fun Project.cbor( version: String = KScienceVersions.serializationVersion ) { @@ -34,15 +47,14 @@ class SerializationTargets( repositories { maven("https://dl.bintray.com/pdvrieze/maven") } - useDependency( - "common" to "net.devrieze:xmlutil-serialization:$version", - "jvm" to "net.devrieze:xmlutil-serialization:$version", - "js" to "net.devrieze:xmlutil-serialization:$version", + useCommonDependency( + "net.devrieze:xmlutil-serialization:$version", dependencySourceSet = sourceSet, dependencyConfiguration = configuration ) } + @Deprecated("Use multiplatform yamlKt instead") fun Project.yaml( version: String = KScienceVersions.Serialization.yamlVersion ) { @@ -53,6 +65,16 @@ class SerializationTargets( ) } + fun Project.yamlKt( + version: String = KScienceVersions.Serialization.yamlKtVersion + ) { + useCommonDependency( + "net.mamoe.yamlkt:yamlkt:$version", + dependencySourceSet = sourceSet, + dependencyConfiguration = configuration + ) + } + fun Project.bson( version: String = KScienceVersions.Serialization.bsonVersion ) { diff --git a/src/main/kotlin/ru/mipt/npm/gradle/common.kt b/src/main/kotlin/ru/mipt/npm/gradle/common.kt deleted file mode 100644 index 9b33cb5..0000000 --- a/src/main/kotlin/ru/mipt/npm/gradle/common.kt +++ /dev/null @@ -1,103 +0,0 @@ -package ru.mipt.npm.gradle - -import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ProjectDependency -import org.gradle.api.artifacts.dsl.RepositoryHandler -import org.gradle.api.tasks.Copy -import org.gradle.kotlin.dsl.maven -import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder -import java.io.File - -internal fun LanguageSettingsBuilder.applySettings(): Unit { - progressiveMode = true - enableLanguageFeature("InlineClasses") - useExperimentalAnnotation("kotlin.Experimental") - useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") - useExperimentalAnnotation("kotlin.ExperimentalStdlibApi") - useExperimentalAnnotation("kotlin.time.ExperimentalTime") - useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") -} - -internal fun RepositoryHandler.applyRepos(): Unit { - mavenCentral() - jcenter() - maven("https://dl.bintray.com/kotlin/kotlin-eap") - maven("https://dl.bintray.com/kotlin/kotlin-dev") - maven("https://kotlin.bintray.com/kotlinx") - maven("https://kotlin.bintray.com/kotlin-js-wrappers/") - maven("https://dl.bintray.com/mipt-npm/kscience") - maven("https://dl.bintray.com/mipt-npm/dev") - maven("https://dl.bintray.com/mipt-npm/dataforge") -} - - -internal fun Copy.copyJSResources(configuration: Configuration): Unit = project.afterEvaluate { - val projectDeps = configuration - .allDependencies - .filterIsInstance() - .map { it.dependencyProject } - - val destination = destinationDir - - projectDeps.forEach { dep -> - dep.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { - dep.tasks.findByName("jsProcessResources")?.let { task -> - val sourceDir = (task as Copy).destinationDir - inputs.files(sourceDir) - dependsOn(task) - from(sourceDir) - } - } - dep.pluginManager.withPlugin("org.jetbrains.kotlin.js") { - dep.tasks.findByName("processResources")?.let { task -> - val sourceDir = (task as Copy).destinationDir - inputs.files(sourceDir) - dependsOn(task) - from(sourceDir) - } - } - } -} - -internal fun Copy.copyJVMResources(configuration: Configuration): Unit = project.afterEvaluate { - val projectDeps = configuration - .allDependencies - .filterIsInstance() - .map { it.dependencyProject } - - val destination = destinationDir - - projectDeps.forEach { dep -> - dep.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { - dep.tasks.findByName("jvmProcessResources")?.let { task -> - val sourceDir = (task as Copy).destinationDir - inputs.files(sourceDir) - dependsOn(task) - from(sourceDir) - } - } - dep.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { - dep.tasks.findByName("processResources")?.let { task -> - val sourceDir = (task as Copy).destinationDir - inputs.files(sourceDir) - dependsOn(task) - from(sourceDir) - } - } - } -} - - -val Project.jsDistDirectory: File - get() { - val distributionName = listOf( - name, - "js", - version.toString() - ).joinToString("-") - - return buildDir.resolve( - "distributions/$distributionName" - ) - } \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/internal/common.kt b/src/main/kotlin/ru/mipt/npm/gradle/internal/common.kt new file mode 100644 index 0000000..6eede47 --- /dev/null +++ b/src/main/kotlin/ru/mipt/npm/gradle/internal/common.kt @@ -0,0 +1,78 @@ +package ru.mipt.npm.gradle.internal + +import org.gradle.api.artifacts.ProjectDependency +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.api.tasks.Copy +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.maven +import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder + +internal fun LanguageSettingsBuilder.applySettings(): Unit { + progressiveMode = true + enableLanguageFeature("InlineClasses") + useExperimentalAnnotation("kotlin.Experimental") + useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") + useExperimentalAnnotation("kotlin.ExperimentalStdlibApi") + useExperimentalAnnotation("kotlin.time.ExperimentalTime") + useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") + useExperimentalAnnotation("kotlin.js.ExperimentalJsExport") +} + +internal fun RepositoryHandler.applyRepos(): Unit { + mavenCentral() + jcenter() + maven("https://dl.bintray.com/kotlin/kotlin-eap") + maven("https://dl.bintray.com/kotlin/kotlin-dev") + maven("https://kotlin.bintray.com/kotlinx") + maven("https://kotlin.bintray.com/kotlin-js-wrappers/") + maven("https://dl.bintray.com/mipt-npm/kscience") + maven("https://dl.bintray.com/mipt-npm/dev") + maven("https://dl.bintray.com/mipt-npm/dataforge") +} + +internal fun Copy.fromDependencies(configurationName: String) = project.afterEvaluate { + val configuration = configurations[configurationName] + ?: error("Configuration with name $configurationName could not be resolved.") + val projectDeps = configuration.allDependencies.filterIsInstance().map { + it.dependencyProject + } + projectDeps.forEach { dep -> + dep.afterEvaluate { + dep.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { + dep.tasks.findByName("jsProcessResources")?.let { task -> + dependsOn(task) + from(task) + } + } + dep.pluginManager.withPlugin("org.jetbrains.kotlin.js") { + dep.tasks.findByName("processResources")?.let { task -> + dependsOn(task) + from(task) + } + } + } + } +} + + +// +//internal fun Copy.copyJVMResources(configuration: Configuration): Unit = project.afterEvaluate { +// val projectDeps = configuration.allDependencies +// .filterIsInstance() +// .map { it.dependencyProject } +// +// projectDeps.forEach { dep -> +// dep.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { +// dep.tasks.findByName("jvmProcessResources")?.let { task -> +// dependsOn(task) +// from(task) +// } +// } +// dep.pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { +// dep.tasks.findByName("processResources")?.let { task -> +// dependsOn(task) +// from(task) +// } +// } +// } +//} \ No newline at end of file diff --git a/src/main/kotlin/ru/mipt/npm/gradle/dependencies.kt b/src/main/kotlin/ru/mipt/npm/gradle/internal/dependencies.kt similarity index 62% rename from src/main/kotlin/ru/mipt/npm/gradle/dependencies.kt rename to src/main/kotlin/ru/mipt/npm/gradle/internal/dependencies.kt index 4dcea9b..eaf260b 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/dependencies.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/internal/dependencies.kt @@ -1,21 +1,13 @@ -package ru.mipt.npm.gradle +package ru.mipt.npm.gradle.internal -import kotlinx.atomicfu.plugin.gradle.sourceSets import org.gradle.api.Project -import org.gradle.kotlin.dsl.findByType +import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.invoke +import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension - -enum class DependencyConfiguration { - API, - IMPLEMENTATION, - COMPILE_ONLY -} - -enum class DependencySourceSet(val setName: String, val suffix: String) { - MAIN("main", "Main"), - TEST("test", "Test") -} +import ru.mipt.npm.gradle.DependencyConfiguration +import ru.mipt.npm.gradle.DependencySourceSet internal fun Project.useDependency( vararg pairs: Pair, @@ -23,7 +15,7 @@ internal fun Project.useDependency( dependencyConfiguration: DependencyConfiguration = DependencyConfiguration.IMPLEMENTATION ) { pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { - extensions.findByType()?.apply { + configure { sourceSets { pairs.forEach { (target, dep) -> val name = target + dependencySourceSet.suffix @@ -43,14 +35,16 @@ internal fun Project.useDependency( pairs.find { it.first == "jvm" }?.let { dep -> pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { - sourceSets.findByName(dependencySourceSet.setName)?.apply { - dependencies.apply { - val configurationName = when (dependencyConfiguration) { - DependencyConfiguration.API -> apiConfigurationName - DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName - DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + configure { + sourceSets.findByName(dependencySourceSet.setName)?.apply { + dependencies.apply { + val configurationName = when (dependencyConfiguration) { + DependencyConfiguration.API -> apiConfigurationName + DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName + DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + } + add(configurationName, dep.second) } - add(configurationName, dep.second) } } } @@ -58,14 +52,16 @@ internal fun Project.useDependency( pairs.find { it.first == "js" }?.let { dep -> pluginManager.withPlugin("org.jetbrains.kotlin.js") { - sourceSets.findByName(dependencySourceSet.setName)?.apply { - dependencies.apply { - val configurationName = when (dependencyConfiguration) { - DependencyConfiguration.API -> apiConfigurationName - DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName - DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + configure { + sourceSets.findByName(dependencySourceSet.setName)?.apply { + dependencies.apply { + val configurationName = when (dependencyConfiguration) { + DependencyConfiguration.API -> apiConfigurationName + DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName + DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + } + add(configurationName, dep.second) } - add(configurationName, dep.second) } } } @@ -76,9 +72,9 @@ internal fun Project.useCommonDependency( dep: String, dependencySourceSet: DependencySourceSet = DependencySourceSet.MAIN, dependencyConfiguration: DependencyConfiguration = DependencyConfiguration.IMPLEMENTATION -): Unit = pluginManager.run{ - withPlugin("org.jetbrains.kotlin.multiplatform"){ - extensions.findByType()?.apply { +): Unit = pluginManager.run { + withPlugin("org.jetbrains.kotlin.multiplatform") { + configure { sourceSets.findByName("common${dependencySourceSet.suffix}")?.apply { dependencies { when (dependencyConfiguration) { @@ -90,27 +86,33 @@ internal fun Project.useCommonDependency( } } } + + withPlugin("org.jetbrains.kotlin.jvm") { - sourceSets.findByName(dependencySourceSet.setName)?.apply { - dependencies.apply { - val configurationName = when (dependencyConfiguration) { - DependencyConfiguration.API -> apiConfigurationName - DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName - DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + configure { + sourceSets.findByName(dependencySourceSet.setName)?.apply { + dependencies.apply { + val configurationName = when (dependencyConfiguration) { + DependencyConfiguration.API -> apiConfigurationName + DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName + DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + } + add(configurationName, dep) } - add(configurationName, dep) } } } withPlugin("org.jetbrains.kotlin.js") { - sourceSets.findByName(dependencySourceSet.setName)?.apply { - dependencies.apply { - val configurationName = when (dependencyConfiguration) { - DependencyConfiguration.API -> apiConfigurationName - DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName - DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + configure { + sourceSets.findByName(dependencySourceSet.setName)?.apply { + dependencies.apply { + val configurationName = when (dependencyConfiguration) { + DependencyConfiguration.API -> apiConfigurationName + DependencyConfiguration.IMPLEMENTATION -> implementationConfigurationName + DependencyConfiguration.COMPILE_ONLY -> compileOnlyConfigurationName + } + add(configurationName, dep) } - add(configurationName, dep) } } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/fx.kt b/src/main/kotlin/ru/mipt/npm/gradle/internal/fx.kt similarity index 68% rename from src/main/kotlin/ru/mipt/npm/gradle/fx.kt rename to src/main/kotlin/ru/mipt/npm/gradle/internal/fx.kt index 76f30c0..83c07df 100644 --- a/src/main/kotlin/ru/mipt/npm/gradle/fx.kt +++ b/src/main/kotlin/ru/mipt/npm/gradle/internal/fx.kt @@ -1,4 +1,4 @@ -package ru.mipt.npm.gradle +package ru.mipt.npm.gradle.internal import org.apache.tools.ant.taskdefs.condition.Os import org.gradle.api.Project @@ -6,22 +6,9 @@ import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler - -enum class FXModule(val artifact: String, vararg val dependencies: FXModule) { - BASE("javafx-base"), - GRAPHICS("javafx-graphics", BASE), - CONTROLS("javafx-controls", GRAPHICS, BASE), - FXML("javafx-fxml", BASE), - MEDIA("javafx-media", GRAPHICS, BASE), - SWING("javafx-swing", GRAPHICS, BASE), - WEB("javafx-web", CONTROLS, GRAPHICS, BASE) -} - -enum class FXPlatform(val id: String) { - WINDOWS("win"), - LINUX("linux"), - MAC("mac") -} +import ru.mipt.npm.gradle.DependencyConfiguration +import ru.mipt.npm.gradle.FXModule +import ru.mipt.npm.gradle.FXPlatform val defaultPlatform: FXPlatform = when { Os.isFamily(Os.FAMILY_WINDOWS) -> FXPlatform.WINDOWS @@ -31,7 +18,7 @@ val defaultPlatform: FXPlatform = when { } private fun KotlinDependencyHandler.addFXDependencies( - vararg modules: FXModule, + modules: List, configuration: DependencyConfiguration, version: String = "14", platform: FXPlatform = defaultPlatform @@ -46,17 +33,17 @@ private fun KotlinDependencyHandler.addFXDependencies( } } -fun Project.useFx( - vararg modules: FXModule, +internal fun Project.useFx( + modules: List, configuration: DependencyConfiguration = DependencyConfiguration.COMPILE_ONLY, version: String = "14", platform: FXPlatform = defaultPlatform -): Unit = afterEvaluate{ +): Unit = afterEvaluate { pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { extensions.findByType()?.apply { sourceSets.findByName("jvmMain")?.apply { dependencies { - addFXDependencies(*modules, configuration = configuration, version = version, platform = platform) + addFXDependencies(modules, configuration = configuration, version = version, platform = platform) } } } @@ -66,7 +53,7 @@ fun Project.useFx( extensions.findByType()?.apply { sourceSets.findByName("main")?.apply { dependencies { - addFXDependencies(*modules, configuration = configuration, version = version, platform = platform) + addFXDependencies(modules, configuration = configuration, version = version, platform = platform) } } } diff --git a/src/main/kotlin/ru/mipt/npm/gradle/internal/publish.kt b/src/main/kotlin/ru/mipt/npm/gradle/internal/publish.kt new file mode 100644 index 0000000..12bb161 --- /dev/null +++ b/src/main/kotlin/ru/mipt/npm/gradle/internal/publish.kt @@ -0,0 +1,157 @@ +package ru.mipt.npm.gradle.internal + +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.* +import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension + +internal fun Project.configurePublishing() { + if (plugins.findPlugin("maven-publish") == null) { + plugins.apply("maven-publish") + } + + val githubOrg: String = project.findProperty("githubOrg") as? String ?: "mipt-npm" + val githubProject: String? by project + val vcs = findProperty("vcs") as? String + ?: githubProject?.let { "https://github.com/$githubOrg/$it" } + + if (vcs == null) { + project.logger.warn("[${project.name}] Missing deployment configuration. Skipping publish.") + return + } + + project.configure { + plugins.withId("org.jetbrains.kotlin.js") { + val kotlin = extensions.findByType()!! + + val sourcesJar: Jar by project.tasks.creating(Jar::class){ + archiveClassifier.set("sources") + from(kotlin.sourceSets["main"].kotlin) + } + + publications { + create("js", MavenPublication::class) { + from(components["kotlin"]) + artifact(sourcesJar) + } + } + } + + plugins.withId("org.jetbrains.kotlin.jvm") { + val kotlin = extensions.findByType()!! + + val sourcesJar: Jar by project.tasks.creating(Jar::class){ + archiveClassifier.set("sources") + from(kotlin.sourceSets["main"].kotlin) + } + + publications { + create("jvm", MavenPublication::class) { + from(components["kotlin"]) + artifact(sourcesJar) + } + } + } + + + // Process each publication we have in this project + publications.withType().forEach { publication -> + publication.pom { + name.set(project.name) + description.set(project.description) + url.set(vcs) + + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("repo") + } + } + developers { + developer { + id.set("MIPT-NPM") + name.set("MIPT nuclear physics methods laboratory") + organization.set("MIPT") + organizationUrl.set("http://npm.mipt.ru") + } + + } + scm { + url.set(vcs) + tag.set(project.version.toString()) + } + } + } + + val githubUser: String? by project + val githubToken: String? by project + + if (githubProject != null && githubUser != null && githubToken != null) { + project.logger.info("Adding github publishing to project [${project.name}]") + repositories { + maven { + name = "github" + url = uri("https://maven.pkg.github.com/mipt-npm/$githubProject/") + credentials { + username = githubUser + password = githubToken + } + } + } + } + + val spaceRepo: String? by project + val spaceUser: String? by project + val spaceToken: String? by project + + if (spaceRepo != null && spaceUser != null && spaceToken != null) { + project.logger.info("Adding mipt-npm Space publishing to project [${project.name}]") + repositories { + maven { + name = "space" + url = uri(spaceRepo!!) + credentials { + username = spaceUser + password = spaceToken + } + + } + } + } + + val bintrayOrg = project.findProperty("bintrayOrg") as? String ?: "mipt-npm" + val bintrayUser: String? by project + val bintrayApiKey: String? by project + + + val bintrayRepo = if (project.version.toString().contains("dev")) { + "dev" + } else { + findProperty("bintrayRepo") as? String + } + + val projectName = project.name + + if (bintrayRepo != null && bintrayUser != null && bintrayApiKey != null) { + project.logger.info("Adding bintray publishing to project [$projectName]") + + repositories { + maven { + name = "bintray" + url = uri( + "https://api.bintray.com/maven/$bintrayOrg/$bintrayRepo/$projectName/;publish=1;override=1" + ) + credentials { + username = bintrayUser + password = bintrayApiKey + } + } + } + + } + } +} \ No newline at end of file