From 9eefb12b73fd6b44d164199c3ef0295c8908054d Mon Sep 17 00:00:00 2001 From: Peter Trifanov Date: Tue, 19 Jan 2021 16:32:06 +0300 Subject: [PATCH] Fix for gradle plugin config (#706) ### What's done: * Gradle file API returns absolute paths relative to project's directory, so no need to check whether it's absolute. Need to use proper way to specify path in build.gradle instead. * Added more tests. --- .../diktat/plugin/gradle/DiktatExtension.kt | 3 +- .../plugin/gradle/DiktatGradlePlugin.kt | 2 +- .../plugin/gradle/DiktatJavaExecTaskBase.kt | 9 +- .../plugin/gradle/DiktatJavaExecTaskTest.kt | 98 +++++++++++++++++-- .../build.gradle.kts | 1 + 5 files changed, 99 insertions(+), 14 deletions(-) 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 88700e21ea..33f2521551 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 @@ -20,8 +20,9 @@ open class DiktatExtension { /** * Path to diktat yml config file. Can be either absolute or relative to project's root directory. + * Default value: `diktat-analysis.yml` in rootDir. */ - var diktatConfigFile: File = File("diktat-analysis.yml") + lateinit var diktatConfigFile: File /** * Paths that will be excluded from diktat run 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 395319a49f..97237e0b7f 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 @@ -20,7 +20,7 @@ class DiktatGradlePlugin : Plugin { inputs = project.fileTree("src").apply { include("**/*.kt") } - reporter = PlainReporter(System.out) + diktatConfigFile = project.rootProject.file("diktat-analysis.yml") excludes = project.files() reporter = PlainReporter(System.out) } 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 794bf397d5..49d608b78a 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 @@ -120,15 +120,14 @@ open class DiktatJavaExecTaskBase @Inject constructor( add((if (negate) "!" else "") + path) } - /** - * todo: share logic with maven plugin, it's basically copy-paste - */ - @Suppress("ForbiddenComment") private fun resolveConfigFile(file: File): String { - if (file.isAbsolute) { + if (file.toPath().startsWith(project.rootDir.toPath())) { + // In gradle, project.files() returns File relative to project.projectDir. + // There is no need to resolve file further if it has been passed via gradle files API. return file.absolutePath } + // otherwise, e.g. if file is passed as java.io.File with relative path, we try to find it return generateSequence(project.projectDir) { it.parentFile } .map { it.resolve(file) } .run { 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 482fa95a5a..533c6ab497 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 @@ -1,11 +1,13 @@ 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.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.io.File +import java.nio.file.Files class DiktatJavaExecTaskTest { private val projectBuilder = ProjectBuilder.builder() @@ -13,7 +15,9 @@ class DiktatJavaExecTaskTest { @BeforeEach fun setUp() { - project = projectBuilder.build() + project = projectBuilder + .withName("testProject") + .build() } @Test @@ -49,22 +53,102 @@ class DiktatJavaExecTaskTest { @Test fun `check command line with non-existent inputs`() { - val task = registerDiktatTask { + val task = project.registerDiktatTask { inputs = project.files() } Assertions.assertFalse(task.shouldRun) } - private fun registerDiktatTask(extensionConfiguration: DiktatExtension.() -> Unit): DiktatJavaExecTaskBase { - DiktatGradlePlugin().apply(project) - project.extensions.configure("diktat", extensionConfiguration) - return project.tasks.getByName("diktatCheck") as DiktatJavaExecTaskBase + @Test + fun `check system property with default config`() { + val task = project.registerDiktatTask { + inputs = project.files() + } + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) + } + + @Test + fun `check system property with custom config`() { + val task = project.registerDiktatTask { + inputs = project.files() + diktatConfigFile = project.file("../diktat-analysis.yml") + } + Assertions.assertEquals(File(project.projectDir.parentFile, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) + } + + @Test + fun `check system property with multiproject build with default config`() { + setupMultiProject() + val subproject = project.subprojects.first() + project.allprojects { + it.registerDiktatTask { + inputs = it.files() + } + } + val task = project.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + val subprojectTask = subproject.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, subprojectTask.systemProperties[DIKTAT_CONF_PROPERTY]) + } + + @Test + fun `check system property with multiproject build with custom config`() { + setupMultiProject() + val subproject = project.subprojects.first() + project.allprojects { + it.registerDiktatTask { + inputs = it.files() + diktatConfigFile = it.rootProject.file("diktat-analysis.yml") + } + } + val task = project.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + val subprojectTask = subproject.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, subprojectTask.systemProperties[DIKTAT_CONF_PROPERTY]) + } + + @Test + fun `check system property with multiproject build with custom config and two config files`() { + setupMultiProject() + val subproject = project.subprojects.single() + subproject.file("diktat-analysis.yml").createNewFile() + project.allprojects { + it.registerDiktatTask { + inputs = it.files() + diktatConfigFile = it.file("diktat-analysis.yml") + } + } + val task = project.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + val subprojectTask = subproject.tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase + Assertions.assertEquals(File(project.projectDir, "diktat-analysis.yml").absolutePath, task.systemProperties[DIKTAT_CONF_PROPERTY]) + Assertions.assertEquals(File(subproject.projectDir, "diktat-analysis.yml").absolutePath, subprojectTask.systemProperties[DIKTAT_CONF_PROPERTY]) + } + + private fun Project.registerDiktatTask(extensionConfiguration: DiktatExtension.() -> Unit): DiktatJavaExecTaskBase { + DiktatGradlePlugin().apply(this) + extensions.configure("diktat", extensionConfiguration) + return tasks.getByName(DIKTAT_CHECK_TASK) as DiktatJavaExecTaskBase } private fun assertCommandLineEquals(expected: List, extensionConfiguration: DiktatExtension.() -> Unit) { - val task = registerDiktatTask(extensionConfiguration) + val task = project.registerDiktatTask(extensionConfiguration) Assertions.assertIterableEquals(expected, task.commandLine) } + private fun setupMultiProject() { + ProjectBuilder.builder() + .withParent(project) + .withName("testSubproject") + .withProjectDir(File(project.projectDir, "testSubproject").also { + Files.createDirectory(it.toPath()) + }) + .build() + project.file("diktat-analysis.yml").createNewFile() + } + private fun combinePathParts(vararg parts: String) = parts.joinToString(File.separator) + + companion object { + private const val DIKTAT_CHECK_TASK = "diktatCheck" + } } diff --git a/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts b/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts index d60bbdc835..229d7c1970 100644 --- a/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts +++ b/examples/gradle-kotlin-dsl-multiproject/build.gradle.kts @@ -12,6 +12,7 @@ allprojects { } apply(plugin = "org.cqfn.diktat.diktat-gradle-plugin") configure { + diktatConfigFile = rootProject.file("diktat-analysis.yml") inputs = files("src/**/*.kt") debug = true }