Skip to content

Commit

Permalink
support suppressing findings
Browse files Browse the repository at this point in the history
fixes #230
  • Loading branch information
RBusarow authored and kodiakhq[bot] committed Oct 26, 2021
1 parent a68473d commit 53d1be0
Show file tree
Hide file tree
Showing 33 changed files with 846 additions and 182 deletions.
25 changes: 24 additions & 1 deletion modulecheck-api/src/main/kotlin/modulecheck/api/Finding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.api

import modulecheck.api.Finding.Position
import modulecheck.parsing.ModuleDependencyDeclaration
import java.io.File

interface Finding {
Expand All @@ -24,9 +25,16 @@ interface Finding {
val dependentPath: String
val buildFile: File

val statementOrNull: ModuleDependencyDeclaration? get() = null
val statementTextOrNull: String? get() = null
val positionOrNull: Position?

fun logElement(): LogElement

fun shouldSkip(): Boolean = statementOrNull?.suppressed
?.contains(problemName)
?: false

fun logString(): String {
return "${buildFile.path}: ${positionString()} $problemName"
}
Expand All @@ -36,8 +44,23 @@ interface Finding {
data class Position(
val row: Int,
val column: Int
) {
) : Comparable<Position> {
fun logString(): String = "($row, $column): "
override fun compareTo(other: Position): Int {
return row.compareTo(other.row)
}
}

data class LogElement(
val dependentPath: String,
val problemName: String,
val sourceOrNull: String?,
val dependencyPath: String,
val positionOrNull: Position?,
val buildFile: File,
var fixed: Boolean = false
) {
val filePathStr = "${buildFile.path}: ${positionOrNull?.logString().orEmpty()}"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.core.internal.positionOf
Expand All @@ -29,7 +30,7 @@ data class CouldUseAnvilFinding(
) : Finding, Fixable {

override val dependencyIdentifier = "com.google.dagger:dagger-compiler"
override val problemName = "could use Anvil factory generator"
override val problemName = "useAnvilFactories"

override val positionOrNull: Position? by lazy {

Expand All @@ -42,5 +43,16 @@ data class CouldUseAnvilFinding(
?.positionOf(statement, "kapt".asConfigurationName())
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyIdentifier,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val statementTextOrNull: String? get() = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package modulecheck.core

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Fixable
import modulecheck.api.positionOfStatement
import modulecheck.core.internal.statementOrNullIn
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2

abstract class DependencyFinding(
Expand All @@ -37,10 +39,26 @@ abstract class DependencyFinding(
.positionOfStatement(statement)
}

override val statementTextOrNull: String? by lazy {
override val statementOrNull: ModuleDependencyDeclaration? by lazy {
dependencyProject
.statementOrNullIn(buildFile, configurationName)
}
override val statementTextOrNull: String? by lazy {
statementOrNull?.statementWithSurroundingText
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

abstract fun fromStringOrEmpty(): String

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package modulecheck.core

import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.core.internal.positionIn
import modulecheck.parsing.ConfigurationName
Expand All @@ -38,11 +39,22 @@ data class InheritedDependencyFinding(
source?.project?.positionIn(buildFile, configurationName)
}

private fun fromStringOrEmpty(): String {
override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fromStringOrEmpty(): String {
return if (dependencyProject.path == source?.project?.path) {
""
} else {
" from: ${source?.project?.path}"
"${source?.project?.path}"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

package modulecheck.core

import modulecheck.api.Finding.LogElement
import modulecheck.core.internal.statementOrNullIn
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.ConfiguredProjectDependency
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2
import java.io.File

Expand All @@ -31,20 +33,35 @@ data class MustBeApiFinding(

override val dependencyIdentifier = dependencyProject.path + fromStringOrEmpty()

override val statementTextOrNull: String? by lazy {
super.statementTextOrNull
override val statementOrNull: ModuleDependencyDeclaration? by lazy {
super.statementOrNull
?: source?.project
?.statementOrNullIn(buildFile, configurationName)
}
override val statementTextOrNull: String? by lazy {
super.statementTextOrNull
?: statementOrNull?.statementWithSurroundingText
}

private fun fromStringOrEmpty(): String {
override fun fromStringOrEmpty(): String {
return if (dependencyProject.path == source?.project?.path) {
""
} else {
" from: ${source?.project?.path}"
"${source?.project?.path}"
}
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = fromStringOrEmpty(),
dependencyPath = dependencyProject.path,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fix(): Boolean = synchronized(buildFile) {

val statement = statementTextOrNull ?: return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ data class OverShotDependencyFinding(
override val dependencyProject: Project2,
override val dependencyIdentifier: String,
override val configurationName: ConfigurationName
) : DependencyFinding("demoted") {
) : DependencyFinding("overshot") {

override fun fix(): Boolean {

Expand Down Expand Up @@ -74,17 +74,14 @@ data class OverShotDependencyFinding(
return false
}

private fun matchingDeclaration(block: DependenciesBlock) =
(
block.allDeclarations
.filterIsInstance<ModuleDependencyDeclaration>()
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.filterNot { it is ModuleDependencyDeclaration }
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.lastOrNull()
)
private fun matchingDeclaration(block: DependenciesBlock) = block.allDeclarations
.filterIsInstance<ModuleDependencyDeclaration>()
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.filterNot { it is ModuleDependencyDeclaration }
.maxByOrNull { declaration -> declaration.configName == configurationName }
?: block.allDeclarations
.lastOrNull()

private fun newModuleDeclaration(match: DependencyDeclaration) = when (match) {
is ExternalDependencyDeclaration -> dependencyProject.path
Expand Down Expand Up @@ -114,6 +111,8 @@ data class OverShotDependencyFinding(
}
}

override fun fromStringOrEmpty(): String = ""

override fun toString(): String {
return "OverShotDependency(\n" +
"\tdependentPath='$dependentPath', \n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ data class RedundantDependencyFinding(

override val dependencyIdentifier = dependencyPath + fromStringOrEmpty()

private fun fromStringOrEmpty(): String {
override fun fromStringOrEmpty(): String {

return if (from.all { dependencyProject.path == it.path }) {
""
} else {
" from: ${from.joinToString { it.path }}"
from.joinToString { it.path }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ data class UnusedDependency(
"\tconfigurationName=$configurationName\n" +
")"
}

override fun fromStringOrEmpty(): String = ""
}

data class UnusedDependencies(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ import modulecheck.api.positionOfStatement
import modulecheck.core.parse
import modulecheck.parsing.ConfigurationName
import modulecheck.parsing.DependencyBlockParser
import modulecheck.parsing.ModuleDependencyDeclaration
import modulecheck.parsing.Project2
import java.io.File

fun Project2.statementOrNullIn(
dependentBuildFile: File,
configuration: ConfigurationName
): String? {
): ModuleDependencyDeclaration? {
return DependencyBlockParser
.parse(dependentBuildFile)
.firstNotNullOfOrNull { block ->
block.getOrEmpty(path, configuration)
.takeIf { it.isNotEmpty() }
}
?.firstOrNull()
?.statementWithSurroundingText
}

fun Project2.positionIn(
Expand All @@ -45,5 +45,5 @@ fun Project2.positionIn(
val statement = statementOrNullIn(dependentBuildFile, configuration) ?: return null

return dependentBuildFile.readText()
.positionOfStatement(statement)
.positionOfStatement(statement.statementWithSurroundingText)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core.kapt

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.core.rule.KAPT_PLUGIN_FUN
Expand All @@ -31,7 +32,18 @@ data class UnusedKaptPluginFinding(

override val dependencyIdentifier = KAPT_PLUGIN_ID

override val problemName = "unused kapt plugin"
override val problemName = "unusedKaptPlugin"

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyIdentifier,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val positionOrNull: Position? by lazy {
val text = buildFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package modulecheck.core.kapt

import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.core.internal.positionOf
import modulecheck.parsing.ConfigurationName
Expand All @@ -29,7 +30,18 @@ data class UnusedKaptProcessorFinding(

override val dependencyIdentifier = dependencyPath

override val problemName = "unused ${configurationName.value} dependency"
override val problemName = "unusedKaptProcessor"

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyPath,
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override val positionOrNull: Position? by lazy {
// Kapt paths are different from other project dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package modulecheck.core.rule.android

import modulecheck.api.Finding
import modulecheck.api.Finding.LogElement
import modulecheck.api.Finding.Position
import modulecheck.api.Fixable
import modulecheck.api.positionOfStatement
Expand All @@ -28,7 +29,7 @@ data class DisableViewBindingGenerationFinding(
override val buildFile: File
) : Finding, Fixable {

override val problemName = "unused ViewBinding generation"
override val problemName = "disableViewBinding"

override val dependencyIdentifier = ""

Expand All @@ -47,6 +48,17 @@ data class DisableViewBindingGenerationFinding(
fileText.positionOfStatement(statement)
}

override fun logElement(): LogElement {
return LogElement(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = "",
positionOrNull = positionOrNull,
buildFile = buildFile
)
}

override fun fix(): Boolean = synchronized(buildFile) {
val ktFile = kotlinBuildFileOrNull() ?: return false

Expand Down
Loading

0 comments on commit 53d1be0

Please sign in to comment.