diff --git a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NamingConventionViolation.kt b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NamingConventionViolation.kt index c9e69d8d827..60852fa56cd 100644 --- a/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NamingConventionViolation.kt +++ b/detekt-rules/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NamingConventionViolation.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtObjectDeclaration +import org.jetbrains.kotlin.psi.KtPackageDirective import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtVariableDeclaration import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType @@ -33,6 +34,15 @@ class NamingConventionViolation(config: Config = Config.empty) : Rule(config) { private val methodPattern = Regex(valueOrDefault(METHOD_PATTERN, "^[a-z$][a-zA-Z$0-9]*$")) private val classPattern = Regex(valueOrDefault(CLASS_PATTERN, "^[A-Z$][a-zA-Z$]*$")) private val enumEntryPattern = Regex(valueOrDefault(ENUM_PATTERN, "^[A-Z$][A-Z_$]*$")) + private val packagePattern = Regex(valueOrDefault(PACKAGE_PATTERN, "^[a-z]+(\\.[a-z][a-z0-9]*)*$")) + + override fun visitPackageDirective(directive: KtPackageDirective, data: Void?): Void? { + val name = directive.qualifiedName + if (name.isNotEmpty() && !name.matches(packagePattern)) { + report(CodeSmell(issue, Entity.from(directive))) + } + return null + } override fun visitNamedDeclaration(declaration: KtNamedDeclaration) { if (declaration.nameAsSafeName.isSpecial) return @@ -84,6 +94,7 @@ class NamingConventionViolation(config: Config = Config.empty) : Rule(config) { const val METHOD_PATTERN = "methodPattern" const val CLASS_PATTERN = "classPattern" const val ENUM_PATTERN = "enumEntryPattern" + const val PACKAGE_PATTERN = "packagePattern" } } diff --git a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/NamingConventionViolationSpec.kt b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/NamingConventionViolationSpec.kt index ddc6d59197a..abd9cb0d566 100644 --- a/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/NamingConventionViolationSpec.kt +++ b/detekt-rules/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/NamingConventionViolationSpec.kt @@ -46,6 +46,26 @@ class NamingConventionTest { )).hasSize(0) } + @Test + fun upperCasePackageDirectiveName() { + assertThat(NamingConventionViolation().lint("package FOO.BAR")).hasSize(1) + } + + @Test + fun upperCamelCasePackageDirectiveName() { + assertThat(NamingConventionViolation().lint("package Foo.Bar")).hasSize(1) + } + + @Test + fun camelCasePackageDirectiveName() { + assertThat(NamingConventionViolation().lint("package fOO.bAR")).hasSize(1) + } + + @Test + fun correctPackageDirectiveName() { + assertThat(NamingConventionViolation().lint("package foo.bar")).hasSize(0) + } + @Test fun uppercaseAndUnderscoreAreAllowedLowercaseNotForEnumEntries() { val lint = NamingConventionViolation().lint(