Skip to content

Reporting #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dependabot-bridge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies {
dependencySync("javax.inject:javax.inject:1")
dependencySync("org.antlr:antlr4:4.9.2")
dependencySync("org.antlr:antlr4-runtime:4.9.2")
dependencySync("org.unbescape:unbescape:1.1.6.RELEASE")
dependencySync("net.swiftzer.semver:semver:1.1.1")
dependencySync("org.codehaus.groovy:groovy-xml:3.0.9")
dependencySync("org.codehaus.groovy:groovy:3.0.9")
Expand Down
10 changes: 5 additions & 5 deletions detekt/detekt-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ complexity:
TooManyFunctions:
active: true
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
thresholdInFiles: 11
thresholdInClasses: 11
thresholdInInterfaces: 11
thresholdInObjects: 11
thresholdInEnums: 11
thresholdInFiles: 13
thresholdInClasses: 13
thresholdInInterfaces: 13
thresholdInObjects: 13
thresholdInEnums: 13
ignoreDeprecated: false
ignorePrivate: false
ignoreOverridden: false
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ kotlinx-knit = { module = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "k

semVer = "net.swiftzer.semver:semver:1.1.1"

unbescape = "org.unbescape:unbescape:1.1.6.RELEASE"

[bundles]
jUnit = ["junit-api", "junit-params", "junit-engine"]
kotest = ["kotest-assertions", "kotest-properties", "kotest-runner"]
Expand Down
23 changes: 14 additions & 9 deletions modulecheck-api/src/main/kotlin/modulecheck/api/Finding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,30 @@ interface Finding {

val problemName: String
val dependentPath: String
val message: String
val buildFile: File

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

fun toResult(fixed: Boolean): FindingResult
fun toResult(fixed: Boolean): FindingResult {
return FindingResult(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = "",
positionOrNull = positionOrNull,
buildFile = buildFile,
message = message,
fixed = fixed
)
}

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

fun logString(): String {
return "${buildFile.path}: ${positionString()} $problemName"
}

fun positionString() = positionOrNull?.logString() ?: ""

data class Position(
val row: Int,
val column: Int
Expand All @@ -57,10 +63,9 @@ interface Finding {
val dependencyPath: String,
val positionOrNull: Position?,
val buildFile: File,
val message: String,
val fixed: Boolean
) {
val filePathString: String = "${buildFile.path}: ${positionOrNull?.logString().orEmpty()}"

val message: String = "TO DO"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2021 Rick Busarow
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package modulecheck.api

import modulecheck.api.Finding.FindingResult

fun interface FindingProcessor {

fun List<Finding>.toResults(
autoCorrect: Boolean,
deleteUnused: Boolean
): List<Finding.FindingResult>
}

class RealFindingProcessor : FindingProcessor {

override fun List<Finding>.toResults(
autoCorrect: Boolean,
deleteUnused: Boolean
): List<FindingResult> {

return onEach { it.positionOrNull }
.map { finding ->

val fixed = when {
!autoCorrect -> false
deleteUnused && finding is Deletable -> {
finding.delete()
}
finding is Fixable -> finding.fix()
else -> false
}

finding.toResult(fixed)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ package modulecheck.api

import modulecheck.api.Finding.FindingResult

fun interface FindingFixer {
fun interface FindingResultFactory {

fun toResults(
fun create(
findings: List<Finding>,
autoCorrect: Boolean,
deleteUnused: Boolean
): List<Finding.FindingResult>
}

class RealFindingFixer : FindingFixer {
class RealFindingResultFactory : FindingResultFactory {

override fun toResults(
override fun create(
findings: List<Finding>,
autoCorrect: Boolean,
deleteUnused: Boolean
Expand Down
15 changes: 13 additions & 2 deletions modulecheck-api/src/main/kotlin/modulecheck/api/Fixable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,23 @@

package modulecheck.api

import modulecheck.api.Finding.FindingResult

interface Fixable : Finding {

val dependencyIdentifier: String

override fun logString(): String {
return "${buildFile.path}: ${positionString()} $problemName: $dependencyIdentifier"
override fun toResult(fixed: Boolean): FindingResult {
return FindingResult(
dependentPath = dependentPath,
problemName = problemName,
sourceOrNull = null,
dependencyPath = dependencyIdentifier,
positionOrNull = positionOrNull,
buildFile = buildFile,
message = message,
fixed = fixed
)
}

fun fix(): Boolean = synchronized(buildFile) {
Expand Down
3 changes: 3 additions & 0 deletions modulecheck-api/src/main/kotlin/modulecheck/api/Logger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
package modulecheck.api

interface Logger {

fun printReport(report: Report)

fun printHeader(message: String)
fun printWarning(message: String)
fun printWarningLine(message: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,27 @@
* limitations under the License.
*/

package modulecheck.core.rule
package modulecheck.api

import modulecheck.api.settings.ChecksSettings
import modulecheck.api.settings.ModuleCheckSettings
import modulecheck.parsing.McProject
import modulecheck.parsing.psi.internal.asKtsFileOrNull
import org.jetbrains.kotlin.psi.KtFile

abstract class ModuleCheckRule<T> {
interface ModuleCheckRule<T> {

abstract val settings: ModuleCheckSettings
abstract val id: String
abstract val description: String
val settings: ModuleCheckSettings
val id: String
val description: String

abstract fun check(project: McProject): List<T>
fun check(project: McProject): List<T>
fun shouldApply(checksSettings: ChecksSettings): Boolean

protected fun McProject.kotlinBuildFileOrNull(): KtFile? = buildFile.asKtsFileOrNull()
fun McProject.kotlinBuildFileOrNull(): KtFile? = buildFile.asKtsFileOrNull()
}

fun interface RuleFactory {

fun create(settings: ModuleCheckSettings): List<ModuleCheckRule<out Finding>>
}
42 changes: 42 additions & 0 deletions modulecheck-api/src/main/kotlin/modulecheck/api/PrintLogger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Rick Busarow
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package modulecheck.api

class PrintLogger : Logger {
override fun printReport(report: Report) {
println(report.joinToString())
}

override fun printHeader(message: String) = println(message)

override fun printWarning(message: String) = print(message)

override fun printWarningLine(message: String) = println(message)

override fun printInfo(message: String) = println(message)

override fun printFailure(message: String) = print(message)

override fun printFailureLine(message: String) = println(message)

override fun printFailureHeader(message: String) = println(message)

override fun printSuccess(message: String) = print(message)

override fun printSuccessLine(message: String) = println(message)

override fun printSuccessHeader(message: String) = println(message)
}
123 changes: 123 additions & 0 deletions modulecheck-api/src/main/kotlin/modulecheck/api/Report.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (C) 2021 Rick Busarow
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package modulecheck.api

import modulecheck.api.Report.ReportEntry.*

data class Report(val entries: List<ReportEntry>) {

fun joinToString(): String = buildString {
entries
.forEach { reportEntry ->
when (reportEntry) {
is AppendNewLine -> appendLine(reportEntry.message.trimEnd())
else -> append(reportEntry.message)
}
}
}

sealed interface ReportEntry {
val message: String

@JvmInline
value class Header(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class Warning(override val message: String) : ReportEntry

@JvmInline
value class WarningLine(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class Info(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class Failure(override val message: String) : ReportEntry

@JvmInline
value class FailureLine(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class FailureHeader(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class Success(override val message: String) : ReportEntry

@JvmInline
value class SuccessLine(override val message: String) : ReportEntry, AppendNewLine

@JvmInline
value class SuccessHeader(override val message: String) : ReportEntry, AppendNewLine

interface AppendNewLine
}

class ReportBuilderScope(
private val entries: MutableList<ReportEntry> = mutableListOf()
) {

fun header(message: String) {
entries.add(Header(message.trimEnd()))
}

fun warning(message: String) {
entries.add(Warning(message))
}

fun warningLine(message: String) {
entries.add(WarningLine(message.trimEnd()))
}

fun info(message: String) {
entries.add(Info(message))
}

fun failure(message: String) {
entries.add(Failure(message))
}

fun failureLine(message: String) {
entries.add(FailureLine(message.trimEnd()))
}

fun failureHeader(message: String) {
entries.add(FailureHeader(message.trimEnd()))
}

fun success(message: String) {
entries.add(Success(message))
}

fun successLine(message: String) {
entries.add(SuccessLine(message.trimEnd()))
}

fun successHeader(message: String) {
entries.add(SuccessHeader(message.trimEnd()))
}
}

companion object {

fun build(buildAction: ReportBuilderScope.() -> Unit): Report {
val entries = mutableListOf<ReportEntry>()

ReportBuilderScope(entries).buildAction()

return Report(entries)
}
}
}
Loading