Forked from caryan/pylint_to_gitlab_codeclimate.py
Last active
January 31, 2022 22:34
-
-
Save quanterium/53a277cab4136963374cf703dfe399bd to your computer and use it in GitHub Desktop.
Convert pylint output to simplified CodeClimate JSON suitable for Gitlab Code Quality checks
This file contains 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
import hashlib | |
import json | |
import sys | |
from typing import TYPE_CHECKING, Optional | |
from pylint.interfaces import IReporter | |
from pylint.reporters import JSONReporter | |
from pylint.lint import Run | |
from pylint.message import Message | |
if TYPE_CHECKING: | |
from pylint.reporters.ureports.nodes import Section | |
# map pylint categories to CodeClimate severity | |
PYLINT_CATEGORY_TO_SEVERITY = { | |
"fatal": "blocker", | |
"error": "critical", | |
"warning": "major", | |
"refactor": "minor", | |
"convention": "minor", | |
} | |
class GitlabCodeClimateReporter(JSONReporter): | |
""" | |
Custom pylint reporter to convert pylint messages into a reduced CodeClimate JSON report | |
suitable for Gitlab's Code Quality. Only reports `description`, `fingerprint`, `severity`, | |
`location`. | |
See: | |
1. https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html#implementing-a-custom-tool. | |
2. https://github.com/PyCQA/pylint/blob/master/pylint/reporters/json_reporter.py | |
Small portions taken from https://github.com/mercos/codeclimate-pylint where no copyright or | |
license was asserted as of February 2020 | |
""" | |
__implements__ = IReporter | |
name = "gitlabcodeclimate" | |
def display_messages(self, layout: Optional["Section"]) -> None: | |
"""Launch layouts display""" | |
json_dumpable = [ | |
{ | |
"description": msg["description"], | |
"severity": msg["severity"], | |
"location": msg["location"], | |
"fingerprint": msg["fingerprint"] | |
} | |
for msg in self.messages | |
] | |
print(json.dumps(json_dumpable, indent=4), file=self.out) | |
def handle_message(self, msg: Message): | |
""" | |
Convert a pylint Message into a reduced CodeClimate report dictionary and append to the messages list. | |
""" | |
codeclimate_dict = dict() | |
message_lines = self._parse_message(msg.msg).splitlines() | |
codeclimate_dict["description"] = message_lines[0] | |
codeclimate_dict["severity"] = PYLINT_CATEGORY_TO_SEVERITY[msg.category] | |
# gitlab only uses the "lines.begin" version of location | |
codeclimate_dict["location"] = {"path": msg.path, "lines": {"begin": msg.line}} | |
# gitlab needs a fingerprint | |
# hash the issue, filename and line number | |
codeclimate_dict["fingerprint"] = hashlib.sha1( | |
(msg.symbol + msg.path + str(msg.line)).encode() | |
).hexdigest() | |
self.messages.append(codeclimate_dict) | |
def _parse_message(self, msg: str): | |
""" Helper to cleanup the message string. """ | |
while " " in msg: | |
msg = msg.replace(" ", " ") | |
msg = msg.replace('"', "`") | |
msg = msg.replace("\\", "") | |
return msg | |
if __name__ == "__main__": | |
Run(sys.argv[1:], reporter=GitlabCodeClimateReporter()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment