diff --git a/CHANGELOG.md b/CHANGELOG.md index e24c1f6..31835d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to this project will be documented in this file. +All notable changes to this project will be documented in this file. 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). @@ -18,22 +18,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security +## 0.15.4-kotlin-2.0.0 - 2024-06-04 + +### Added + +- Pass `compose` extension to the kscience extension so compose dependencies could be called directly from kscience block + +### Changed + +- Use ES6 modules by default in JS +- Kotlin 2.0 + +## 0.15.2-kotlin-1.9.22 - 2024-02-09 + +### Added + +- Add development mode for fullstack. + +### Changed + +- Kotlin 1.9.20 +- Remove publishing defaults for Space and GitHub. Now publishing repositories is configured quasi-manually. Property keys for username and tokens are generated automatically. +- All publishing targets are enabled by default. Introduce `publishing.targets` variable to regulate what is added to the module. + +### Deprecated + +- JVM plugin in favor of Mpp. + +### Removed + +- JS plugin. It is deprecated in favor of MPP. +- Unnecessary `dependsOn` for native dependencies. +- Groovy gradle dependency notation. + ## 0.14.4-kotlin-1.8.20-RC - 2023-03-12 ### Added + - Easier dependency handling in `kscience` block - Customizable base jdk version ### Changed + - MPP does not use JVM and JS(IR) targets anymore. They could be turned manually via `js()`, `jvm()` or `fullStack()` - Signing is not applied if signingId is not provided ### Removed + - FX plugins - Unnecessary library shortcuts (html and datetime) - deploy/release tasks ### Fixed + - Gradle 8 compatibility - Dokka publication - issues with test sourcesets @@ -41,9 +78,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.13.4-kotlin-1.8.0 - 2022-12-31 ### Added + - Public `isInDevelopment` project flag ### Changed + - Require manual pom config for publications - Kotlin 1.8.0 - Versions update @@ -51,139 +90,172 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved `yarn.lock` to `gradle` directory ### Deprecated + - FX configuration ### Removed + - Xjdk-release flag because it is broken until https://youtrack.jetbrains.com/issue/KT-52823 - Use CSS loader in JS by default ## 0.11.6-kotlin-1.7.0 ### Changed + - Coroutines tests are applied only when explicit `useCoroutines` is used. ### Removed + - Atomicfu support inside the plugin ### Fixed + - Rollback coroutines to 1.6.1 ## 0.11.5-kotlin-1.7.0 ### Added + - Coroutine tests as default dependency for tests - Context receiver flag ### Changed + - Separate release tasks for each target - Kotlin 1.7.0 - Ktor 2.0.1 - ExplicitAPI does not override existing value ### Removed + - Ktor specific artifacts from version catalog ### Fixed + - Moved signing out of sonatype block ## 0.11.1-kotlin-1.6.10 ### Added + - Default templates for README and ARTIFACT ### Changed + - Replaced Groovy templates by FreeMarker ### Fixed + - JS publication sources jar ## 0.10.9-kotlin-1.6.10 ### Added + - html builders for readme ### Changed + - Kotlin 1.6.0 - Use indy lambdas by default #32 - Change version scheme to `-kotlin-` ### Fixed + - remove `nativeMain` dependency from `nativeTest` ## 0.10.4 ### Changed + - Kotlin 1.6 ### Fixed + - Some issues with opt-ins ## 0.10.2 ### Added + - Experimental automatic JS project bundling in MPP ### Changed + - Remove vcs requirement for Space publication ## 0.10.0 ### Added + - Lazy readme properties - BOM for kotlin-wrappers on JS - Jupyter loader ### Changed + - API validation disabled for dev versions - Kotlin plugins are propagated downstream ### Removed + - bson support ## 0.9.5 ### Added + - Disable API validation for snapshots - `-Xjvm-default=all` on JVM ### Changed + - `publication.platform` changed to `publishing.platform` - Dokka version to `1.4.30` - `useDateTime` in extension - Kotlin 1.5 ### Removed + - Publish plugin. Use MavenPublish instead ### Fixed + - Removed unnecessary `afterEvaluate` for compatibility with gradle 7.0 ## 0.9.0 ### Added + - Skip sonatype publishing for dev versions ### Changed + - Publishing repositories are explicit and defined in the top level project - Paths to publishing properties now use dot notation like `publishing.github.user` ### Deprecated + - Publishing plugin ### Removed + - Bintray publishing ## 0.8.4 ### Added + - Adaptive support for host OS in native - CSS support for JS targets ### Changed + - Kotlin 1.4.31 - Coroutines 1.4.3 ### Fixed + - Plugin loading order for publishing - Release task - Readme generation for multi-module project @@ -191,11 +263,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.8.1 ### Added + - Ktor version to versions - Add sonatype publishing - Per-platform release publishing ### Changed + - Kotlin to 1.4.30 stable. - Added intermediate jsCommon main/test sourcesSet for node plugin. - Plugin names changed to `ru.mipt.npm` package. @@ -203,15 +277,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Plugins group changed to `ru.mipt.npm` with `gradle` prefix ### Removed + - kaml ### Fixed + - Fix publishing load order for sonatype - Fix root project readme ## 0.7.4 ### 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. @@ -220,6 +297,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Suppress API validation for modules with maturity below DEVELOPMENT ### Changed + - Remove node plugin. Node binaries should be turned on manually. - Use default webpack distribution path. - `ru.mipt.npm.base` -> `ru.mipt.npm.project`. @@ -230,15 +308,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Kotlin 1.4.30-RC ### Deprecated + - Support of `kaml` and `snake-yaml` in favor of `yamlKt` - Publish plugin ### Removed + - `useDokka` method. Documentation jar should be added manually if needed. ## 0.6.0 ### Added + - Migrate to kotlin 1.4.0 - Separate Native (current platform) and nodeJs plugins. - Add `application()` toggle in plugin configuration to produce binaries on JS and applicaion plugin on jvm. @@ -247,4 +328,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.5.2 ### Added + - Copy resources for jvm modules and jvm source sets in mpp. diff --git a/build.gradle.kts b/build.gradle.kts index 31937c6..6e3f9e0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,15 @@ + plugins { `java-gradle-plugin` `kotlin-dsl` `maven-publish` - signing +// signing `version-catalog` - alias(libs.plugins.changelog) - alias(libs.plugins.dokka) + alias(libs.plugins.maven.publish) + alias(libs.plugins.jetbrains.changelog) + alias(libs.plugins.jetbrains.dokka) + alias(libs.plugins.versions) + alias(libs.plugins.versions.update) } group = "space.kscience" @@ -21,21 +25,20 @@ repositories { maven("https://repo.kotlin.link") } -kotlin.explicitApiWarning() - dependencies { api(libs.kotlin.gradle) + api(libs.foojay.resolver) implementation(libs.binary.compatibility.validator) implementation(libs.changelog.gradle) implementation(libs.dokka.gradle) implementation(libs.kotlin.jupyter.gradle) implementation(libs.kotlin.serialization) implementation(libs.kotlinx.html) - implementation("org.tomlj:tomlj:1.1.0") + implementation(libs.tomlj) // // nexus publishing plugin -// implementation("io.github.gradle-nexus:publish-plugin:1.1.0") +// implementation("io.github.gradle-nexus:publish-plugin:_") - implementation("org.freemarker:freemarker:2.3.31") + implementation(libs.freemarker) testImplementation(kotlin("test")) } @@ -65,23 +68,17 @@ gradlePlugin { description = "Pre-configured JVM project" implementationClass = "space.kscience.gradle.KScienceJVMPlugin" } - - create("js") { - id = "space.kscience.gradle.js" - description = "Pre-configured JS project" - implementationClass = "space.kscience.gradle.KScienceJSPlugin" - } } } tasks.create("version") { group = "publishing" - val versionFile = project.buildDir.resolve("project-version.txt") - outputs.file(versionFile) + val versionFileProvider = project.layout.buildDirectory.file("project-version.txt") + outputs.file(versionFileProvider) doLast { + val versionFile = versionFileProvider.get().asFile versionFile.createNewFile() versionFile.writeText(project.version.toString()) - println(project.version) } } @@ -116,106 +113,76 @@ val emptySourcesJar by tasks.creating(Jar::class) { archiveBaseName.set("empty") } -publishing { - val vcs = "https://github.com/mipt-npm/gradle-tools" +mavenPublishing { + configure( + com.vanniktech.maven.publish.GradlePlugin( + javadocJar = com.vanniktech.maven.publish.JavadocJar.Dokka("dokkaHtml"), + sourcesJar = true, + ) + ) - // Process each publication we have in this project - publications { - create("catalog") { - from(components["versionCatalog"]) - artifactId = "version-catalog" + project.publishing.publications.create("maven", MavenPublication::class.java) { + from(project.components.getByName("versionCatalog")) + } - pom { - name.set("version-catalog") + val vcs = "https://git.sciprog.center/kscience/gradle-tools" + + 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("https://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("repo") } } - withType { - // thanks @vladimirsitnikv for the fix - artifact(if (name == "catalog") emptySourcesJar else sourcesJar) - artifact(if (name == "catalog") emptyJavadocJar else javadocsJar) - - - 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("https://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("https://npm.mipt.ru") - } - } - - scm { - url.set(vcs) - tag.set(project.version.toString()) - } + developers { + developer { + id.set("SPC") + name.set("Scientific Programming Centre") + organization.set("SPC") + organizationUrl.set("https://sciprog.center/") } } + + scm { + url.set(vcs) + tag.set(project.version.toString()) + } } - val spaceRepo = "https://maven.pkg.jetbrains.space/spc/p/sci/maven" - val spaceUser: String? = findProperty("publishing.space.user") as? String - val spaceToken: String? = findProperty("publishing.space.token") as? String + val spaceRepo = "https://maven.sciprog.center/kscience" + val spcUser: String? = findProperty("publishing.spc.user") as? String + val spcToken: String? = findProperty("publishing.spc.token") as? String - if (spaceUser != null && spaceToken != null) { - project.logger.info("Adding mipt-npm Space publishing to project [${project.name}]") - - repositories.maven { - name = "space" + if (spcUser != null && spcToken != null) { + publishing.repositories.maven { + name = "spc" url = uri(spaceRepo) credentials { - username = spaceUser - password = spaceToken + username = spcUser + password = spcToken } } } - val sonatypeUser: String? = project.findProperty("publishing.sonatype.user") as? String - val sonatypePassword: String? = project.findProperty("publishing.sonatype.password") as? String + val centralUser: String? = project.findProperty("mavenCentralUsername") as? String + val centralPassword: String? = project.findProperty("mavenCentralPassword") as? String - if (sonatypeUser != null && sonatypePassword != null) { - val sonatypeRepo: String = if (project.version.toString().contains("dev")) { - "https://oss.sonatype.org/content/repositories/snapshots" - } else { - "https://oss.sonatype.org/service/local/staging/deploy/maven2" - } - - repositories.maven { - name = "sonatype" - url = uri(sonatypeRepo) - - credentials { - username = sonatypeUser - password = sonatypePassword - } - } - - signing { - //useGpgCmd() - sign(publications) - } + if (centralUser != null && centralPassword != null) { + publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.CENTRAL_PORTAL) + signAllPublications() } } - kotlin { - jvmToolchain { - languageVersion.set(JavaLanguageVersion.of(11)) - } + explicitApiWarning() + jvmToolchain(17) } tasks.processResources.configure { @@ -226,4 +193,14 @@ tasks.processResources.configure { // Workaround for https://github.com/gradle/gradle/issues/15568 tasks.withType().configureEach { mustRunAfter(tasks.withType()) -} \ No newline at end of file +} + +versionCatalogUpdate { + sortByKey.set(false) + keep { + keepUnusedVersions = true + keepUnusedPlugins = true + keepUnusedLibraries = true + } +} + \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 7fc6f1f..cd8d64d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,3 @@ kotlin.code.style=official + +nl.littlerobots.vcu.resolver=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fb846f7..8f1e72b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,103 +1,42 @@ [versions] -tools = "0.14.4-kotlin-1.8.20-RC" -kotlin = "1.8.20-RC" -atomicfu = "0.19.0" -binary-compatibility-validator = "0.12.1" -changelog = "2.0.0" -dokka = "1.7.20" -kotlin-jupyter = "0.11.0-317" -kotlinx-benchmark = "0.4.7" -kotlinx-cli = "0.3.5" -kotlinx-coroutines = "1.6.4" -kotlinx-datetime = "0.4.0" -kotlinx-html = "0.8.0" -kotlinx-knit = "0.4.0" +# @pin +kotlin = "2.1.0" +# @pin +tools = "0.15.8-kotlin-2.1.0" +atomicfu = "0.26.1" +changelog = "2.2.1" +compose = "1.7.1" +dokka = "2.0.0-Beta" +jsBom = "1.0.0-pre.847" +junit = "5.10.2" +kotlin-jupyter = "0.12.0-352" +kotlinx-benchmark = "0.4.13" +kotlinx-cli = "0.3.6" +kotlinx-coroutines = "1.9.0" +kotlinx-datetime = "0.6.1" +kotlinx-html = "0.11.0" +kotlinx-knit = "0.5.0" kotlinx-nodejs = "0.0.7" -kotlinx-serialization = "1.4.1" -ktor = "2.2.3" -xmlutil = "0.84.3" -yamlkt = "0.12.0" -jsBom = "1.0.0-pre.509" -junit = "5.9.2" -compose = "1.3.0" -logback = "1.4.5" - -[libraries] -atomicfu-gradle = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "atomicfu" } -atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu" } - -binary-compatibility-validator = { module = "org.jetbrains.kotlinx:binary-compatibility-validator", version.ref = "binary-compatibility-validator" } - -changelog-gradle = { module = "org.jetbrains.intellij.plugins:gradle-changelog-plugin", version.ref = "changelog" } - -dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } - -kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } -kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } - -kotlin-jupyter-gradle = { module = "org.jetbrains.kotlin:kotlin-jupyter-api-gradle-plugin", version.ref = "kotlin-jupyter" } - -kotlinx-benchmark-runtime = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark" } - -kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-reactive = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactive", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-reactor = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactor", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-rx2 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-rx3 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx3", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-javafx = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-javafx", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-jdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-slf4j = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j", version.ref = "kotlinx-coroutines" } -kotlinx-coroutines-play-services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinx-coroutines" } - -kotlinx-cli = { module = "org.jetbrains.kotlinx:kotlinx-cli", version.ref = "kotlinx-cli" } - -kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } - -kotlinx-html = { module = "org.jetbrains.kotlinx:kotlinx-html", version.ref = "kotlinx-html" } - -kotlinx-knit = { module = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "kotlinx-knit" } - -kotlinx-nodejs = { module = "org.jetbrains.kotlinx:kotlinx-nodejs", version.ref = "kotlinx-nodejs" } - -kotlinx-serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-cbor", version.ref = "kotlinx-serialization" } -kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" } -kotlinx-serialization-hocon = { module = "org.jetbrains.kotlinx:kotlinx-serialization-hocon", version.ref = "kotlinx-serialization" } -kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } -kotlinx-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinx-serialization" } -kotlinx-serialization-properties = { module = "org.jetbrains.kotlinx:kotlinx-serialization-properties", version.ref = "kotlinx-serialization" } - -ktor-bom = { module = "io.ktor:ktor-bom", version.ref = "ktor" } - -xmlutil-core = { module = "io.github.pdvrieze.xmlutil:core", version.ref = "xmlutil" } -xmlutil-ktor = { module = "io.github.pdvrieze.xmlutil:ktor", version.ref = "xmlutil" } -xmlutil-serialization = { module = "io.github.pdvrieze.xmlutil:serialization", version.ref = "xmlutil" } - -yamlkt = { module = "net.mamoe.yamlkt:yamlkt", version.ref = "yamlkt" } - -logback-classic = {module = "ch.qos.logback:logback-classic", version.ref = "logback"} +kotlinx-serialization = "1.7.3" +kover = "0.8.3" +ktor = "3.0.2" +ksp = "2.1.0-1.0.29" +logback = "1.5.12" +slf4j = "2.0.16" +xmlutil = "0.90.3" +yamlkt = "0.13.0" [plugins] -changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } - -dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } -compose = {id = "org.jetbrains.compose", version.ref = "compose"} - -gradle-common = { id = "space.kscience.gradle.common", version.ref = "tools" } -gradle-project = { id = "space.kscience.gradle.project", version.ref = "tools" } -gradle-mpp = { id = "space.kscience.gradle.mpp", version.ref = "tools" } -gradle-jvm = { id = "space.kscience.gradle.jvm", version.ref = "tools" } -gradle-js = { id = "space.kscience.gradle.js", version.ref = "tools" } -gradle-native = { id = "space.kscience.gradle.native", version.ref = "tools" } -gradle-node = { id = "space.kscience.gradle.node", version.ref = "tools" } - +maven-publish = { id = "com.vanniktech.maven.publish", version = "0.30.0" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +compose-jb = { id = "org.jetbrains.compose", version.ref = "compose" } +jetbrains-changelog = "org.jetbrains.changelog:2.2.1" +jetbrains-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-android-extensions = { id = "org.jetbrains.kotlin.android.extensions", version.ref = "kotlin" } +kotlin-dsl = "org.gradle.kotlin.kotlin-dsl:5.1.2" kotlin-js = { id = "org.jetbrains.kotlin.js", version.ref = "kotlin" } +kotlin-jupyter-api = { id = "org.jetbrains.kotlin.jupyter.api", version.ref = "kotlin-jupyter" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } @@ -110,7 +49,70 @@ kotlin-plugin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", versio kotlin-plugin-scripting = { id = "org.jetbrains.kotlin.plugin.scripting", version.ref = "kotlin" } kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } kotlin-plugin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" } - -kotlin-jupyter-api = { id = "org.jetbrains.kotlin.jupyter.api", version.ref = "kotlin-jupyter" } - kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlinx-benchmark" } +kotlinx-kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } +kscience-mpp = { id = "space.kscience.gradle.mpp", version.ref = "tools" } +kscience-project = { id = "space.kscience.gradle.project", version.ref = "tools" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +ktor = { id = "io.ktor.plugin", version.ref = "ktor" } +versions = "com.github.ben-manes.versions:0.51.0" +versions-update = "nl.littlerobots.version-catalog-update:0.8.5" + +[libraries] +atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "atomicfu" } +atomicfu-gradle = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "atomicfu" } +binary-compatibility-validator = "org.jetbrains.kotlinx:binary-compatibility-validator:0.15.0-Beta.3" +changelog-gradle = { module = "org.jetbrains.intellij.plugins:gradle-changelog-plugin", version.ref = "changelog" } +dokka-base = { module = "org.jetbrains.dokka:dokka-base", version.ref = "dokka" } +dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +foojay-resolver = "org.gradle.toolchains:foojay-resolver:0.9.0" +freemarker = "org.freemarker:freemarker:2.3.33" +gradle-changelog-plugin = { module = "org.jetbrains.intellij.plugins:gradle-changelog-plugin", version.ref = "changelog" } +kotlin-assignment-compiler-plugin-embeddable = { module = "org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable", version.ref = "kotlin" } +kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-js-wrappers = { module = "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom", version.ref = "jsBom" } +kotlin-jupyter-api-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-jupyter-api-gradle-plugin", version.ref = "kotlin" } +kotlin-jupyter-gradle = { module = "org.jetbrains.kotlin:kotlin-jupyter-api-gradle-plugin", version.ref = "kotlin-jupyter" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } +kotlin-sam-with-receiver-compiler-plugin-embeddable = { module = "org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable", version.ref = "kotlin" } +kotlin-scripting-compiler-embeddable = { module = "org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable", version.ref = "kotlin" } +kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test" } +kotlinx-benchmark-runtime = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlinx-benchmark" } +kotlinx-cli = { module = "org.jetbrains.kotlinx:kotlinx-cli", version.ref = "kotlinx-cli" } +kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-guava = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-guava", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-javafx = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-javafx", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-jdk8 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-play-services = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-play-services", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-reactive = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactive", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-reactor = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-reactor", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-rx2 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-rx3 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx3", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-slf4j = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-slf4j", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } +kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } +kotlinx-html = { module = "org.jetbrains.kotlinx:kotlinx-html", version.ref = "kotlinx-html" } +kotlinx-knit = { module = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "kotlinx-knit" } +kotlinx-nodejs = { module = "org.jetbrains.kotlinx:kotlinx-nodejs", version.ref = "kotlinx-nodejs" } +kotlinx-serialization-cbor = { module = "org.jetbrains.kotlinx:kotlinx-serialization-cbor", version.ref = "kotlinx-serialization" } +kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serialization" } +kotlinx-serialization-hocon = { module = "org.jetbrains.kotlinx:kotlinx-serialization-hocon", version.ref = "kotlinx-serialization" } +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +kotlinx-serialization-properties = { module = "org.jetbrains.kotlinx:kotlinx-serialization-properties", version.ref = "kotlinx-serialization" } +kotlinx-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlinx-serialization" } +ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } +ktor-bom = { module = "io.ktor:ktor-bom", version.ref = "ktor" } +logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } +slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +tomlj = "org.tomlj:tomlj:1.1.1" +xmlutil-core = { module = "io.github.pdvrieze.xmlutil:core", version.ref = "xmlutil" } +xmlutil-ktor = { module = "io.github.pdvrieze.xmlutil:ktor", version.ref = "xmlutil" } +xmlutil-serialization = { module = "io.github.pdvrieze.xmlutil:serialization", version.ref = "xmlutil" } +yamlkt = { module = "net.mamoe.yamlkt:yamlkt", version.ref = "yamlkt" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1bef7e..e1adfb4 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-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index c4a5192..c799878 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,5 @@ rootProject.name = "gradle-tools" + +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version("0.8.0") +} diff --git a/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt b/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt index 1ac0bfb..66c9914 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceExtension.kt @@ -3,28 +3,33 @@ package space.kscience.gradle import org.gradle.api.Project import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.plugins.ApplicationPlugin +import org.gradle.api.plugins.ExtensionAware import org.gradle.api.provider.Property import org.gradle.api.tasks.Copy import org.gradle.api.tasks.testing.Test import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.kotlin.dsl.* import org.gradle.language.jvm.tasks.ProcessResources +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget -import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBrowserDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl -import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmTargetDsl +import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWasmJsTargetDsl import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlinx.jupyter.api.plugin.tasks.JupyterApiResourcesTask import space.kscience.gradle.internal.defaultKotlinJvmArgs import space.kscience.gradle.internal.fromJsDependencies +import space.kscience.gradle.internal.requestPropertyOrNull import space.kscience.gradle.internal.useCommonDependency +import javax.inject.Inject public enum class DependencyConfiguration { API, @@ -47,9 +52,9 @@ public val Project.isInDevelopment: Boolean || version.toString().endsWith("SNAPSHOT") -private const val defaultJdkVersion = 11 +private const val defaultJdkVersion = 17 -public open class KScienceExtension(public val project: Project) { +public abstract class KScienceExtension @Inject constructor(public val project: Project): ExtensionAware { public val jdkVersionProperty: Property = project.objects.property().apply { set(defaultJdkVersion) @@ -105,7 +110,7 @@ public open class KScienceExtension(public val project: Project) { configure { sourceSets.findByName("commonMain")?.apply { dependencies { - api(platform("io.ktor:ktor-bom:$version")) + api(project.dependencies.platform("io.ktor:ktor-bom:$version")) } } } @@ -114,7 +119,7 @@ public open class KScienceExtension(public val project: Project) { configure { sourceSets.findByName("main")?.apply { dependencies { - api(platform("io.ktor:ktor-bom:$version")) + api(project.dependencies.platform("io.ktor:ktor-bom:$version")) } } } @@ -123,7 +128,7 @@ public open class KScienceExtension(public val project: Project) { configure { sourceSets.findByName("main")?.apply { dependencies { - api(platform("io.ktor:ktor-bom:$version")) + api(project.dependencies.platform("io.ktor:ktor-bom:$version")) } } } @@ -153,14 +158,6 @@ public open class KScienceExtension(public val project: Project) { } } - project.pluginManager.withPlugin("org.jetbrains.kotlin.js") { - project.configure { - sourceSets.getByName(sourceSet ?: "main") { - dependencies(dependencyBlock) - } - } - } - project.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { project.configure { sourceSets.getByName(sourceSet ?: "commonMain") { @@ -179,13 +176,6 @@ public open class KScienceExtension(public val project: Project) { } } - project.pluginManager.withPlugin("org.jetbrains.kotlin.js") { - project.configure { - sourceSets.getByName(sourceSet ?: "test") { - dependencies(dependencyBlock) - } - } - } project.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { project.configure { @@ -207,6 +197,7 @@ public open class KScienceExtension(public val project: Project) { /** * Mark this module as an application module. JVM application should be enabled separately */ + @Deprecated("Use platform-specific applications") public fun application() { project.extensions.findByType()?.apply { explicitApi = null @@ -231,7 +222,7 @@ public open class KScienceExtension(public val project: Project) { binaries.executable() } - targets.withType { + targets.withType { binaries.executable() } } @@ -242,8 +233,8 @@ public open class KScienceExtension(public val project: Project) { */ public fun useContextReceivers() { project.tasks.withType { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" + compilerOptions{ + freeCompilerArgs.add("-Xcontext-receivers") } } } @@ -261,8 +252,8 @@ public open class KScienceExtension(public val project: Project) { public val jsTest: DefaultSourceSet get() = DefaultSourceSet("jsTest") public val nativeMain: DefaultSourceSet get() = DefaultSourceSet("nativeMain") public val nativeTest: DefaultSourceSet get() = DefaultSourceSet("nativeTest") - public val wasmMain: DefaultSourceSet get() = DefaultSourceSet("wasmMain") - public val wasmTest: DefaultSourceSet get() = DefaultSourceSet("wasmTest") + public val wasmJsMain: DefaultSourceSet get() = DefaultSourceSet("wasmJsMain") + public val wasmJsTest: DefaultSourceSet get() = DefaultSourceSet("wasmJsTest") } @@ -285,21 +276,37 @@ public data class KScienceNativeTarget( public val linuxX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.linuxX64) public val mingwX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.mingwX64) public val macosX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.macosX64) - public val macosArm64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.macosX64) + public val macosArm64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.macosArm64) public val iosX64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.iosX64) public val iosArm64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.iosArm64) public val iosSimulatorArm64: KScienceNativeTarget = KScienceNativeTarget(KotlinNativePreset.iosSimulatorArm64) } } -public class KScienceNativeConfiguration { +public class KScienceNativeConfiguration(private val project: Project) { internal companion object { - private fun defaultNativeTargets(): Map { - + private fun defaultNativeTargets(project: Project): Map { val hostOs = System.getProperty("os.name") + + val targets = project.requestPropertyOrNull("publishing.targets") + return when { + targets == "all" -> listOf( + KScienceNativeTarget.linuxX64, + KScienceNativeTarget.mingwX64, + KScienceNativeTarget.macosX64, + KScienceNativeTarget.macosArm64, + KScienceNativeTarget.iosX64, + KScienceNativeTarget.iosArm64, + KScienceNativeTarget.iosSimulatorArm64, + ) + + targets != null -> { + targets.split(",").map { KScienceNativeTarget(KotlinNativePreset.valueOf(it)) } + } + hostOs.startsWith("Windows") -> listOf( KScienceNativeTarget.linuxX64, KScienceNativeTarget.mingwX64 @@ -314,6 +321,7 @@ public class KScienceNativeConfiguration { ) hostOs == "Linux" -> listOf(KScienceNativeTarget.linuxX64) + else -> { emptyList() } @@ -322,7 +330,7 @@ public class KScienceNativeConfiguration { } - internal var targets: Map = defaultNativeTargets() + internal var targets: Map = defaultNativeTargets(project) /** @@ -346,7 +354,8 @@ public class KScienceNativeConfiguration { ): Unit = target(KScienceNativeTarget(preset, targetName, targetConfiguration)) } -public open class KScienceMppExtension(project: Project) : KScienceExtension(project) { +public abstract class KScienceMppExtension @Inject constructor(project: Project) : KScienceExtension(project) { + /** * Enable jvm target */ @@ -354,10 +363,9 @@ public open class KScienceMppExtension(project: Project) : KScienceExtension(pro project.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { project.configure { jvm { - compilations.all { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + defaultKotlinJvmArgs - } + @OptIn(ExperimentalKotlinGradlePluginApi::class) + compilerOptions{ + freeCompilerArgs.addAll(defaultKotlinJvmArgs) } block() } @@ -387,6 +395,7 @@ public open class KScienceMppExtension(project: Project) : KScienceExtension(pro project.configure { js(IR) { browser() + useEsModules() block() } sourceSets { @@ -403,14 +412,31 @@ public open class KScienceMppExtension(project: Project) : KScienceExtension(pro } } + /** + * Add Wasm/Js target + */ @OptIn(ExperimentalWasmDsl::class) - public fun wasm(block: KotlinWasmTargetDsl.() -> Unit = {}) { + public fun wasm(block: KotlinWasmJsTargetDsl.() -> Unit = {}) { + project.pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { project.configure { - wasm { - browser() + wasmJs { + browser { + testTask { + useKarma { + useChromeHeadless() + } + } + } block() } + sourceSets { + getByName("wasmJsTest") { + dependencies { + implementation(kotlin("test-wasm-js")) + } + } + } } } } @@ -425,26 +451,30 @@ public open class KScienceMppExtension(project: Project) : KScienceExtension(pro */ public fun fullStack( bundleName: String = "js/bundle.js", + development: Boolean = false, jvmConfig: KotlinJvmTarget.() -> Unit = {}, jsConfig: KotlinJsTargetDsl.() -> Unit = {}, browserConfig: KotlinJsBrowserDsl.() -> Unit = {}, ) { js { - binaries.executable() browser { - webpackTask { + commonWebpackConfig{ outputFileName = bundleName } browserConfig() } + useEsModules() jsConfig() + binaries.executable() } jvm { val processResourcesTaskName = - compilations[org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.MAIN_COMPILATION_NAME] - .processResourcesTaskName + compilations[KotlinCompilation.MAIN_COMPILATION_NAME].processResourcesTaskName - val jsBrowserDistribution = project.tasks.getByName("jsBrowserDistribution") + + val jsBrowserDistribution = project.tasks.getByName( + if (development) "jsBrowserDevelopmentExecutableDistribution" else "jsBrowserDistribution" + ) project.tasks.getByName(processResourcesTaskName) { duplicatesStrategy = DuplicatesStrategy.WARN @@ -459,90 +489,59 @@ public open class KScienceMppExtension(project: Project) : KScienceExtension(pro * Enable all supported native targets */ public fun native(block: KScienceNativeConfiguration.() -> Unit = {}): Unit = with(project) { - val nativeConfiguration = KScienceNativeConfiguration().apply(block) + val nativeConfiguration = KScienceNativeConfiguration(this).apply(block) pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { configure { - val nativeTargets: List = - nativeConfiguration.targets.values.map { nativeTarget -> - when (nativeTarget.preset) { - KotlinNativePreset.linuxX64 -> linuxX64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + nativeConfiguration.targets.values.forEach { nativeTarget -> + when (nativeTarget.preset) { + KotlinNativePreset.linuxX64 -> linuxX64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.mingwX64 -> mingwX64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + KotlinNativePreset.mingwX64 -> mingwX64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.macosX64 -> macosX64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + KotlinNativePreset.macosX64 -> macosX64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.macosArm64 -> macosArm64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + KotlinNativePreset.macosArm64 -> macosArm64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.iosX64 -> iosX64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + KotlinNativePreset.iosX64 -> iosX64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.iosArm64 -> iosArm64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) + KotlinNativePreset.iosArm64 -> iosArm64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) - KotlinNativePreset.iosSimulatorArm64 -> iosSimulatorArm64( - nativeTarget.targetName, - nativeTarget.targetConfiguration - ) - -// else -> { -// logger.error("Native preset ${nativeTarget.preset} not recognised.") -// null -// } - } - } - - sourceSets { - val commonMain by getting - val commonTest by getting - - val nativeMain by creating { - dependsOn(commonMain) - } - - val nativeTest by creating { - //should NOT depend on nativeMain because automatic dependency by plugin - dependsOn(commonTest) - } - - configure(nativeTargets) { - compilations["main"]?.apply { - configure(kotlinSourceSets) { - dependsOn(nativeMain) - } - } - - compilations["test"]?.apply { - configure(kotlinSourceSets) { - dependsOn(nativeTest) - } - } + KotlinNativePreset.iosSimulatorArm64 -> iosSimulatorArm64( + nativeTarget.targetName, + nativeTarget.targetConfiguration + ) } } + applyDefaultHierarchyTemplate() } } } } -internal inline fun Project.registerKScienceExtension(constructor: (Project) -> T): T { - extensions.findByType()?.let { return it } - return constructor(this).also { - extensions.add("kscience", it) - } +internal inline fun Project.registerKScienceExtension():T { +// extensions.findByType()?.let { return it } +// return constructor(this).also { +// extensions.add("kscience", it) +// } + + return extensions.create("kscience", T::class.java) } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceJSPlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceJSPlugin.kt deleted file mode 100644 index 0610cd3..0000000 --- a/src/main/kotlin/space/kscience/gradle/KScienceJSPlugin.kt +++ /dev/null @@ -1,56 +0,0 @@ -package space.kscience.gradle - -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.tasks.Copy -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.get -import org.jetbrains.dokka.gradle.DokkaPlugin -import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension -import space.kscience.gradle.internal.applySettings -import space.kscience.gradle.internal.fromJsDependencies - -public open class KScienceJSPlugin : Plugin { - override fun apply(project: Project): Unit = project.run { - if (!plugins.hasPlugin("org.jetbrains.kotlin.js")) { - plugins.apply("org.jetbrains.kotlin.js") - } else { - logger.info("Kotlin JS plugin is already present") - } - registerKScienceExtension(::KScienceExtension) - - //logger.info("Applying KScience configuration for JS project") - configure { - js(IR) { browser { } } - - sourceSets.all { - languageSettings.applySettings() - } - - sourceSets["main"].apply { - dependencies { - api(project.dependencies.platform("org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${KScienceVersions.jsBom}")) - } - } - - sourceSets["test"].apply { - dependencies { - implementation(kotlin("test-js")) - } - } - - if (explicitApi == null) explicitApiWarning() - } - - (tasks.findByName("processResources") as? Copy)?.apply { - fromJsDependencies("runtimeClasspath") - } - - - // apply dokka for all projects - if (!plugins.hasPlugin("org.jetbrains.dokka")) { - apply() - } - } -} diff --git a/src/main/kotlin/space/kscience/gradle/KScienceJVMPlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceJVMPlugin.kt index 168297b..1cb85e1 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceJVMPlugin.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceJVMPlugin.kt @@ -10,23 +10,27 @@ import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.withType import org.jetbrains.dokka.gradle.DokkaPlugin import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import space.kscience.gradle.internal.applySettings import space.kscience.gradle.internal.defaultKotlinJvmArgs public open class KScienceJVMPlugin : Plugin { override fun apply(project: Project): Unit = project.run { + + logger.warn("KSCience JVM plugin is deprecated. Use MPP.") if (!plugins.hasPlugin("org.jetbrains.kotlin.jvm")) { plugins.apply("org.jetbrains.kotlin.jvm") } else { logger.info("Kotlin JVM plugin is already present") } - val extension = registerKScienceExtension(::KScienceExtension) + val extension = registerKScienceExtension() //logger.info("Applying KScience configuration for JVM project") configure { sourceSets.all { languageSettings.applySettings() + compilerOptions{ + freeCompilerArgs.addAll(defaultKotlinJvmArgs) + } } sourceSets["test"].apply { @@ -42,12 +46,6 @@ public open class KScienceJVMPlugin : Plugin { } } - tasks.withType { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + defaultKotlinJvmArgs - } - } - tasks.withType { useJUnitPlatform() } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceMPPlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceMPPlugin.kt index cb02302..8741a82 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceMPPlugin.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceMPPlugin.kt @@ -4,45 +4,57 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.hasPlugin import org.gradle.kotlin.dsl.invoke import org.jetbrains.dokka.gradle.DokkaPlugin +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import space.kscience.gradle.internal.applySettings +import space.kscience.gradle.internal.defaultKotlinCommonArgs public open class KScienceMPPlugin : Plugin { + override fun apply(project: Project): Unit = project.run { - if (!plugins.hasPlugin(KotlinMultiplatformPlugin::class)) { + if (!plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) { //apply() for some reason it does not work plugins.apply("org.jetbrains.kotlin.multiplatform") } else { logger.info("Kotlin MPP plugin is already present") } - registerKScienceExtension(::KScienceMppExtension) + val kscience = registerKScienceExtension() configure { - sourceSets { - getByName("commonMain"){ + getByName("commonMain") { dependencies { api(project.dependencies.platform("org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${KScienceVersions.jsBom}")) } } - getByName("commonTest"){ + getByName("commonTest") { dependencies { - implementation(kotlin("test-common")) + implementation(kotlin("test")) implementation(kotlin("test-annotations-common")) } } + all { + languageSettings.applySettings() + } } - - sourceSets.all { - languageSettings.applySettings() + @OptIn(ExperimentalKotlinGradlePluginApi::class) + compilerOptions { + freeCompilerArgs.addAll(defaultKotlinCommonArgs) } if (explicitApi == null) explicitApiWarning() + + //pass compose extension inside kscience extensions to make it available inside kscience block + plugins.withId("org.jetbrains.compose") { + kscience.extensions.add( + "compose", + (this@configure as org.gradle.api.plugins.ExtensionAware).extensions.getByName("compose") + ) + } + } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceProjectPlugin.kt b/src/main/kotlin/space/kscience/gradle/KScienceProjectPlugin.kt index b979c69..d1ec666 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceProjectPlugin.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceProjectPlugin.kt @@ -12,7 +12,12 @@ import org.jetbrains.changelog.ChangelogPlugin import org.jetbrains.changelog.ChangelogPluginExtension import org.jetbrains.dokka.gradle.AbstractDokkaTask import org.jetbrains.dokka.gradle.DokkaPlugin -import space.kscience.gradle.internal.* +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin +import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension +import space.kscience.gradle.internal.addPublishing +import space.kscience.gradle.internal.addSonatypePublishing +import space.kscience.gradle.internal.setupPublication /** * Simplifies adding repositories for Maven publishing, responds for releasing tasks for projects. @@ -51,46 +56,24 @@ public class KSciencePublishingExtension(public val project: Project) { } /** - * Adds GitHub as VCS and adds GitHub Packages Maven repository to publishing. - * - * @param githubProject the GitHub project. - * @param githubOrg the GitHub user or organization. - * @param deploy publish packages in the `deploy` task to the GitHub repository. + * Add a repository with [repositoryName]. Uses "publishing.$repositoryName.user" and "publishing.$repositoryName.token" + * properties pattern to store user and token */ - public fun github( - githubOrg: String, - githubProject: String, - deploy: Boolean = project.requestPropertyOrNull("publishing.github") == "true", + public fun repository( + repositoryName: String, + url: String, ) { - if (deploy) { - try { - project.addGithubPublishing(githubOrg, githubProject) - } catch (t: Throwable) { - project.logger.error("Failed to set up github publication", t) - } - } - } - - /** - * Adds Space Packages Maven repository to publishing. - * - * @param spaceRepo the repository URL. - * @param deploy publish packages in the `deploy` task to the Space repository. - */ - public fun space( - spaceRepo: String, - ) { - project.addSpacePublishing(spaceRepo) + require(isVcsInitialized) { "The project vcs is not set up use 'pom' method to do so" } + project.addPublishing(repositoryName, url) } /** * Adds Sonatype Maven repository to publishing. - * - * @param addToRelease publish packages in the `release` task to the Sonatype repository. + */ - public fun sonatype() { + public fun sonatype(sonatypeRoot: String = "https://s01.oss.sonatype.org") { require(isVcsInitialized) { "The project vcs is not set up use 'pom' method to do so" } - project.addSonatypePublishing() + project.addSonatypePublishing(sonatypeRoot) } } @@ -104,11 +87,11 @@ public open class KScienceProjectPlugin : Plugin { apply() apply() - allprojects{ - repositories{ + allprojects { + repositories { mavenCentral() maven("https://repo.kotlin.link") - maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev") + google() } // Workaround for https://github.com/gradle/gradle/issues/15568 @@ -139,11 +122,12 @@ public open class KScienceProjectPlugin : Plugin { val readmeExtension = KScienceReadmeExtension(this) extensions.add("readme", readmeExtension) - @Suppress("UNUSED_VARIABLE") - val generateReadme by tasks.creating { + tasks.create("generateReadme") { group = "documentation" description = "Generate a README file if stub is present" + inputs.property("extension", readmeExtension) + if (readmeExtension.readmeTemplate.exists()) { inputs.file(readmeExtension.readmeTemplate) } @@ -179,6 +163,8 @@ public open class KScienceProjectPlugin : Plugin { } } + inputs.property("extension", rootReadmeExtension) + if (rootReadmeExtension.readmeTemplate.exists()) { inputs.file(rootReadmeExtension.readmeTemplate) } @@ -206,7 +192,7 @@ public open class KScienceProjectPlugin : Plugin { subproject.extensions.findByType()?.let { ext -> val path = subproject.path.replaceFirst(":", "").replace(":", "/") appendLine("\n### [$path]($path)") - appendLine("> ${ext.description}") + ext.description?.let { appendLine("> ${ext.description}") } appendLine(">\n> **Maturity**: ${ext.maturity}") val featureString = ext.featuresString(itemPrefix = "> - ", pathPrefix = "$path/") if (featureString.isNotBlank()) { @@ -233,12 +219,12 @@ public open class KScienceProjectPlugin : Plugin { tasks.create("version") { group = "publishing" - val versionFile = project.buildDir.resolve("project-version.txt") - outputs.file(versionFile) + val versionFileProvider = project.layout.buildDirectory.file("project-version.txt") + outputs.file(versionFileProvider) doLast { + val versionFile = versionFileProvider.get().asFile versionFile.createNewFile() versionFile.writeText(project.version.toString()) - println(project.version) } } @@ -250,9 +236,11 @@ public open class KScienceProjectPlugin : Plugin { } } - plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin::class.java) { - rootProject.the().lockFileDirectory = - rootDir.resolve("gradle") + plugins.withType() { + rootProject.configure { + lockFileDirectory = rootDir.resolve("gradle") + yarnLockMismatchReport = YarnLockMismatchReport.WARNING + } } } diff --git a/src/main/kotlin/space/kscience/gradle/KScienceReadmeExtension.kt b/src/main/kotlin/space/kscience/gradle/KScienceReadmeExtension.kt index b79e64f..8345fac 100644 --- a/src/main/kotlin/space/kscience/gradle/KScienceReadmeExtension.kt +++ b/src/main/kotlin/space/kscience/gradle/KScienceReadmeExtension.kt @@ -10,6 +10,7 @@ import kotlinx.html.stream.createHTML import kotlinx.validation.ApiValidationExtension import org.gradle.api.Project import org.gradle.kotlin.dsl.findByType +import org.intellij.lang.annotations.Language import java.io.File import java.io.StringWriter import kotlin.collections.component1 @@ -32,7 +33,8 @@ private fun Template.processToString(args: Map): String { public class KScienceReadmeExtension(public val project: Project) { - public var description: String = project.description ?: "" + public var description: String? = null + get() = field ?: project.description public var maturity: Maturity = Maturity.EXPERIMENTAL set(value) { @@ -88,12 +90,23 @@ public class KScienceReadmeExtension(public val project: Project) { public data class Feature(val id: String, val description: String, val ref: String?, val name: String = id) - public val features: MutableList = ArrayList() + public val features: MutableList = mutableListOf() - public fun feature(id: String, ref: String? = null, name: String = id, description: () -> String) { + /** + * A plain readme feature with description + */ + public fun feature( + id: String, + @Language("File") ref: String? = null, + name: String = id, + description: () -> String, + ) { features += Feature(id, description(), ref, name) } + /** + * A readme feature with HTML description + */ public fun featureWithHtml( id: String, ref: String? = null, @@ -177,4 +190,38 @@ public class KScienceReadmeExtension(public val project: Project) { project.logger.warn("Template with name ${ex.templateName} not found in ${project.name}") null } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KScienceReadmeExtension + + if (project != other.project) return false + if (maturity != other.maturity) return false + if (useDefaultReadmeTemplate != other.useDefaultReadmeTemplate) return false + if (readmeTemplate != other.readmeTemplate) return false + if (fmLoader != other.fmLoader) return false + if (fmCfg != other.fmCfg) return false + if (features != other.features) return false + if (properties != other.properties) return false + if (inputFiles != other.inputFiles) return false + + return true + } + + override fun hashCode(): Int { + var result = project.hashCode() + result = 31 * result + maturity.hashCode() + result = 31 * result + useDefaultReadmeTemplate.hashCode() + result = 31 * result + readmeTemplate.hashCode() + result = 31 * result + fmLoader.hashCode() + result = 31 * result + fmCfg.hashCode() + result = 31 * result + features.hashCode() + result = 31 * result + properties.hashCode() + result = 31 * result + inputFiles.hashCode() + return result + } + + } diff --git a/src/main/kotlin/space/kscience/gradle/internal/common.kt b/src/main/kotlin/space/kscience/gradle/internal/common.kt index 0979bd2..8013390 100644 --- a/src/main/kotlin/space/kscience/gradle/internal/common.kt +++ b/src/main/kotlin/space/kscience/gradle/internal/common.kt @@ -7,8 +7,13 @@ import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder import space.kscience.gradle.KScienceVersions -internal val defaultKotlinJvmArgs: List = - listOf("-Xjvm-default=all", "-Xlambdas=indy"/* "-Xjdk-release=${KScienceVersions.JVM_TARGET}"*/) +internal val defaultKotlinJvmArgs: List = listOf( + "-Xjvm-default=all" +) + +internal val defaultKotlinCommonArgs: List = listOf( + "-Xexpect-actual-classes" +) internal fun resolveKotlinVersion(): KotlinVersion { val (major, minor, patch) = KScienceVersions.kotlinVersion.split(".", "-") @@ -23,6 +28,7 @@ internal fun LanguageSettingsBuilder.applySettings( apiVersion = versionString progressiveMode = true + optIn("kotlin.RequiresOptIn") optIn("kotlin.ExperimentalUnsignedTypes") optIn("kotlin.ExperimentalStdlibApi") diff --git a/src/main/kotlin/space/kscience/gradle/internal/publishing.kt b/src/main/kotlin/space/kscience/gradle/internal/publishing.kt index f0d15c3..3b94276 100644 --- a/src/main/kotlin/space/kscience/gradle/internal/publishing.kt +++ b/src/main/kotlin/space/kscience/gradle/internal/publishing.kt @@ -8,9 +8,7 @@ import org.gradle.api.tasks.bundling.Jar import org.gradle.kotlin.dsl.* import org.gradle.plugins.signing.SigningExtension import org.gradle.plugins.signing.SigningPlugin -import org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.targets import space.kscience.gradle.isInDevelopment internal fun Project.requestPropertyOrNull(propertyName: String): String? = findProperty(propertyName) as? String @@ -24,26 +22,6 @@ internal fun Project.setupPublication(mavenPomConfiguration: MavenPom.() -> Unit plugins.withId("maven-publish") { configure { - plugins.withId("org.jetbrains.kotlin.js") { - val kotlin: KotlinJsProjectExtension = extensions.findByType()!! - - val sourcesJar by tasks.creating(Jar::class) { - archiveClassifier.set("sources") - kotlin.sourceSets.forEach { - from(it.kotlin) - } - } - - publications.create("js") { - kotlin.targets.flatMap { it.components }.forEach { - from(it) - } - - artifact(sourcesJar) - } - - } - plugins.withId("org.jetbrains.kotlin.jvm") { val kotlin = extensions.findByType()!! @@ -55,9 +33,7 @@ internal fun Project.setupPublication(mavenPomConfiguration: MavenPom.() -> Unit } publications.create("jvm") { - kotlin.target.components.forEach { - from(it) - } + from(project.components["java"]) artifact(sourcesJar) } @@ -100,7 +76,7 @@ internal fun Project.setupPublication(mavenPomConfiguration: MavenPom.() -> Unit val signingKey: String = requestProperty("publishing.signing.key") val signingPassphrase: String = requestProperty("publishing.signing.passPhrase") - // if key is provided, use it + // if a key is provided, use it useInMemoryPgpKeys(signingId, signingKey, signingPassphrase) } // else use agent signing sign(publications) @@ -112,34 +88,31 @@ internal fun Project.setupPublication(mavenPomConfiguration: MavenPom.() -> Unit } } -internal fun Project.addGithubPublishing( - githubOrg: String, - githubProject: String, -) { - if (requestPropertyOrNull("publishing.enabled") != "true") { - logger.info("Skipping github publishing because publishing is disabled") - return - } - if (requestPropertyOrNull("publishing.github") != "false") { - logger.info("Skipping github publishing because `publishing.github != true`") - return - } +internal fun Project.addPublishing( + repositoryName: String, + urlString:String +){ + require(repositoryName.matches("\\w*".toRegex())){"Repository name must contain only letters or numbers"} + val user: String? = requestPropertyOrNull("publishing.$repositoryName.user") + val token: String? = requestPropertyOrNull("publishing.$repositoryName.token") - val githubUser: String = requestProperty("publishing.github.user") - val githubToken: String = requestProperty("publishing.github.token") + if (user == null || token == null) { + logger.info("Skipping $repositoryName publishing because $repositoryName credentials are not defined") + return + } allprojects { plugins.withId("maven-publish") { configure { - logger.info("Adding github publishing to project [${project.name}]") + logger.info("Adding $repositoryName publishing to project [${project.name}]") repositories.maven { - name = "github" - url = uri("https://maven.pkg.github.com/$githubOrg/$githubProject/") + name = repositoryName + url = uri(urlString) credentials { - username = githubUser - password = githubToken + username = user + password = token } } } @@ -147,72 +120,11 @@ internal fun Project.addGithubPublishing( } } -internal fun Project.addSpacePublishing(spaceRepo: String) { - if (requestPropertyOrNull("publishing.enabled") != "true") { - logger.info("Skipping space publishing because publishing is disabled") - return - } - - if (requestPropertyOrNull("publishing.space") == "false") { - logger.info("Skipping space publishing because `publishing.space == false`") - return - } - - val spaceUser: String = requestProperty("publishing.space.user") - val spaceToken: String = requestProperty("publishing.space.token") - - allprojects { - plugins.withId("maven-publish") { - configure { - project.logger.info("Adding mipt-npm Space publishing to project [${project.name}]") - - repositories.maven { - name = "space" - url = uri(spaceRepo) - - credentials { - username = spaceUser - password = spaceToken - } - } - } - } - } -} - -internal fun Project.addSonatypePublishing() { - if (requestPropertyOrNull("publishing.enabled") != "true") { - logger.info("Skipping sonatype publishing because publishing is disabled") - return - } +internal fun Project.addSonatypePublishing(sonatypeRoot: String) { if (isInDevelopment) { logger.info("Sonatype publishing skipped for development version") - return - } - - if (requestPropertyOrNull("publishing.sonatype") == "false") { - logger.info("Skipping sonatype publishing because `publishing.sonatype == false`") - return - } - - val sonatypeUser: String = requestProperty("publishing.sonatype.user") - val sonatypePassword: String = requestProperty("publishing.sonatype.password") - - allprojects { - plugins.withId("maven-publish") { - configure { - repositories.maven { - val sonatypeRepo = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2" - name = "sonatype" - url = uri(sonatypeRepo) - - credentials { - username = sonatypeUser - password = sonatypePassword - } - } - } - } + } else { + addPublishing("sonatype", "$sonatypeRoot/service/local/staging/deploy/maven2") } } diff --git a/src/main/kotlin/space/kscience/gradle/pomConfig.kt b/src/main/kotlin/space/kscience/gradle/pomConfig.kt index 5cea379..dc4770d 100644 --- a/src/main/kotlin/space/kscience/gradle/pomConfig.kt +++ b/src/main/kotlin/space/kscience/gradle/pomConfig.kt @@ -17,7 +17,7 @@ public fun MavenPom.useSPCTeam(){ developer { id.set("SPC") name.set("Scientific programming centre") - organization.set("MIPT") + organization.set("SPC") organizationUrl.set("https://sciprog.center/") } } diff --git a/src/main/resources/templates/ARTIFACT-TEMPLATE.md b/src/main/resources/templates/ARTIFACT-TEMPLATE.md index 4f04b4d..5d39742 100644 --- a/src/main/resources/templates/ARTIFACT-TEMPLATE.md +++ b/src/main/resources/templates/ARTIFACT-TEMPLATE.md @@ -2,17 +2,6 @@ The Maven coordinates of this project are `${group}:${name}:${version}`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation '${group}:${name}:${version}' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories {