diff --git a/detekt-report-html/src/main/kotlin/io/github/detekt/report/html/HtmlOutputReport.kt b/detekt-report-html/src/main/kotlin/io/github/detekt/report/html/HtmlOutputReport.kt
index bbbf1ebb08e..91c82f955e9 100644
--- a/detekt-report-html/src/main/kotlin/io/github/detekt/report/html/HtmlOutputReport.kt
+++ b/detekt-report-html/src/main/kotlin/io/github/detekt/report/html/HtmlOutputReport.kt
@@ -7,7 +7,9 @@ import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.OutputReport
import io.gitlab.arturbosch.detekt.api.ProjectMetric
import io.gitlab.arturbosch.detekt.api.RuleSet
+import io.gitlab.arturbosch.detekt.api.SetupContext
import io.gitlab.arturbosch.detekt.api.TextLocation
+import io.gitlab.arturbosch.detekt.api.getOrNull
import io.gitlab.arturbosch.detekt.api.internal.BuiltInOutputReport
import io.gitlab.arturbosch.detekt.api.internal.whichDetekt
import kotlinx.html.CommonAttributeGroupFacadeFlowInteractiveContent
@@ -27,11 +29,14 @@ import kotlinx.html.span
import kotlinx.html.stream.createHTML
import kotlinx.html.ul
import kotlinx.html.visit
+import java.nio.file.Path
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Locale
+import kotlin.io.path.absolute
import kotlin.io.path.invariantSeparatorsPathString
+import kotlin.io.path.relativeTo
private const val DEFAULT_TEMPLATE = "default-html-report-template.html"
private const val PLACEHOLDER_METRICS = "@@@metrics@@@"
@@ -51,6 +56,12 @@ class HtmlOutputReport : BuiltInOutputReport, OutputReport() {
override val id: String = "HtmlOutputReport"
override val ending = "html"
+ var basePath: Path? = null
+
+ override fun init(context: SetupContext) {
+ basePath = context.getOrNull(DETEKT_OUTPUT_REPORT_BASE_PATH_KEY)?.absolute()
+ }
+
override fun render(detektion: Detektion) =
javaClass.getResource("/$DEFAULT_TEMPLATE")!!
.openSafeStream()
@@ -146,7 +157,8 @@ class HtmlOutputReport : BuiltInOutputReport, OutputReport() {
}
private fun FlowContent.renderIssue(issue: Issue) {
- val filePath = issue.location.filePath.relativePath ?: issue.location.filePath.absolutePath
+ val filePath = basePath?.let { issue.location.filePath.absolutePath.relativeTo(it) }
+ ?: issue.location.filePath.absolutePath
val pathString = filePath.invariantSeparatorsPathString
span("location") {
text(
diff --git a/detekt-report-html/src/test/kotlin/io/github/detekt/report/html/HtmlOutputReportSpec.kt b/detekt-report-html/src/test/kotlin/io/github/detekt/report/html/HtmlOutputReportSpec.kt
index 5d526779b3d..3189e08c88a 100644
--- a/detekt-report-html/src/test/kotlin/io/github/detekt/report/html/HtmlOutputReportSpec.kt
+++ b/detekt-report-html/src/test/kotlin/io/github/detekt/report/html/HtmlOutputReportSpec.kt
@@ -82,6 +82,9 @@ class HtmlOutputReportSpec {
@Test
fun `renders the right file locations for relative paths`() {
+ val htmlReport = HtmlOutputReport()
+ htmlReport.basePath = Path("Users/tester/detekt/").absolute()
+
val result = htmlReport.render(createTestDetektionFromRelativePath())
assertThat(result).contains("src/main/com/sample/Sample1.kt:11:1")
@@ -208,10 +211,11 @@ private fun createTestDetektionWithMultipleSmells(): Detektion {
}
private fun createTestDetektionFromRelativePath(): Detektion {
+ val basePath = "${System.getProperty("user.dir")}/Users/tester/detekt/"
val entity1 = createEntity(
location = createLocation(
path = "src/main/com/sample/Sample1.kt",
- basePath = "Users/tester/detekt/",
+ basePath = basePath,
position = 11 to 1,
text = 10..14,
),
@@ -220,14 +224,14 @@ private fun createTestDetektionFromRelativePath(): Detektion {
val entity2 = createEntity(
location = createLocation(
path = "src/main/com/sample/Sample2.kt",
- basePath = "Users/tester/detekt/",
+ basePath = basePath,
position = 22 to 2,
)
)
val entity3 = createEntity(
location = createLocation(
path = "src/main/com/sample/Sample3.kt",
- basePath = "Users/tester/detekt/",
+ basePath = basePath,
position = 33 to 3,
)
)
diff --git a/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt b/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt
index 71f4ef27f87..028036b1536 100644
--- a/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt
+++ b/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt
@@ -15,14 +15,19 @@ import io.gitlab.arturbosch.detekt.api.Detektion
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.OutputReport
import io.gitlab.arturbosch.detekt.api.ProjectMetric
+import io.gitlab.arturbosch.detekt.api.SetupContext
import io.gitlab.arturbosch.detekt.api.SourceLocation
+import io.gitlab.arturbosch.detekt.api.getOrNull
import io.gitlab.arturbosch.detekt.api.internal.BuiltInOutputReport
import io.gitlab.arturbosch.detekt.api.internal.whichDetekt
+import java.nio.file.Path
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Locale
+import kotlin.io.path.absolute
import kotlin.io.path.invariantSeparatorsPathString
+import kotlin.io.path.relativeTo
import kotlin.math.max
import kotlin.math.min
@@ -39,6 +44,12 @@ class MdOutputReport : BuiltInOutputReport, OutputReport() {
override val id: String = "MdOutputReport"
override val ending: String = "md"
+ var basePath: Path? = null
+
+ override fun init(context: SetupContext) {
+ basePath = context.getOrNull(DETEKT_OUTPUT_REPORT_BASE_PATH_KEY)?.absolute()
+ }
+
override fun render(detektion: Detektion) = markdown {
h1 { "detekt" }
@@ -48,7 +59,7 @@ class MdOutputReport : BuiltInOutputReport, OutputReport() {
h2 { "Complexity Report" }
renderComplexity(getComplexityMetrics(detektion))
- renderIssues(detektion.issues)
+ renderIssues(detektion.issues, basePath)
emptyLine()
paragraph {
@@ -81,17 +92,17 @@ private fun MarkdownContent.renderComplexity(complexityReport: List) {
}
}
-private fun MarkdownContent.renderGroup(issues: List) {
+private fun MarkdownContent.renderGroup(issues: List, basePath: Path?) {
issues
.groupBy { it.ruleInfo }
.toList()
.sortedBy { (ruleInfo, _) -> ruleInfo.id.value }
.forEach { (ruleInfo, ruleIssues) ->
- renderRule(ruleInfo, ruleIssues)
+ renderRule(ruleInfo, ruleIssues, basePath)
}
}
-private fun MarkdownContent.renderRule(ruleInfo: Issue.RuleInfo, issues: List) {
+private fun MarkdownContent.renderRule(ruleInfo: Issue.RuleInfo, issues: List, basePath: Path?) {
val ruleId = ruleInfo.id.value
val ruleSetId = ruleInfo.ruleSetId.value
h3 { "$ruleSetId, $ruleId (%,d)".format(Locale.ROOT, issues.size) }
@@ -114,12 +125,12 @@ private fun MarkdownContent.renderRule(ruleInfo: Issue.RuleInfo, issues: List) {
+private fun MarkdownContent.renderIssues(issues: List, basePath: Path?) {
val total = issues.count()
h2 { "Issues (%,d)".format(Locale.ROOT, total) }
@@ -129,12 +140,13 @@ private fun MarkdownContent.renderIssues(issues: List) {
.toList()
.sortedBy { (group, _) -> group.value }
.forEach { (_, groupIssues) ->
- renderGroup(groupIssues)
+ renderGroup(groupIssues, basePath)
}
}
-private fun MarkdownContent.renderIssue(issue: Issue): String {
- val filePath = issue.location.filePath.relativePath ?: issue.location.filePath.absolutePath
+private fun MarkdownContent.renderIssue(issue: Issue, basePath: Path?): String {
+ val filePath = basePath?.let { issue.location.filePath.absolutePath.relativeTo(it) }
+ ?: issue.location.filePath.absolutePath
val location =
"${filePath.invariantSeparatorsPathString}:${issue.location.source.line}:${issue.location.source.column}"
diff --git a/detekt-report-xml/src/main/kotlin/io/github/detekt/report/xml/XmlOutputReport.kt b/detekt-report-xml/src/main/kotlin/io/github/detekt/report/xml/XmlOutputReport.kt
index 8a4c00ba1b7..831b939f99e 100644
--- a/detekt-report-xml/src/main/kotlin/io/github/detekt/report/xml/XmlOutputReport.kt
+++ b/detekt-report-xml/src/main/kotlin/io/github/detekt/report/xml/XmlOutputReport.kt
@@ -3,9 +3,14 @@ package io.github.detekt.report.xml
import io.gitlab.arturbosch.detekt.api.Detektion
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.OutputReport
+import io.gitlab.arturbosch.detekt.api.SetupContext
+import io.gitlab.arturbosch.detekt.api.getOrNull
import io.gitlab.arturbosch.detekt.api.internal.BuiltInOutputReport
+import java.nio.file.Path
import java.util.Locale
+import kotlin.io.path.absolute
import kotlin.io.path.invariantSeparatorsPathString
+import kotlin.io.path.relativeTo
/**
* Contains rule violations in an XML format. The report follows the structure of a Checkstyle report.
@@ -19,13 +24,22 @@ class XmlOutputReport : BuiltInOutputReport, OutputReport() {
private val Issue.severityLabel: String
get() = severity.name.lowercase(Locale.US)
+ var basePath: Path? = null
+
+ override fun init(context: SetupContext) {
+ basePath = context.getOrNull(DETEKT_OUTPUT_REPORT_BASE_PATH_KEY)?.absolute()
+ }
+
override fun render(detektion: Detektion): String {
val lines = ArrayList()
lines += ""
lines += ""
detektion.issues
- .groupBy { it.location.filePath.relativePath ?: it.location.filePath.absolutePath }
+ .groupBy {
+ basePath?.let { path -> it.location.filePath.absolutePath.relativeTo(path) }
+ ?: it.location.filePath.absolutePath
+ }
.forEach { (filePath, issues) ->
lines += ""
issues.forEach {
diff --git a/detekt-report-xml/src/test/kotlin/io/github/detekt/report/xml/XmlOutputFormatSpec.kt b/detekt-report-xml/src/test/kotlin/io/github/detekt/report/xml/XmlOutputFormatSpec.kt
index e305ff9334a..64037bba763 100644
--- a/detekt-report-xml/src/test/kotlin/io/github/detekt/report/xml/XmlOutputFormatSpec.kt
+++ b/detekt-report-xml/src/test/kotlin/io/github/detekt/report/xml/XmlOutputFormatSpec.kt
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource
import java.util.Locale
+import kotlin.io.path.Path
+import kotlin.io.path.absolute
import kotlin.io.path.invariantSeparatorsPathString
private const val TAB = "\t"
@@ -114,13 +116,18 @@ class XmlOutputFormatSpec {
fun `renders issues with relative path`() {
val issueA = createIssueForRelativePath(
ruleInfo = createRuleInfo("id_a"),
+ basePath = "${System.getProperty("user.dir")}/Users/tester/detekt/",
relativePath = "Sample1.kt"
)
val issueB = createIssueForRelativePath(
ruleInfo = createRuleInfo("id_b"),
+ basePath = "${System.getProperty("user.dir")}/Users/tester/detekt/",
relativePath = "Sample2.kt"
)
+ val outputFormat = XmlOutputReport()
+ outputFormat.basePath = Path("Users/tester/detekt/").absolute()
+
val result = outputFormat.render(TestDetektion(issueA, issueB))
assertThat(result).isEqualTo(