nbadal / ktlint-intellij-plugin

Ktlint plugin for IntelliJ IDEA + Android Studio
MIT License
157 stars 23 forks source link

Rules from Compose ruleset are not (properly) executed #425

Closed chrimaeon closed 8 months ago

chrimaeon commented 8 months ago

When applying a custom lint rule via a jar from the settings, the plugin does not apply custom config from .editconfig.

Use case: Applying the custom Compose rules from https://github.com/mrmans0n/compose-rules and then enabling ktlint_function_naming_ignore_when_annotated_with=Composable from the local .editorconfig does not disable the "ktlint:standard:function-naming" "error" in the IDE.

paul-dingemans commented 8 months ago

Rule id ktlint_function_naming_ignore_when_annotated_with is not complete. It should consist of 3 parts. First part is ktlint. Third part is the id of the rule within its ruleset. In your case that is most likely function_naming_ignore_when_annotated_with, but normally this is written in kebab case (function-naming-ignore-when-annotated-with). You are missing the second part, which is the id of the ruleset. Based on https://github.com/mrmans0n/compose-rules/blob/5edba09c8718a6a0dc387371d7e276ac9115b8dd/rules/ktlint/src/main/kotlin/io/nlopez/compose/rules/ktlint/ComposeRuleSetProvider.kt#L38, I would say that you need to use compose.

So try ktlint_compose_function-naming-ignore-when-annotated-with. I could however not locate any rule in the compose ruleset with id function-naming-ignore-when-annotated-with. So please at the compose project for the rule-id if it does not work.

chrimaeon commented 8 months ago

it's actually a config from ktlint

https://github.com/pinterest/ktlint/blob/master/CHANGELOG.md#-features-1

and it works when running ktlint from the command line.

it was your PR 🙂 https://github.com/pinterest/ktlint/pull/2275

paul-dingemans commented 8 months ago

Lol, I totally forgot about that already. Could it be that you still are running version '0.13.0' of the plugin? That one uses an old ktlint version (0.48).

New version of plugin is on its way.

chrimaeon commented 8 months ago

no, I downloaded the 0.20.0-beta-6 from the beta channel.

paul-dingemans commented 8 months ago

Most likely you are seeing a violation of a default inspection of IntelliJ. Ktlint can not disable those inspections.

In 'Problems' you can see that the violations do not contain a reference to a ktlint rule. Screenshot 2023-12-27 at 12 18 55

Also when you choose a quick fix for the violation, you can go to the inspections page and disable the inspection. Screenshot 2023-12-27 at 12 19 14

chrimaeon commented 8 months ago

no its a standard:function-naming from ktlint

image
chrimaeon commented 8 months ago

And after updating to 0.20.0 I don't see any "warnings"/"errors" for a custom rule set in the IDE. formatting works fine but it does not show any ktlint related issues that are shown using the CLI.

Also the idea.log does not show any outputs anymore - are they disabled in this release?

chrimaeon commented 8 months ago
Screenshot 2023-12-27 at 13 22 39
paul-dingemans commented 8 months ago

As user of the beta version you might need to re-enable the plugin in the preferences page of ktlint. Logging has indeed been disabled, but can be enabled again by setting environment variable KTLINT_PLUGIN_LOG_TO_STDOUT=TRUE.

Please also post the code snippet as code (jnstead of image) as well as your .editorconfig.

chrimaeon commented 8 months ago

Post.kt

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

@Composable
fun Post() {
    Text("foo")
}

.editorconfig

root = true
[*.{kt,kts}]
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma_on_call_site = false
ktlint_function_naming_ignore_when_annotated_with=Composable

CLI error

/opt/homebrew/bin/ktlint -F -R <path>/scripts/ktlint-compose-0.3.8-all.jar .../Post.kt
<path>/Post.kt:11:5: This @Composable function emits content but doesn't have a modifier parameter.

See https://mrmans0n.github.io/compose-rules/rules/#when-should-i-expose-modifier-parameters for more information. (compose:modifier-missing-check)

Summary error count (descending) by rule:
  compose:modifier-missing-check: 1

Process finished with exit code 1

ktlint-plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="KtLint plugin">
    <ktlintMode>DISTRACT_FREE</ktlintMode>
    <externalJarPaths>
      <list>
        <option value="$PROJECT_DIR$/scripts/ktlint-compose-0.3.8-all.jar" />
      </list>
    </externalJarPaths>
  </component>
</project>
paul-dingemans commented 8 months ago

I have located a bug that might explain above. After adding or modifying the external ruleset that have to be run, the internal state of the plugin is not updated correctly. Can you restart you IDEA to see whether this resolves the problem?

chrimaeon commented 8 months ago

Did that couple of times already. Re-install, disable, changing config - all if these don't show any changes.

Do you happen to know how Android Studio/IDEA would catch up the KTLINT_PLUGIN_LOG_TO_STDOUT=TRUE. I export it in my .zshrc but still no output in the logs.

started it from the command line. it shows logs now.

chrimaeon commented 8 months ago

looks like the custom rule is at least loaded:

2023-12-28 11:56:18,540 [  16402]   INFO - STDOUT - Loaded 1 providers from ktlint jars
2023-12-28 11:56:18,570 [  16432]   INFO - STDOUT - Loaded 1 custom ruleset providers from file:/Users/christian/AndroidStudioProjects/phonews-android/scripts/ktlint-compose-0.3.8-all.jar

but no lint erros are showing up.

2023-12-28 12:00:20,062 [ 257924]   INFO - STDOUT - Finished ktlintFormat on file 'Post.kt' triggered by 'KtlintAnnotator' successfully
2023-12-28 12:00:20,456 [ 258318]   INFO - STDOUT - Annotator: KtlintAnnotatorUserData(modificationTimestamp=2146, lintErrors=[], displayAllKtlintViolations=false)
2023-12-28 12:00:20,486 [ 258348]   INFO - STDOUT - Start ktlintFormat on file 'Post.kt' triggered by 'KtlintActionOnSave'
2023-12-28 12:00:20,562 [ 258424]   INFO - STDOUT - Finished ktlintFormat on file 'Post.kt' 
paul-dingemans commented 8 months ago

I can confirm that the Compose rules do not work in the plugin. The rules are properly provided to the KtLintRuleEngine, which also calls the specific rule. Unfortunately, I loose track when debuging the actual call to the Compose rule.

To verify that custom ruleset work in the plugin, I have created a new custom ruleset with the no-var rule. When running with Ktlint CLI:

$ ktlint-1.1.0 --relative -R ~/Downloads/ktlint-compose-0.3.8-all.jar -R ~/Downloads/ktlint-custom-ruleset-example.jar
12:26:23.254 [main] INFO com.pinterest.ktlint.cli.internal.KtlintCommandLine -- Enable default patterns [**/*.kt, **/*.kts]
src/main/kotlin/Foo.kt:4:5: This @Composable function emits content but doesn't have a modifier parameter.

See https://mrmans0n.github.io/compose-rules/rules/#when-should-i-expose-modifier-parameters for more information. (compose:modifier-missing-check)
src/main/kotlin/Foo.kt:8:5: Function name should start with a lowercase letter (except factory methods) and use camel case (standard:function-naming)
src/main/kotlin/Foo.kt:11:5: Unexpected var, use val instead (custom-rule-set-id:no-var)

Summary error count (descending) by rule:
  compose:modifier-missing-check: 1
  custom-rule-set-id:no-var: 1
  standard:function-naming: 1

The plugin reports: Screenshot 2023-12-29 at 12 30 55

paul-dingemans commented 8 months ago

With 0.3.9-SNAPSHOT version of the compose rules, this problem is fixed in https://github.com/mrmans0n/compose-rules/issues/176. No further action needed in ktlint-intellij-plugin.

paul-dingemans commented 7 months ago

Problem needs another fix in compose rules. See https://github.com/mrmans0n/compose-rules/issues/190