Skip to content
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

Rule with id 'RuleId(value=standard:string-template-indent)' requires rule with id 'RuleId(value=standard:multiline-expression-wrapping)' to be loaded #2378

Closed
vanniktech opened this issue Nov 25, 2023 · 9 comments

Comments

@vanniktech
Copy link
Contributor

When using the following configuration:

[*.{kt,kts}]
ktlint_code_style=intellij_idea
indent_size=2
continuation_indent_size=2
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
insert_final_newline=true
ktlint_standard_annotation=disabled
ktlint_standard_max-line-length=disabled
ktlint_standard_filename=disabled
ktlint_standard_discouraged-comment-location=disabled
ktlint_standard_class-signature=disabled
ktlint_standard_string-template-indent=enabled
ktlint_standard_spacing-between-declarations-with-annotations=disabled
ktlint_experimental=enabled

I'm getting:

  - Rule with id 'RuleId(value=standard:string-template-indent)' requires rule with id 'RuleId(value=standard:multiline-expression-wrapping)' to be loaded
        at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.parallel(KtlintCommandLine.kt:708)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.parallel$default(KtlintCommandLine.kt:671)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.lintFiles(KtlintCommandLine.kt:443)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.run(KtlintCommandLine.kt:323)
        at com.pinterest.ktlint.Main.main(Main.kt:35)

However I do not want to enable the multiline-expression-wrapping rule. Would it be possible to also separate them?

@paul-dingemans
Copy link
Collaborator

From #2338:

The multiline-expression-wrapping is required for string-template-indent to handle code like:

val foo = """
    some text
   """.trimIndent()

The string-template-indent has no idea how to calculate the identation of a multiline raw string for which the opening quotes are not aligned with the closing quotes.

Next to above, the multiline-expression-wrapping contains other logic like preventing that a multiline string template after a return is wrapped as that would result in a compilation error. This logic has to executed before the basic indent rule is executed, which in turn needs to be executed before the string-template-indent.

@paul-dingemans paul-dingemans closed this as not planned Won't fix, can't repro, duplicate, stale Nov 26, 2023
@vanniktech
Copy link
Contributor Author

Isn't it possible to reuse the logic without the rule being enabled? I feel like template strings deserve the extra treating.

@paul-dingemans
Copy link
Collaborator

From an architectural viewpoint I do not want rules to call methods in other rules. Also extracting logic from Rule classes to other utility classes, or using shared superclasses is not something that I want to do.

@vanniktech
Copy link
Contributor Author

Alright, then I guess the user experience will just suffer from this.

@jeremymailen
Copy link
Contributor

I sympathize with @paul-dingemans viewpoint about the challenges these choices present both technically and conceptually. On a smaller scale, I've experienced similar tradeoffs managing my open source project and there have been, frankly, features I've avoided which users desire, but I my intuition tells me would create a lot of tangles and headaches.

Some questions worth asking though that might be helpful for perspective:

  1. Are the rule dependencies there for a user reason (otherwise it would lead to inconsistency or trouble) or a technical reason (makes the technical design harder)?
  2. Are there precedents in other linting frameworks (tslint / eslint / pylint / etc) for having lint rule application be dependent on the presence of another rule or generally do they allow rules to be used a la carte?

@paul-dingemans
Copy link
Collaborator

  1. Are the rule dependencies there for a user reason (otherwise it would lead to inconsistency or trouble) or a technical reason (makes the technical design harder)?

Rule dependencies have been introduced to avoid inconsistenties. In several occasions conflicts between rules were reported where two different rules did not agree about the way how an element had to be formatted. Some of those problems were caused by a non-deterministic order in which the rules were executed. Rule ordering can not be hard coded in ktlint as API Consumers determine which rules are executed. Also, there is a need to support third party rule sets which can have depencies on standard rules.

A non-deterministic order of executing the rules, can lead to endless loops where formatting of element would alternates between the different ways of formatting. With the rule dependencies it can be made explicit that a rule can only be executed after another specific rules has been executed before.

From a technical perspective, a rule dependency can also be used to 'solve' the problem of repeating the same/similar logic in multiple rules. Although ktlint allows rules to be disabled on discretion of the user, the intended way of using ktlint is to use the default configuration (e.g. a certain code style). Tuning the ktlint configuration violates the 'anti-bikeshedding` principle of ktlint. If enabling/disabling some rules works for a given project than that is okay. But, I cannot support that any random permutation of rules works.

  1. Are there precedents in other linting frameworks (tslint / eslint / pylint / etc) for having lint rule application be dependent on the presence of another rule or generally do they allow rules to be used a la carte?

I don't know. And to be honest, I don't really care about that as well.

@vanniktech
Copy link
Contributor Author

Then what was the motivation for #2371?

@jeremymailen
Copy link
Contributor

Because we're beginning the bike shedding process of deciding which rules ought to be dependent on others.

@vanniktech
Copy link
Contributor Author

Alright then I'm hoping this will also be considered. 🤞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants