pyright-to-gitlab 1.2.0__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyright-to-gitlab
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Convert Pyright JSON output to GitLab CI/CD format
5
5
  Project-URL: homepage, https://github.com/schollm/pyright-to-gitlab/
6
6
  Project-URL: repository, https://github.com/schollm/pyright-to-gitlab/
@@ -52,12 +52,12 @@ $ pip install pyright-to-gitlab
52
52
  $ pyright . --outputjson | python -m pyright_to_gitlab > code-quality.json
53
53
  ```
54
54
  ### Custom path prefix
55
- The `--prefix` option adds a custom prefix to the file paths in the output. This is
56
- useful if the paths in the pyright output are not relative to the root of the repository.
55
+ The `--prefix` option adds a custom prefix path to the file paths in the output. This is
56
+ useful for mono-repos, where the paths in the pyright output is not the repository root.
57
57
 
58
58
 
59
59
  ```shell
60
- $ pyright . --outputjson | pyright-to-gitlab --prefix my-app/ > code-quality.json
60
+ $ pyright . --outputjson | pyright-to-gitlab --prefix my-app > code-quality.json
61
61
  ```
62
62
 
63
63
  ## Testing
@@ -0,0 +1,6 @@
1
+ pyright_to_gitlab.py,sha256=qqTJVAQ9OS44gj9L4KPpWDTliKNP39vEe27SZfxW_zY,6289
2
+ pyright_to_gitlab-1.3.0.dist-info/METADATA,sha256=Q63XdhBtllH0kPKRUdcul0Y2jUHZVuQSm9AY7P_iDBs,2634
3
+ pyright_to_gitlab-1.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
4
+ pyright_to_gitlab-1.3.0.dist-info/entry_points.txt,sha256=0RnHrvYlZf3zD9BRTVQL564gF_fSuwF5IP13OB18540,61
5
+ pyright_to_gitlab-1.3.0.dist-info/licenses/LICENSE,sha256=tY29-MdtyUNoC3XN4IBzu_jxmb8U82z9UvLkQJuBiJM,1070
6
+ pyright_to_gitlab-1.3.0.dist-info/RECORD,,
pyright_to_gitlab.py CHANGED
@@ -11,25 +11,25 @@ from typing import Literal, TextIO, TypedDict
11
11
 
12
12
 
13
13
  ### Typing for PyRight Issue
14
- class PyrightRangeElement(TypedDict):
14
+ class PyrightRangeElement(TypedDict, total=False):
15
15
  """Pyright Range Element (part of Range)."""
16
16
 
17
17
  line: int
18
18
  character: int
19
19
 
20
20
 
21
- class PyrightRange(TypedDict):
21
+ class PyrightRange(TypedDict, total=False):
22
22
  """Pyright Range (Part of Issue)."""
23
23
 
24
24
  start: PyrightRangeElement
25
25
  end: PyrightRangeElement
26
26
 
27
27
 
28
- class PyrightIssue(TypedDict):
28
+ class PyrightIssue(TypedDict, total=False):
29
29
  """Single Pyright Issue.
30
30
 
31
- Note: 'rule' field is optional in practice but marked as required in type hints.
32
- Runtime code handles this with defensive .get() calls.
31
+ Note: total=False makes all fields optional. Runtime code handles this with
32
+ defensive .get() calls.
33
33
  """
34
34
 
35
35
  file: str
@@ -78,7 +78,7 @@ def _pyright_to_gitlab(input_: TextIO, prefix: str = "") -> str:
78
78
  Line numbers from Pyright are passed through unchanged (0-based per LSP spec).
79
79
  GitLab expects the same format, so no conversion is needed.
80
80
 
81
- :arg prefix: A string to prepend to each file path in the output.
81
+ :arg prefix: A path to prepend to each file path in the output.
82
82
  This is useful if the application is in a subdirectory of the repository.
83
83
  :return: JSON of issues in GitLab Code Quality report format.
84
84
  :raises ValueError: If input is not a JSON object.
@@ -87,6 +87,9 @@ def _pyright_to_gitlab(input_: TextIO, prefix: str = "") -> str:
87
87
  Pyright format at https://github.com/microsoft/pyright/blob/main/docs/command-line.md
88
88
  Gitlab format at https://docs.gitlab.com/ci/testing/code_quality/#code-quality-report-format
89
89
  """
90
+ if prefix and not prefix.endswith("/"):
91
+ prefix += "/"
92
+
90
93
  try:
91
94
  data = json.load(input_)
92
95
  except json.JSONDecodeError as e:
@@ -116,22 +119,22 @@ def _pyright_issue_to_gitlab(issue: PyrightIssue, prefix: str) -> GitlabIssue:
116
119
  :param prefix: The path prefix.
117
120
  :returns: A gitlab single issue.
118
121
  """
119
- start, end = (
120
- issue.get("range", {}).get("start", {}),
121
- issue.get("range", {}).get("end", {}),
122
- )
122
+ range_ = issue.get("range", {})
123
+ start, end = (range_.get("start", {}), range_.get("end", {}))
123
124
  rule = "pyright: " + issue.get("rule", "unknown")
124
- # Unique fingerprint including file path to prevent collisions across files
125
- fp_str = "--".join([issue.get("file", "<anonymous>"), str(start), str(end), rule])
125
+ # Hash input must contain file, location and rule to generate a unique fingerprint.
126
+ # (This takes advantage of stable dict order).
127
+ fingerprint = f"{issue.get('file', '<anonymous>')}--{range_}--{rule}"
126
128
 
127
129
  return GitlabIssue(
128
130
  description=issue.get("message", ""),
131
+ # Map 'error' to 'major', all others, including empty, to 'minor'
129
132
  severity="major" if issue.get("severity") == "error" else "minor",
130
133
  # Any hash function really works, does not have to be cryptographic.
131
- fingerprint=hashlib.sha3_224(fp_str.encode()).hexdigest(),
134
+ fingerprint=_hash(fingerprint),
132
135
  check_name=rule,
133
136
  location=GitlabIssueLocation(
134
- path=f"{prefix}{issue['file']}" if "file" in issue else "<anonymous>",
137
+ path=f"{prefix}{issue.get('file', '<anonymous>')}",
135
138
  positions=GitlabIssuePositions(
136
139
  begin=GitlabIssuePositionLocation(
137
140
  line=start.get("line", 0), column=start.get("character", 0)
@@ -144,7 +147,16 @@ def _pyright_issue_to_gitlab(issue: PyrightIssue, prefix: str) -> GitlabIssue:
144
147
  )
145
148
 
146
149
 
147
- def main() -> None:
150
+ def _hash(data: str) -> str:
151
+ """Generate an (non-secure) hash of the given data string.
152
+
153
+ :param data: The input string to hash.
154
+ :returns: The hexadecimal representation of the MD5 hash.
155
+ """
156
+ return hashlib.new("md5", data.encode(), usedforsecurity=False).hexdigest()
157
+
158
+
159
+ def cli() -> None:
148
160
  """Parse arguments and call the conversion function."""
149
161
  parser = argparse.ArgumentParser(
150
162
  description=textwrap.dedent("""
@@ -178,12 +190,13 @@ def main() -> None:
178
190
  "--prefix",
179
191
  type=str,
180
192
  default="",
181
- help="Prefix to add to each file entry. This can be used if pyright is run"
193
+ help="Prefix path to add to each file entry. This can be used if pyright is run"
182
194
  " from a subdirectory of the repository. (default: empty string)",
183
195
  )
196
+ parser.add_argument("--version", action="version", version="%(prog)s 1.3.0")
184
197
  args = parser.parse_args()
185
198
  args.output.write(_pyright_to_gitlab(input_=args.input, prefix=args.prefix))
186
199
 
187
200
 
188
201
  if __name__ == "__main__": # pragma: no cover
189
- main()
202
+ cli()
@@ -1,6 +0,0 @@
1
- pyright_to_gitlab.py,sha256=6b1sRM7aYWQShpWpAxmz5ANYOZla6-wEOxaZba20f6o,5794
2
- pyright_to_gitlab-1.2.0.dist-info/METADATA,sha256=R__O7qdhzXfc6Vos3LTzr2q-BNceCWCL1LFpBCEdEoQ,2632
3
- pyright_to_gitlab-1.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
4
- pyright_to_gitlab-1.2.0.dist-info/entry_points.txt,sha256=0RnHrvYlZf3zD9BRTVQL564gF_fSuwF5IP13OB18540,61
5
- pyright_to_gitlab-1.2.0.dist-info/licenses/LICENSE,sha256=tY29-MdtyUNoC3XN4IBzu_jxmb8U82z9UvLkQJuBiJM,1070
6
- pyright_to_gitlab-1.2.0.dist-info/RECORD,,