diff --git a/.github/changelog_config.json b/.github/changelog_config.json index c53db87..2d8f82d 100644 --- a/.github/changelog_config.json +++ b/.github/changelog_config.json @@ -50,7 +50,7 @@ ], "label_extractor" : [ { - "pattern" : "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)", + "pattern" : "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|feat!|breaking|api){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)", "target" : "$1" } ] diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties index 6489d6c..b517966 100644 --- a/.github/ci-gradle.properties +++ b/.github/ci-gradle.properties @@ -1,5 +1,6 @@ -org.gradle.jvmargs=-Xmx3g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -Dfile.encoding=UTF-8 -kotlin.daemon.jvmargs=-Xmx3g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -XX:MaxMetaspaceSize=1g +# suppress inspection "UnusedProperty" for whole file +org.gradle.jvmargs=-Xmx6g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -Dfile.encoding=UTF-8 +kotlin.daemon.jvmargs=-Xmx6g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -XX:MaxMetaspaceSize=2g android.useAndroidX=true kotlin.code.style=official org.gradle.caching=true @@ -8,21 +9,37 @@ android.enableR8.fullMode=true org.gradle.configureondemand=true android.enableJetifier=false kotlin.incremental.usePreciseJavaTracking=true +org.gradle.configuration-cache.problems=warn android.nonTransitiveRClass=true android.experimental.enableSourceSetPathsMap=true android.experimental.cacheCompileLibResources=true kotlin.mpp.enableCInteropCommonization=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.androidGradlePluginCompatibility.nowarn=true org.gradle.unsafe.configuration-cache=true kotlin.mpp.androidSourceSetLayoutVersion=2 android.disableResourceValidation=false -org.gradle.daemon=true +org.gradle.daemon=false android.nonFinalResIds=true -kotlin.native.ignoreIncorrectDependencies=true kotlinx.atomicfu.enableJvmIrTransformation=true -org.jetbrains.compose.experimental.macos.enabled=true -org.gradle.configuration-cache.problems=warn +android.lint.useK2Uast=true nl.littlerobots.vcu.resolver=true -org.gradle.console=plain +org.jetbrains.compose.experimental.jscanvas.enabled=true +org.jetbrains.compose.experimental.wasm.enabled=true +org.jetbrains.compose.experimental.macos.enabled=true +# Do not garbage collect on timeout on native when appExtensions are used and app is in bacground +kotlin.native.binary.appStateTracking=enabled +# Lift main thread suspending function invocation restriction +kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none +# Native incremental compilation +kotlin.incremental.native=true +android.experimental.additionalArtifactsInModel=true +kotlin.apple.xcodeCompatibility.nowarn=true +# Enable new k/n GC +kotlin.native.binary.gc=cms +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true +org.gradle.configuration-cache.parallel=true release=true +#kotlin.kmp.isolated-projects.support=enable +kotlin.incremental.wasm=true +#org.gradle.unsafe.isolated-projects=true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf42574..fc20b40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: with: distribution: 'zulu' check-latest: true - java-version: 22 + java-version: 23 cache: 'gradle' - name: Validate gradle wrapper diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 230acc8..a2e02d4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -29,7 +29,7 @@ jobs: with: distribution: 'zulu' check-latest: true - java-version: 22 + java-version: 23 cache: 'gradle' - name: Validate gradle wrapper @@ -39,10 +39,13 @@ jobs: run: cp ./README.md ./docs/README.md - name: Generate docs - run: ./gradlew :dokkaHtmlMultiModule --no-configuration-cache + run: ./gradlew dokkaGenerate + + - name: Make javadoc dir + run: mkdir -p ./docs/javadocs - name: Move docs to the parent docs dir - run: cp -r ./build/dokka/htmlMultiModule/ ./docs/javadocs/ + run: cp -r ./build/dokka/html/ ./docs/javadocs - name: Setup Pages uses: actions/configure-pages@v5 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2089086..0a889fc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,17 +21,18 @@ jobs: environment: publishing steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - name: Copy CI gradle.properties run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties - - name: set up JDK + - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'zulu' check-latest: true - java-version: 22 + java-version: 23 cache: 'gradle' - name: Validate gradle wrapper @@ -41,6 +42,19 @@ jobs: with: xcode-version: latest + - name: Create local properties + env: + LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }} + run: echo "$LOCAL_PROPERTIES" | base64 --decode > local.properties + + - name: Cache konan directory + uses: actions/cache@v4 + with: + path: ~/.konan + key: ${{ runner.os }}-konan-${{ hashFiles('*.gradle.kts', 'buildSrc/*') }} + restore-keys: | + ${{ runner.os }}-konan- + - name: Publish to sonatype env: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 3b7cb78..eec6ccd 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -8,6 +8,6 @@ jobs: assign_author: runs-on: macos-latest steps: - - uses: samspills/assign-pr-to-author@v1 + - uses: samspills/assign-pr-to-author@v1.0.2 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.gitignore b/.gitignore index 6661414..00e4996 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,5 @@ hs_err_pid* !gradle/gradle-wrapper.jar /.idea/appInsightsSettings.xml /.idea/migrations.xml +.kotlin +kotlin-js-store/yarn.lock diff --git a/build.gradle.kts b/build.gradle.kts index 365aac2..05108dc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,86 +1,42 @@ +import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.KotlinMultiplatform import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.MavenPublishBasePlugin import com.vanniktech.maven.publish.SonatypeHost import nl.littlerobots.vcu.plugin.versionCatalogUpdate import nl.littlerobots.vcu.plugin.versionSelector import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradleSubplugin -import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag.Companion.OptimizeNonSkippingGroups +import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag 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 org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { alias(libs.plugins.detekt) alias(libs.plugins.gradleDoctor) alias(libs.plugins.version.catalog.update) - alias(libs.plugins.dokka) - alias(libs.plugins.dependencyAnalysis) - alias(libs.plugins.atomicfu) - alias(libs.plugins.maven.publish) apply false alias(libs.plugins.compose.compiler) apply false - alias(libs.plugins.compose) apply false - alias(libs.plugins.serialization) apply false + alias(libs.plugins.maven.publish) apply false + // alias(libs.plugins.atomicfu) apply false + dokkaDocumentation // plugins already on a classpath (conventions) + // alias(libs.plugins.dokka) apply false // alias(libs.plugins.androidApplication) apply false // alias(libs.plugins.androidLibrary) apply false // alias(libs.plugins.kotlinMultiplatform) apply false } -buildscript { - dependencies { - classpath(libs.android.gradle) - classpath(libs.kotlin.gradle) - classpath(libs.detekt.gradle) - } -} - allprojects { group = Config.artifactId version = Config.versionName - - tasks.withType().configureEach { - compilerOptions { - jvmTarget.set(Config.jvmTarget) - freeCompilerArgs.addAll(Config.jvmCompilerArgs) - optIn.addAll(Config.optIns) - } - } -} - -atomicfu { - dependenciesVersion = rootProject.libs.versions.kotlinx.atomicfu.get() - transformJvm = false - jvmVariant = "VH" - transformJs = false } subprojects { - apply(plugin = rootProject.libs.plugins.dokka.id) - - dependencies { - dokkaPlugin(rootProject.libs.dokka.android) - } - - tasks { - withType().configureEach { - useJUnitPlatform() - filter { isFailOnNoMatchingTests = true } - } - register("dokkaJavadocJar") { - dependsOn(dokkaJavadoc) - from(dokkaJavadoc.flatMap { it.outputDirectory }) - archiveClassifier.set("javadoc") - } - - register("emptyJavadocJar") { - archiveClassifier.set("javadoc") - } - } plugins.withType().configureEach { the().apply { - featureFlags.addAll(OptimizeNonSkippingGroups) - stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_definitions.txt") + featureFlags.addAll(ComposeFeatureFlag.OptimizeNonSkippingGroups) + stabilityConfigurationFiles.add(rootProject.layout.projectDirectory.file("stability_definitions.txt")) if (properties["enableComposeCompilerReports"] == "true") { val metricsDir = layout.buildDirectory.dir("compose_metrics") metricsDestination = metricsDir @@ -88,9 +44,16 @@ subprojects { } } } - afterEvaluate { - extensions.findByType()?.run { + plugins.withType { + the().apply { val isReleaseBuild = properties["release"]?.toString().toBoolean() + configure( + KotlinMultiplatform( + javadocJar = JavadocJar.Empty(), + sourcesJar = true, + androidVariantsToPublish = listOf("release"), + ) + ) publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, false) if (isReleaseBuild) signAllPublications() coordinates(Config.artifactId, name, Config.version(isReleaseBuild)) @@ -120,6 +83,12 @@ subprojects { } } } + tasks { + withType().configureEach { + useJUnitPlatform() + filter { isFailOnNoMatchingTests = true } + } + } } doctor { @@ -128,12 +97,6 @@ doctor { } } -dependencyAnalysis { - structure { - ignoreKtx(true) - } -} - dependencies { detektPlugins(rootProject.libs.detekt.formatting) detektPlugins(rootProject.libs.detekt.compose) @@ -152,11 +115,12 @@ versionCatalogUpdate { } } +// atomicfu { +// dependenciesVersion = libs.versions.atomicfu.get() +// jvmVariant = "VH" +// } + tasks { - dokkaHtmlMultiModule.configure { - moduleName.set(rootProject.name) - } - // needed to generate compose compiler reports. See /scripts withType().configureEach { buildUponDefaultConfig = true parallel = true @@ -197,3 +161,14 @@ rootProject.plugins.withType().configureEach { yarnLockAutoReplace = true } } + +dependencies { + detektPlugins(rootProject.libs.detekt.formatting) + detektPlugins(rootProject.libs.detekt.compose) + detektPlugins(rootProject.libs.detekt.libraries) + projects.run { + listOf( + common, compose, coroutines, datetime, inputforms + ).forEach { dokka(it) } + } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 133166f..0a525a1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -8,4 +8,5 @@ plugins { dependencies { implementation(libs.android.gradle) implementation(libs.kotlin.gradle) + implementation(libs.dokka.gradle) } diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index 1e0ca07..d540712 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -17,8 +17,8 @@ object Config { const val artifactId = "$group.$artifact" const val majorRelease = 1 - const val minorRelease = 4 - const val patch = 4 + const val minorRelease = 5 + const val patch = 0 const val postfix = "" const val versionName = "$majorRelease.$minorRelease.$patch$postfix" @@ -34,31 +34,40 @@ object Config { const val name = "KMPUtils" // kotlin + val jvmTarget = JvmTarget.JVM_11 + val javaVersion = JavaVersion.VERSION_11 + const val compileSdk = 35 + const val targetSdk = compileSdk + const val minSdk = 21 + const val appMinSdk = 26 + const val publishingVariant = "release" + val optIns = listOf( "kotlinx.coroutines.ExperimentalCoroutinesApi", "kotlinx.coroutines.FlowPreview", "kotlin.RequiresOptIn", "kotlin.experimental.ExperimentalTypeInference", - "kotlin.contracts.ExperimentalContracts" + "kotlin.uuid.ExperimentalUuidApi", + "kotlin.contracts.ExperimentalContracts", ) val compilerArgs = listOf( + "-Xbackend-threads=0", // parallel IR compilation + "-Xexpect-actual-classes", + "-Xwasm-use-new-exception-proposal", "-Xconsistent-data-class-copy-visibility", + "-Xsuppress-warning=NOTHING_TO_INLINE", + "-Xsuppress-warning=UNUSED_ANONYMOUS_PARAMETER", + "-Xwasm-debugger-custom-formatters" ) val jvmCompilerArgs = buildList { + addAll(compilerArgs) add("-Xjvm-default=all") // enable all jvm optimizations + add("-Xcontext-receivers") add("-Xstring-concat=inline") - add("-Xbackend-threads=0") // parallel IR compilation - addAll(optIns.map { "-opt-in=$it" }) + add("-Xlambdas=indy") + add("-Xjdk-release=${jvmTarget.target}") } - val jvmTarget = JvmTarget.JVM_11 - val javaVersion = JavaVersion.VERSION_11 - const val compileSdk = 35 - const val targetSdk = compileSdk - const val minSdk = 21 - const val appMinSdk = 26 - const val publishingVariant = "release" - // android const val namespace = artifactId const val testRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/buildSrc/src/main/kotlin/ConfigureMultiplatform.kt b/buildSrc/src/main/kotlin/ConfigureMultiplatform.kt index f7c01f8..356935b 100644 --- a/buildSrc/src/main/kotlin/ConfigureMultiplatform.kt +++ b/buildSrc/src/main/kotlin/ConfigureMultiplatform.kt @@ -1,4 +1,4 @@ -@file:Suppress("MissingPackageDeclaration", "unused", "UndocumentedPublicFunction", "LongMethod") +@file:Suppress("MissingPackageDeclaration", "unused", "UndocumentedPublicFunction", "LongMethod", "UnusedImports") import org.gradle.api.Project import org.gradle.kotlin.dsl.getValue @@ -8,11 +8,11 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyBuilder -@OptIn(ExperimentalWasmDsl::class, ExperimentalKotlinGradlePluginApi::class) +@OptIn(ExperimentalKotlinGradlePluginApi::class, ExperimentalWasmDsl::class) fun Project.configureMultiplatform( ext: KotlinMultiplatformExtension, jvm: Boolean = true, - android: Boolean = false, + android: Boolean = true, linux: Boolean = true, iOs: Boolean = true, js: Boolean = true, @@ -21,17 +21,19 @@ fun Project.configureMultiplatform( watchOs: Boolean = true, windows: Boolean = true, wasmJs: Boolean = true, - wasmWasi: Boolean = false, // TODO: Coroutines do not support wasmWasi yet + wasmWasi: Boolean = false, + explicitApi: Boolean = true, configure: KotlinHierarchyBuilder.Root.() -> Unit = {}, ) = ext.apply { val libs by versionCatalog - explicitApi() + if (explicitApi) explicitApi() applyDefaultHierarchyTemplate(configure) withSourcesJar(true) - compilerOptions { + extraWarnings.set(true) freeCompilerArgs.addAll(Config.compilerArgs) optIn.addAll(Config.optIns) + progressiveMode.set(true) } if (linux) { @@ -54,13 +56,24 @@ fun Project.configureMultiplatform( binaries.library() } - if (wasmWasi) wasmWasi() + if (wasmWasi) wasmWasi { + nodejs() + } if (android) androidTarget { - publishLibraryVariants("release") + publishLibraryVariants(Config.publishingVariant) + compilerOptions { + jvmTarget.set(Config.jvmTarget) + freeCompilerArgs.addAll(Config.jvmCompilerArgs) + } } - if (jvm) jvm() + if (jvm) jvm { + compilerOptions { + jvmTarget.set(Config.jvmTarget) + freeCompilerArgs.addAll(Config.jvmCompilerArgs) + } + } sequence { if (iOs) { @@ -96,6 +109,7 @@ fun Project.configureMultiplatform( all { languageSettings { progressiveMode = true + Config.optIns.forEach { optIn(it) } } } } diff --git a/buildSrc/src/main/kotlin/Util.kt b/buildSrc/src/main/kotlin/Util.kt index 9e93d23..08154cc 100644 --- a/buildSrc/src/main/kotlin/Util.kt +++ b/buildSrc/src/main/kotlin/Util.kt @@ -5,7 +5,10 @@ import org.gradle.api.artifacts.VersionCatalog import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.kotlin.dsl.getByType import org.gradle.plugin.use.PluginDependency +import java.io.File +import java.io.FileInputStream import java.util.Base64 +import java.util.Properties /** * Load version catalog for usage in places where it is not available yet with gradle 7.x. @@ -46,6 +49,17 @@ fun List.toJavaArrayString() = buildString { fun String.toBase64() = Base64.getEncoder().encodeToString(toByteArray()) +fun Project.localProperties() = lazy { + Properties().apply { + val file = File(rootProject.rootDir.absolutePath, "local.properties") + if (!file.exists()) { + println("w: Local.properties file does not exist. You may be missing some publishing keys") + return@apply + } + load(FileInputStream(file)) + } +} + fun stabilityLevel(version: String): Int { Config.stabilityLevels.forEachIndexed { index, postfix -> val regex = """.*[.\-]$postfix[.\-\d]*""".toRegex(RegexOption.IGNORE_CASE) @@ -53,8 +67,9 @@ fun stabilityLevel(version: String): Int { } return Config.stabilityLevels.size } - fun Config.version(isRelease: Boolean) = buildString { append(versionName) if (!isRelease) append("-SNAPSHOT") } + +fun Project.namespaceByPath() = "${Config.namespace}.${path.replace(":", ".").removePrefix(".")}" diff --git a/buildSrc/src/main/kotlin/dokkaDocumentation.gradle.kts b/buildSrc/src/main/kotlin/dokkaDocumentation.gradle.kts new file mode 100644 index 0000000..35cc93b --- /dev/null +++ b/buildSrc/src/main/kotlin/dokkaDocumentation.gradle.kts @@ -0,0 +1,37 @@ +import org.jetbrains.dokka.gradle.engine.parameters.VisibilityModifier + +plugins { + id("org.jetbrains.dokka") + // id("org.jetbrains.dokka-javadoc") +} + +val libs by versionCatalog + +dokka { + dokkaGeneratorIsolation = ClassLoaderIsolation() + moduleName = project.name + moduleVersion = project.version.toString() + pluginsConfiguration.html { + footerMessage = "© ${Config.vendorName}" + homepageLink = Config.url + } + dokkaPublications.configureEach { + suppressInheritedMembers = false + suppressObviousFunctions = true + } + dokkaSourceSets.configureEach { + reportUndocumented = false + enableJdkDocumentationLink = true + enableAndroidDocumentationLink = true + enableKotlinStdLibDocumentationLink = true + skipEmptyPackages = true + skipDeprecated = true + jdkVersion = Config.javaVersion.majorVersion.toInt() + documentedVisibilities(VisibilityModifier.Public) + } + // remoteUrl = Config.docsUrl +} + +dependencies { + dokkaPlugin(libs.requireLib("dokka-android")) +} diff --git a/buildSrc/src/main/kotlin/pro.respawn.android-library.gradle.kts b/buildSrc/src/main/kotlin/pro.respawn.android-library.gradle.kts new file mode 100644 index 0000000..36d0e87 --- /dev/null +++ b/buildSrc/src/main/kotlin/pro.respawn.android-library.gradle.kts @@ -0,0 +1,16 @@ +plugins { + kotlin("android") + id("com.android.library") +} + +kotlin { + explicitApi() +} + +android { + configureAndroidLibrary(this) + + kotlinOptions { + jvmTarget = Config.jvmTarget.target + } +} diff --git a/buildSrc/src/main/kotlin/pro.respawn.shared-library.gradle.kts b/buildSrc/src/main/kotlin/pro.respawn.shared-library.gradle.kts index 9eb6ecf..9a6be11 100644 --- a/buildSrc/src/main/kotlin/pro.respawn.shared-library.gradle.kts +++ b/buildSrc/src/main/kotlin/pro.respawn.shared-library.gradle.kts @@ -1,12 +1,16 @@ +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi + plugins { kotlin("multiplatform") - // id("com.android.library") + id("com.android.library") } kotlin { + @OptIn(ExperimentalKotlinGradlePluginApi::class) configureMultiplatform(this) } -// android { -// configureAndroidLibrary(this) -// } +android { + namespace = namespaceByPath() + configureAndroidLibrary(this) +} diff --git a/common/build.gradle.kts b/common/build.gradle.kts index cb04b03..58216ca 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -1,4 +1,5 @@ plugins { id("pro.respawn.shared-library") alias(libs.plugins.maven.publish) + dokkaDocumentation } diff --git a/common/src/commonMain/kotlin/pro/respawn/kmmutils/common/CommonExt.kt b/common/src/commonMain/kotlin/pro/respawn/kmmutils/common/CommonExt.kt index 674a43e..d284cbf 100644 --- a/common/src/commonMain/kotlin/pro/respawn/kmmutils/common/CommonExt.kt +++ b/common/src/commonMain/kotlin/pro/respawn/kmmutils/common/CommonExt.kt @@ -110,7 +110,7 @@ public fun T?.requireNotNull(): T & Any = requireNotNull(this) /** * Calls [requireNotNull] on this value and returns it */ -public inline fun T?.requireNotNull(lazyMessage: () -> Unit): T & Any = requireNotNull(this, lazyMessage) +public inline fun T?.requireNotNull(lazyMessage: () -> Any): T & Any = requireNotNull(this, lazyMessage) /** * If this is an [Error], throws it, otherwise returns [this] as an [Exception] diff --git a/compose/build.gradle.kts b/compose/build.gradle.kts index 4d70443..2470acf 100644 --- a/compose/build.gradle.kts +++ b/compose/build.gradle.kts @@ -6,11 +6,12 @@ plugins { alias(libs.plugins.compose) alias(libs.plugins.compose.compiler) alias(libs.plugins.maven.publish) + dokkaDocumentation } android { configureAndroidLibrary(this) - namespace = "${Config.namespace}.compose" + namespace = namespaceByPath() buildFeatures { compose = true @@ -31,6 +32,7 @@ kotlin { js = true, wasmJs = true, windows = false, + wasmWasi = false, ) { common { group("web") { diff --git a/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/FadingEdge.kt b/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/FadingEdge.kt index 55a5f4a..3e3d0b5 100644 --- a/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/FadingEdge.kt +++ b/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/FadingEdge.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.unit.LayoutDirection /** * The edge to use with [fadingEdge] modifier. */ +@Suppress("UndocumentedPublicProperty") // what's here to document? public enum class FadingEdge { Start, End, Top, Bottom } diff --git a/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/Flip.kt b/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/Flip.kt index f697404..3d91b08 100644 --- a/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/Flip.kt +++ b/compose/src/commonMain/kotlin/pro/respawn/kmmutils/compose/modifier/Flip.kt @@ -10,6 +10,7 @@ import androidx.compose.ui.graphics.drawscope.withTransform /** * Defines available modes for the [flip] modifier */ +@Suppress("UndocumentedPublicProperty") // what's here to document? public enum class FlipDirection(internal val x: Float, internal val y: Float) { Vertical(1f, -1f), Horizontal(-1f, 1f) diff --git a/coroutines/build.gradle.kts b/coroutines/build.gradle.kts index 3119646..894b2a4 100644 --- a/coroutines/build.gradle.kts +++ b/coroutines/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("pro.respawn.shared-library") alias(libs.plugins.atomicfu) alias(libs.plugins.maven.publish) + dokkaDocumentation } dependencies { commonMainApi(libs.kotlinx.coroutines.core) diff --git a/datetime/build.gradle.kts b/datetime/build.gradle.kts index deb71bf..83d63c1 100644 --- a/datetime/build.gradle.kts +++ b/datetime/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("pro.respawn.shared-library") alias(libs.plugins.maven.publish) + dokkaDocumentation } dependencies { diff --git a/gradle.properties b/gradle.properties index ed26c10..b183749 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,16 +15,31 @@ android.experimental.enableSourceSetPathsMap=true android.experimental.cacheCompileLibResources=true kotlin.mpp.enableCInteropCommonization=true kotlin.mpp.stability.nowarn=true -kotlin.mpp.androidGradlePluginCompatibility.nowarn=true org.gradle.unsafe.configuration-cache=true kotlin.mpp.androidSourceSetLayoutVersion=2 android.disableResourceValidation=true org.gradle.daemon=true android.nonFinalResIds=true -kotlin.native.ignoreIncorrectDependencies=true kotlinx.atomicfu.enableJvmIrTransformation=true android.lint.useK2Uast=true nl.littlerobots.vcu.resolver=true -org.jetbrains.compose.experimental.macos.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.wasm.enabled=true +org.jetbrains.compose.experimental.macos.enabled=true +# Do not garbage collect on timeout on native when appExtensions are used and app is in bacground +kotlin.native.binary.appStateTracking=enabled +# Lift main thread suspending function invocation restriction +kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none +# Native incremental compilation +kotlin.incremental.native=true +android.experimental.additionalArtifactsInModel=true +kotlin.apple.xcodeCompatibility.nowarn=true +# Enable new k/n GC +kotlin.native.binary.gc=cms +org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled +org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true +org.gradle.configuration-cache.parallel=true +release=false +#kotlin.kmp.isolated-projects.support=enable +kotlin.incremental.wasm=true +#org.gradle.unsafe.isolated-projects=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1869a3a..22a4be5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,23 +1,23 @@ [versions] -androidx-activity = "1.9.1" -androidx-core = "1.13.1" -compose = "1.7.0-alpha03" +androidx-activity = "1.10.0-rc01" +androidx-core = "1.15.0" +compose = "1.7.3" composeDetektPlugin = "1.4.0" -coroutines = "1.9.0-RC.2" +coroutines = "1.10.1" datetime = "0.6.1" dependencyAnalysisPlugin = "1.32.0" -detekt = "1.23.6" -dokka = "1.9.20" -gradleAndroid = "8.6.0-rc01" +detekt = "1.23.7" +dokka = "2.0.0" +gradleAndroid = "8.8.0-rc02" gradleDoctorPlugin = "0.10.0" junit = "4.13.2" -kotest = "5.9.1" +kotest = "6.0.0.M1" # @pin -kotlin = "2.0.20" -kotlinx-atomicfu = "0.25.0" -lifecycle = "2.8.0" +kotlin = "2.1.0" +kotlinx-atomicfu = "0.26.1" +lifecycle = "2.8.4" maven-publish-plugin = "0.29.0" -turbine = "1.1.0" +turbine = "1.2.0" versionCatalogUpdatePlugin = "0.8.4" [libraries] @@ -25,7 +25,8 @@ android-gradle = { module = "com.android.tools.build:gradle", version.ref = "gra androidx-activity = { module = "androidx.activity:activity-ktx", version.ref = "androidx-activity" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } -androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-compose-android", version.ref = "lifecycle" } +androidx-lifecycle-viewmodel = "androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.7" +compose-window-size = { module = "org.jetbrains.compose.material3:material3-window-size-class", version.ref = "compose" } detekt-compose = { module = "ru.kode:detekt-rules-compose", version.ref = "composeDetektPlugin" } detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } detekt-gradle = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } @@ -43,11 +44,11 @@ kotlinx-atomicfu = { module = "org.jetbrains.kotlinx:atomicfu", version.ref = "k kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" } +lifecycle-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" } lifecycle-runtime = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime", version.ref = "lifecycle" } lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel", version.ref = "lifecycle" } -lifecycle-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" } -compose-window-size = { module = "org.jetbrains.compose.material3:material3-window-size-class", version.ref = "compose" } turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } +dokka-gradle = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } [bundles] unittest = [ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c35211..a4b76b9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..cea7a79 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..f3b75f3 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/inputforms/build.gradle.kts b/inputforms/build.gradle.kts index 60093a7..2ec19ea 100644 --- a/inputforms/build.gradle.kts +++ b/inputforms/build.gradle.kts @@ -1,6 +1,7 @@ plugins { id("pro.respawn.shared-library") alias(libs.plugins.maven.publish) + dokkaDocumentation } dependencies { commonMainApi(projects.common) diff --git a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Form.kt b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Form.kt index c576ef2..574b66d 100644 --- a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Form.kt +++ b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Form.kt @@ -24,5 +24,6 @@ public open class Form( */ public open fun validate(input: String): Input = rules(input, strategy).fold(input) + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object } diff --git a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Input.kt b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Input.kt index a5af91b..c172c59 100644 --- a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Input.kt +++ b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Input.kt @@ -51,5 +51,6 @@ public sealed interface Input { is Valid -> Valid(value) } + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object } diff --git a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Rule.kt b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Rule.kt index a02eb44..0a994ba 100644 --- a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Rule.kt +++ b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/Rule.kt @@ -13,5 +13,6 @@ public fun interface Rule { */ public operator fun invoke(value: String): Sequence + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object } diff --git a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationError.kt b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationError.kt index d326a6f..e6239b5 100644 --- a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationError.kt +++ b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationError.kt @@ -224,5 +224,6 @@ public sealed interface ValidationError { @JvmInline public value class NoUppercaseLetters(override val value: String) : ValidationError + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object } diff --git a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationStrategy.kt b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationStrategy.kt index fc244fc..79bf546 100644 --- a/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationStrategy.kt +++ b/inputforms/src/commonMain/kotlin/pro/respawn/kmmutils/inputforms/ValidationStrategy.kt @@ -21,5 +21,6 @@ public sealed interface ValidationStrategy { */ public data object LazyEval : ValidationStrategy + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object } diff --git a/system/build.gradle.kts b/system/build.gradle.kts index 92d8460..5588ba2 100644 --- a/system/build.gradle.kts +++ b/system/build.gradle.kts @@ -2,6 +2,7 @@ plugins { kotlin("multiplatform") id("com.android.library") alias(libs.plugins.maven.publish) + dokkaDocumentation } kotlin { @@ -17,6 +18,6 @@ kotlin { } android { - namespace = "${Config.namespace}.system" + namespace = namespaceByPath() configureAndroidLibrary(this) } diff --git a/system/src/androidMain/kotlin/pro/respawn/kmmutils/system/android/NetworkExt.kt b/system/src/androidMain/kotlin/pro/respawn/kmmutils/system/android/NetworkExt.kt index d174c91..b840846 100644 --- a/system/src/androidMain/kotlin/pro/respawn/kmmutils/system/android/NetworkExt.kt +++ b/system/src/androidMain/kotlin/pro/respawn/kmmutils/system/android/NetworkExt.kt @@ -47,6 +47,7 @@ public val Uri.linkType: LinkType /** * Type of the [Uri]'s scheme */ +@Suppress("UndocumentedPublicProperty") // what's here to document? public enum class LinkType { Web, Mail, @@ -85,6 +86,7 @@ public data class Email( val body: String? = null, ) { + @Suppress("UndocumentedPublicClass") // what's here to document? public companion object { /**