Repository: awelzel/flake8-gl-codeclimate

Issue:
Fix relative file path
Thanks for this great utility. We've been using it for several months.

I noticed today that the reported violations do not show up in the diff view on a merge request (it's an Ultimate feature). The reason seems to be that the relative file path starts with `./` whereas GitLab seems to expect it not to start with that (see [docs](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implementing-a-custom-tool)).

I did a test by removing those as follows in our pipeline:

```shell
flake8 --format gl-codeclimate | python -c "import sys; import json; lines = [line.replace('./', '') for line in sys.stdin]; print(json.dumps(json.loads('\n'.join(lines)), indent='\t'));" > gl-code-quality-report.json
```

And GitLab successfully showed it in the diff after.

Happy to contribute a PR but might need a little pointer in how to achieve this. It's not immediately clear to me what type `v` and `v.filename` are.

Comments:

Patch:
diff --git a/flake8_gl_codeclimate/__init__.py b/flake8_gl_codeclimate/__init__.py
index 6ef76ba..3f4ac5d 100644
--- a/flake8_gl_codeclimate/__init__.py
+++ b/flake8_gl_codeclimate/__init__.py
@@ -115,7 +115,7 @@ class GitlabCodeClimateFormatter(BaseFormatter):
             # issue, including deeper explanations and links to other resources.
             "categories": cls._guess_categories(v),
             "location": {
-                "path": v.filename,
+                "path": v.filename[2:] if v.filename.startswith("./") else v.filename,
                 "lines": {
                     "begin": v.line_number,
                     "end": v.line_number,


Test patch:
diff --git a/tests/test_formatter.py b/tests/test_formatter.py
index a558a1a..d70df44 100644
--- a/tests/test_formatter.py
+++ b/tests/test_formatter.py
@@ -20,7 +20,7 @@ class TestGitlabCodeClimateFormatter(unittest.TestCase):
         self.formatter = GitlabCodeClimateFormatter(self.options)
         self.error1 = Violation(
             code="E302",
-            filename="examples/hello-world.py",
+            filename="./examples/hello-world.py",
             line_number=23,
             column_number=None,
             text="expected 2 blank lines, found 1",
@@ -29,7 +29,7 @@ class TestGitlabCodeClimateFormatter(unittest.TestCase):
 
         self.error2 = Violation(
             code="X111",  # unknown
-            filename="examples/unknown.py",
+            filename="./examples/unknown.py",
             line_number=99,
             column_number=None,
             text="Some extension produced this.",
@@ -38,7 +38,7 @@ class TestGitlabCodeClimateFormatter(unittest.TestCase):
 
         self.logging_error = Violation(
             code="G001",  # This is coming from flake8-logging-format
-            filename="examples/logging-format.py",
+            filename="./examples/logging-format.py",
             line_number=4,
             column_number=None,
             text="Logging statement uses string.format()",
@@ -47,7 +47,7 @@ class TestGitlabCodeClimateFormatter(unittest.TestCase):
 
         self.complexity_error = Violation(
             code="C901",  # This is coming from flake8-logging-format
-            filename="examples/complex-code.py",
+            filename="./examples/complex-code.py",
             line_number=42,
             column_number=None,
             text="Something is too complex",
@@ -141,3 +141,25 @@ class TestGitlabCodeClimateFormatter(unittest.TestCase):
         self.assertEqual("bandit", violations[0]["check_name"])
         self.assertEqual(["Security"], violations[0]["categories"])
         self.assertEqual("critical", violations[0]["severity"])
+
+    def test_error_filepath_with_prefix(self):
+        self.formatter.start()
+        self.formatter.handle(self.security_error)
+        self.formatter.stop()
+
+        with open(self.options.output_file) as fp:
+            violations = json.load(fp)
+
+        self.assertEqual(1, len(violations))
+        self.assertEqual("examples/insecure-code.py", violations[0]["location"]["path"])
+
+    def test_error_filepath(self):
+        self.formatter.start()
+        self.formatter.handle(self.error1)
+        self.formatter.stop()
+
+        with open(self.options.output_file) as fp:
+            violations = json.load(fp)
+
+        self.assertEqual(1, len(violations))
+        self.assertEqual("examples/hello-world.py", violations[0]["location"]["path"])