detekt.yml file is not able to identify my custom rules

270 views Asked by At

I'm using detekt to add lint to my project for the first time, I followed the instructions from different articles online. But now the after finishing all the steps, when I add my custom rule to detekt.yml file the complier gives me an error:

Property 'mycustom-rule' is misspelled or does not exist.

These are my custom rules, which I've found online:

class CustomRuleSetProvider : RuleSetProvider {
  override val ruleSetId: String = "synthetic-import-rule"
  override fun instance(config: Config): RuleSet = RuleSet(ruleSetId, listOf(NoSyntheticImportRule()))
}

class NoSyntheticImportRule : Rule() {
  //2
  override val issue = Issue("NoSyntheticImport",
    Severity.Maintainability, "Don’t import Kotlin Synthetics "
            + "as it is already deprecated.", Debt.TWENTY_MINS)
  //3
  override fun visitImportDirective(
    importDirective: KtImportDirective
  ) {
    val import = importDirective.importPath?.pathStr
    if (import?.contains("androidx.activity.R") == true) {
      report(
        CodeSmell(issue, Entity.from(importDirective),
          "Importing '$import' which is a Kotlin Synthetics import.")
      )
    }
  }
}

I also created a file with the name of io.gitlab.arturbosch.detekt.api.RuleSetProvider and added this line:

> com.example.testlint.rules.CustomRuleSetProvider

my detekt.yml file:

synthetic-import-rule:
  active: true
  NoSyntheticImportRule:
    active: true

What could be causing the problem?

edit:

When I enable debug, I get the registered rules, and my custom rule set is not among them:

    Registered rule sets: 

io.gitlab.arturbosch.detekt.rules.complexity.ComplexityProvider@69296a0b
io.gitlab.arturbosch.detekt.rules.coroutines.CoroutinesProvider@49ba4fa3
io.gitlab.arturbosch.detekt.rules.documentation.CommentSmellProvider@5554065d
io.gitlab.arturbosch.detekt.rules.empty.EmptyCodeProvider@13d11c5f
io.gitlab.arturbosch.detekt.rules.bugs.PotentialBugProvider@310a551c
io.gitlab.arturbosch.detekt.rules.exceptions.ExceptionsProvider@2a56d3c9
io.gitlab.arturbosch.detekt.rules.naming.NamingProvider@5fc55e30
io.gitlab.arturbosch.detekt.rules.performance.PerformanceProvider@446d9273
io.gitlab.arturbosch.detekt.rules.style.StyleGuideProvider@272c8d57
1

There are 1 answers

3
VonC On

Make sure the path specified in io.gitlab.arturbosch.detekt.api.RuleSetProvider is correct and matches the package structure of your CustomRuleSetProvider.
The file should be located in the src/main/resources/META-INF/services directory of your module (as mentioned in "Extending detekt"). The file should contain the fully qualified name of your CustomRuleSetProvider class. For example, if your class is in the package com.example.testlint.rules, the content of the file should be:

com.example.testlint.rules.CustomRuleSetProvider

Make sure that your custom rules are compiled and included in the build path. If you are using Gradle, you may need to adjust your build script to include these classes. That will look something like this (adjust the path and version accordingly):

dependencies {
    detektPlugins "your.package:custom-rules-module:1.0.0"
}

In your detekt.yml, the rule names should exactly match the ones you have defined in your Kotlin code.
If your rule is named NoSyntheticImportRule in Kotlin, it should be the same in detekt.yml.

synthetic-import-rule:
active: true
NoSyntheticImportRule:
    active: true

In your build script (e.g., build.gradle), specify the Detekt version, to confirm you are using the latest version:

dependencies {
    detekt "io.gitlab.arturbosch.detekt:detekt-cli:1.23.3" // Use the latest version
}

To troubleshoot, you could add some logging or breakpoints in your custom rule provider to see if it is being loaded at all.


The OP Roony confirms in the comments:

Actually, my project consists of multiple modules, and I thought that I need to include the line related to Detekt plugins only inside the modules that I want to use Detekt inside.

The problem of detecting the custom provider is solved after including the <line in all the other modules.
But still, my rules are not being detected, and my build is successful even when violating my custom rules.

Everything works fine now, I only have to delete the jar file every time I make changes to the rules

The main challenge now is making sure that changes to your custom rules are recognized without needing to delete the JAR file each time. That is a common issue in multi-module projects, where build artifacts can become out-of-sync with source changes.

In a multi-module project, especially when using Gradle, it is essential to make sure your build system is correctly tracking changes to your custom rules. You can configure your build script to automatically rebuild the JAR file when changes are detected in the source code. That can be achieved using Gradle's up-to-date checks (aka incremental build).

Modify your Gradle task that packages your custom rules into a JAR. That task should depend on your source code, so any changes trigger a rebuild.

task customRuleJar(type: Jar) {
    from sourceSets.main.output
    dependsOn classes
}

By correctly configuring inputs and outputs for your tasks, Gradle can intelligently determine which parts of your project need to be rebuilt. Documentation on Gradle's incremental builds can provide more insights on this.

If you are using a CI/CD pipeline, make sure it is configured to rebuild all relevant modules and their dependencies when changes are detected.

Also, make sure your Detekt Gradle task depends on the task that builds your custom rules JAR. That ensures the JAR is always up-to-date when Detekt runs.

tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
    dependsOn customRuleJar
}

For local development, consider setting up a Gradle task or a script that cleans and rebuilds your custom rules before running Detekt. That can be a simple command that you run before checking for lint errors.

Verify in your detekt.yml configuration that your custom rules are marked as active: true. Inactive rules will not be executed, even if they are correctly detected.