Skip to content

Commit

Permalink
Supported multiple reporters in maven (#1824)
Browse files Browse the repository at this point in the history
- supported reporters to configure reporters in maven
- supported a default location for all reporters
  • Loading branch information
nulls authored Nov 27, 2023
1 parent 2030a14 commit 3c572f1
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

/**
Expand All @@ -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 },
)
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -12,4 +14,10 @@ interface Reporter {
*/
@get:OutputFile
val output: RegularFileProperty

/**
* @param sourceRootDir
* @return [DiktatReporterCreationArguments] to create this reporter
*/
fun toCreationArguments(sourceRootDir: Path): DiktatReporterCreationArguments
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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<Reporter> = (reporters?.getAll() ?: listOf(PlainReporter()))
.let { all ->
if (githubActions && all.filterIsInstance<GitHubActionsReporter>().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(
Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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}")
Original file line number Diff line number Diff line change
@@ -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,
)
Original file line number Diff line number Diff line change
@@ -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,
)
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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<Reporter> = listOfNotNull(
plain,
json,
sarif,
gitHubActions,
checkstyle,
html,
)
}

0 comments on commit 3c572f1

Please sign in to comment.