diff --git a/.editorconfig b/.editorconfig index 56390eeb..65447b4e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -[*.{kt,kts}] +[*.{kt, kts}] max_line_length = 140 indent_size = 4 insert_final_newline = true diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f4e235cf..3dc3eb68 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,3 +18,15 @@ updates: interval: "daily" assignees: - "mateuszkwiecinski" + - package-ecosystem: "gradle" + directory: "sample/android" + schedule: + interval: "daily" + assignees: + - "mateuszkwiecinski" + - package-ecosystem: "gradle" + directory: "sample/kotlin" + schedule: + interval: "daily" + assignees: + - "mateuszkwiecinski" diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index 82e38d73..5eef191e 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -15,62 +15,107 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - - name: set up Java + + - name: set up JDK uses: actions/setup-java@v1 with: java-version: 8 + - name: Cache .gradle uses: burrunan/gradle-cache-action@v1 with: - job-id: build-all-sample-projects + job-id: build + gradle-distribution-sha-256-sum-warning: false + - name: Gradle Wrapper Validation uses: gradle/wrapper-validation-action@v1 + - name: Code style run: ./gradlew projectCodestyle + - name: Assemble run: ./gradlew assemble + - name: Validate Plugins - run: ./gradlew validatePlugins validateTaskProperties + run: ./gradlew validatePlugins + - name: Jacoco test report - run: ./gradlew projectCoverage - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} + run: ./gradlew test + +# - name: Upload coverage to Codecov +# uses: codecov/codecov-action@v1 +# with: +# token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: test-results path: "${{ github.workspace }}/**/build/reports/tests" - - name: Upload jacoco report - uses: actions/upload-artifact@v2 + +# - name: Upload jacoco report +# uses: actions/upload-artifact@v2 +# with: +# name: jacoco-report +# path: "${{ github.workspace }}/**/build/reports/jacoco" + + build-all-sample-android-projects: + runs-on: ubuntu-latest + strategy: + matrix: + gradle: [ 6.5.1, current, rc ] + task: [ build, projectTest, projectLint, projectCodeStyle, projectCoverage, issueLinksReport ] + name: (Android) Gradle version ${{ matrix.gradle }}, task ${{ matrix.task }} + steps: + - uses: actions/checkout@v2 with: - name: jacoco-report - path: "${{ github.workspace }}/**/build/reports/jacoco" + fetch-depth: 0 - build-all-sample-projects: + - name: set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Pre-compile plugin using gradle wrapper + uses: burrunan/gradle-cache-action@v1 + with: + job-id: build-all-sample-android-projects + gradle-distribution-sha-256-sum-warning: false + arguments: publishToMavenLocal -Pgroup=com.project.starter.local + + - uses: eskatos/gradle-command-action@v1 + with: + build-root-directory: sample/android + gradle-version: ${{ matrix.gradle }} + arguments: ${{ matrix.task }} -PuseMavenLocal + + build-all-sample-kotlin-projects: runs-on: ubuntu-latest strategy: matrix: - gradle: [ 6.5.1, current, rc] - task: [ build, projectTest, projectLint, projectCodeStyle, projectCoverage, issueLinksReport] - name: Gradle version ${{ matrix.gradle }}, task ${{ matrix.task }} + gradle: [ 6.5.1, current, rc ] + task: [ build, projectTest, projectCodeStyle, projectCoverage, issueLinksReport ] + name: (Kotlin) Gradle ${{ matrix.gradle }}, task ${{ matrix.task }} steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - - name: set up JAVA 8 + + - name: set up JDK uses: actions/setup-java@v1 with: - java-version: 8 + java-version: 11 + - name: Pre-compile plugin using gradle wrapper uses: burrunan/gradle-cache-action@v1 with: - job-id: build-all-sample-projects - arguments: publishToMavenLocal -Pgroup=com.project.starter.local + job-id: build-all-sample-kotlin-projects + gradle-distribution-sha-256-sum-warning: false + arguments: publishToMavenLocal -Pgroup=com.project.starter.local + - uses: eskatos/gradle-command-action@v1 with: - build-root-directory: sample + build-root-directory: sample/kotlin gradle-version: ${{ matrix.gradle }} arguments: ${{ matrix.task }} -PuseMavenLocal diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 2f35d8a6..6b65e491 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -6,37 +6,56 @@ on: jobs: generate-diff: runs-on: ubuntu-latest - + steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: set up Java - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Cache .gradle - uses: burrunan/gradle-cache-action@v1 - - id: dependency-diff - name: Generate dependency diff - uses: usefulness/dependency-tree-diff-action@v1 - with: - configuration: 'runtimeClasspath' - project: 'plugins' - - uses: peter-evans/find-comment@v1 - id: find_comment - with: - issue-number: ${{ github.event.pull_request.number }} - body-includes: Dependency diff - - uses: peter-evans/create-or-update-comment@v1 - if: ${{ steps.dependency-diff.outputs.text-diff != null || steps.find_comment.outputs.comment-id != null }} - with: - body: | - Dependency diff: - ```diff - ${{ steps.dependency-diff.outputs.text-diff }} - ``` - edit-mode: replace - comment-id: ${{ steps.find_comment.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: set up JDK + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Cache .gradle + uses: burrunan/gradle-cache-action@v1 + with: + gradle-distribution-sha-256-sum-warning: false + + - id: dependency-diff-jvm + name: Generate dependency diff + uses: usefulness/dependency-tree-diff-action@v1 + with: + configuration: 'runtimeClasspath' + project: 'jvm' + + - id: dependency-diff-android + name: Generate dependency diff + uses: usefulness/dependency-tree-diff-action@v1 + with: + configuration: 'runtimeClasspath' + project: 'android' + + - uses: peter-evans/find-comment@v1 + id: find_comment + with: + issue-number: ${{ github.event.pull_request.number }} + body-includes: Dependency diff + + - uses: peter-evans/create-or-update-comment@v1 + if: ${{ steps.dependency-diff-jvm.outputs.text-diff != null || steps.dependency-diff-android.outputs.text-diff != null || steps.find_comment.outputs.comment-id != null }} + with: + body: | + Dependency diff: + `:jvm`: + ```diff + ${{ steps.dependency-diff-jvm.outputs.text-diff }} + ``` + `:android`: + ```diff + ${{ steps.dependency-diff-android.outputs.text-diff }} + ``` + edit-mode: replace + comment-id: ${{ steps.find_comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 4cee947b..27575b35 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -14,16 +14,20 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: set up Java - uses: actions/setup-java@v1 - with: - java-version: 8 - - name: Build app with Gradle - run: ./gradlew build - - name: Publish to Gradle Plugin Portal - run: ./gradlew publishPlugins -Pgradle.publish.key=${{ secrets.gradle_publish_key }} -Pgradle.publish.secret=${{ secrets.gradle_publish_secret }} - - name: Publish to Github Package Registry - run: ./gradlew publish --continue || true + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: set up Java + uses: actions/setup-java@v1 + with: + java-version: 8 + + - name: Build app with Gradle + run: ./gradlew build + + - name: Publish to Gradle Plugin Portal + run: ./gradlew publishPlugins -Pgradle.publish.key=${{ secrets.gradle_publish_key }} -Pgradle.publish.secret=${{ secrets.gradle_publish_secret }} + + - name: Publish to Github Package Registry + run: ./gradlew publish --continue || true diff --git a/.github/workflows/publish_snapshot.yml b/.github/workflows/publish_snapshot.yml index f563c14b..a33ee5a2 100644 --- a/.github/workflows/publish_snapshot.yml +++ b/.github/workflows/publish_snapshot.yml @@ -12,14 +12,17 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: set up Java - uses: actions/setup-java@v1 - with: - java-version: 8 - - name: Build app with Gradle - run: ./gradlew assemble - - name: Publish to Github Package Registry - run: ./gradlew publish --continue || true + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: set up Java + uses: actions/setup-java@v1 + with: + java-version: 8 + + - name: Build app with Gradle + run: ./gradlew assemble + + - name: Publish to Github Package Registry + run: ./gradlew publish --continue || true diff --git a/Changelog.md b/Changelog.md index b45c4787..03dbef8b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ## Changed - The `issuechecker` dependency has been moved from `jcenter()` to `mavenCentral()` -- `kapt` is not enabled automatically by default. use `useKapt` config property to change the default behavior -- Update Kotlin plugin to [1.4.31](https://github.com/JetBrains/kotlin/releases/tag/v1.4.31) +- `kapt` is not enabled automatically by default +- Update Kotlin plugin to [1.4.32](https://github.com/JetBrains/kotlin/releases/tag/v1.4.32) +- Divide plugins into multiple functional groups to avoid adding unnecessary dependencies +- Update _Detekt_ to version _1.16.0_ see [release notes](https://github.com/detekt/detekt/releases/tag/v1.16.0) +- Update _kotlinter-gradle_ to version _3.4.0_, see [release notes](https://github.com/jeremymailen/kotlinter-gradle/releases/tag/3.4.0) ## [0.23.0] - 2021-02-06 ## Changed diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 00000000..c1b44a1c --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'java-gradle-plugin' + id 'com.starter.library.kotlin' + id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' + id 'com.starter.publishing' +} + +repositories { + mavenCentral() + google() + gradlePluginPortal() +} + +dependencies { + api 'com.android.tools.build:gradle:4.1.3' + implementation project(":jvm") + implementation project(":config") + implementation project(":versioning") + implementation project(":quality") + + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +tasks.withType(Test) { + useJUnitPlatform() + jacoco.includeNoLocationClasses = true + jacoco.excludes = ['jdk.internal.*'] +} + +gradlePlugin { + plugins { + androidLibrary { + id = 'com.starter.library.android' + displayName = 'Android Library Plugin' + implementationClass = 'com.project.starter.modules.plugins.AndroidLibraryPlugin' + } + androidApplication { + id = 'com.starter.application.android' + displayName = 'Android Applicataion Plugin' + implementationClass = 'com.project.starter.modules.plugins.AndroidApplicationPlugin' + } + } +} diff --git a/plugins/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt b/android/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt similarity index 69% rename from plugins/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt rename to android/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt index b8394189..4e954951 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt +++ b/android/src/main/kotlin/com/project/starter/modules/extensions/AndroidPluginExtensions.kt @@ -1,11 +1,12 @@ package com.project.starter.modules.extensions +import com.project.starter.quality.extensions.JavaSourcesAware + @Suppress("UnnecessaryAbstractClass") -abstract class AndroidExtension { - var javaFilesAllowed: Boolean? = null +abstract class AndroidExtension : JavaSourcesAware { + override var javaFilesAllowed: Boolean? = null var defaultVariants: List = emptyList() var coverageExclusions: List = emptyList() - val useKapt: Boolean? = null } open class AndroidLibraryConfigExtension : AndroidExtension() { diff --git a/plugins/src/main/kotlin/com/project/starter/modules/internal/AndroidLint.kt b/android/src/main/kotlin/com/project/starter/modules/internal/AndroidLint.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/internal/AndroidLint.kt rename to android/src/main/kotlin/com/project/starter/modules/internal/AndroidLint.kt diff --git a/plugins/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt b/android/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt similarity index 85% rename from plugins/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt rename to android/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt index 15e6c022..a3ee87c0 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt +++ b/android/src/main/kotlin/com/project/starter/modules/internal/AndroidPluginUtils.kt @@ -1,10 +1,11 @@ package com.project.starter.modules.internal +import com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION import com.android.build.gradle.BaseExtension import com.android.build.gradle.TestedExtension import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.internal.tasks.factory.dependsOn import com.project.starter.config.extensions.RootConfigExtension +import com.project.starter.config.getByType import com.project.starter.config.plugins.rootConfig import com.project.starter.modules.extensions.AndroidExtension import com.project.starter.modules.tasks.ForbidJavaFilesTask.Companion.registerForbidJavaFilesTask @@ -14,7 +15,8 @@ import com.project.starter.modules.tasks.ProjectTestTask.Companion.registerProje import com.project.starter.quality.internal.configureAndroidCoverage import org.gradle.api.DomainObjectSet import org.gradle.api.Project -import org.gradle.api.plugins.ExtensionContainer + +private const val LAST_STABLE_AGP_VERSION = 4 internal fun BaseExtension.configureAndroidPlugin(rootConfig: RootConfigExtension) { defaultConfig.apply { @@ -23,7 +25,12 @@ internal fun BaseExtension.configureAndroidPlugin(rootConfig: RootConfigExtensio targetSdkVersion(rootConfig.android.targetSdkVersion ?: rootConfig.android.compileSdkVersion) setTestInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner") } - dexOptions.preDexLibraries = true + + if (ANDROID_GRADLE_PLUGIN_VERSION.split(".").firstOrNull()?.toIntOrNull() ?: 0 <= LAST_STABLE_AGP_VERSION) { + @Suppress("deprecation") + dexOptions.preDexLibraries = true + } + addKotlinSourceSets() compileOptions.apply { @@ -65,21 +72,12 @@ internal fun Project.configureAndroidProject(variants: DomainObjectSet ExtensionContainer.getByType() = - getByType(T::class.java) - -internal inline fun ExtensionContainer.findByType() = - findByType(T::class.java) - -internal inline fun Project.withExtension(crossinline action: Project.(T) -> Unit) = - afterEvaluate { - it.action(it.extensions.getByType()) - } - private fun BaseExtension.addKotlinSourceSets() { sourceSets.configureEach { set -> val withKotlin = set.java.srcDirs.map { it.path.replace("java", "kotlin") } diff --git a/plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt b/android/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt similarity index 80% rename from plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt rename to android/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt index 3faf01d4..8ff52831 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt +++ b/android/src/main/kotlin/com/project/starter/modules/plugins/AndroidApplicationPlugin.kt @@ -1,14 +1,13 @@ package com.project.starter.modules.plugins import com.android.build.gradle.AppExtension +import com.project.starter.config.getByType import com.project.starter.config.plugins.rootConfig +import com.project.starter.config.withExtension import com.project.starter.modules.extensions.AndroidApplicationConfigExtension import com.project.starter.modules.internal.configureAndroidLint import com.project.starter.modules.internal.configureAndroidPlugin import com.project.starter.modules.internal.configureAndroidProject -import com.project.starter.modules.internal.configureKapt -import com.project.starter.modules.internal.getByType -import com.project.starter.modules.internal.withExtension import org.gradle.api.Plugin import org.gradle.api.Project @@ -28,10 +27,6 @@ class AndroidApplicationPlugin : Plugin { withExtension { projectConfig -> configureAndroidProject(android.applicationVariants, projectConfig) - - if (projectConfig.useKapt ?: rootConfig.useKapt) { - configureKapt() - } } } } diff --git a/plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt b/android/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt similarity index 84% rename from plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt rename to android/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt index 952b1dda..870ebd78 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt +++ b/android/src/main/kotlin/com/project/starter/modules/plugins/AndroidLibraryPlugin.kt @@ -1,14 +1,13 @@ package com.project.starter.modules.plugins import com.android.build.gradle.LibraryExtension +import com.project.starter.config.getByType import com.project.starter.config.plugins.rootConfig +import com.project.starter.config.withExtension import com.project.starter.modules.extensions.AndroidLibraryConfigExtension import com.project.starter.modules.internal.configureAndroidLint import com.project.starter.modules.internal.configureAndroidPlugin import com.project.starter.modules.internal.configureAndroidProject -import com.project.starter.modules.internal.configureKapt -import com.project.starter.modules.internal.getByType -import com.project.starter.modules.internal.withExtension import org.gradle.api.Plugin import org.gradle.api.Project @@ -36,10 +35,6 @@ class AndroidLibraryPlugin : Plugin { variants.configureEach { variant -> variant.generateBuildConfigProvider.configure { it.enabled = projectConfig.generateBuildConfig } } - - if (projectConfig.useKapt ?: rootConfig.useKapt) { - configureKapt() - } } } } diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt b/android/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt similarity index 83% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt rename to android/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt index 7270a543..d648afd6 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt +++ b/android/src/main/kotlin/com/project/starter/quality/internal/AndroidCoverage.kt @@ -1,15 +1,24 @@ package com.project.starter.quality.internal import com.android.build.gradle.api.BaseVariant -import com.project.starter.modules.internal.getByType +import com.project.starter.config.getByType +import com.project.starter.modules.internal.daggerCoverageExclusions import org.gradle.api.DomainObjectSet import org.gradle.api.Project +import org.gradle.api.tasks.testing.Test import org.gradle.testing.jacoco.plugins.JacocoTaskExtension import org.gradle.testing.jacoco.tasks.JacocoReport internal fun Project.configureAndroidCoverage(variants: DomainObjectSet, projectExclusions: List) { pluginManager.apply("jacoco") + tasks.withType(Test::class.java) { + it.extensions.getByType(JacocoTaskExtension::class.java).apply { + isIncludeNoLocationClasses = true + excludes = listOf("jdk.internal.*") + } + } + variants.configureEach { variant -> tasks.register("jacoco${variant.name.capitalize()}TestReport", JacocoReport::class.java) { report -> val capitalizedVariant = variant.name.capitalize() @@ -56,16 +65,5 @@ private val framework = listOf( "**/BuildConfig.*", "**/Manifest*.*" ) -private val butterKnife = listOf( - "**/*${"$"}ViewInjector*.*", - "**/*${"$"}ViewBinder*.*" -) -internal val dagger = listOf( - "**/*_MembersInjector.class", - "**/Dagger*Component.class", - "**/Dagger*Component${"$"}Builder.class", - "**/*_*Factory.class", - "**/*_Factory.class" -) -private val excludes = databinding + framework + butterKnife + dagger +private val excludes = databinding + framework + daggerCoverageExclusions diff --git a/plugins/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt b/android/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt similarity index 99% rename from plugins/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt rename to android/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt index a61d2009..9806cb5d 100644 --- a/plugins/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt +++ b/android/src/test/kotlin/com/project/starter/modules/AndroidApplicataionPluginTest.kt @@ -218,7 +218,7 @@ internal class AndroidApplicataionPluginTest : WithGradleProjectTest() { } @Test - fun `does not configured quality plugin if disable using configuration plugin`() { + fun `does not configure quality plugin if disabled using configuration plugin`() { @Language("groovy") val qualityScript = """ diff --git a/plugins/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt b/android/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt similarity index 100% rename from plugins/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt rename to android/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt index bf0688ac..24f7a421 100644 --- a/plugins/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt +++ b/android/src/test/kotlin/com/project/starter/modules/AndroidLibraryPluginTest.kt @@ -4,12 +4,12 @@ import com.project.starter.WithGradleProjectTest import com.project.starter.javaClass import com.project.starter.kotlinClass import com.project.starter.kotlinTestClass -import java.io.File import org.assertj.core.api.Assertions.assertThat import org.gradle.testkit.runner.TaskOutcome import org.intellij.lang.annotations.Language import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import java.io.File internal class AndroidLibraryPluginTest : WithGradleProjectTest() { diff --git a/plugins/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt b/android/src/test/kotlin/com/project/starter/modules/tasks/ConfigurationCacheTest.kt similarity index 98% rename from plugins/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt rename to android/src/test/kotlin/com/project/starter/modules/tasks/ConfigurationCacheTest.kt index b9e97c8b..16273f18 100644 --- a/plugins/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt +++ b/android/src/test/kotlin/com/project/starter/modules/tasks/ConfigurationCacheTest.kt @@ -1,4 +1,4 @@ -package com.project.starter.modules +package com.project.starter.modules.tasks import com.project.starter.WithGradleProjectTest import com.project.starter.javaClass diff --git a/plugins/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt b/android/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt similarity index 94% rename from plugins/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt rename to android/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt index baac78ec..cbdca13b 100644 --- a/plugins/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt +++ b/android/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt @@ -27,7 +27,7 @@ internal class ForbidJavaFilesTaskTest : WithGradleProjectTest() { val buildScript = """ plugins { - id('com.starter.library.kotlin') + id('com.starter.library.android') } projectConfig { @@ -44,6 +44,13 @@ internal class ForbidJavaFilesTaskTest : WithGradleProjectTest() { resolve("java/KotlinInJavaDir.kt") { writeText(kotlinClass("KotlinInJavaDir")) } + resolve("AndroidManifest.xml") { + writeText( + """ + + """.trimIndent() + ) + } } test = resolve("src/test") { resolve("kotlin/Test1.kt") { diff --git a/plugins/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt b/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt similarity index 99% rename from plugins/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt rename to android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt index d58625f5..0faa82ec 100644 --- a/plugins/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt +++ b/android/src/test/kotlin/com/project/starter/quality/AndroidQualityPluginTest.kt @@ -10,7 +10,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.io.File -internal class QualityPluginTest : WithGradleProjectTest() { +internal class AndroidQualityPluginTest : WithGradleProjectTest() { private lateinit var module1Root: File private lateinit var module2Root: File diff --git a/plugins/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt b/android/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt similarity index 100% rename from plugins/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt rename to android/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt diff --git a/plugins/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt b/android/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt similarity index 100% rename from plugins/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt rename to android/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt diff --git a/plugins/src/test/kotlin/com/project/starter/versioning/AndroidVersioningPluginTest.kt b/android/src/test/kotlin/com/project/starter/versioning/AndroidVersioningPluginTest.kt similarity index 100% rename from plugins/src/test/kotlin/com/project/starter/versioning/AndroidVersioningPluginTest.kt rename to android/src/test/kotlin/com/project/starter/versioning/AndroidVersioningPluginTest.kt diff --git a/build.gradle b/build.gradle index 7e06adc5..8455c0b8 100644 --- a/build.gradle +++ b/build.gradle @@ -20,10 +20,11 @@ allprojects { } } - pluginManager.withPlugin("java") { - java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(8)) + configurations.configureEach { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + def requested = details.requested + if (requested.group == 'org.jetbrains.kotlin' && requested.name.startsWith("kotlin")) { + details.useVersion "1.4.32" } } } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 6445756e..77f0ccbe 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,17 +1,17 @@ plugins { id 'java-gradle-plugin' - id "org.jmailen.kotlinter" version "3.3.0" - id 'org.jetbrains.kotlin.jvm' version '1.4.31' + id "org.jmailen.kotlinter" version "3.4.0" + id 'org.jetbrains.kotlin.jvm' version '1.4.32' } repositories { - google() mavenCentral() gradlePluginPortal() } dependencies { implementation "org.jetbrains.kotlin:kotlin-gradle-plugin" + implementation "com.gradle.publish:plugin-publish-plugin:0.13.0" } gradlePlugin { diff --git a/buildSrc/src/main/groovy/myproject.java-conventions.gradle b/buildSrc/src/main/groovy/myproject.java-conventions.gradle new file mode 100644 index 00000000..5dd38970 --- /dev/null +++ b/buildSrc/src/main/groovy/myproject.java-conventions.gradle @@ -0,0 +1,5 @@ +java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } +} diff --git a/buildSrc/src/main/kotlin/PublishingPlugin.kt b/buildSrc/src/main/kotlin/PublishingPlugin.kt index ef2f912b..0b1aa435 100644 --- a/buildSrc/src/main/kotlin/PublishingPlugin.kt +++ b/buildSrc/src/main/kotlin/PublishingPlugin.kt @@ -1,3 +1,4 @@ +import com.gradle.publish.PluginBundleExtension import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.ExtensionContainer @@ -9,6 +10,7 @@ class PublishingPlugin : Plugin { override fun apply(target: Project) = with(target) { pluginManager.apply("maven-publish") + pluginManager.apply("com.gradle.plugin-publish") extensions.configure { withSourcesJar() @@ -30,6 +32,12 @@ class PublishingPlugin : Plugin { } } } + extensions.configure { + website = "https://github.com/usefulness/project-starter/" + vcsUrl = "https://github.com/usefulness/project-starter.git" + description = "Set of plugins that might be useful for Multi-Module Android projects." + tags = listOf("android", "kotlin", "quickstart", "codestyle", "library", "baseline") + } } private inline fun ExtensionContainer.configure(crossinline receiver: T.() -> Unit) { diff --git a/config/build.gradle b/config/build.gradle new file mode 100644 index 00000000..6df2ea9f --- /dev/null +++ b/config/build.gradle @@ -0,0 +1,27 @@ +plugins { + id 'java-gradle-plugin' + id 'com.starter.library.kotlin' + id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' + id 'com.starter.publishing' +} + +dependencies { + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +test { + useJUnitPlatform() +} + +gradlePlugin { + plugins { + commonConfig { + id = 'com.starter.config' + displayName = 'Common Configuration Plugin' + implementationClass = 'com.project.starter.config.plugins.CommonSettingsPlugin' + } + } +} diff --git a/config/src/main/kotlin/com/project/starter/config/PluginUtils.kt b/config/src/main/kotlin/com/project/starter/config/PluginUtils.kt new file mode 100644 index 00000000..0d876d83 --- /dev/null +++ b/config/src/main/kotlin/com/project/starter/config/PluginUtils.kt @@ -0,0 +1,12 @@ +package com.project.starter.config + +import org.gradle.api.Project +import org.gradle.api.plugins.ExtensionContainer + +inline fun ExtensionContainer.getByType() = + getByType(T::class.java) + +inline fun Project.withExtension(crossinline action: Project.(T) -> Unit) = + afterEvaluate { + it.action(it.extensions.getByType()) + } diff --git a/plugins/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt b/config/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt similarity index 98% rename from plugins/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt rename to config/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt index 0bdb4fe4..43b50db2 100644 --- a/plugins/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt +++ b/config/src/main/kotlin/com/project/starter/config/extensions/RootConfigExtension.kt @@ -8,7 +8,6 @@ import org.gradle.util.ConfigureUtil open class RootConfigExtension( var javaVersion: JavaVersion = JavaVersion.VERSION_1_8, var javaFilesAllowed: Boolean = true, - val useKapt: Boolean = false, ) { val quality = QualityPluginConfig() diff --git a/plugins/src/main/kotlin/com/project/starter/config/plugins/CommonSettingsPlugin.kt b/config/src/main/kotlin/com/project/starter/config/plugins/CommonSettingsPlugin.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/config/plugins/CommonSettingsPlugin.kt rename to config/src/main/kotlin/com/project/starter/config/plugins/CommonSettingsPlugin.kt diff --git a/plugins/src/test/kotlin/com/project/starter/config/plugins/CommonSettingsPluginTest.kt b/config/src/test/kotlin/com/project/starter/plugins/CommonSettingsPluginTest.kt similarity index 93% rename from plugins/src/test/kotlin/com/project/starter/config/plugins/CommonSettingsPluginTest.kt rename to config/src/test/kotlin/com/project/starter/plugins/CommonSettingsPluginTest.kt index 1238fae5..a58a12e6 100644 --- a/plugins/src/test/kotlin/com/project/starter/config/plugins/CommonSettingsPluginTest.kt +++ b/config/src/test/kotlin/com/project/starter/plugins/CommonSettingsPluginTest.kt @@ -17,7 +17,7 @@ internal class CommonSettingsPluginTest : WithGradleProjectTest() { @BeforeEach fun setUp() { rootDirectory.apply { - resolve("settings.gradle").writeText("""include ":module1", ":module2" """) + resolve("settings.gradle").writeText("""include ":module1" """) rootBuildScript = resolve("build.gradle") module1Root = resolve("module1") { @@ -25,7 +25,7 @@ internal class CommonSettingsPluginTest : WithGradleProjectTest() { writeText( """ plugins { - id('kotlin') + id('org.jetbrains.kotlin.jvm') version "1.4.32" } """.trimIndent() @@ -51,9 +51,9 @@ internal class CommonSettingsPluginTest : WithGradleProjectTest() { javaVersion = JavaVersion.VERSION_1_8 javaFilesAllowed = false androidPlugin { - compileSdkVersion = 29 + compileSdkVersion = 30 minSdkVersion = 23 - targetSdkVersion = 29 + targetSdkVersion = 30 } qualityPlugin { enabled = true @@ -84,9 +84,9 @@ internal class CommonSettingsPluginTest : WithGradleProjectTest() { javaVersion JavaVersion.VERSION_1_8 javaFilesAllowed false androidPlugin { - compileSdkVersion 29 + compileSdkVersion 30 minSdkVersion 23 - targetSdkVersion 29 + targetSdkVersion 30 } qualityPlugin { enabled true diff --git a/gradle.properties b/gradle.properties index 90975828..56d3f8ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,4 @@ org.gradle.parallel=true -org.gradle.caching=true +org.gradle.caching=false +kotlin.parallel.tasks.in.project=true org.gradle.vfs.watch=true diff --git a/jvm/build.gradle b/jvm/build.gradle new file mode 100644 index 00000000..918df6e1 --- /dev/null +++ b/jvm/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'java-gradle-plugin' + id 'com.starter.library.kotlin' + id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' + id 'com.starter.publishing' +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + api 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' + implementation project(":versioning") + implementation project(":quality") + implementation project(":config") + + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +test { + useJUnitPlatform() +} + +gradlePlugin { + plugins { + kotlinLibrary { + id = 'com.starter.library.kotlin' + displayName = 'Kotlin Library Plugin' + implementationClass = 'com.project.starter.modules.plugins.KotlinLibraryPlugin' + } + } +} diff --git a/jvm/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt b/jvm/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt new file mode 100644 index 00000000..b4232d9d --- /dev/null +++ b/jvm/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt @@ -0,0 +1,7 @@ +package com.project.starter.modules.extensions + +import com.project.starter.quality.extensions.JavaSourcesAware + +open class KotlinLibraryConfigExtension( + override var javaFilesAllowed: Boolean? = null, +) : JavaSourcesAware diff --git a/plugins/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt b/jvm/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt similarity index 88% rename from plugins/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt rename to jvm/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt index bc7fdf59..b1a6a80a 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt +++ b/jvm/src/main/kotlin/com/project/starter/modules/internal/Kapt.kt @@ -3,7 +3,7 @@ package com.project.starter.modules.internal import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.KaptExtension -internal fun Project.configureKapt() { +fun Project.configureKapt() { pluginManager.apply("kotlin-kapt") extensions.configure(KaptExtension::class.java) { it.correctErrorTypes = true diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/KotlinCoverage.kt b/jvm/src/main/kotlin/com/project/starter/modules/internal/KotlinCoverage.kt similarity index 52% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/KotlinCoverage.kt rename to jvm/src/main/kotlin/com/project/starter/modules/internal/KotlinCoverage.kt index 56074a0c..90839947 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/internal/KotlinCoverage.kt +++ b/jvm/src/main/kotlin/com/project/starter/modules/internal/KotlinCoverage.kt @@ -1,7 +1,8 @@ -package com.project.starter.quality.internal +package com.project.starter.modules.internal -import com.project.starter.modules.internal.getByType +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 @@ -9,6 +10,12 @@ import org.gradle.testing.jacoco.tasks.JacocoReport internal fun Project.configureKotlinCoverage() { pluginManager.apply("jacoco") + tasks.withType(Test::class.java) { + it.extensions.getByType().apply { + isIncludeNoLocationClasses = true + excludes = daggerCoverageExclusions + "jdk.internal.*" + } + } extensions.configure(JacocoPluginExtension::class.java) { it.toolVersion = "0.8.6" } @@ -19,9 +26,12 @@ internal fun Project.configureKotlinCoverage() { html.isEnabled = true } } - tasks.named("test") { testTask -> - testTask.extensions.getByType().apply { - excludes = dagger - } - } } + +val daggerCoverageExclusions = listOf( + "**/*_MembersInjector.class", + "**/Dagger*Component.class", + "**/Dagger*Component${"$"}Builder.class", + "**/*_*Factory.class", + "**/*_Factory.class" +) diff --git a/plugins/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt b/jvm/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt rename to jvm/src/main/kotlin/com/project/starter/modules/internal/Repositories.kt diff --git a/plugins/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt b/jvm/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt similarity index 55% rename from plugins/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt rename to jvm/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt index c2e56a22..c2091a9f 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt +++ b/jvm/src/main/kotlin/com/project/starter/modules/plugins/ConfigurationPlugin.kt @@ -7,16 +7,20 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -internal class ConfigurationPlugin : Plugin { +class ConfigurationPlugin : Plugin { override fun apply(target: Project): Unit = with(target) { - if (rootConfig.quality.enabled) { - pluginManager.apply("com.starter.quality") + afterEvaluate { + if (rootConfig.quality.enabled) { + pluginManager.apply("com.starter.quality") + } } - if (rootConfig.versioning.enabled) { - if (!rootProject.pluginManager.hasPlugin("com.starter.versioning")) { - logger.debug("Apply com.starter.versioning to $rootProject") - rootProject.pluginManager.apply(VersioningPlugin::class.java) + afterEvaluate { + if (rootConfig.versioning.enabled) { + if (!rootProject.pluginManager.hasPlugin("com.starter.versioning")) { + logger.info("Apply com.starter.versioning to $rootProject") + rootProject.pluginManager.apply(VersioningPlugin::class.java) + } } } configureRepositories() diff --git a/plugins/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt b/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt similarity index 64% rename from plugins/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt rename to jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt index 4865646e..ecbebe33 100644 --- a/plugins/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt +++ b/jvm/src/main/kotlin/com/project/starter/modules/plugins/KotlinLibraryPlugin.kt @@ -1,18 +1,12 @@ package com.project.starter.modules.plugins -import com.android.build.gradle.internal.dsl.LintOptions -import com.android.build.gradle.internal.tasks.factory.dependsOn import com.project.starter.config.plugins.rootConfig +import com.project.starter.config.withExtension import com.project.starter.modules.extensions.KotlinLibraryConfigExtension -import com.project.starter.modules.internal.configureAndroidLint -import com.project.starter.modules.internal.configureKapt -import com.project.starter.modules.internal.getByType -import com.project.starter.modules.internal.withExtension +import com.project.starter.modules.internal.configureKotlinCoverage import com.project.starter.modules.tasks.ForbidJavaFilesTask.Companion.registerForbidJavaFilesTask import com.project.starter.modules.tasks.ProjectCoverageTask.Companion.registerProjectCoverageTask import com.project.starter.modules.tasks.ProjectTestTask.Companion.registerProjectTestTask -import com.project.starter.modules.tasks.ProjectLintTask.Companion.registerProjectLintTask -import com.project.starter.quality.internal.configureKotlinCoverage import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginConvention @@ -33,13 +27,6 @@ class KotlinLibraryPlugin : Plugin { registerProjectCoverageTask { it.dependsOn("jacocoTestReport") } - pluginManager.withPlugin("com.android.lint") { - registerProjectLintTask { projectLint -> - projectLint.dependsOn("$path:lint") - } - - configureAndroidLint(extensions.getByType()) - } withExtension { config -> val javaFilesAllowed = config.javaFilesAllowed ?: rootConfig.javaFilesAllowed if (!javaFilesAllowed) { @@ -51,11 +38,9 @@ class KotlinLibraryPlugin : Plugin { } } } - tasks.named("compileKotlin").dependsOn(forbidJavaFiles) - } - - if (config.useKapt ?: rootConfig.useKapt) { - configureKapt() + tasks.named("compileKotlin") { + it.dependsOn(forbidJavaFiles) + } } } } diff --git a/plugins/src/main/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTask.kt b/jvm/src/main/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTask.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTask.kt rename to jvm/src/main/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTask.kt diff --git a/plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectCoverageTask.kt b/jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectCoverageTask.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectCoverageTask.kt rename to jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectCoverageTask.kt diff --git a/plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectLintTask.kt b/jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectLintTask.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectLintTask.kt rename to jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectLintTask.kt diff --git a/plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectTestTask.kt b/jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectTestTask.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/modules/tasks/ProjectTestTask.kt rename to jvm/src/main/kotlin/com/project/starter/modules/tasks/ProjectTestTask.kt diff --git a/jvm/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt b/jvm/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt new file mode 100644 index 00000000..23ee609a --- /dev/null +++ b/jvm/src/test/kotlin/com/project/starter/modules/ConfigurationCacheTest.kt @@ -0,0 +1,43 @@ +package com.project.starter.modules + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class ConfigurationCacheTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + @Language("groovy") + val script = + """ + plugins { + id 'com.starter.library.kotlin' + } + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + resolve("src/main/java/ValidJava2.java") { + writeText(javaClass("ValidJava2")) + } + resolve("src/test/java/ValidJavaTest2.java") { + writeText(javaClass("ValidJavaTest2")) + } + } + } + + /** + * https://youtrack.jetbrains.com/issue/KT-38498 + * https://issuetracker.google.com/issues/156552742 + */ + @Disabled("Configuration cache is not yet supported") + @Test + fun `does not fail with configuration cache`() { + runTask("--configuration-cache") + } +} diff --git a/plugins/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt b/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt similarity index 91% rename from plugins/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt rename to jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt index 186990bc..b1699d9b 100644 --- a/plugins/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt +++ b/jvm/src/test/kotlin/com/project/starter/modules/KotlinLibraryPluginTest.kt @@ -108,25 +108,6 @@ internal class KotlinLibraryPluginTest : WithGradleProjectTest() { } } - @Test - fun `projectLint runs coverage for all modules`() { - module1Root.resolve("build.gradle").appendText( - """ - apply plugin: "com.android.lint" - """.trimIndent() - ) - module2Root.resolve("build.gradle").appendText( - """ - apply plugin: "com.android.lint" - """.trimIndent() - ) - - val result = runTask("projectLint") - - assertThat(result.task(":module1:lint")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(result.task(":module2:lint")!!.outcome).isEqualTo(TaskOutcome.SUCCESS) - } - @Test fun `does not fail on java files by default`() { module2Root.resolve("src/main/java/JavaClass.java") { diff --git a/jvm/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt b/jvm/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt new file mode 100644 index 00000000..1239aff2 --- /dev/null +++ b/jvm/src/test/kotlin/com/project/starter/modules/tasks/ForbidJavaFilesTaskTest.kt @@ -0,0 +1,104 @@ +package com.project.starter.modules.tasks + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import com.project.starter.kotlinClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.io.File + +internal class ForbidJavaFilesTaskTest : WithGradleProjectTest() { + + lateinit var main: File + lateinit var test: File + + @BeforeEach + fun setUp() { + rootDirectory.apply { + mkdirs() + resolve("settings.gradle").writeText("""include ":module1" """) + + resolve("module1") { + @Language("groovy") + val buildScript = + """ + plugins { + id('com.starter.library.kotlin') + } + + projectConfig { + javaFilesAllowed = false + } + """.trimIndent() + resolve("build.gradle") { + writeText(buildScript) + } + main = resolve("src/main") { + resolve("kotlin/ValidKotlin.kt") { + writeText(kotlinClass("ValidKotlin")) + } + resolve("java/KotlinInJavaDir.kt") { + writeText(kotlinClass("KotlinInJavaDir")) + } + } + test = resolve("src/test") { + resolve("kotlin/Test1.kt") { + writeText(kotlinClass("Test1")) + } + } + } + } + } + + @Test + fun `task passes configuration phase`() { + runTask("help") + } + + @Test + fun `task fails on main sources`() { + main.resolve("java/JavaClass.java") { + writeText(javaClass("JavaClass")) + } + + val result = runTask("assemble", shouldFail = true) + + assertThat(result.task(":module1:forbidJavaFiles")?.outcome).isEqualTo(TaskOutcome.FAILED) + assertThat(result.output).contains("Java files are not allowed within :module1") + } + + @Test + fun `task fails on test sources`() { + test.resolve("java/JavaTest.java") { + writeText(javaClass("JavaTest")) + } + + val result = runTask("assemble", shouldFail = true) + + assertThat(result.task(":module1:forbidJavaFiles")?.outcome).isEqualTo(TaskOutcome.FAILED) + assertThat(result.output).contains("Java files are not allowed within :module1") + } + + @Test + fun `task is cacheable`() { + runTask(":module1:assemble") + + val secondRun = runTask(":module1:assemble") + + assertThat(secondRun.task(":module1:forbidJavaFiles")?.outcome).isNotEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `doesn't check generated files`() { + rootDirectory.resolve("build/generated/source/apollo/classes/main/JavaTest.java") { + writeText(javaClass("JavaTest")) + } + + val secondRun = runTask("assemble") + + assertThat(secondRun.task(":module1:forbidJavaFiles")?.outcome).isNotEqualTo(TaskOutcome.SUCCESS) + } +} diff --git a/jvm/src/test/kotlin/com/project/starter/quality/KotlinQualityPluginTest.kt b/jvm/src/test/kotlin/com/project/starter/quality/KotlinQualityPluginTest.kt new file mode 100644 index 00000000..69f9a927 --- /dev/null +++ b/jvm/src/test/kotlin/com/project/starter/quality/KotlinQualityPluginTest.kt @@ -0,0 +1,90 @@ +package com.project.starter.quality + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import com.project.starter.kotlinClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +internal class KotlinQualityPluginTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + resolve("build.gradle") { + writeText( + """ + plugins { + id('com.starter.library.kotlin') + } + """.trimIndent() + ) + } + resolve("src/main/kotlin/ValidKotlinFile1.kt") { + writeText(kotlinClass("ValidKotlinFile1")) + } + resolve("src/main/java/ValidJava1.java") { + writeText(javaClass("ValidJava1")) + } + resolve("src/debug/java/DebugJava.java") { + writeText(javaClass("DebugJava")) + } + resolve("src/test/kotlin/ValidKotlinTest1.kt") { + writeText(kotlinClass("ValidKotlinTest1")) + } + resolve("src/test/java/ValidJavaTest1.java") { + writeText(javaClass("ValidJavaTest1")) + } + } + } + + @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(":lintKotlinMain")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinTest")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `projectCodeStyle fails if Checkstyle violation found`() { + rootDirectory.resolve("src/test/java/JavaFileWithCheckstyleIssues.java") { + @Language("java") + val javaClass = + """ + import java.io.IOException; + + public class JavaFileWithCheckstyleIssues { + + int test() throws IOException { + int variable = System.in.read(); + if(variable % 2 == 1){ + return 2; + } else { + return 3; + } + } + } + + """.trimIndent() + writeText(javaClass) + } + + val result = runTask("projectCodeStyle", shouldFail = true) + + assertThat(result.task(":checkstyleTest")?.outcome).isEqualTo(TaskOutcome.FAILED) + assertThat(result.output) + .contains("WhitespaceAround: 'if' is not followed by whitespace.") + .contains("WhitespaceAround: '{' is not preceded with whitespace") + } +} diff --git a/jvm/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt b/jvm/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt new file mode 100644 index 00000000..b9f3d9cf --- /dev/null +++ b/jvm/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt @@ -0,0 +1,143 @@ +package com.project.starter.quality.tasks + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class IssueLinksCheckerTaskTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + @Language("groovy") + val script = + """ + plugins { + id 'com.starter.library.kotlin' + } + + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + resolve("src/main/java/ValidJava2.java") { + writeText(javaClass("ValidJava2")) + } + resolve("src/test/java/ValidJavaTest2.java") { + writeText(javaClass("ValidJavaTest2")) + } + } + } + + @Test + fun `does not warn on regular project`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://issuetracker.google.com/issues/145439806 + **/ + object ValidKotlin { + // https://www.example.com + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + @Disabled("Google Issue tracker is not supported yet") + fun `reports issuetracker issues`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://news.ycombinator.com/ + **/ + object ValidKotlin { + // https://issuetracker.google.com/issues/121092282 + val animations = 0 // Set animation: https://issuetracker.google.com/issues/154643058 + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `reports youtrack 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/main/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) + } + + @Test + fun `reports github issues`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://github.com/isaacs/github/issues/5 + **/ + object ValidKotlin { + // https://www.example.com + // https://github.com/apollographql/apollo-android/issues/2207 <- closed + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(rootDirectory.resolve("build/reports/issue_comments.txt")) + .hasContent( + """ + ✅ https://github.com/isaacs/github/issues/5 (Opened) + 👉 https://github.com/apollographql/apollo-android/issues/2207 (Closed) + """.trimIndent() + ) + assertThat(result.output).contains("✅ https://github.com/isaacs/github/issues/5 (Opened)") + assertThat(result.output).contains("\uD83D\uDC49 https://github.com/apollographql/apollo-android/issues/2207 (Closed)") + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } +} diff --git a/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt b/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt new file mode 100644 index 00000000..3c352f0a --- /dev/null +++ b/jvm/src/test/kotlin/com/project/starter/versioning/KotlinVersioningPluginTest.kt @@ -0,0 +1,67 @@ +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 KotlinVersioningPluginTest : 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.kotlin' + } + """.trimIndent() + ) + } + } + module2Root = resolve("module2") { + resolve("build.gradle") { + writeText( + """ + plugins { + id 'com.starter.library.kotlin' + } + """.trimIndent() + ) + } + } + } + git = setupGit(origin) + git.tag("release-1.1.0") + } + + @Test + fun `sets version to all projects`() { + git.commit("features in 1.2.0") + git.tag("release-1.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/plugins/build.gradle b/plugins/build.gradle index 1d0425c0..f4827d65 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradle.plugin-publish' version '0.13.0' + id 'com.gradle.plugin-publish' version '0.14.0' id 'java-gradle-plugin' id 'com.starter.library.kotlin' id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' @@ -13,12 +13,10 @@ repositories { } dependencies { - api 'org.jmailen.gradle:kotlinter-gradle:3.3.0' + api 'org.jmailen.gradle:kotlinter-gradle:3.4.0' api 'io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.15.0' - api 'com.android.tools.build:gradle:4.1.2' - api 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.31' - implementation 'pl.allegro.tech.build:axion-release-plugin:1.12.1' - implementation 'com.github.usefulness:issuechecker:0.1.1' + api 'com.android.tools.build:gradle:4.1.3' + api 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' testImplementation "org.assertj:assertj-core:3.19.0" testImplementation "org.junit.jupiter:junit-jupiter:5.7.1" @@ -57,12 +55,12 @@ gradlePlugin { androidLibrary { id = 'com.starter.library.android' displayName = 'Android Library Plugin' - implementationClass = 'com.project.starter.modules.plugins.AndroidLibraryPlugin' + implementationClass = 'AndroidLibraryPlugin' } androidApplication { id = 'com.starter.application.android' displayName = 'Android Applicataion Plugin' - implementationClass = 'com.project.starter.modules.plugins.AndroidApplicationPlugin' + implementationClass = 'AndroidApplicationPlugin' } commonConfig { id = 'com.starter.config' diff --git a/plugins/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt b/plugins/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt deleted file mode 100644 index 6b003263..00000000 --- a/plugins/src/main/kotlin/com/project/starter/modules/extensions/KotlinLibraryConfigExtension.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.project.starter.modules.extensions - -open class KotlinLibraryConfigExtension( - var javaFilesAllowed: Boolean? = null, - val useKapt: Boolean? = null -) diff --git a/quality/build.gradle b/quality/build.gradle new file mode 100644 index 00000000..9a3ac25d --- /dev/null +++ b/quality/build.gradle @@ -0,0 +1,40 @@ +plugins { + id 'java-gradle-plugin' + id 'com.starter.library.kotlin' + id 'pl.droidsonroids.jacoco.testkit' version '1.0.7' + id 'com.starter.publishing' +} + +repositories { + mavenCentral() + google() + gradlePluginPortal() +} + +dependencies { + api 'org.jmailen.gradle:kotlinter-gradle:3.3.0' + api 'io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.16.0' + api 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' + compileOnly 'com.android.tools.build:gradle:4.1.3' + implementation 'com.github.usefulness:issuechecker:0.2.0' + implementation project(":config") + + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +test { + useJUnitPlatform() +} + +gradlePlugin { + plugins { + quality { + id = 'com.starter.quality' + displayName = 'Code Quality Plugin' + implementationClass = 'com.project.starter.quality.plugins.QualityPlugin' + } + } +} diff --git a/quality/src/main/kotlin/com/project/starter/quality/extensions/JavaSourcesAware.kt b/quality/src/main/kotlin/com/project/starter/quality/extensions/JavaSourcesAware.kt new file mode 100644 index 00000000..190ceb00 --- /dev/null +++ b/quality/src/main/kotlin/com/project/starter/quality/extensions/JavaSourcesAware.kt @@ -0,0 +1,5 @@ +package com.project.starter.quality.extensions + +interface JavaSourcesAware { + val javaFilesAllowed: Boolean? +} diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt similarity index 76% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt rename to quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt index bd82562a..33da5c79 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/internal/Checkstyle.kt @@ -6,10 +6,8 @@ import com.android.build.gradle.BaseExtension import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.internal.tasks.factory.dependsOn import com.project.starter.config.extensions.RootConfigExtension -import com.project.starter.modules.extensions.AndroidApplicationConfigExtension -import com.project.starter.modules.extensions.AndroidLibraryConfigExtension -import com.project.starter.modules.extensions.KotlinLibraryConfigExtension -import com.project.starter.modules.internal.withExtension +import com.project.starter.config.withExtension +import com.project.starter.quality.extensions.JavaSourcesAware import com.project.starter.quality.tasks.GenerateCheckstyleBaselineTask.Companion.addGenerateCheckstyleBaselineTask import com.project.starter.quality.tasks.ProjectCodeStyleTask import org.gradle.api.Project @@ -21,25 +19,16 @@ private val pluginsWithConfgiuration = listOf( Config( plugin = "kotlin", starterPlugin = "com.starter.library.kotlin", - checkIfJavaAllowed = { callback -> - withExtension { callback(it.javaFilesAllowed) } - }, configuration = Project::configureKotlinCheckstyle ), Config( plugin = "com.android.library", starterPlugin = "com.starter.library.android", - checkIfJavaAllowed = { callback -> - withExtension { callback(it.javaFilesAllowed) } - }, configuration = Project::configureAndroidCheckstyle ), Config( plugin = "com.android.application", starterPlugin = "com.starter.application.android", - checkIfJavaAllowed = { callback -> - withExtension { callback(it.javaFilesAllowed) } - }, configuration = Project::configureAndroidCheckstyle ) ) @@ -47,22 +36,23 @@ private val pluginsWithConfgiuration = listOf( private data class Config( val plugin: String, val starterPlugin: String, - val checkIfJavaAllowed: Project.((Boolean?) -> Unit) -> Unit, val configuration: Project.() -> Unit ) internal fun Project.configureCheckstyle(rootConfig: RootConfigExtension) { - pluginsWithConfgiuration.forEach { (plugin, starterPlugin, checkIfJavaAllowed, configuration) -> + pluginsWithConfgiuration.forEach { (plugin, starterPlugin, configuration) -> pluginManager.withPlugin(plugin) { if (pluginManager.hasPlugin(starterPlugin)) { - checkIfJavaAllowed { javaFilesAllowed -> - if (javaFilesAllowed ?: rootConfig.javaFilesAllowed) { + withExtension { + if (it.javaFilesAllowed ?: rootConfig.javaFilesAllowed) { configuration() } } } else { - if (rootConfig.javaFilesAllowed) { - configuration() + afterEvaluate { + if (rootConfig.javaFilesAllowed) { + configuration() + } } } } @@ -77,7 +67,9 @@ private fun Project.configureKotlinCheckstyle() { it.dependsOn("checkstyleMain", "checkstyleTest") } addGenerateCheckstyleBaselineTask() - tasks.named(ProjectCodeStyleTask.TASK_NAME).dependsOn(checkstyle) + tasks.named(ProjectCodeStyleTask.TASK_NAME) { + it.dependsOn(checkstyle) + } } private fun Project.configureAndroidCheckstyle() { @@ -94,10 +86,14 @@ private fun Project.configureAndroidCheckstyle() { task.source(files) } - checkstyle.dependsOn(variantCheck) + checkstyle.configure { + it.dependsOn(variantCheck) + } } } - tasks.named(ProjectCodeStyleTask.TASK_NAME).dependsOn(checkstyle) + tasks.named(ProjectCodeStyleTask.TASK_NAME) { + it.dependsOn(checkstyle) + } addGenerateCheckstyleBaselineTask() } diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt rename to quality/src/main/kotlin/com/project/starter/quality/internal/Detekt.kt diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/Ktlint.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/Ktlint.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/Ktlint.kt rename to quality/src/main/kotlin/com/project/starter/quality/internal/Ktlint.kt diff --git a/plugins/src/main/kotlin/com/project/starter/quality/internal/ResourceLoader.kt b/quality/src/main/kotlin/com/project/starter/quality/internal/ResourceLoader.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/quality/internal/ResourceLoader.kt rename to quality/src/main/kotlin/com/project/starter/quality/internal/ResourceLoader.kt diff --git a/plugins/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt b/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt similarity index 82% rename from plugins/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt rename to quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt index e2e2b42b..2f6ffeab 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/plugins/QualityPlugin.kt @@ -1,13 +1,11 @@ package com.project.starter.quality.plugins import com.android.build.gradle.BaseExtension -import com.android.build.gradle.internal.tasks.factory.dependsOn import com.project.starter.config.plugins.rootConfig -import com.project.starter.modules.internal.findByType -import com.project.starter.quality.tasks.IssueLinksTask.Companion.registerIssueCheckerTask import com.project.starter.quality.internal.configureCheckstyle import com.project.starter.quality.internal.configureDetekt import com.project.starter.quality.internal.configureKtlint +import com.project.starter.quality.tasks.IssueLinksTask.Companion.registerIssueCheckerTask import com.project.starter.quality.tasks.ProjectCodeStyleTask.Companion.addProjectCodeStyleTask import org.gradle.api.Plugin import org.gradle.api.Project @@ -31,15 +29,18 @@ class QualityPlugin : Plugin { configureIssueCheckerTask() val config = rootConfig.quality - if (config.formatOnCompile) { - applyFormatOnRecompile() + afterEvaluate { + if (config.formatOnCompile) { + applyFormatOnRecompile() + } } } private fun Project.configureIssueCheckerTask() { registerIssueCheckerTask { - val extension = project.extensions.findByType() + val extension = project.extensions.findByName("android") if (extension != null) { + extension as BaseExtension extension.sourceSets.configureEach { sourceSet -> source += sourceSet.java.srcDirs .map { dir -> project.fileTree(dir) } @@ -60,13 +61,19 @@ class QualityPlugin : Plugin { private fun Project.applyFormatOnRecompile() { pluginManager.withPlugin("kotlin") { - tasks.named("compileKotlin").dependsOn("$path:formatKotlin") + tasks.named("compileKotlin") { + it.dependsOn("$path:formatKotlin") + } } pluginManager.withPlugin("com.android.library") { - tasks.named("preBuild").dependsOn("$path:formatKotlin") + tasks.named("preBuild") { + it.dependsOn("$path:formatKotlin") + } } pluginManager.withPlugin("com.android.application") { - tasks.named("preBuild").dependsOn("$path:formatKotlin") + tasks.named("preBuild") { + it.dependsOn("$path:formatKotlin") + } } } diff --git a/plugins/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt b/quality/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt similarity index 98% rename from plugins/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt rename to quality/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt index 219214f0..9a0c15c4 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTask.kt @@ -1,6 +1,6 @@ package com.project.starter.quality.tasks -import com.project.starter.modules.internal.getByType +import com.project.starter.config.getByType import java.io.File import javax.xml.parsers.DocumentBuilderFactory import org.gradle.api.DefaultTask diff --git a/plugins/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt b/quality/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt similarity index 98% rename from plugins/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt rename to quality/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt index f44f842f..aff543fb 100644 --- a/plugins/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt +++ b/quality/src/main/kotlin/com/project/starter/quality/tasks/IssueLinksTask.kt @@ -5,6 +5,7 @@ package com.project.starter.quality.tasks import com.starter.issuechecker.CheckResult import com.starter.issuechecker.IssueChecker import com.starter.issuechecker.IssueStatus +import com.starter.issuechecker.reportBlocking import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.FileTree diff --git a/plugins/src/main/kotlin/com/project/starter/quality/tasks/ProjectCodeStyleTask.kt b/quality/src/main/kotlin/com/project/starter/quality/tasks/ProjectCodeStyleTask.kt similarity index 100% rename from plugins/src/main/kotlin/com/project/starter/quality/tasks/ProjectCodeStyleTask.kt rename to quality/src/main/kotlin/com/project/starter/quality/tasks/ProjectCodeStyleTask.kt diff --git a/plugins/src/main/resources/checkstyle-config.xml b/quality/src/main/resources/checkstyle-config.xml similarity index 100% rename from plugins/src/main/resources/checkstyle-config.xml rename to quality/src/main/resources/checkstyle-config.xml diff --git a/plugins/src/main/resources/checkstyle-suppressions.xml b/quality/src/main/resources/checkstyle-suppressions.xml similarity index 100% rename from plugins/src/main/resources/checkstyle-suppressions.xml rename to quality/src/main/resources/checkstyle-suppressions.xml diff --git a/plugins/src/main/resources/detekt-config.yml b/quality/src/main/resources/detekt-config.yml similarity index 93% rename from plugins/src/main/resources/detekt-config.yml rename to quality/src/main/resources/detekt-config.yml index ff804a1b..39836668 100644 --- a/plugins/src/main/resources/detekt-config.yml +++ b/quality/src/main/resources/detekt-config.yml @@ -17,18 +17,25 @@ processors: active: false exclude: # - 'DetektProgressListener' + # - 'KtFileCountProcessor' + # - 'PackageCountProcessor' + # - 'ClassCountProcessor' # - 'FunctionCountProcessor' # - 'PropertyCountProcessor' - # - 'ClassCountProcessor' - # - 'PackageCountProcessor' - # - 'KtFileCountProcessor' + # - 'ProjectComplexityProcessor' + # - 'ProjectCognitiveComplexityProcessor' + # - 'ProjectLLOCProcessor' + # - 'ProjectCLOCProcessor' + # - 'ProjectLOCProcessor' + # - 'ProjectSLOCProcessor' + # - 'LicenseHeaderLoaderExtension' console-reports: active: true exclude: - # - 'ProjectStatisticsReport' - # - 'ComplexityReport' - # - 'NotificationReport' + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' # - 'FindingsReport' - 'FileBasedFindingsReport' @@ -45,6 +52,7 @@ comments: AbsentOrWrongFileLicense: active: false licenseTemplateFile: 'license.template' + licenseTemplateIsRegex: false CommentOverPrivateFunction: active: false CommentOverPrivateProperty: @@ -132,6 +140,8 @@ coroutines: active: false RedundantSuspendModifier: active: true + SleepInsteadOfDelay: + active: true SuspendFunWithFlowReturnType: active: true @@ -173,22 +183,24 @@ empty-blocks: exceptions: active: true ExceptionRaisedInUnexpectedLocation: - active: false + active: true methodNames: [ toString, hashCode, equals, finalize ] InstanceOfCheckForException: active: false excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**' ] NotImplementedDeclaration: active: false - PrintStackTrace: + ObjectExtendsThrowable: active: false + PrintStackTrace: + active: true RethrowCaughtException: - active: false + active: true ReturnFromFinally: - active: false + active: true ignoreLabeled: false SwallowedException: - active: false + active: true ignoredExceptionTypes: - InterruptedException - NumberFormatException @@ -196,18 +208,18 @@ exceptions: - MalformedURLException allowedExceptionNameRegex: '_|(ignore|expected).*' ThrowingExceptionFromFinally: - active: false + active: true ThrowingExceptionInMain: active: false ThrowingExceptionsWithoutMessageOrCause: - active: false + active: true excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**' ] exceptions: - IllegalArgumentException - IllegalStateException - IOException ThrowingNewInstanceOfSameException: - active: false + active: true TooGenericExceptionCaught: active: true excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**' ] @@ -317,6 +329,9 @@ formatting: active: true autoCorrect: true indentSize: 4 + SpacingAroundAngleBrackets: + active: false + autoCorrect: true SpacingAroundColon: active: true autoCorrect: true @@ -344,6 +359,9 @@ formatting: SpacingAroundRangeOperator: active: true autoCorrect: true + SpacingAroundUnaryOperator: + active: false + autoCorrect: true SpacingBetweenDeclarationsWithAnnotations: active: false autoCorrect: true @@ -398,6 +416,7 @@ naming: ignoreOverridden: true InvalidPackageDeclaration: active: false + excludes: [ '*.kts' ] rootPackage: '' MatchingDeclarationName: active: true @@ -405,6 +424,8 @@ naming: MemberNameEqualsClassName: active: true ignoreOverridden: true + NoNameShadowing: + active: false NonBooleanPropertyPrefixedWithIs: active: false excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**' ] @@ -455,14 +476,20 @@ performance: potential-bugs: active: true + CastToNullableType: + active: false Deprecation: active: false + DontDowncastCollectionTypes: + active: false DuplicateCaseInWhenExpression: active: true EqualsAlwaysReturnsTrueOrFalse: active: true EqualsWithHashCodeExist: active: true + ExitOutsideMain: + active: false ExplicitGarbageCollectionCall: active: true HasPlatformType: @@ -472,7 +499,7 @@ potential-bugs: restrictToAnnotatedMethods: true returnValueAnnotations: [ '*.CheckReturnValue', '*.CheckResult' ] ImplicitDefaultLocale: - active: false + active: true ImplicitUnitReturnType: active: false allowExplicitReturnType: true @@ -502,11 +529,15 @@ potential-bugs: active: true UnnecessarySafeCall: active: true + UnreachableCatchBlock: + active: false UnreachableCode: active: true UnsafeCallOnNullableType: active: true UnsafeCast: + active: true + UnusedUnaryOperator: active: false UselessPostfixExpression: active: false @@ -524,6 +555,9 @@ style: conversionFunctionPrefix: 'to' DataClassShouldBeImmutable: active: false + DestructuringDeclarationWithTooManyEntries: + active: false + maxDestructuringEntries: 3 EqualsNullCall: active: true EqualsOnSignatureLine: @@ -548,6 +582,7 @@ style: methods: [ 'kotlin.io.println', 'kotlin.io.print' ] ForbiddenPublicDataClass: active: false + excludes: [ '**' ] ignorePackages: [ '*.internal', '*.internal.*' ] ForbiddenVoid: active: false @@ -556,12 +591,15 @@ style: FunctionOnlyReturningConstant: active: true ignoreOverridableFunction: true + ignoreActualFunction: true excludedFunctions: 'describeContents' excludeAnnotatedFunction: [ 'dagger.Provides' ] LibraryCodeMustSpecifyReturnType: active: true + excludes: [ '**' ] LibraryEntitiesShouldNotBePublic: active: false + excludes: [ '**' ] LoopWithTooManyJumpStatements: active: true maxJumpCount: 1 @@ -578,6 +616,7 @@ style: ignoreNamedArgument: true ignoreEnums: false ignoreRanges: false + ignoreExtensionFunctions: true MandatoryBracesIfStatements: active: false MandatoryBracesLoops: @@ -592,6 +631,8 @@ style: active: true ModifierOrder: active: true + MultilineLambdaItParameter: + active: false NestedClassesVisibility: active: false NewLineAtEndOfFile: @@ -624,7 +665,7 @@ style: SafeCast: active: true SerialVersionUIDInSerializableClass: - active: false + active: true SpacingBetweenPackageAndImports: active: false ThrowsCount: @@ -641,6 +682,8 @@ style: UnnecessaryAnnotationUseSiteTarget: active: false UnnecessaryApply: + active: true + UnnecessaryFilter: active: false UnnecessaryInheritance: active: true @@ -673,16 +716,20 @@ style: active: true UseIfInsteadOfWhen: active: true + UseIsNullOrEmpty: + active: true + UseOrEmpty: + active: true UseRequire: active: false UseRequireNotNull: - active: true + active: false UselessCallOnNotNull: active: true UtilityClassWithPublicConstructor: active: true VarCouldBeVal: - active: false + active: true WildcardImport: active: true excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**' ] diff --git a/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt b/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt new file mode 100644 index 00000000..d81bd38f --- /dev/null +++ b/quality/src/test/kotlin/com/project/starter/quality/QualityPluginTest.kt @@ -0,0 +1,171 @@ +package com.project.starter.quality + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import com.project.starter.kotlinClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +internal class QualityPluginTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + resolve("build.gradle") { + writeText( + """ + plugins { + id('com.starter.quality') + id('org.jetbrains.kotlin.jvm') + } + + repositories.jcenter() + """.trimIndent() + ) + } + resolve("src/main/kotlin/ValidKotlinFile1.kt") { + writeText(kotlinClass("ValidKotlinFile1")) + } + resolve("src/main/java/ValidJava1.java") { + writeText(javaClass("ValidJava1")) + } + resolve("src/debug/java/DebugJava.java") { + writeText(javaClass("DebugJava")) + } + resolve("src/test/kotlin/ValidKotlinTest1.kt") { + writeText(kotlinClass("ValidKotlinTest1")) + } + resolve("src/test/java/ValidJavaTest1.java") { + writeText(javaClass("ValidJavaTest1")) + } + } + } + + @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(":lintKotlinMain")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(result.task(":lintKotlinTest")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `formatOnCompile option enables failing builds if code style errors found`() { + val enableFormatOnCompile = { + @Language("groovy") + val buildscript = + """ + plugins { + id('com.starter.config') + id('com.starter.quality') + id('org.jetbrains.kotlin.jvm') + } + + commonConfig { + qualityPlugin { + formatOnCompile = true + } + } + """.trimIndent() + rootDirectory.resolve("build.gradle").writeText(buildscript) + } + + rootDirectory.resolve("src/main//kotlin/WrongFileName.kt") { + writeText(kotlinClass("DifferentClassName")) + } + + val formatOnCompileOff = runTask("assemble") + + assertThat(formatOnCompileOff.task(":formatKotlin")?.outcome).isNull() + + enableFormatOnCompile() + val formatOnCompileOn = runTask("assemble") + + assertThat(formatOnCompileOn.task(":formatKotlin")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `projectCodeStyle fails if Checkstyle violation found`() { + rootDirectory.resolve("src/test/java/JavaFileWithCheckstyleIssues.java") { + @Language("java") + val javaClass = + """ + import java.io.IOException; + + public class JavaFileWithCheckstyleIssues { + + int test() throws IOException { + int variable = System.in.read(); + if(variable % 2 == 1){ + return 2; + } else { + return 3; + } + } + } + + """.trimIndent() + writeText(javaClass) + } + + val result = runTask("projectCodeStyle", shouldFail = true) + + assertThat(result.task(":checkstyleTest")?.outcome).isEqualTo(TaskOutcome.FAILED) + assertThat(result.output) + .contains("WhitespaceAround: 'if' is not followed by whitespace.") + .contains("WhitespaceAround: '{' is not preceded with whitespace") + } + + @Test + fun `projectCodeStyle is not present if java files are not allowed`() { + @Language("groovy") + val buildscript = + """ + plugins { + id('com.starter.config') + id('com.starter.quality') + id('org.jetbrains.kotlin.jvm') + } + + commonConfig { + javaFilesAllowed false + } + + repositories.jcenter() + """.trimIndent() + rootDirectory.resolve("build.gradle").writeText(buildscript) + + val result = runTask("projectCodeStyle") + + assertThat(result.task(":checkstyle")).isNull() + } + + @Test + fun `detekt fails on magic number`() { + rootDirectory.resolve("src/main/kotlin/MagicNumber.kt") { + @Language("kotlin") + val kotlinClass = + """ + class MagicNumber { + var value: Int = 16 + } + + """.trimIndent() + writeText(kotlinClass) + } + + val result = runTask("projectCodeStyle", shouldFail = true) + + assertThat(result.task(":detekt")?.outcome).isEqualTo(TaskOutcome.FAILED) + } +} 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 new file mode 100644 index 00000000..b166794d --- /dev/null +++ b/quality/src/test/kotlin/com/project/starter/quality/tasks/GenerateCheckstyleBaselineTaskTest.kt @@ -0,0 +1,86 @@ +package com.project.starter.quality.tasks + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.io.File + +internal class GenerateCheckstyleBaselineTaskTest : WithGradleProjectTest() { + + private lateinit var moduleRoot: File + + @BeforeEach + fun setUp() { + rootDirectory.apply { + resolve("settings.gradle").writeText("""include ':javaModule' """) + + resolve("build.gradle").writeText("") + moduleRoot = resolve("javaModule") { + @Language("groovy") + val script = + """ + plugins { + id('com.starter.quality') + id('org.jetbrains.kotlin.jvm') + } + + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + resolve("src/main/java/ValidJava2.java") { + writeText(javaClass("ValidJava2")) + } + resolve("src/test/java/ValidJavaTest2.java") { + writeText(javaClass("ValidJavaTest2")) + } + } + } + } + + @Test + fun `generating baseline makes build to pass on old code, but fail on new one`() { + moduleRoot.resolve("src/test/java/OldCode.java") { + @Language("java") + val javaClass = + """ + public class OldCode { + + void test(){ + System.out.println(""); + } + } + """.trimIndent() + writeText(javaClass) + } + + val baselineResult = runTask("generateCheckstyleBaseline") + val checkStyleOldCode = runTask("checkstyle") + + assertThat(baselineResult.task(":javaModule:generateCheckstyleBaseline")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(checkStyleOldCode.task(":javaModule:checkstyle")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + + moduleRoot.resolve("src/test/java/NewCode.java") { + @Language("java") + val javaClass = + """ + public class NewCode { + + void test(){ + System.out.println(""); + } + } + """.trimIndent() + writeText(javaClass) + } + + val checkstyleNewCode = runTask("checkstyle", shouldFail = true) + + assertThat(checkstyleNewCode.task(":javaModule:checkstyleTest")?.outcome).isEqualTo(TaskOutcome.FAILED) + assertThat(checkstyleNewCode.output).contains("""NewCode.java:3:16: WhitespaceAround: '{' is not preceded with whitespace""") + } +} diff --git a/quality/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt b/quality/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt new file mode 100644 index 00000000..47af8d5e --- /dev/null +++ b/quality/src/test/kotlin/com/project/starter/quality/tasks/IssueLinksCheckerTaskTest.kt @@ -0,0 +1,145 @@ +package com.project.starter.quality.tasks + +import com.project.starter.WithGradleProjectTest +import com.project.starter.javaClass +import org.assertj.core.api.Assertions.assertThat +import org.gradle.testkit.runner.TaskOutcome +import org.intellij.lang.annotations.Language +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +internal class IssueLinksCheckerTaskTest : WithGradleProjectTest() { + + @BeforeEach + fun setUp() { + rootDirectory.apply { + @Language("groovy") + val script = + """ + plugins { + id 'com.starter.quality' + id 'org.jetbrains.kotlin.jvm' + } + + + """.trimIndent() + resolve("build.gradle") { + writeText(script) + } + resolve("src/main/java/ValidJava2.java") { + writeText(javaClass("ValidJava2")) + } + resolve("src/test/java/ValidJavaTest2.java") { + writeText(javaClass("ValidJavaTest2")) + } + } + } + + @Test + fun `does not warn on regular project`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://issuetracker.google.com/issues/145439806 + **/ + object ValidKotlin { + // https://www.example.com + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + @Disabled("Google Issue tracker is not supported yet") + fun `reports issuetracker issues`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://news.ycombinator.com/ + **/ + object ValidKotlin { + // https://issuetracker.google.com/issues/121092282 + val animations = 0 // Set animation: https://issuetracker.google.com/issues/154643058 + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `reports youtrack 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/main/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) + } + + @Test + fun `reports github issues`() { + rootDirectory.resolve("src/main/kotlin/ValidKotlin.kt") { + @Language("kotlin") + val randomLinks = + """ + /** + * https://github.com/isaacs/github/issues/5 + **/ + object ValidKotlin { + // https://www.example.com + // https://github.com/apollographql/apollo-android/issues/2207 <- closed + } + """.trimIndent() + writeText(randomLinks) + } + + val result = runTask("issueLinksReport") + + assertThat(rootDirectory.resolve("build/reports/issue_comments.txt")) + .hasContent( + """ + ✅ https://github.com/isaacs/github/issues/5 (Opened) + 👉 https://github.com/apollographql/apollo-android/issues/2207 (Closed) + """.trimIndent() + ) + assertThat(result.output).contains("✅ https://github.com/isaacs/github/issues/5 (Opened)") + assertThat(result.output).contains("\uD83D\uDC49 https://github.com/apollographql/apollo-android/issues/2207 (Closed)") + assertThat(result.task(":issueLinksReport")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } +} diff --git a/sample/build.gradle b/sample/android/build.gradle similarity index 68% rename from sample/build.gradle rename to sample/android/build.gradle index 7366df5f..875df687 100644 --- a/sample/build.gradle +++ b/sample/android/build.gradle @@ -8,22 +8,25 @@ buildscript { includeGroupByRegex "com\\.google.*" } } + gradlePluginPortal { + content { + excludeGroup("com.project.starter") + } + } if (project.hasProperty("useMavenLocal")) { mavenLocal() } } dependencies { if (project.hasProperty("useMavenLocal")) { - classpath "com.project.starter.local:plugins:+" + classpath "com.project.starter.local:android:+" } else { - classpath "com.project.starter:plugins" + classpath "com.project.starter:android" } } } -plugins { - id 'com.starter.config' version "0.17.0" -} +apply plugin: 'com.starter.config' commonConfig { javaFilesAllowed false diff --git a/sample/moduleAndroidApplication/build.gradle b/sample/android/moduleAndroidApplication/build.gradle similarity index 100% rename from sample/moduleAndroidApplication/build.gradle rename to sample/android/moduleAndroidApplication/build.gradle diff --git a/sample/moduleAndroidApplication/src/main/AndroidManifest.xml b/sample/android/moduleAndroidApplication/src/main/AndroidManifest.xml similarity index 100% rename from sample/moduleAndroidApplication/src/main/AndroidManifest.xml rename to sample/android/moduleAndroidApplication/src/main/AndroidManifest.xml diff --git a/sample/moduleAndroidApplication/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleAndroidApplication/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleAndroidApplication/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleAndroidApplication/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleAndroidApplication/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleAndroidApplication/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleAndroidApplication/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleAndroidApplication/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleAndroidLibrary/build.gradle b/sample/android/moduleAndroidLibrary/build.gradle similarity index 100% rename from sample/moduleAndroidLibrary/build.gradle rename to sample/android/moduleAndroidLibrary/build.gradle diff --git a/sample/moduleAndroidLibrary/src/main/AndroidManifest.xml b/sample/android/moduleAndroidLibrary/src/main/AndroidManifest.xml similarity index 100% rename from sample/moduleAndroidLibrary/src/main/AndroidManifest.xml rename to sample/android/moduleAndroidLibrary/src/main/AndroidManifest.xml diff --git a/sample/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleKotlinLibrary/build.gradle b/sample/android/moduleKotlinLibrary/build.gradle similarity index 100% rename from sample/moduleKotlinLibrary/build.gradle rename to sample/android/moduleKotlinLibrary/build.gradle diff --git a/sample/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleRoot/build.gradle b/sample/android/moduleRoot/build.gradle similarity index 100% rename from sample/moduleRoot/build.gradle rename to sample/android/moduleRoot/build.gradle diff --git a/sample/moduleRoot/moduleAndroidLibrary/build.gradle b/sample/android/moduleRoot/moduleAndroidLibrary/build.gradle similarity index 100% rename from sample/moduleRoot/moduleAndroidLibrary/build.gradle rename to sample/android/moduleRoot/moduleAndroidLibrary/build.gradle diff --git a/sample/moduleRoot/moduleAndroidLibrary/src/main/AndroidManifest.xml b/sample/android/moduleRoot/moduleAndroidLibrary/src/main/AndroidManifest.xml similarity index 100% rename from sample/moduleRoot/moduleAndroidLibrary/src/main/AndroidManifest.xml rename to sample/android/moduleRoot/moduleAndroidLibrary/src/main/AndroidManifest.xml diff --git a/sample/moduleRoot/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleRoot/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleRoot/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleRoot/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleRoot/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleRoot/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleRoot/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleRoot/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleRoot/moduleKotlinLibrary/build.gradle b/sample/android/moduleRoot/moduleKotlinLibrary/build.gradle similarity index 100% rename from sample/moduleRoot/moduleKotlinLibrary/build.gradle rename to sample/android/moduleRoot/moduleKotlinLibrary/build.gradle diff --git a/sample/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleRootAndroid/build.gradle b/sample/android/moduleRootAndroid/build.gradle similarity index 100% rename from sample/moduleRootAndroid/build.gradle rename to sample/android/moduleRootAndroid/build.gradle diff --git a/sample/moduleRootAndroid/moduleAndroidLibrary/build.gradle b/sample/android/moduleRootAndroid/moduleAndroidLibrary/build.gradle similarity index 100% rename from sample/moduleRootAndroid/moduleAndroidLibrary/build.gradle rename to sample/android/moduleRootAndroid/moduleAndroidLibrary/build.gradle diff --git a/sample/moduleRootAndroid/moduleAndroidLibrary/src/main/AndroidManifest.xml b/sample/android/moduleRootAndroid/moduleAndroidLibrary/src/main/AndroidManifest.xml similarity index 100% rename from sample/moduleRootAndroid/moduleAndroidLibrary/src/main/AndroidManifest.xml rename to sample/android/moduleRootAndroid/moduleAndroidLibrary/src/main/AndroidManifest.xml diff --git a/sample/moduleRootAndroid/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleRootAndroid/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleRootAndroid/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleRootAndroid/moduleAndroidLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleRootAndroid/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleRootAndroid/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleRootAndroid/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleRootAndroid/moduleAndroidLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleRootAndroid/moduleKotlinLibrary/build.gradle b/sample/android/moduleRootAndroid/moduleKotlinLibrary/build.gradle similarity index 100% rename from sample/moduleRootAndroid/moduleKotlinLibrary/build.gradle rename to sample/android/moduleRootAndroid/moduleKotlinLibrary/build.gradle diff --git a/sample/moduleRootAndroid/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleRootAndroid/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleRootAndroid/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleRootAndroid/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleRootAndroid/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleRootAndroid/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleRootAndroid/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleRootAndroid/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/moduleRootAndroid/src/main/AndroidManifest.xml b/sample/android/moduleRootAndroid/src/main/AndroidManifest.xml similarity index 100% rename from sample/moduleRootAndroid/src/main/AndroidManifest.xml rename to sample/android/moduleRootAndroid/src/main/AndroidManifest.xml diff --git a/sample/moduleRootAndroid/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/android/moduleRootAndroid/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt similarity index 100% rename from sample/moduleRootAndroid/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt rename to sample/android/moduleRootAndroid/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt diff --git a/sample/moduleRootAndroid/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/android/moduleRootAndroid/src/test/kotlin/com/starter/sample/SampleTestClass.kt similarity index 100% rename from sample/moduleRootAndroid/src/test/kotlin/com/starter/sample/SampleTestClass.kt rename to sample/android/moduleRootAndroid/src/test/kotlin/com/starter/sample/SampleTestClass.kt diff --git a/sample/settings.gradle b/sample/android/settings.gradle similarity index 94% rename from sample/settings.gradle rename to sample/android/settings.gradle index 717f97ac..e59cb8e0 100644 --- a/sample/settings.gradle +++ b/sample/android/settings.gradle @@ -11,5 +11,5 @@ include ":moduleRootAndroid:moduleAndroidLibrary" include ":moduleRootAndroid:moduleKotlinLibrary" if (!hasProperty("useMavenLocal")) { - includeBuild ".." + includeBuild "../.." } diff --git a/sample/kotlin/build.gradle b/sample/kotlin/build.gradle new file mode 100644 index 00000000..f32c1de9 --- /dev/null +++ b/sample/kotlin/build.gradle @@ -0,0 +1,28 @@ +buildscript { + repositories { + gradlePluginPortal { + content { + excludeGroup("com.project.starter") + } + } + if (project.hasProperty("useMavenLocal")) { + mavenLocal() + } + } + dependencies { + if (project.hasProperty("useMavenLocal")) { + classpath "com.project.starter.local:jvm:+" + } else { + classpath "com.project.starter:jvm" + } + } +} + +apply plugin: 'com.starter.config' + +commonConfig { + javaFilesAllowed false + versioningPlugin { + enabled false + } +} diff --git a/sample/kotlin/moduleKotlinLibrary/build.gradle b/sample/kotlin/moduleKotlinLibrary/build.gradle new file mode 100644 index 00000000..ae322542 --- /dev/null +++ b/sample/kotlin/moduleKotlinLibrary/build.gradle @@ -0,0 +1,3 @@ +plugins { + id("com.starter.library.kotlin") +} diff --git a/sample/kotlin/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/kotlin/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt new file mode 100644 index 00000000..2452149c --- /dev/null +++ b/sample/kotlin/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt @@ -0,0 +1,3 @@ +package com.starter.sample.application.android + +class AndroidAplicationClass diff --git a/sample/kotlin/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/kotlin/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt new file mode 100644 index 00000000..d4479bda --- /dev/null +++ b/sample/kotlin/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt @@ -0,0 +1,3 @@ +package com.starter.sample + +object SampleTestClass diff --git a/sample/kotlin/moduleRoot/build.gradle b/sample/kotlin/moduleRoot/build.gradle new file mode 100644 index 00000000..ae322542 --- /dev/null +++ b/sample/kotlin/moduleRoot/build.gradle @@ -0,0 +1,3 @@ +plugins { + id("com.starter.library.kotlin") +} diff --git a/sample/kotlin/moduleRoot/moduleKotlinLibrary/build.gradle b/sample/kotlin/moduleRoot/moduleKotlinLibrary/build.gradle new file mode 100644 index 00000000..ae322542 --- /dev/null +++ b/sample/kotlin/moduleRoot/moduleKotlinLibrary/build.gradle @@ -0,0 +1,3 @@ +plugins { + id("com.starter.library.kotlin") +} diff --git a/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt b/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt new file mode 100644 index 00000000..2452149c --- /dev/null +++ b/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/main/kotlin/com/starter/sample/AndroidAplicationClass.kt @@ -0,0 +1,3 @@ +package com.starter.sample.application.android + +class AndroidAplicationClass diff --git a/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt b/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt new file mode 100644 index 00000000..d4479bda --- /dev/null +++ b/sample/kotlin/moduleRoot/moduleKotlinLibrary/src/test/kotlin/com/starter/sample/SampleTestClass.kt @@ -0,0 +1,3 @@ +package com.starter.sample + +object SampleTestClass diff --git a/sample/kotlin/settings.gradle b/sample/kotlin/settings.gradle new file mode 100644 index 00000000..8364eb13 --- /dev/null +++ b/sample/kotlin/settings.gradle @@ -0,0 +1,8 @@ +rootProject.name = "com.project.starter.sample" + +include ":moduleKotlinLibrary" +include ":moduleRoot:moduleKotlinLibrary" + +if (!hasProperty("useMavenLocal")) { + includeBuild "../.." +} diff --git a/settings.gradle b/settings.gradle index fbc5a819..9aa3234c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,8 @@ rootProject.name = 'com.project.starter' -include ":plugins" +include ":jvm", + ":android", + ":testing", + ":config", + ":quality", + ":versioning" + diff --git a/testing/build.gradle b/testing/build.gradle new file mode 100644 index 00000000..70629132 --- /dev/null +++ b/testing/build.gradle @@ -0,0 +1,15 @@ +plugins { + id("org.jetbrains.kotlin.jvm") +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + api gradleTestKit() + api 'org.junit.jupiter:junit-jupiter:5.7.1' + api 'org.assertj:assertj-core:3.19.0' + api "org.eclipse.jgit:org.eclipse.jgit:5.9.0.202009080501-r" +} diff --git a/plugins/src/test/kotlin/com/project/starter/Factories.kt b/testing/src/main/kotlin/com/project/starter/Factories.kt similarity index 74% rename from plugins/src/test/kotlin/com/project/starter/Factories.kt rename to testing/src/main/kotlin/com/project/starter/Factories.kt index e069a7f4..86b67853 100644 --- a/plugins/src/test/kotlin/com/project/starter/Factories.kt +++ b/testing/src/main/kotlin/com/project/starter/Factories.kt @@ -3,7 +3,7 @@ package com.project.starter import org.intellij.lang.annotations.Language @Language("java") -internal fun javaClass(className: String) = +fun javaClass(className: String) = """ public class $className { @@ -12,14 +12,14 @@ internal fun javaClass(className: String) = """.trimIndent() @Language("kotlin") -internal fun kotlinClass(className: String) = +fun kotlinClass(className: String) = """ object $className """.trimIndent() @Language("kotlin") -internal fun kotlinTestClass(className: String) = +fun kotlinTestClass(className: String) = """ class $className { diff --git a/plugins/src/test/kotlin/com/project/starter/GitSetup.kt b/testing/src/main/kotlin/com/project/starter/GitSetup.kt similarity index 90% rename from plugins/src/test/kotlin/com/project/starter/GitSetup.kt rename to testing/src/main/kotlin/com/project/starter/GitSetup.kt index fcbbb635..79cacfea 100644 --- a/plugins/src/test/kotlin/com/project/starter/GitSetup.kt +++ b/testing/src/main/kotlin/com/project/starter/GitSetup.kt @@ -8,7 +8,7 @@ import org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE import org.eclipse.jgit.lib.Constants import org.eclipse.jgit.transport.URIish -internal fun WithGradleProjectTest.setupGit(origin: File): Git { +fun WithGradleProjectTest.setupGit(origin: File): Git { Git.init().setDirectory(origin).call() val git = Git.init().apply { setDirectory(rootDirectory) @@ -39,7 +39,7 @@ internal fun WithGradleProjectTest.setupGit(origin: File): Git { return git } -internal fun Git.checkout(branchName: String) { +fun Git.checkout(branchName: String) { checkout().apply { setName(branchName) }.call() @@ -50,7 +50,7 @@ internal fun Git.checkout(branchName: String) { }.save() } -internal fun Git.commit(commitMessage: String) { +fun Git.commit(commitMessage: String) { repository.directory.resolve("File.txt").appendText( """ | Text @@ -66,7 +66,7 @@ internal fun Git.commit(commitMessage: String) { }.call() } -internal fun Git.tag(tagName: String) { +fun Git.tag(tagName: String) { tag().apply { name = tagName isAnnotated = false diff --git a/plugins/src/test/kotlin/com/project/starter/WithGradleProjectTest.kt b/testing/src/main/kotlin/com/project/starter/WithGradleProjectTest.kt similarity index 96% rename from plugins/src/test/kotlin/com/project/starter/WithGradleProjectTest.kt rename to testing/src/main/kotlin/com/project/starter/WithGradleProjectTest.kt index f6226183..3b67f58c 100644 --- a/plugins/src/test/kotlin/com/project/starter/WithGradleProjectTest.kt +++ b/testing/src/main/kotlin/com/project/starter/WithGradleProjectTest.kt @@ -5,7 +5,7 @@ import java.io.InputStream import org.gradle.testkit.runner.GradleRunner import org.junit.jupiter.api.io.TempDir -internal abstract class WithGradleProjectTest { +abstract class WithGradleProjectTest { @TempDir lateinit var rootDirectory: File diff --git a/versioning/build.gradle b/versioning/build.gradle new file mode 100644 index 00000000..a390d460 --- /dev/null +++ b/versioning/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 { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + compileOnly 'com.android.tools.build:gradle:4.1.3' + implementation 'pl.allegro.tech.build:axion-release-plugin:1.12.1' + implementation project(":config") + + testImplementation project(":testing") +} + +jacoco { + toolVersion = "0.8.6" +} +test { + useJUnitPlatform() +} + +gradlePlugin { + plugins { + versioning { + id = 'com.starter.versioning' + displayName = 'Versioning Plugin' + implementationClass = 'com.project.starter.versioning.plugins.VersioningPlugin' + } + } +} diff --git a/plugins/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt b/versioning/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt similarity index 87% rename from plugins/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt rename to versioning/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt index 2b413046..11c4d263 100644 --- a/plugins/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt +++ b/versioning/src/main/kotlin/com/project/starter/versioning/plugins/VersioningPlugin.kt @@ -3,8 +3,8 @@ package com.project.starter.versioning.plugins import com.android.build.gradle.AppExtension import com.android.build.gradle.BaseExtension import com.android.build.gradle.LibraryExtension -import com.project.starter.modules.internal.getByType -import com.project.starter.modules.internal.withExtension +import com.project.starter.config.getByType +import com.project.starter.config.withExtension import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode import org.eclipse.jgit.api.Git import org.gradle.api.GradleException @@ -56,15 +56,16 @@ class VersioningPlugin : Plugin { } } - withExtension { + val configureVersion = { allprojects { project -> project.version = scmConfig.version } + allprojects { + it.setupAndroidVersioning(scmConfig) + } } - - allprojects { - it.setupAndroidVersioning(scmConfig) - } + configureVersion() + withExtension { configureVersion() } } private fun Project.setupAndroidVersioning(scmConfig: VersionConfig) { @@ -76,14 +77,10 @@ class VersioningPlugin : Plugin { defaultConfig.versionName = "$minor.$major.$patch" } pluginManager.withPlugin("com.android.library") { - withExtension { - it.configureVersion(scmConfig.undecoratedVersion) - } + extensions.getByType().configureVersion(scmConfig.undecoratedVersion) } pluginManager.withPlugin("com.android.application") { - withExtension { - it.configureVersion(scmConfig.undecoratedVersion) - } + extensions.getByType().configureVersion(scmConfig.undecoratedVersion) } } diff --git a/plugins/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt b/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt similarity index 96% rename from plugins/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt rename to versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt index 1040511e..76a2ff78 100644 --- a/plugins/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt +++ b/versioning/src/test/kotlin/com/project/starter/versioning/VersioningPluginTest.kt @@ -40,7 +40,7 @@ internal class VersioningPluginTest : WithGradleProjectTest() { writeText( """ plugins { - id 'kotlin' + id 'org.jetbrains.kotlin.jvm' version "1.4.32" } """.trimIndent() ) @@ -51,7 +51,7 @@ internal class VersioningPluginTest : WithGradleProjectTest() { writeText( """ plugins { - id 'kotlin' + id 'org.jetbrains.kotlin.jvm' version "1.4.32" } """.trimIndent() )