From a7ea4cdb5c0348ac2d2943675c41596b2020904a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwieci=C5=84ski?= <36954793+mateuszkwiecinski@users.noreply.github.com> Date: Thu, 15 Apr 2021 18:30:37 +0200 Subject: [PATCH] feat: Add `com.starter.library.multiplatform` plugin to easily configure multiplatform libraries (#211) --- .../quality/AndroidQualityPluginTest.kt | 1 - buildSrc/build.gradle | 2 +- .../modules/plugins/KotlinLibraryPlugin.kt | 4 +- .../modules/KotlinLibraryPluginTest.kt | 2 +- .../versioning/KotlinVersioningPluginTest.kt | 4 +- multiplatform/build.gradle | 36 ++++ .../MultiplatfromLibraryConfigExtension.kt | 3 + .../modules/internal/MultiplatformCoverage.kt | 33 ++++ .../starter/modules/internal/Repositories.kt | 18 ++ .../plugins/MultiplatformLibraryPlugin.kt | 29 ++++ .../modules/MultiplatformLibraryPluginTest.kt | 156 ++++++++++++++++++ .../quality/MultiplatformQualityPluginTest.kt | 70 ++++++++ .../tasks/IssueLinksCheckerTaskTest.kt | 64 +++++++ .../MultiplatformVersioningPluginTest.kt | 75 +++++++++ .../starter/quality/internal/Checkstyle.kt | 2 +- .../starter/quality/internal/Detekt.kt | 8 + .../starter/quality/plugins/QualityPlugin.kt | 36 +++- .../starter/quality/QualityPluginTest.kt | 1 - .../GenerateCheckstyleBaselineTaskTest.kt | 2 +- settings.gradle | 3 +- .../kotlin/com/project/starter/Factories.kt | 2 +- .../versioning/VersioningPluginTest.kt | 4 +- 22 files changed, 534 insertions(+), 21 deletions(-) create mode 100644 multiplatform/build.gradle create mode 100644 multiplatform/src/main/kotlin/com/project/starter/modules/extensions/MultiplatfromLibraryConfigExtension.kt create mode 100644 multiplatform/src/main/kotlin/com/project/starter/modules/internal/MultiplatformCoverage.kt create mode 100644 multiplatform/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt create mode 100644 multiplatform/src/main/kotlin/com/project/starter/modules/plugins/MultiplatformLibraryPlugin.kt create mode 100644 multiplatform/src/test/kotlin/com/project/starter/modules/MultiplatformLibraryPluginTest.kt create mode 100644 multiplatform/src/test/kotlin/com/project/starter/quality/MultiplatformQualityPluginTest.kt create mode 100644 multiplatform/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt create mode 100644 multiplatform/src/test/kotlin/com/project/starter/versioning/MultiplatformVersioningPluginTest.kt diff --git a/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt b/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt index 15ec5d90..cf25591b 100644 --- a/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt +++ b/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt @@ -30,7 +30,6 @@ internal class AndroidQualityPluginTest : WithGradleProjectTest() { id('kotlin') } - repositories.jcenter() """.trimIndent() ) } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 47a4b2e5..8440317e 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java-gradle-plugin' id "org.jmailen.kotlinter" version "3.4.0" - id 'org.jetbrains.kotlin.jvm' version '1.4.32' + id 'org.jetbrains.kotlin.jvm' version '1.5.0-RC' } repositories { diff --git a/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt b/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt index c037910c..e0c389c4 100644 --- a/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt +++ b/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt @@ -25,8 +25,8 @@ class KotlinLibraryPlugin : Plugin { } configureKotlinCoverage() - registerProjectCoverageTask { - it.dependsOn("jacocoTestReport") + registerProjectCoverageTask { projectCoverage -> + projectCoverage.dependsOn("jacocoTestReport") } withExtension { config -> val javaFilesAllowed = config.javaFilesAllowed ?: rootConfig.javaFilesAllowed diff --git a/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt b/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt index 71ba6fd6..41ec256d 100644 --- a/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt +++ b/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt @@ -148,7 +148,7 @@ internal class KotlinLibraryPluginTest : WithGradleProjectTest() { @Test fun `configures versioning plugin by default`() { val git = setupGit(origin) - git.tag("release-1.2.2") + git.tag("v1.2.2") git.commit("random commit") val versioningEnabled = runTask("currentVersion") diff --git a/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt b/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt index 3c352f0a..a4fc20a7 100644 --- a/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt +++ b/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt @@ -48,13 +48,13 @@ internal class KotlinVersioningPluginTest : WithGradleProjectTest() { } } git = setupGit(origin) - git.tag("release-1.1.0") + git.tag("v1.1.0") } @Test fun `sets version to all projects`() { git.commit("features in 1.2.0") - git.tag("release-1.2.0") + git.tag("v1.2.0") val modules = listOf(":module1", ":module2", "") diff --git a/multiplatform/build.gradle b/multiplatform/build.gradle new file mode 100644 index 00000000..6dc80fdb --- /dev/null +++ b/multiplatform/build.gradle @@ -0,0 +1,36 @@ +plugins { + id 'java-gradle-plugin' + id 'com.starter.library.kotlin' + id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' + id 'com.starter.publishing' +} + +repositories { + gradlePluginPortal() +} + +dependencies { + api 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' + implementation project(":jvm") + implementation project(":quality") + implementation project(":config") + + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +test { + useJUnitPlatform() +} + +gradlePlugin { + plugins { + kotlinLibrary { + id = 'com.starter.library.multiplatform' + displayName = 'Kotlin Multiplatform Library Plugin' + implementationClass = 'com.project.starter.modules.plugins.MultiplatformLibraryPlugin' + } + } +} diff --git a/multiplatform/src/main/kotlin/com/project/starter/modules/extensions/MultiplatfromLibraryConfigExtension.kt b/multiplatform/src/main/kotlin/com/project/starter/modules/extensions/MultiplatfromLibraryConfigExtension.kt new file mode 100644 index 00000000..b9048630 --- /dev/null +++ b/multiplatform/src/main/kotlin/com/project/starter/modules/extensions/MultiplatfromLibraryConfigExtension.kt @@ -0,0 +1,3 @@ +package com.project.starter.modules.extensions + +open class MultiplatfromLibraryConfigExtension diff --git a/multiplatform/src/main/kotlin/com/project/starter/modules/internal/MultiplatformCoverage.kt b/multiplatform/src/main/kotlin/com/project/starter/modules/internal/MultiplatformCoverage.kt new file mode 100644 index 00000000..310c947a --- /dev/null +++ b/multiplatform/src/main/kotlin/com/project/starter/modules/internal/MultiplatformCoverage.kt @@ -0,0 +1,33 @@ +package com.project.starter.modules.internal + +import com.project.starter.config.getByType +import org.gradle.api.Project +import org.gradle.api.tasks.testing.Test +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport + +internal fun Project.configureMultiplatformCoverage() { + pluginManager.apply("jacoco") + + tasks.withType(Test::class.java) { + it.extensions.getByType().apply { + isIncludeNoLocationClasses = true + excludes = listOf("jdk.internal.*") + } + } + + extensions.configure(JacocoPluginExtension::class.java) { + it.toolVersion = "0.8.6" + } + tasks.register("jacocoTestReport", JacocoReport::class.java) { + it.dependsOn(":$path:jvmTest") + it.classDirectories.setFrom(buildDir.resolve("classes/kotlin/jvm/main")) + it.sourceDirectories.setFrom(files("src/commonMain/kotlin", "src/jvmMain/kotlin")) + it.executionData.setFrom(buildDir.resolve("jacoco/jvmTest.exec")) + it.reports.apply { + xml.isEnabled = true + html.isEnabled = true + } + } +} diff --git a/multiplatform/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt b/multiplatform/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt new file mode 100644 index 00000000..2a5d531f --- /dev/null +++ b/multiplatform/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt @@ -0,0 +1,18 @@ +package com.project.starter.modules.internal + +import org.gradle.api.Project + +internal fun Project.configureRepositories(): Unit = with(repositories) { + google { repository -> + repository.mavenContent { content -> + val googleLibraries = listOf( + "com\\.android.*", + "androidx.*", + "android.arch.*", + "com\\.google.*" + ) + googleLibraries.forEach(content::includeGroupByRegex) + } + } + mavenCentral() +} diff --git a/multiplatform/src/main/kotlin/com/project/starter/modules/plugins/MultiplatformLibraryPlugin.kt b/multiplatform/src/main/kotlin/com/project/starter/modules/plugins/MultiplatformLibraryPlugin.kt new file mode 100644 index 00000000..acb1f73f --- /dev/null +++ b/multiplatform/src/main/kotlin/com/project/starter/modules/plugins/MultiplatformLibraryPlugin.kt @@ -0,0 +1,29 @@ +package com.project.starter.modules.plugins + +import com.project.starter.modules.extensions.MultiplatfromLibraryConfigExtension +import com.project.starter.modules.internal.configureMultiplatformCoverage +import com.project.starter.modules.tasks.ProjectCoverageTask.Companion.registerProjectCoverageTask +import com.project.starter.modules.tasks.ProjectTestTask.Companion.registerProjectTestTask +import org.gradle.api.Plugin +import org.gradle.api.Project + +class MultiplatformLibraryPlugin : Plugin { + + override fun apply(target: Project) = with(target) { + pluginManager.apply("org.jetbrains.kotlin.multiplatform") + pluginManager.apply("com.starter.quality") + pluginManager.apply(ConfigurationPlugin::class.java) + + extensions.create("projectConfig", MultiplatfromLibraryConfigExtension::class.java) + + registerProjectTestTask { + it.dependsOn("allTests") + } + + configureMultiplatformCoverage() + registerProjectCoverageTask { projectCoverage -> + projectCoverage.dependsOn("jacocoTestReport") + } + Unit + } +} diff --git a/multiplatform/src/test/kotlin/com/project/starter/modules/MultiplatformLibraryPluginTest.kt b/multiplatform/src/test/kotlin/com/project/starter/modules/MultiplatformLibraryPluginTest.kt new file mode 100644 index 00000000..5f660365 --- /dev/null +++ b/multiplatform/src/test/kotlin/com/project/starter/modules/MultiplatformLibraryPluginTest.kt @@ -0,0 +1,156 @@ +package com.project.starter.modules + +import com.project.starter.WithGradleProjectTest +import com.project.starter.commit +import com.project.starter.kotlinClass +import com.project.starter.kotlinTestClass +import com.project.starter.setupGit +import com.project.starter.tag +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import java.io.File + +internal class MultiplatformLibraryPluginTest : WithGradleProjectTest() { + + lateinit var rootBuildScript: File + lateinit var module1Root: File + lateinit var module2Root: File + + @TempDir + lateinit var origin: File + + @BeforeEach + fun setUp() { + rootDirectory.apply { + mkdirs() + resolve("settings.gradle").writeText("""include ":module1", ":module2" """) + + rootBuildScript = resolve("build.gradle") + module1Root = resolve("module1") { + resolve("build.gradle") { + writeText( + """ + plugins { + id('com.starter.library.multiplatform') + } + + kotlin { + jvm() + } + + dependencies { + "jvmTestImplementation"("junit:junit:4.13.2") + } + + """.trimIndent() + ) + } + resolve("src/commonMain/kotlin/ValidKotlinFile1.kt") { + writeText(kotlinClass("ValidKotlinFile1")) + } + resolve("src/jvmTest/kotlin/JvmTest1.kt") { + writeText(kotlinTestClass("JvmTest1")) + } + } + module2Root = resolve("module2") { + resolve("build.gradle") { + writeText( + """ + plugins { + id('com.starter.library.multiplatform') + } + + kotlin { + ios() + jvm() + } + + + dependencies { + "jvmTestImplementation"("junit:junit:4.13.2") + } + + """.trimIndent() + ) + } + resolve("src/commonMain/kotlin/ValidKotlinFile2.kt") { + writeText(kotlinClass("ValidKotlinFile2")) + } + resolve("src/jvmTest/kotlin/JvmTest2.kt") { + writeText(kotlinTestClass("JvmTest2")) + } + } + } + } + + @Test + fun `kotlin library plugin compiles 'src_main_kotlin' classes`() { + val result = runTask("assemble") + + assertThat(result.task(":module1:assemble")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":module2:assemble")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `projectTest runs tests for all modules`() { + val result = runTask("projectTest") + + assertThat(result.task(":module1:allTests")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":module2:allTests")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `projectCoverage runs coverage for all modules`() { + val result = runTask("projectCoverage") + + assertThat(result.task(":module1:jvmTest")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":module2:jvmTest")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(module1Root.resolve("build/reports/jacoco/jacocoTestReport")).isDirectoryContaining { + it.name == "jacocoTestReport.xml" + } + } + + @Test + fun `configures quality plugin by default`() { + val qualityEnabled = runTask("projectCodeStyle") + + assertThat(qualityEnabled.task(":module1:projectCodeStyle")?.outcome).isNotNull() + assertThat(qualityEnabled.task(":module2:projectCodeStyle")?.outcome).isNotNull() + } + + @Test + fun `configures versioning plugin by default`() { + val git = setupGit(origin) + git.tag("v1.2.2") + git.commit("random commit") + + val versioningEnabled = runTask("currentVersion") + + assertThat(versioningEnabled.output).contains("version: 1.3.0-SNAPSHOT") + } + + @Test + fun `does not configure versioning plugin if disabled using configuration plugin`() { + //language=groovy + val versioningScript = + """ + plugins { + id('com.starter.config') + } + + commonConfig { + versioningPlugin { + enabled false + } + } + """.trimIndent() + rootBuildScript.writeText(versioningScript) + + val versioningDisabled = runTask("currentVersion", shouldFail = true) + + assertThat(versioningDisabled.output).contains("Task 'currentVersion' not found ") + } +} diff --git a/multiplatform/src/test/kotlin/com/project/starter/quality/MultiplatformQualityPluginTest.kt b/multiplatform/src/test/kotlin/com/project/starter/quality/MultiplatformQualityPluginTest.kt new file mode 100644 index 00000000..1cf2b280 --- /dev/null +++ b/multiplatform/src/test/kotlin/com/project/starter/quality/MultiplatformQualityPluginTest.kt @@ -0,0 +1,70 @@ +package com.project.starter.quality + +import com.project.starter.WithGradleProjectTest +import com.project.starter.kotlinClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +internal class MultiplatformQualityPluginTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + //language=groovy + val script = + """ + plugins { + id('com.starter.library.multiplatform') + } + + kotlin { + jvm() + ios() + } + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + resolve("src/commonMain/kotlin/ValidKotlinFile1.kt") { + writeText(kotlinClass("ValidKotlinFile1")) + } + resolve("src/commonTest/kotlin/ValidKotlinTest1.kt") { + writeText(kotlinClass("ValidKotlinTest1")) + } + resolve("src/jvmMain/kotlin/ValidKotlinJvmFile1.kt") { + writeText(kotlinClass("ValidKotlinJvmFile1")) + } + resolve("src/jvmTest/kotlin/ValidJvmKotlinTest1.kt") { + writeText(kotlinClass("ValidJvmKotlinTest1")) + } + resolve("src/iosMain/kotlin/ValidKotlinIosFile1.kt") { + writeText(kotlinClass("ValidKotlinIosFile1")) + } + resolve("src/iosTest/kotlin/ValidIosKotlinTest1.kt") { + writeText(kotlinClass("ValidIosKotlinTest1")) + } + } + } + + @Test + fun `projectCodeStyle runs Detekt`() { + val result = runTask("projectCodeStyle") + + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `projectCodeStyle runs ktlint`() { + val result = runTask("projectCodeStyle") + + assertThat(result.task(":lintKotlinIosMain")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinJvmMain")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinCommonMain")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + + assertThat(result.task(":lintKotlinIosTest")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinJvmTest")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinCommonTest")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } +} diff --git a/multiplatform/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt b/multiplatform/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt new file mode 100644 index 00000000..237c59be --- /dev/null +++ b/multiplatform/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt @@ -0,0 +1,64 @@ +package com.project.starter.quality.tasks + +import com.project.starter.WithGradleProjectTest +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +internal class IssueLinksCheckerTaskTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + //language=groovy + val script = + """ + plugins { + id('com.starter.library.multiplatform') + } + + kotlin { + jvm() + ios() + } + + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + } + } + + @Test + fun `reports issue tracker issues`() { + //language=kotlin + val randomLinks = + """ + /** + * https://news.ycombinator.com/ + * https://youtrack.jetbrains.com/issue/KT-31666 + **/ + object ValidKotlin { + // https://youtrack.jetbrains.com/issue/KT-34230 + } + """.trimIndent() + + rootDirectory.resolve("src/commonMain/kotlin/ValidKotlin.kt") { + writeText(randomLinks) + } + + val result = runTask(":issueLinksReport") + + assertThat(rootDirectory.resolve("build/reports/issue_comments.txt")) + .hasContent( + """ + 👉 https://youtrack.jetbrains.com/issue/KT-31666 (Closed) + ✅ https://youtrack.jetbrains.com/issue/KT-34230 (Opened) + """.trimIndent() + ) + assertThat(result.output).contains("\uD83D\uDC49 https://youtrack.jetbrains.com/issue/KT-31666 (Closed)") + assertThat(result.output).contains("✅ https://youtrack.jetbrains.com/issue/KT-34230 (Opened)") + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } +} diff --git a/multiplatform/src/test/kotlin/com/project/starter/versioning/MultiplatformVersioningPluginTest.kt b/multiplatform/src/test/kotlin/com/project/starter/versioning/MultiplatformVersioningPluginTest.kt new file mode 100644 index 00000000..a7725d3e --- /dev/null +++ b/multiplatform/src/test/kotlin/com/project/starter/versioning/MultiplatformVersioningPluginTest.kt @@ -0,0 +1,75 @@ +package com.project.starter.versioning + +import com.project.starter.WithGradleProjectTest +import com.project.starter.commit +import com.project.starter.setupGit +import com.project.starter.tag +import org.assertj.core.api.Assertions.assertThat +import org.eclipse.jgit.api.Git +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import java.io.File + +internal class MultiplatformVersioningPluginTest : WithGradleProjectTest() { + + private lateinit var module1Root: File + private lateinit var module2Root: File + private lateinit var git: Git + + @TempDir + lateinit var origin: File + + @BeforeEach + fun setUp() { + rootDirectory.apply { + resolve("settings.gradle").writeText("""include ":module1", ":module2" """) + module1Root = resolve("module1") { + resolve("build.gradle") { + writeText( + """ + plugins { + id 'com.starter.library.multiplatform' + } + + kotlin { + ios() + } + """.trimIndent() + ) + } + } + module2Root = resolve("module2") { + resolve("build.gradle") { + writeText( + """ + plugins { + id 'com.starter.library.multiplatform' + } + + kotlin { + jvm() + } + """.trimIndent() + ) + } + } + } + git = setupGit(origin) + git.tag("v1.1.0") + } + + @Test + fun `sets version to all projects`() { + git.commit("features in 1.2.0") + git.tag("v1.2.0") + + val modules = listOf(":module1", ":module2", "") + + modules.forEach { + val moduleResult = runTask("$it:properties") + + assertThat(moduleResult?.output).contains("version: 1.2.0") + } + } +} diff --git a/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt index 82430f51..30c1941f 100644 --- a/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt @@ -111,7 +111,7 @@ private fun Project.getResourceFiles(sourceSet: AndroidSourceSet) = sourceSet.re private fun Project.applyCheckstyle() { pluginManager.apply("checkstyle") extensions.configure("checkstyle") { - it.toolVersion = "8.29" + it.toolVersion = "8.41.1" } } diff --git a/quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt index 7303afd2..2837427e 100644 --- a/quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt @@ -1,6 +1,7 @@ package com.project.starter.quality.internal import com.project.starter.config.plugins.rootConfig +import com.project.starter.quality.plugins.onMultiplatform import com.project.starter.quality.tasks.ProjectCodeStyleTask import io.gitlab.arturbosch.detekt.Detekt import io.gitlab.arturbosch.detekt.DetektPlugin @@ -17,6 +18,13 @@ internal fun Project.configureDetekt() { txt.enabled = false } + onMultiplatform { + sourceSets.configureEach { + detekt.input.from(it.kotlin.srcDirs) + // detekt.input.from(it.kotlin.srcDirTrees) + } + } + detekt.config.setFrom(loadFromResources("detekt-config.yml")) } tasks.named("detekt", Detekt::class.java) { diff --git a/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt b/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt index 9cc8c378..78bc9bde 100644 --- a/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt @@ -13,6 +13,7 @@ import org.gradle.api.file.FileTree import org.gradle.api.internal.HasConvention import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.SourceSet +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet class QualityPlugin : Plugin { @@ -22,6 +23,12 @@ class QualityPlugin : Plugin { override fun apply(project: Project) = with(project) { repositories.mavenCentral() + repositories.exclusiveContent { + it.forRepositories(repositories.jcenter()) + it.filter { + it.includeModule("org.jetbrains.kotlinx", "kotlinx-html-jvm") + } + } addProjectCodeStyleTask() configureKtlint() configureDetekt() @@ -32,17 +39,20 @@ class QualityPlugin : Plugin { private fun Project.configureIssueCheckerTask() { registerIssueCheckerTask { - val extension = project.extensions.findByName("android") - if (extension != null) { - extension as BaseExtension - extension.sourceSets.configureEach { sourceSet -> + onAndroid { + sourceSets.configureEach { sourceSet -> source += sourceSet.java.srcDirs .map { dir -> project.fileTree(dir) } .reduce { merged: FileTree, tree: FileTree -> merged + tree } } - } else { - val javaPlugin = project.convention.getPlugin(JavaPluginConvention::class.java) - javaPlugin.sourceSets.configureEach { sourceSet -> + } + onMultiplatform { + sourceSets.configureEach { sourceSet -> + source += sourceSet.kotlin.sourceDirectories.asFileTree + } + } + onJvm { + sourceSets.configureEach { sourceSet -> source += sourceSet.java val kotlin = sourceSet.kotlin ?: return@configureEach source += kotlin.sourceDirectories.asFileTree @@ -80,3 +90,15 @@ class QualityPlugin : Plugin { private fun SourceSet.getConvention(name: String) = (this as HasConvention).convention.plugins[name] } + +internal inline fun Project.onAndroid(crossinline function: BaseExtension.() -> Unit) { + project.extensions.findByName("android")?.let { (it as? BaseExtension)?.function() } +} + +internal inline fun Project.onMultiplatform(crossinline function: KotlinMultiplatformExtension.() -> Unit) { + project.extensions.findByName("kotlin")?.let { (it as? KotlinMultiplatformExtension)?.function() } +} + +internal inline fun Project.onJvm(crossinline function: JavaPluginConvention.() -> Unit) { + project.convention.findPlugin(JavaPluginConvention::class.java)?.let(function) +} diff --git a/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt b/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt index 4c5b74f3..fc355cf9 100644 --- a/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt +++ b/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt @@ -141,7 +141,6 @@ internal class QualityPluginTest : WithGradleProjectTest() { javaFilesAllowed = false } - repositories.jcenter() """.trimIndent() rootDirectory.resolve("build.gradle").writeText(buildscript) diff --git a/quality/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt b/quality/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt index b166794d..7d0b45d5 100644 --- a/quality/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt +++ b/quality/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt @@ -58,7 +58,7 @@ internal class GenerateCheckstyleBaselineTaskTest : WithGradleProjectTest() { writeText(javaClass) } - val baselineResult = runTask("generateCheckstyleBaseline") + val baselineResult = runTask("generateCheckstyleBaseline", "--stacktrace") val checkStyleOldCode = runTask("checkstyle") assertThat(baselineResult.task(":javaModule:generateCheckstyleBaseline")?.outcome).isEqualTo(TaskOutcome.SUCCESS) diff --git a/settings.gradle b/settings.gradle index 59a234bf..bc5096b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,5 +7,6 @@ include ":jvm", ":testing", ":config", ":quality", - ":versioning" + ":versioning", + ":multiplatform" diff --git a/testing/src/main/kotlin/com/project/starter/Factories.kt b/testing/src/main/kotlin/com/project/starter/Factories.kt index 86b67853..939fe6a3 100644 --- a/testing/src/main/kotlin/com/project/starter/Factories.kt +++ b/testing/src/main/kotlin/com/project/starter/Factories.kt @@ -24,7 +24,7 @@ fun kotlinTestClass(className: String) = class $className { @org.junit.Test - fun ${className.toLowerCase()}() = Unit + fun test${className.toLowerCase()}() = Unit } """.trimIndent() diff --git a/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt b/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt index 263fa4c8..adda8179 100644 --- a/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt +++ b/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt @@ -59,7 +59,7 @@ internal class VersioningPluginTest : WithGradleProjectTest() { } } git = setupGit(origin) - git.tag("release-1.1.0") + git.tag("v1.1.0") } @Test @@ -79,7 +79,7 @@ internal class VersioningPluginTest : WithGradleProjectTest() { @Test fun `sets version to all projects`() { git.commit("features in 1.2.0") - git.tag("release-1.2.0") + git.tag("v1.2.0") val modules = listOf(":module1", ":module1", "")