From 3c572f1e246a2ea8a20194fcb69b8446e6c4f1fb Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Mon, 27 Nov 2023 17:15:26 +0300 Subject: [PATCH] Supported multiple reporters in maven (#1824) - supported reporters to configure reporters in maven - supported a default location for all reporters --- .../saveourtool/diktat/plugin/gradle/Utils.kt | 2 - .../gradle/extension/DefaultReporter.kt | 9 +++ .../plugin/gradle/extension/Reporter.kt | 8 ++ .../diktat/plugin/maven/DiktatBaseMojo.kt | 58 +++++--------- .../saveourtool/diktat/plugin/maven/Utils.kt | 21 +++++ .../plugin/maven/reporters/DefaultReporter.kt | 79 +++++++++++++++++++ .../maven/reporters/GitHubActionsReporter.kt | 21 +++++ .../diktat/plugin/maven/reporters/Reporter.kt | 32 ++++++++ .../plugin/maven/reporters/Reporters.kt | 56 +++++++++++++ 9 files changed, 245 insertions(+), 41 deletions(-) create mode 100644 diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/Utils.kt create mode 100644 diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/DefaultReporter.kt create mode 100644 diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/GitHubActionsReporter.kt create mode 100644 diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporter.kt create mode 100644 diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporters.kt diff --git a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/Utils.kt b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/Utils.kt index 65259bf542..40a3224d18 100644 --- a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/Utils.kt +++ b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/Utils.kt @@ -2,8 +2,6 @@ * Utilities for diktat gradle plugin */ -@file:Suppress("FILE_NAME_MATCH_CLASS", "MatchingDeclarationName") - package com.saveourtool.diktat.plugin.gradle import org.gradle.api.Project diff --git a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/DefaultReporter.kt b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/DefaultReporter.kt index 6f55a3d243..82612e5406 100644 --- a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/DefaultReporter.kt +++ b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/DefaultReporter.kt @@ -6,6 +6,7 @@ package com.saveourtool.diktat.plugin.gradle.extension +import com.saveourtool.diktat.api.DiktatReporterCreationArguments import com.saveourtool.diktat.api.DiktatReporterType import com.saveourtool.diktat.plugin.gradle.defaultReportLocation import org.gradle.api.Project @@ -14,6 +15,8 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Provider import java.io.File +import java.nio.file.Files +import java.nio.file.Path import javax.inject.Inject /** @@ -32,6 +35,12 @@ abstract class DefaultReporter @Inject constructor( .also { fileProperty -> fileProperty.convention(project.defaultReportLocation(extension = type.extension)) } + + override fun toCreationArguments(sourceRootDir: Path): DiktatReporterCreationArguments = DiktatReporterCreationArguments( + reporterType = type, + outputStream = output.map { file -> file.asFile.also { Files.createDirectories(it.parentFile.toPath()) }.outputStream() }.orNull, + sourceRootDir = sourceRootDir.takeIf { type == DiktatReporterType.SARIF }, + ) } /** diff --git a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/Reporter.kt b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/Reporter.kt index 2ccb3c0060..ec0cfd18fb 100644 --- a/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/Reporter.kt +++ b/diktat-gradle-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/gradle/extension/Reporter.kt @@ -1,7 +1,9 @@ package com.saveourtool.diktat.plugin.gradle.extension +import com.saveourtool.diktat.api.DiktatReporterCreationArguments import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.OutputFile +import java.nio.file.Path /** * A base interface for reporter @@ -12,4 +14,10 @@ interface Reporter { */ @get:OutputFile val output: RegularFileProperty + + /** + * @param sourceRootDir + * @return [DiktatReporterCreationArguments] to create this reporter + */ + fun toCreationArguments(sourceRootDir: Path): DiktatReporterCreationArguments } diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt index 2e9a19d4c1..1dc1678eca 100644 --- a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/DiktatBaseMojo.kt @@ -2,9 +2,11 @@ package com.saveourtool.diktat.plugin.maven import com.saveourtool.diktat.DiktatRunner import com.saveourtool.diktat.DiktatRunnerArguments -import com.saveourtool.diktat.api.DiktatReporterCreationArguments -import com.saveourtool.diktat.api.DiktatReporterType import com.saveourtool.diktat.diktatRunnerFactory +import com.saveourtool.diktat.plugin.maven.reporters.GitHubActionsReporter +import com.saveourtool.diktat.plugin.maven.reporters.PlainReporter +import com.saveourtool.diktat.plugin.maven.reporters.Reporter +import com.saveourtool.diktat.plugin.maven.reporters.Reporters import com.saveourtool.diktat.util.isKotlinCodeOrScript import org.apache.maven.plugin.AbstractMojo @@ -15,8 +17,6 @@ import org.apache.maven.plugins.annotations.Parameter import org.apache.maven.project.MavenProject import java.io.File -import java.io.FileOutputStream -import java.io.OutputStream import java.nio.file.Path import java.nio.file.Paths import kotlin.io.path.inputStream @@ -33,17 +33,10 @@ abstract class DiktatBaseMojo : AbstractMojo() { var githubActions = false /** - * Type of the reporter to use + * The reporters to use */ - @Parameter(property = "diktat.reporter") - var reporter = "plain" - - /** - * Type of output - * Default: System.out - */ - @Parameter(property = "diktat.output") - var output = "" + @Parameter + var reporters: Reporters? = null /** * Baseline file, containing a list of errors that will be ignored. @@ -100,19 +93,23 @@ abstract class DiktatBaseMojo : AbstractMojo() { if (excludes.isNotEmpty()) " and excluding $excludes" else "" ) - val sourceRootDir = mavenProject.basedir.parentFile.toPath() - val reporterType = getReporterType() - val reporterArgs = DiktatReporterCreationArguments( - reporterType = reporterType, - outputStream = getReporterOutput(), - sourceRootDir = sourceRootDir.takeIf { reporterType == DiktatReporterType.SARIF }, - ) + val sourceRootDir = generateSequence(mavenProject) { it.parent }.last().basedir.toPath() + val reporters: List = (reporters?.getAll() ?: listOf(PlainReporter())) + .let { all -> + if (githubActions && all.filterIsInstance().isEmpty()) { + all + GitHubActionsReporter() + } else { + all + } + } + + val reporterArgsList = reporters.map { it.toCreationArguments(mavenProject, sourceRootDir) } val args = DiktatRunnerArguments( configInputStream = configFile.inputStream(), sourceRootDir = sourceRootDir, files = files(), baselineFile = baseline?.toPath(), - reporterArgsList = listOf(reporterArgs), + reporterArgsList = reporterArgsList, ) val diktatRunner = diktatRunnerFactory(args) val errorCounter = runAction( @@ -124,23 +121,6 @@ abstract class DiktatBaseMojo : AbstractMojo() { } } - private fun getReporterType(): DiktatReporterType = if (githubActions) { - DiktatReporterType.SARIF - } else { - DiktatReporterType.entries.firstOrNull { it.id.equals(reporter, ignoreCase = true) } ?: run { - log.warn("Reporter name ${this.reporter} was not specified or is invalid. Falling to 'plain' reporter") - DiktatReporterType.PLAIN - } - } - - private fun getReporterOutput(): OutputStream? = if (output.isNotBlank()) { - FileOutputStream(this.output, false) - } else if (githubActions) { - FileOutputStream("${mavenProject.basedir}/${mavenProject.name}.sarif", false) - } else { - null - } - /** * Function that searches diktat config file in maven project hierarchy. * If [diktatConfigFile] is absolute, it's path is used. If [diktatConfigFile] is relative, this method looks for it in all maven parent projects. diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/Utils.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/Utils.kt new file mode 100644 index 0000000000..1f1ffdcb3c --- /dev/null +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/Utils.kt @@ -0,0 +1,21 @@ +/** + * Utilities for diktat maven plugin + */ + +package com.saveourtool.diktat.plugin.maven + +import com.saveourtool.diktat.api.DiktatReporterType +import org.apache.maven.project.MavenProject +import java.io.File + +/** + * @param reporterType + * @return default location of report with provided [reporterType] + */ +internal fun MavenProject.defaultReportLocation( + reporterType: DiktatReporterType, +): File = basedir + .resolve(build.directory) + .resolve("reports") + .resolve("diktat") + .resolve("diktat.${reporterType.extension}") diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/DefaultReporter.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/DefaultReporter.kt new file mode 100644 index 0000000000..bb61106c17 --- /dev/null +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/DefaultReporter.kt @@ -0,0 +1,79 @@ +/** + * All default reporters + */ + +package com.saveourtool.diktat.plugin.maven.reporters + +import com.saveourtool.diktat.api.DiktatReporterCreationArguments +import com.saveourtool.diktat.api.DiktatReporterType +import com.saveourtool.diktat.plugin.maven.defaultReportLocation +import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.project.MavenProject +import java.io.File +import java.nio.file.Path + +/** + * A base interface for a default reporter + * + * @param type type of reporter + */ +open class DefaultReporter( + private val type: DiktatReporterType, +) : Reporter { + /** + * Location for output + */ + @Parameter + var output: File? = null + + override fun getOutput(project: MavenProject): File? = output ?: project.defaultReportLocation(type) + + override fun toCreationArguments( + project: MavenProject, + sourceRootDir: Path, + ): DiktatReporterCreationArguments = DiktatReporterCreationArguments( + reporterType = type, + outputStream = getOutputStream(project), + sourceRootDir = sourceRootDir.takeIf { type == DiktatReporterType.SARIF }, + ) +} + +/** + * Plain reporter + */ +class PlainReporter : DefaultReporter( + type = DiktatReporterType.PLAIN, +) { + /** + * Plain reporter prints to stdout by default + */ + override fun getOutput(project: MavenProject): File? = output +} + +/** + * JSON reporter + */ +class JsonReporter : DefaultReporter( + type = DiktatReporterType.JSON, +) + +/** + * SARIF reporter + */ +class SarifReporter : DefaultReporter( + type = DiktatReporterType.SARIF, +) + +/** + * Checkstyle reporter + */ +class CheckstyleReporter : DefaultReporter( + type = DiktatReporterType.CHECKSTYLE, +) + +/** + * HTML reporter + */ +class HtmlReporter : DefaultReporter( + type = DiktatReporterType.HTML, +) diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/GitHubActionsReporter.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/GitHubActionsReporter.kt new file mode 100644 index 0000000000..29ba7a8529 --- /dev/null +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/GitHubActionsReporter.kt @@ -0,0 +1,21 @@ +package com.saveourtool.diktat.plugin.maven.reporters + +import com.saveourtool.diktat.api.DiktatReporterCreationArguments +import com.saveourtool.diktat.api.DiktatReporterType +import com.saveourtool.diktat.plugin.maven.defaultReportLocation +import org.apache.maven.project.MavenProject +import java.io.File +import java.nio.file.Path + +/** + * GitHub actions reporter + */ +class GitHubActionsReporter : Reporter { + override fun getOutput(project: MavenProject): File = project.defaultReportLocation(DiktatReporterType.SARIF) + override fun toCreationArguments(project: MavenProject, sourceRootDir: Path): DiktatReporterCreationArguments = + DiktatReporterCreationArguments( + reporterType = DiktatReporterType.SARIF, + outputStream = getOutputStream(project), + sourceRootDir = sourceRootDir, + ) +} diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporter.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporter.kt new file mode 100644 index 0000000000..585caeac78 --- /dev/null +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporter.kt @@ -0,0 +1,32 @@ +package com.saveourtool.diktat.plugin.maven.reporters + +import com.saveourtool.diktat.api.DiktatReporterCreationArguments +import org.apache.maven.project.MavenProject +import java.io.File +import java.io.OutputStream +import java.nio.file.Files +import java.nio.file.Path + +/** + * A base interface for reporter + */ +interface Reporter { + /** + * @param project + * @return location as a [File] for output or default value resolved by [project] + */ + fun getOutput(project: MavenProject): File? + + /** + * @param project + * @return location as an [OutputStream] for output or default value resolved by [project] + */ + fun getOutputStream(project: MavenProject): OutputStream? = getOutput(project)?.also { Files.createDirectories(it.parentFile.toPath()) }?.outputStream() + + /** + * @param project + * @param sourceRootDir + * @return [DiktatReporterCreationArguments] to create this reporter + */ + fun toCreationArguments(project: MavenProject, sourceRootDir: Path): DiktatReporterCreationArguments +} diff --git a/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporters.kt b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporters.kt new file mode 100644 index 0000000000..a84b8ca170 --- /dev/null +++ b/diktat-maven-plugin/src/main/kotlin/com/saveourtool/diktat/plugin/maven/reporters/Reporters.kt @@ -0,0 +1,56 @@ +package com.saveourtool.diktat.plugin.maven.reporters + +import org.apache.maven.plugins.annotations.Parameter + +/** + * Configuration for reporters + */ +class Reporters { + /** + * Configure *plain* reporter + */ + @Parameter + var plain: PlainReporter? = null + + /** + * Configure *json* reporter + */ + @Parameter + var json: JsonReporter? = null + + /** + * Configure *sarif* reporter + */ + @Parameter + var sarif: SarifReporter? = null + + /** + * Configure *sarif* reporter for GitHub actions + */ + @Parameter + var gitHubActions: GitHubActionsReporter? = null + + /** + * Configure *checkstyle* reporter + */ + @Parameter + var checkstyle: CheckstyleReporter? = null + + /** + * Configure *html* reporter + */ + @Parameter + var html: HtmlReporter? = null + + /** + * @return all configured reporters + */ + fun getAll(): List = listOfNotNull( + plain, + json, + sarif, + gitHubActions, + checkstyle, + html, + ) +}