Skip to content

Commit

Permalink
update InvalidPackageDeclaration to report if rootPackage is not pres…
Browse files Browse the repository at this point in the history
…ent (detekt#4484)
  • Loading branch information
mateot1 authored and Goooler committed Feb 10, 2022
1 parent ebb78c1 commit de65436
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
1 change: 1 addition & 0 deletions detekt-core/src/main/resources/default-detekt-config.yml
Expand Up @@ -316,6 +316,7 @@ naming:
InvalidPackageDeclaration:
active: false
rootPackage: ''
requireRootInDeclaration: false
LambdaParameterNaming:
active: false
parameterPattern: '[a-z][A-Za-z0-9]*|_'
Expand Down
Expand Up @@ -28,12 +28,20 @@ class InvalidPackageDeclaration(config: Config = Config.empty) : Rule(config) {
@Configuration("if specified this part of the package structure is ignored")
private val rootPackage: String by config("")

@Configuration("requires the declaration to start with the specified rootPackage")
private val requireRootInDeclaration: Boolean by config(false)

override fun visitPackageDirective(directive: KtPackageDirective) {
super.visitPackageDirective(directive)
val declaredPath = directive.packageNames.map(KtElement::getText).toNormalizedForm()
if (declaredPath.isNotBlank()) {
val normalizedFilePath = directive.containingKtFile.absolutePath().parent.toNormalizedForm()
val normalizedRootPackage = packageNameToNormalizedForm(rootPackage)
if (requireRootInDeclaration && !declaredPath.startsWith(normalizedRootPackage)) {
directive.reportInvalidPackageDeclaration("The package declaration is missing the root package")
return
}

val expectedPath =
if (normalizedRootPackage.isBlank()) {
declaredPath
Expand All @@ -43,17 +51,17 @@ class InvalidPackageDeclaration(config: Config = Config.empty) : Rule(config) {

val isInRootPackage = expectedPath.isBlank()
if (!isInRootPackage && !normalizedFilePath.endsWith(expectedPath)) {
report(
CodeSmell(
issue,
Entity.from(directive),
"The package declaration does not match the actual file location.",
)
directive.reportInvalidPackageDeclaration(
"The package declaration does not match the actual file location."
)
}
}
}

private fun KtElement.reportInvalidPackageDeclaration(message: String) {
report(CodeSmell(issue, Entity.from(this), message))
}

private fun <T> Iterable<T>.toNormalizedForm() = joinToString("|")

private fun packageNameToNormalizedForm(packageName: String) = packageName.split('.').toNormalizedForm()
Expand Down
Expand Up @@ -10,6 +10,7 @@ import java.nio.file.FileSystems
import java.nio.file.Paths

private const val ROOT_PACKAGE = "rootPackage"
private const val REQUIRE_ROOT_PACKAGE = "requireRootInDeclaration"

internal class InvalidPackageDeclarationSpec : Spek({

Expand Down Expand Up @@ -93,6 +94,7 @@ internal class InvalidPackageDeclarationSpec : Spek({

assertThat(findings).hasSize(1)
}

it("should report if file path matches root package but package declaration differs") {
val source = """
package io.foo.bar
Expand All @@ -106,6 +108,42 @@ internal class InvalidPackageDeclarationSpec : Spek({
assertThat(findings).hasSize(1)
}
}

describe("with root package required") {

val config by memoized { TestConfig(mapOf(ROOT_PACKAGE to "com.example", REQUIRE_ROOT_PACKAGE to true)) }

it("should pass if declaration starts with root package") {
val source = """
package com.example.foo.bar
class C
"""

val ktFileWithRelativePath = compileContentForTest(source, createPath("src/foo/bar/File.kt"))
val findingsForRelativePath = InvalidPackageDeclaration(config).lint(ktFileWithRelativePath)

assertThat(findingsForRelativePath).isEmpty()

val ktFileWithFullPath = compileContentForTest(source, createPath("src/com/example/foo/bar/File.kt"))
val findingsForFullPath = InvalidPackageDeclaration(config).lint(ktFileWithFullPath)

assertThat(findingsForFullPath).isEmpty()
}

it("should report if root package is missing") {
val source = """
package foo.bar
class C
"""

val ktFile = compileContentForTest(source, createPath("src/foo/bar/File.kt"))
val findings = InvalidPackageDeclaration(config).lint(ktFile)

assertThat(findings).hasSize(1)
}
}
}
})

Expand Down

0 comments on commit de65436

Please sign in to comment.