fix(kotlin): parse ktlint --reporter=json output correctly - #680
Open
violinyanev wants to merge 1 commit into
Open
fix(kotlin): parse ktlint --reporter=json output correctly#680violinyanev wants to merge 1 commit into
violinyanev wants to merge 1 commit into
Conversation
The kotlin plugin declared the ktlint tool with fmt="json", which maps
to the generic parse_json parser. That parser expects a flat list of
objects with top-level file/line/message keys (like most linters), but
ktlint's --reporter=json output nests violations per file:
[{"file": ..., "errors": [{"line", "column", "message", "rule"}]}]
Because parse_json looked for top-level "line"/"message" keys that
don't exist on ktlint's file objects, every entry was silently dropped,
so ktlint_violation always produced zero entries despite ktlint exiting
non-zero with real violations. This surfaced as a permanent
'Coverage reduced (ktlint_violation): ... tool_failed_unparsed_output'
warning and meant Kotlin projects never got real ktlint findings from
desloppify.
Add a dedicated parse_ktlint parser that understands the nested
file/errors shape, register it in PARSERS, and switch the kotlin plugin
to fmt="ktlint". Verified against a real multi-module Kotlin project:
ktlint_violation coverage is no longer reduced and the mechanical
'Code quality' score reflects real lint findings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The kotlin plugin declares its ktlint tool with
fmt=\"json\", which maps tothe generic
parse_jsonparser. That parser expects a flat list ofobjects with top-level
file/line/messagekeys (the shape most lintersuse), but
ktlint --reporter=jsonnests violations per file:[ { "file": "src/main/Foo.kt", "errors": [ {"line": 10, "column": 5, "message": "Newline expected", "rule": "standard:class-signature"} ] } ]Since
parse_jsonlooks for a top-level"line"/"message"key thatdoesn't exist on these file objects, every entry is silently dropped. The
result:
ktlint_violationalways returns zero entries even when ktlintexits non-zero with real violations, and the scan reports a permanent
warning — so Kotlin projects never actually get ktlint findings out of
desloppify, regardless of whether ktlint is installed and working.
Repro (any Kotlin project with ktlint on PATH and at least one lint
violation):
Fix
Add a dedicated
parse_ktlintparser that understands ktlint's nestedfile/errorsshape (one entry per error, with the rule id appended to themessage), register it in
PARSERS, and switch the kotlin plugin's tool specto
fmt=\"ktlint\"instead of the generic\"json\".Verified against a real multi-module Kotlin (Android) project:
ktlint_violationcoverage reduced, mechanical "Code quality"score understated (e.g. 60.7%).
desloppify next/show, and "Code quality" score reflects them (e.g. 90.9%).Added unit tests (
TestParseKtlint) covering rule-suffix formatting,multiple files/errors, files with no errors, empty output, and invalid
JSON. Full test suite passes locally (
5200 passed, 1 skipped).