Ktlint: Easy way to disable specific rules?

Created on 14 Jan 2017  路  13Comments  路  Source: pinterest/ktlint

Is there an easy way to disable specific rules?

I'm testing ktlint (inside spotless) on some random kotlin repos, and wildcard imports seem to be pretty common, and thus a barrier to initial adoption.

Most helpful comment

Thanks for the workaround!

FWIW, I agree 100% on wildcard imports. But for adoption, I think it's critical to support "tightening clamp" operation. A way to apply the plugin and turn off rules until it works, and fix things over time until you can have the clamp all-the-way tight. Greenfield development doesn't happen that often - the dominant use case is an existing project with lots of code already written and inconsistent formatting.

All 13 comments

Hi Ned.

There is no way to disable rules in ktlint (apart from https://github.com/shyiko/ktlint#how-do-i-suppress-an-error). This is intentional.

Wildcard imports are discouraged for variety of reasons (it makes it hard to tell where the class is actually coming from (which compilations things both for humans and static analysis tools); creates an incentive for bikesheding in form of "what are the rules for using wild-card imports? how many classes are allowed to be imported before they should be collapsed into *?"; etc).

"Explicit is better than implicit." Zen Of Python.

Having said that, I'm pondering the idea of introducing "auto-correction" mode which would only include rules that can be... well, auto-corrected. In other words, you would never have to fix anything by hand. Ever. This would, however, mean that "No wildcard import" rule have to be disabled when "auto-correction" mode is on).

Anyway, until that happens it's easy to disable rules on your side considering that spotless is using API instead of CLI entry point. One way would be to filter out any rules you're not interested in:

RuleSet standardRuleSet = new StandardRuleSetProvider().get();
RuleSet ruleSet = new RuleSet(
    "semi-standard",
    Stream.of(standardRuleSet.getRules())
         // https://github.com/shyiko/ktlint/blob/master/ktlint-ruleset-standard/src/main/kotlin/com/gihub/shyiko/ktlint/ruleset/standard/NoUnusedImportsRule.kt#L9
        .filter(rule -> !"no-wildcard-imports".equals(rule.getId()))
        .toArray(Rule[]::new)
);

Another one, would be to change https://github.com/shyiko/ktlint/issues/20#issuecomment-271730398 a little bit to only warn (or even suppress completely) LintErrors with specific ruleIds:

output = KtLint.INSTANCE.format(
    input, 
    Collections.singletonList(new StandardRuleSetProvider().get()),
    (lintError, corrected) -> {
        if (!corrected) {
            // https://github.com/shyiko/ktlint/blob/master/ktlint-ruleset-standard/src/main/kotlin/com/gihub/shyiko/ktlint/ruleset/standard/NoUnusedImportsRule.kt#L9
            if ("no-wildcard-imports".equals(lintError.getRuleId())) {
                System.err.println("WARN: " + lintError.getDetail());
            } else {
                throw new RuntimeException(lintError.getDetail());
            }
        }
        return null;
    });

But then again, I'd not recommend doing this. Intellij IDEA allows you to fix all style violations (including * imports) across all the classes with a single stroke of "Ctrl + Alt + L" so unless users want to paint bikeshed in a different color it's hardly a problem. ktlint contains no rules that cannot be fixed automatically by Intellij formatter.

Thanks for the workaround!

FWIW, I agree 100% on wildcard imports. But for adoption, I think it's critical to support "tightening clamp" operation. A way to apply the plugin and turn off rules until it works, and fix things over time until you can have the clamp all-the-way tight. Greenfield development doesn't happen that often - the dominant use case is an existing project with lots of code already written and inconsistent formatting.

Hi,

@shyiko @nedtwigg I'm looking to disable a rule as well (wildcard imports) could you explain me where should I add the code snippets provided here above

Thank you very much :)

@EGI-OCTO right now the only way is https://github.com/shyiko/ktlint#how-do-i-suppress-an-error. Snippets above are meant for projects including ktlint through API.

Hi @shyiko, thank you for your answer. I would like to use Ktlint through Spotless (as a Gradle Plugin) so I hoped "Anyway, until that happens it's easy to disable rules on your side considering that spotless is using API instead of CLI entry point." applied to me too...

I respectfully disagree with the conclusion that such linter does not need a way to disable specific rules easily. Adoption of style in legacy code is not easy when the linter reports ~1000 occurrence of line-length limit violation, which is not automatically formattable. We are now stuck on an earlier version of ktlint which couldn't detect long lines. Eventually we'll sort out the long line issues, but until that happens (it's a long task to do) we cannot lint our code properly.

Edit: I tried IntelliJ's auto-format, but that couldn't fix long lines either for me.

@TamasBarta set max_line_length=120 (adjust the number if needed) in .editorconfig (ktlint won't check line length if max_line_length is <= 0).

@shyiko, thanks for the tip. I set it to off earlier in combination with --android switch, when running ktlint, and that didn't work, so I thought --android completely overrides this. I tried your suggestion, and it works. Other legacy format issues were solved by the format feature, so now all is fine. Thanks!

@TamasBarta great. I'll make sure "max_line_length=off" is supported in https://github.com/shyiko/ktlint/issues/292.

I was a bit fast stating all is ok now, because if I set max_line_length=0, I get a ton of Missing newline before ")". That's probably because it tries to keep lines below 0 length. Also it destroys auto-format of both command-line ktlint, and IntelliJ, and the ruler in IntelliJ.

I still believe some mechanism should be available to allow slow, but steady migrations to new style.

Hi, detekt maintainer here.

If you use the detekt-formatting ruleset, which wrapps KtLint rules, you can disable specific rules -> https://arturbosch.github.io/detekt/formatting.html.
Feel free to reach to us on the kotlin slack or the github project if you need further support in doing this.

@shyiko so is there no way to filter rules out using spotless? The only thing they expose is a user map. I have a lot of code that was converted from Java, and therefore have javadocs. The parameter docs are all lined up, and ktlint strips all multi spaces, which messes up the formatting.

For those like me who scoured the internet looking for this, KTLint now supports disabling individual rules in editorconfig.
https://github.com/pinterest/ktlint#editorconfig

Was this page helpful?
0 / 5 - 0 ratings