From 2230b711774ad01968cdf7d8f4191931b836a07e Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 15:32:13 +0300 Subject: [PATCH 1/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Changed logic * Changed examples * Changed tests --- README.md | 6 +- diktat-gradle-plugin/build.gradle.kts | 1 + diktat-gradle-plugin/settings.gradle.kts | 2 +- .../diktat/plugin/gradle/DiktatExtension.kt | 36 ++++++-- .../plugin/gradle/DiktatGradlePlugin.kt | 16 ++-- .../plugin/gradle/DiktatJavaExecTaskBase.kt | 87 +++++++++++++------ .../plugin/gradle/DiktatGradlePluginTest.kt | 5 +- .../plugin/gradle/DiktatJavaExecTaskTest.kt | 51 ++++++----- examples/gradle-groovy-dsl/build.gradle | 2 +- .../build.gradle.kts | 2 +- examples/gradle-kotlin-dsl/build.gradle.kts | 2 +- 11 files changed, 141 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 378355098a..18d196bc02 100644 --- a/README.md +++ b/README.md @@ -133,9 +133,11 @@ apply(plugin = "org.cqfn.diktat.diktat-gradle-plugin") You can then configure diktat using `diktat` extension: ```kotlin diktat { - inputs = files("src/**/*.kt") // file collection that will be checked by diktat + inputs { + include("src/**/*.kt") // path matching this pattern (per PatternFilterable) that will be checked by diktat + exclude("src/test/kotlin/excluded/**") // path matching this pattern will not be checked by diktat + } debug = true // turn on debug logging - excludes = files("src/test/kotlin/excluded") // these files will not be checked by diktat } ``` diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 65641a707d..3a4216e934 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { exclude("org.jetbrains.kotlin", "kotlin-stdlib-jdk7") exclude("org.jetbrains.kotlin", "kotlin-stdlib") exclude("org.jetbrains.kotlin", "kotlin-stdlib-common") + exclude("org.slf4j", "slf4j-log4j12") } testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") diff --git a/diktat-gradle-plugin/settings.gradle.kts b/diktat-gradle-plugin/settings.gradle.kts index 764fd320f2..1442a83658 100644 --- a/diktat-gradle-plugin/settings.gradle.kts +++ b/diktat-gradle-plugin/settings.gradle.kts @@ -3,4 +3,4 @@ pluginManagement { mavenCentral() gradlePluginPortal() } -} \ No newline at end of file +} diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatExtension.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatExtension.kt index 6311944b17..abd56fed5e 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatExtension.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatExtension.kt @@ -1,12 +1,19 @@ package org.cqfn.diktat.plugin.gradle import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.util.PatternFilterable +import org.gradle.api.tasks.util.PatternSet import java.io.File /** * An extension to configure diktat in build.gradle(.kts) file */ -open class DiktatExtension { +open class DiktatExtension( + private val patternSet: PatternSet +) { /** * Boolean flag to support `ignoreFailures` property of [VerificationTask]. */ @@ -29,18 +36,31 @@ open class DiktatExtension { var output: String = "" /** - * Path to diktat yml config file. Can be either absolute or relative to project's root directory. - * Default value: `diktat-analysis.yml` in rootDir. + * Paths that will be excluded from diktat run */ - lateinit var diktatConfigFile: File + @Deprecated("Configuration via inputs/excludes is unsupported, use inputs(Action)") + var excludes: FileCollection? = null /** - * Paths that will be excluded from diktat run + * Paths that will be scanned for .kt(s) files */ - lateinit var excludes: FileCollection + @Deprecated("Configuration via inputs/excludes is unsupported, use inputs(Action)") + var inputs: FileCollection? = null /** - * Paths that will be scanned for .kt(s) files + * Path to diktat yml config file. Can be either absolute or relative to project's root directory. + * Default value: `diktat-analysis.yml` in rootDir. + */ + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + lateinit var diktatConfigFile: File + + /** + * Configure input files for diktat task + * + * @param action configuration lambda for `PatternFilterable` */ - lateinit var inputs: FileCollection + fun inputs(action: PatternFilterable.() -> Unit) { + action.invoke(patternSet) + } } diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt index 226c34064d..097f44a850 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePlugin.kt @@ -6,6 +6,7 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.ExternalModuleDependency import org.gradle.api.attributes.Bundling +import org.gradle.api.tasks.util.PatternSet /** * Plugin that configures diktat and registers tasks to run diktat @@ -16,12 +17,13 @@ class DiktatGradlePlugin : Plugin { * @param project a gradle [Project] that the plugin is applied to */ override fun apply(project: Project) { - val diktatExtension = project.extensions.create(DIKTAT_EXTENSION, DiktatExtension::class.java).apply { - inputs = project.fileTree("src").apply { - include("**/*.kt") - } + val patternSet = PatternSet() + val diktatExtension = project.extensions.create( + DIKTAT_EXTENSION, + DiktatExtension::class.java, + patternSet + ).apply { diktatConfigFile = project.rootProject.file("diktat-analysis.yml") - excludes = project.files() } // only gradle 7+ (or maybe 6.8) will embed kotlin 1.4+, kx.serialization is incompatible with kotlin 1.3, so until then we have to use JavaExec wrapper @@ -43,8 +45,8 @@ class DiktatGradlePlugin : Plugin { configuration.dependencies.add(project.dependencies.create("org.cqfn.diktat:diktat-rules:$DIKTAT_VERSION")) } - project.registerDiktatCheckTask(diktatExtension, diktatConfiguration) - project.registerDiktatFixTask(diktatExtension, diktatConfiguration) + project.registerDiktatCheckTask(diktatExtension, diktatConfiguration, patternSet) + project.registerDiktatFixTask(diktatExtension, diktatConfiguration, patternSet) } companion object { diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt index 831a208e4f..982d692a0c 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt @@ -8,12 +8,20 @@ import generated.DIKTAT_VERSION import generated.KTLINT_VERSION import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection import org.gradle.api.provider.Property +import org.gradle.api.tasks.IgnoreEmptyDirectories +import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.gradle.api.tasks.JavaExec +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.SkipWhenEmpty import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.VerificationTask +import org.gradle.api.tasks.util.PatternFilterable +import org.gradle.api.tasks.util.PatternSet import org.gradle.util.GradleVersion import java.io.File @@ -28,6 +36,7 @@ open class DiktatJavaExecTaskBase @Inject constructor( gradleVersionString: String, diktatExtension: DiktatExtension, diktatConfiguration: Configuration, + private val inputs: PatternFilterable, additionalFlags: Iterable = emptyList() ) : JavaExec(), VerificationTask { /** @@ -42,6 +51,34 @@ open class DiktatJavaExecTaskBase @Inject constructor( @get:Internal internal var shouldRun = true + /** + * Files that will be analyzed by diktat + */ + @get:IgnoreEmptyDirectories + @get:SkipWhenEmpty + @get:PathSensitive(PathSensitivity.RELATIVE) + @get:InputFiles + val actualInputs: FileCollection by lazy { + with(diktatExtension) { + // validate configuration + require( + inputs == null && excludes == null + ) { + "`inputs` and `excludes` for diktat should be changed for inputs(Action)" + } + } + + if (inputs.includes.isEmpty() && inputs.excludes.isEmpty()) { + inputs.include("src/**/*.kt") + } + project.objects.fileCollection().from( + project.fileTree("${project.projectDir}").apply { + exclude("${project.buildDir}") + } + .matching(inputs) + ) + } + init { group = "verification" if (isMainClassPropertySupported(gradleVersionString)) { @@ -69,25 +106,20 @@ open class DiktatJavaExecTaskBase @Inject constructor( if (diktatExtension.debug) { add("--debug") } - diktatExtension - .inputs - .also { - if (it.isEmpty) { - /* - If ktlint receives empty patterns, it implicitly uses **/*.kt, **/*.kts instead. - This can lead to diktat analyzing gradle buildscripts and so on. We want to prevent it. - */ - project.logger.warn("Inputs for $name do not exist, will not run diktat") - shouldRun = false - } + actualInputs.also { + if (it.isEmpty) { + /* + If ktlint receives empty patterns, it implicitly uses **/*.kt, **/*.kts instead. + This can lead to diktat analyzing gradle buildscripts and so on. We want to prevent it. + */ + project.logger.warn("Inputs for $name do not exist, will not run diktat") + shouldRun = false } + } .files .forEach { - addPattern(it) + addInput(it) } - diktatExtension.excludes.files.forEach { - addPattern(it, negate = true) - } add(createReporterFlag(diktatExtension)) } @@ -155,13 +187,8 @@ open class DiktatJavaExecTaskBase @Inject constructor( private fun isMainClassPropertySupported(gradleVersionString: String) = GradleVersion.version(gradleVersionString) >= GradleVersion.version("6.4") - private fun MutableList.addPattern(pattern: File, negate: Boolean = false) { - val path = if (pattern.isAbsolute) { - pattern.relativeTo(project.projectDir) - } else { - pattern - } - add((if (negate) "!" else "") + path) + private fun MutableList.addInput(file: File) { + add(file.toRelativeString(project.projectDir)) } private fun resolveConfigFile(file: File): String { @@ -184,21 +211,29 @@ open class DiktatJavaExecTaskBase @Inject constructor( /** * @param diktatExtension [DiktatExtension] with some values for task configuration * @param diktatConfiguration dependencies of diktat run + * @param patternSet [PatternSet] to discover files for diktat check * @return a [TaskProvider] */ -fun Project.registerDiktatCheckTask(diktatExtension: DiktatExtension, diktatConfiguration: Configuration): TaskProvider = +fun Project.registerDiktatCheckTask(diktatExtension: DiktatExtension, + diktatConfiguration: Configuration, + patternSet: PatternSet +): TaskProvider = tasks.register( DIKTAT_CHECK_TASK, DiktatJavaExecTaskBase::class.java, gradle.gradleVersion, - diktatExtension, diktatConfiguration + diktatExtension, diktatConfiguration, patternSet ) /** * @param diktatExtension [DiktatExtension] with some values for task configuration * @param diktatConfiguration dependencies of diktat run + * @param patternSet [PatternSet] to discover files for diktat fix * @return a [TaskProvider] */ -fun Project.registerDiktatFixTask(diktatExtension: DiktatExtension, diktatConfiguration: Configuration): TaskProvider = +fun Project.registerDiktatFixTask(diktatExtension: DiktatExtension, + diktatConfiguration: Configuration, + patternSet: PatternSet +): TaskProvider = tasks.register( DIKTAT_FIX_TASK, DiktatJavaExecTaskBase::class.java, gradle.gradleVersion, - diktatExtension, diktatConfiguration, listOf("-F ") + diktatExtension, diktatConfiguration, patternSet, listOf("-F ") ) diff --git a/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginTest.kt b/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginTest.kt index 676e6237a0..439b8ee823 100644 --- a/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginTest.kt +++ b/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginTest.kt @@ -28,9 +28,10 @@ class DiktatGradlePluginTest { @Test fun `check default extension properties`() { val diktatExtension = project.extensions.getByName("diktat") as DiktatExtension + val actualInputs = project.tasks.named("diktatCheck", DiktatJavaExecTaskBase::class.java).get().actualInputs Assertions.assertFalse(diktatExtension.debug) - Assertions.assertIterableEquals(project.fileTree("src").files, diktatExtension.inputs.files) - Assertions.assertTrue(diktatExtension.inputs.files.isNotEmpty()) + Assertions.assertIterableEquals(project.fileTree("src").files, actualInputs.files) + Assertions.assertTrue(actualInputs.files.isNotEmpty()) } @Test diff --git a/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskTest.kt b/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskTest.kt index fa1c8a2840..0d3710723d 100644 --- a/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskTest.kt +++ b/diktat-gradle-plugin/src/test/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskTest.kt @@ -3,6 +3,7 @@ package org.cqfn.diktat.plugin.gradle import org.cqfn.diktat.ruleset.rules.DIKTAT_CONF_PROPERTY import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -18,43 +19,53 @@ class DiktatJavaExecTaskTest { project = projectBuilder .withName("testProject") .build() + // mock kotlin sources + project.mkdir("src/main/kotlin") + project.file("src/main/kotlin/Test.kt").createNewFile() + } + + @AfterEach + fun tearDown() { + project.buildDir.deleteRecursively() } @Test fun `check command line for various inputs`() { assertCommandLineEquals( - listOf(null, combinePathParts("src", "**", "*.kt"), "--reporter=plain") + listOf(null, combinePathParts("src", "main", "kotlin", "Test.kt"), "--reporter=plain") ) { - inputs = project.files("src/**/*.kt") + inputs { include("src/**/*.kt") } } } @Test fun `check command line in debug mode`() { assertCommandLineEquals( - listOf(null, "--debug", combinePathParts("src", "**", "*.kt"), "--reporter=plain") + listOf(null, "--debug", combinePathParts("src", "main", "kotlin", "Test.kt"), "--reporter=plain") ) { - inputs = project.files("src/**/*.kt") + inputs { include("src/**/*.kt") } debug = true } } @Test fun `check command line with excludes`() { + project.file("src/main/kotlin/generated").mkdirs() + project.file("src/main/kotlin/generated/Generated.kt").createNewFile() assertCommandLineEquals( - listOf(null, combinePathParts("src", "**", "*.kt"), - "!${combinePathParts("src", "main", "kotlin", "generated")}", "--reporter=plain" - ) + listOf(null, combinePathParts("src", "main", "kotlin", "Test.kt"), "--reporter=plain") ) { - inputs = project.files("src/**/*.kt") - excludes = project.files("src/main/kotlin/generated") + inputs { + include("src/**/*.kt") + exclude("src/main/kotlin/generated") + } } } @Test fun `check command line with non-existent inputs`() { val task = project.registerDiktatTask { - inputs = project.files() + inputs { exclude("*") } } Assertions.assertFalse(task.shouldRun) } @@ -62,7 +73,7 @@ class DiktatJavaExecTaskTest { @Test fun `check system property with default config`() { val task = project.registerDiktatTask { - inputs = project.files() + inputs { exclude("*") } } Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) } @@ -70,7 +81,7 @@ class DiktatJavaExecTaskTest { @Test fun `check system property with custom config`() { val task = project.registerDiktatTask { - inputs = project.files() + inputs { exclude("*") } diktatConfigFile = project.file("../diktat-analysis.yml") } Assertions.assertEquals(File(project.projectDir.parentFile, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) @@ -81,7 +92,7 @@ class DiktatJavaExecTaskTest { assertCommandLineEquals( listOf(null, "--reporter=json,output=some.txt") ) { - inputs = project.files() + inputs { exclude("*") } diktatConfigFile = project.file("../diktat-analysis.yml") reporterType = "json" output = "some.txt" @@ -93,7 +104,7 @@ class DiktatJavaExecTaskTest { assertCommandLineEquals( listOf(null, "--reporter=json") ) { - inputs = project.files() + inputs { exclude("*") } diktatConfigFile = project.file("../diktat-analysis.yml") reporterType = "json" } @@ -104,7 +115,7 @@ class DiktatJavaExecTaskTest { assertCommandLineEquals( listOf(null, "--reporter=customName,artifact=customPath") ) { - inputs = project.files() + inputs { exclude("*") } diktatConfigFile = project.file("../diktat-analysis.yml") reporterType = "custom:customName:customPath" } @@ -113,7 +124,7 @@ class DiktatJavaExecTaskTest { @Test fun `check that project has html dependency`() { val task = project.registerDiktatTask { - inputs = project.files() + inputs { exclude("*") } diktatConfigFile = project.file("../diktat-analysis.yml") reporterType = "html" } @@ -133,7 +144,7 @@ class DiktatJavaExecTaskTest { val subproject = project.subprojects.first() project.allprojects { it.registerDiktatTask { - inputs = it.files() + inputs { exclude("*") } } } val task = project.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase @@ -148,7 +159,7 @@ class DiktatJavaExecTaskTest { val subproject = project.subprojects.first() project.allprojects { it.registerDiktatTask { - inputs = it.files() + inputs { exclude("*") } diktatConfigFile = it.rootProject.file("diktat-analysis.yml") } } @@ -165,7 +176,7 @@ class DiktatJavaExecTaskTest { subproject.file("diktat-analysis.yml").createNewFile() project.allprojects { it.registerDiktatTask { - inputs = it.files() + inputs { exclude("*") } diktatConfigFile = it.file("diktat-analysis.yml") } } @@ -176,7 +187,7 @@ class DiktatJavaExecTaskTest { } private fun Project.registerDiktatTask(extensionConfiguration: DiktatExtension.() -> Unit): DiktatJavaExecTaskBase { - DiktatGradlePlugin().apply(this) + pluginManager.apply(DiktatGradlePlugin::class.java) extensions.configure("diktat", extensionConfiguration) return tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase } diff --git a/examples/gradle-groovy-dsl/build.gradle b/examples/gradle-groovy-dsl/build.gradle index a60283e4c0..86bb1e9e80 100644 --- a/examples/gradle-groovy-dsl/build.gradle +++ b/examples/gradle-groovy-dsl/build.gradle @@ -7,5 +7,5 @@ repositories { } diktat { - inputs = files("src/**/*.kt") + inputs { include ("src/**/*.kt") } } diff --git a/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts b/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts index 229d7c1970..84a87c424a 100644 --- a/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts +++ b/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts @@ -13,7 +13,7 @@ allprojects { apply(plugin = "org.cqfn.diktat.diktat-gradle-plugin") configure { diktatConfigFile = rootProject.file("diktat-analysis.yml") - inputs = files("src/**/*.kt") + inputs { include("src/**/*.kt") } debug = true } } diff --git a/examples/gradle-kotlin-dsl/build.gradle.kts b/examples/gradle-kotlin-dsl/build.gradle.kts index f33420dbcd..2e9dae03eb 100644 --- a/examples/gradle-kotlin-dsl/build.gradle.kts +++ b/examples/gradle-kotlin-dsl/build.gradle.kts @@ -7,5 +7,5 @@ repositories { } diktat { - inputs = files("src/**/*.kt") + inputs { include("src/**/*.kt") } } From 8713d4dec517c26869606e11abd674569440c2b3 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 16:04:35 +0300 Subject: [PATCH 2/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Refactor build_and_test.yml --- .github/workflows/build_and_test.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4a06cf24f2..704f962bd7 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -37,6 +37,13 @@ jobs: path: diktat-ruleset/target/diktat-*.jar # no need to store artifact longer, it is used only by dependant jobs retention-days: 1 + - name: Upload gradle reports + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: gradle-test-report-${{ matrix.os }} + path: 'diktat-gradle-plugin/build/reports/' + retention-days: 1 run_diktat_from_CLI: name: Run diktat via CLI @@ -110,7 +117,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] + os: [ windows-latest, macos-latest ] steps: - uses: actions/checkout@v2.3.4 - name: Set up JDK 11 From 5bb78854136b452ea317d062b26d8f7fa6e5a495 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 16:37:30 +0300 Subject: [PATCH 3/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Fix functional test --- .github/workflows/build_and_test.yml | 2 +- .../DiktatGradlePluginFunctionalTest.kt | 27 ++++++++----------- ...tGradlePluginMultiprojectFunctionalTest.kt | 2 +- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 704f962bd7..cbdf5eb7fb 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -41,7 +41,7 @@ jobs: if: ${{ failure() }} uses: actions/upload-artifact@v2 with: - name: gradle-test-report-${{ matrix.os }} + name: gradle-test-report-${{ runner.os }} path: 'diktat-gradle-plugin/build/reports/' retention-days: 1 diff --git a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt index 31f2af4e60..cfc306a6d6 100644 --- a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt +++ b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt @@ -46,7 +46,7 @@ class DiktatGradlePluginFunctionalTest { buildFile.appendText( """${System.lineSeparator()} diktat { - inputs = files("src/**/*.kt") + inputs { include("src/**/*.kt") } reporterType = "json" output = "test.txt" } @@ -69,7 +69,7 @@ class DiktatGradlePluginFunctionalTest { buildFile.appendText( """${System.lineSeparator()} diktat { - inputs = files("src/**/*.kt") + inputs { include("src/**/*.kt") } } """.trimIndent() ) @@ -88,8 +88,10 @@ class DiktatGradlePluginFunctionalTest { buildFile.appendText( """${System.lineSeparator()} diktat { - inputs = files("src/**/*.kt") - excludes = files("src/**/Test.kt") + inputs { + include("src/**/*.kt") + exclude("src/**/Test.kt") + } } """.trimIndent() ) @@ -97,7 +99,7 @@ class DiktatGradlePluginFunctionalTest { val diktatCheckBuildResult = result.task(":$DIKTAT_CHECK_TASK") requireNotNull(diktatCheckBuildResult) - Assertions.assertEquals(TaskOutcome.SUCCESS, diktatCheckBuildResult.outcome) + Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckBuildResult.outcome) } @Test @@ -105,22 +107,18 @@ class DiktatGradlePluginFunctionalTest { buildFile.appendText( """${System.lineSeparator()} diktat { - inputs = files("nonexistent-directory/src/**/*.kt") + inputs { include ("nonexistent-directory/src/**/*.kt") } } """.trimIndent() ) val result = runDiktat(testProjectDir, arguments = listOf("--info")) - // if patterns in gradle are not checked for matching, they are passed to ktlint, which does nothing val diktatCheckBuildResult = result.task(":$DIKTAT_CHECK_TASK") requireNotNull(diktatCheckBuildResult) - Assertions.assertEquals(TaskOutcome.SUCCESS, diktatCheckBuildResult.outcome) + Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckBuildResult.outcome) Assertions.assertFalse( result.output.contains("Skipping diktat execution") ) - Assertions.assertFalse( - result.output.contains("Inputs for $DIKTAT_CHECK_TASK do not exist, will not run diktat") - ) } @Test @@ -128,7 +126,7 @@ class DiktatGradlePluginFunctionalTest { buildFile.appendText( """${System.lineSeparator()} diktat { - inputs = fileTree("nonexistent-directory/src").apply { include("**/*.kt") } + inputs { include("nonexistent-directory/src/**/*.kt") } } """.trimIndent() ) @@ -136,13 +134,10 @@ class DiktatGradlePluginFunctionalTest { val diktatCheckBuildResult = result.task(":$DIKTAT_CHECK_TASK") requireNotNull(diktatCheckBuildResult) - Assertions.assertEquals(TaskOutcome.SUCCESS, diktatCheckBuildResult.outcome) + Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckBuildResult.outcome) Assertions.assertTrue( result.output.contains("Skipping diktat execution") ) - Assertions.assertTrue( - result.output.contains("Inputs for $DIKTAT_CHECK_TASK do not exist, will not run diktat") - ) } @Test diff --git a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginMultiprojectFunctionalTest.kt b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginMultiprojectFunctionalTest.kt index 0b9cb06278..1d40218b0a 100644 --- a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginMultiprojectFunctionalTest.kt +++ b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginMultiprojectFunctionalTest.kt @@ -33,7 +33,7 @@ class DiktatGradlePluginMultiprojectFunctionalTest { val diktatCheckRootResult = result.task(":$DIKTAT_CHECK_TASK") requireNotNull(diktatCheckRootResult) - Assertions.assertEquals(TaskOutcome.SUCCESS, diktatCheckRootResult.outcome) { + Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckRootResult.outcome) { "Task for root project with empty sources should succeed" } From 51f4d68a64ecba10c6304ca9051dd1ea8984b3cc Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 17:33:36 +0300 Subject: [PATCH 4/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Fix functional test --- diktat-gradle-plugin/build.gradle.kts | 21 +++++++------------ .../DiktatGradlePluginFunctionalTest.kt | 19 ----------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 3a4216e934..cb2dbb0cf0 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -29,7 +29,7 @@ repositories { // default value is needed for correct gradle loading in IDEA; actual value from maven is used during build val ktlintVersion = project.properties.getOrDefault("ktlintVersion", "0.43.0") as String val diktatVersion = project.version.takeIf { it.toString() != Project.DEFAULT_VERSION } ?: "0.5.2" -val junitVersion = project.properties.getOrDefault("junitVersion", "5.7.0") as String +val junitVersion = project.properties.getOrDefault("junitVersion", "5.8.1") as String val jacocoVersion = project.properties.getOrDefault("jacocoVersion", "0.8.7") as String dependencies { implementation(kotlin("gradle-plugin-api")) @@ -94,7 +94,6 @@ java { // === testing & code coverage, jacoco is run independent from maven val functionalTestTask by tasks.register("functionalTest") -val jacocoMergeTask by tasks.register("jacocoMerge") tasks.withType { useJUnitPlatform() } @@ -103,7 +102,7 @@ jacoco.toolVersion = jacocoVersion // === integration testing // fixme: should probably use KotlinSourceSet instead val functionalTest = sourceSets.create("functionalTest") { - compileClasspath += sourceSets.main.get().output + configurations.testRuntimeClasspath + compileClasspath += sourceSets.main.get().output + configurations.testRuntimeClasspath.get() runtimeClasspath += output + compileClasspath } tasks.getByName("functionalTest") { @@ -114,8 +113,8 @@ tasks.getByName("functionalTest") { maxHeapSize = "1024m" retry { failOnPassedAfterRetry.set(false) - maxFailures.set(10) - maxRetries.set(3) + maxFailures.set(1) + maxRetries.set(1) } doLast { if (getCurrentOperatingSystem().isWindows) { @@ -124,25 +123,21 @@ tasks.getByName("functionalTest") { Thread.sleep(5_000) } } - finalizedBy(jacocoMergeTask) + finalizedBy(tasks.jacocoTestReport) } tasks.check { dependsOn(tasks.jacocoTestReport) } jacocoTestKit { applyTo("functionalTestRuntimeOnly", tasks.named("functionalTest")) } -tasks.getByName("jacocoMerge", JacocoMerge::class) { - dependsOn(functionalTestTask) +tasks.jacocoTestReport { + dependsOn(tasks.withType()) executionData( fileTree("$buildDir/jacoco").apply { include("*.exec") } ) -} -tasks.jacocoTestReport { - dependsOn(jacocoMergeTask) - executionData("$buildDir/jacoco/jacocoMerge.exec") reports { // xml report is used by codecov - xml.isEnabled = true + xml.required.set(true) } } diff --git a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt index cfc306a6d6..5290047aca 100644 --- a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt +++ b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt @@ -121,25 +121,6 @@ class DiktatGradlePluginFunctionalTest { ) } - @Test - fun `should not run diktat with ktlint's default includes when no files match include patterns - 2`() { - buildFile.appendText( - """${System.lineSeparator()} - diktat { - inputs { include("nonexistent-directory/src/**/*.kt") } - } - """.trimIndent() - ) - val result = runDiktat(testProjectDir, arguments = listOf("--info")) - - val diktatCheckBuildResult = result.task(":$DIKTAT_CHECK_TASK") - requireNotNull(diktatCheckBuildResult) - Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckBuildResult.outcome) - Assertions.assertTrue( - result.output.contains("Skipping diktat execution") - ) - } - @Test fun `should execute diktatCheck with gradle older than 6_4`() { val result = runDiktat(testProjectDir, shouldSucceed = false, arguments = listOf("--info")) { From 9eb15ff84c93a5fe76e32cda5e0f3b1999c7bdc5 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 17:46:15 +0300 Subject: [PATCH 5/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Fix functional test --- diktat-gradle-plugin/build.gradle.kts | 6 ++++-- .../plugin/gradle/DiktatGradlePluginFunctionalTest.kt | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index cb2dbb0cf0..2ef83f5ba0 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -50,6 +50,8 @@ dependencies { val generateVersionsFile by tasks.registering { val versionsFile = File("$buildDir/generated/src/generated/Versions.kt") + inputs.property("diktat version", diktatVersion) + inputs.property("ktlint version", ktlintVersion) outputs.file(versionsFile) doFirst { @@ -113,8 +115,8 @@ tasks.getByName("functionalTest") { maxHeapSize = "1024m" retry { failOnPassedAfterRetry.set(false) - maxFailures.set(1) - maxRetries.set(1) + maxFailures.set(10) + maxRetries.set(3) } doLast { if (getCurrentOperatingSystem().isWindows) { diff --git a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt index 5290047aca..81a2b180de 100644 --- a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt +++ b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt @@ -8,8 +8,6 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.junit.jupiter.api.condition.DisabledOnOs -import org.junit.jupiter.api.condition.OS import java.io.File class DiktatGradlePluginFunctionalTest { From d70491a32bc71334f252b4f3d970bb23a5742fb4 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Thu, 11 Nov 2021 18:20:58 +0300 Subject: [PATCH 6/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Remove `useIR`, because for kotlin 1.5.x it does nothing and IR is used anyway --- diktat-gradle-plugin/build.gradle.kts | 1 - .../cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt | 8 +++++--- .../src/test/resources/test/smoke/build.gradle_.kts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/diktat-gradle-plugin/build.gradle.kts b/diktat-gradle-plugin/build.gradle.kts index 2ef83f5ba0..3c579aa3ef 100644 --- a/diktat-gradle-plugin/build.gradle.kts +++ b/diktat-gradle-plugin/build.gradle.kts @@ -75,7 +75,6 @@ tasks.withType { languageVersion = "1.3" apiVersion = "1.3" jvmTarget = "1.8" - useIR = false // for compatibility with older gradle } dependsOn.add(generateVersionsFile) diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt index 982d692a0c..e3b2fbbee8 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt @@ -61,9 +61,7 @@ open class DiktatJavaExecTaskBase @Inject constructor( val actualInputs: FileCollection by lazy { with(diktatExtension) { // validate configuration - require( - inputs == null && excludes == null - ) { + require(inputs == null && excludes == null) { "`inputs` and `excludes` for diktat should be changed for inputs(Action)" } } @@ -117,6 +115,10 @@ open class DiktatJavaExecTaskBase @Inject constructor( } } .files + .also { files -> + project.logger.info("Analyzing ${files.size} files with diktat in project ${project.name}") + project.logger.debug("Analyzing $files") + } .forEach { addInput(it) } diff --git a/diktat-rules/src/test/resources/test/smoke/build.gradle_.kts b/diktat-rules/src/test/resources/test/smoke/build.gradle_.kts index 257aa943cb..6ef1da3310 100644 --- a/diktat-rules/src/test/resources/test/smoke/build.gradle_.kts +++ b/diktat-rules/src/test/resources/test/smoke/build.gradle_.kts @@ -28,5 +28,5 @@ val updateDocumentation = tasks.register("updateDocumentation") { diktat { debug = true - inputs = files("buildSrc/**/*.kt", "*.kts") + inputs { include("buildSrc/**/*.kt", "*.kts") } } From 250ce647eb9085564a1c635863f25ff75794b499 Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Fri, 12 Nov 2021 10:31:13 +0300 Subject: [PATCH 7/8] Gradle plugin: use `PatternSet` instead of `FileCollection` for inputs ### What's done: * Fix description * Fix codecov link in README.md --- README.md | 2 +- .../org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 18d196bc02..4be5054fe6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![deteKT static analysis](https://github.com/cqfn/diKTat/workflows/Run%20deteKT/badge.svg) ![diKTat code style](https://github.com/cqfn/diKTat/workflows/Run%20diKTat%20from%20release%20version/badge.svg?branch=master) [![License](https://img.shields.io/github/license/cqfn/diKtat)](https://github.com/cqfn/diKTat/blob/master/LICENSE) -[![codecov](https://codecov.io/gh/cqfn/diKTat/branch/master/graph/badge.svg)](https://codecov.io/gh/cqfn/diKTat) +[![codecov](https://codecov.io/gh/diktat-static-analysis/diKTat/branch/master/graph/badge.svg)](https://codecov.io/gh/diktat-static-analysis/diKTat) [![Releases](https://img.shields.io/github/v/release/cqfn/diKTat)](https://github.com/cqfn/diKTat/releases) [![Maven Central](https://img.shields.io/maven-central/v/org.cqfn.diktat/diktat-rules)](https://mvnrepository.com/artifact/org.cqfn.diktat) diff --git a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt index e3b2fbbee8..ca9442ff6a 100644 --- a/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt +++ b/diktat-gradle-plugin/src/main/kotlin/org/cqfn/diktat/plugin/gradle/DiktatJavaExecTaskBase.kt @@ -62,7 +62,8 @@ open class DiktatJavaExecTaskBase @Inject constructor( with(diktatExtension) { // validate configuration require(inputs == null && excludes == null) { - "`inputs` and `excludes` for diktat should be changed for inputs(Action)" + "`inputs` and `excludes` arguments for diktat task are deprecated and now should be changed for `inputs {}` " + + "with configuration for PatternFilterable. Please check https://github.com/diktat-static-analysis/diktat/README.md for more info." } } From b86417b2e3850f4b5c23a989ba8263e542e4543b Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Wed, 17 Nov 2021 11:23:51 +0300 Subject: [PATCH 8/8] gradle ### What's done: * More tests --- .../gradle/DiktatGradlePluginFunctionalTest.kt | 4 ++-- .../src/main/kotlin/AnotherTest.kt | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 examples/gradle-kotlin-dsl/src/main/kotlin/AnotherTest.kt diff --git a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt index 81a2b180de..723368d3eb 100644 --- a/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt +++ b/diktat-gradle-plugin/src/functionalTest/kotlin/org/cqfn/diktat/plugin/gradle/DiktatGradlePluginFunctionalTest.kt @@ -93,11 +93,11 @@ class DiktatGradlePluginFunctionalTest { } """.trimIndent() ) - val result = runDiktat(testProjectDir) + val result = runDiktat(testProjectDir, shouldSucceed = false) val diktatCheckBuildResult = result.task(":$DIKTAT_CHECK_TASK") requireNotNull(diktatCheckBuildResult) - Assertions.assertEquals(TaskOutcome.NO_SOURCE, diktatCheckBuildResult.outcome) + Assertions.assertEquals(TaskOutcome.FAILED, diktatCheckBuildResult.outcome) } @Test diff --git a/examples/gradle-kotlin-dsl/src/main/kotlin/AnotherTest.kt b/examples/gradle-kotlin-dsl/src/main/kotlin/AnotherTest.kt new file mode 100644 index 0000000000..9694c4bf1c --- /dev/null +++ b/examples/gradle-kotlin-dsl/src/main/kotlin/AnotherTest.kt @@ -0,0 +1,16 @@ +package whate.ver + +fun String.createPluginConfig() { + val pluginConfig = TomlDecoder.decode( + serializer(), + fakeFileNode, + DecoderConf() + ) + pluginConfig.configLocation = this.toPath() + pluginConfig.prop1 = property1 + // comment1 + pluginConfig.configLocation2 = this.toPath() + // comment2 + pluginConfig.prop2 = property2 +} +