ruff-sync 0.1.6.dev2__py3-none-any.whl → 0.1.6.dev3__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.
- ruff_sync/validation.py +102 -2
- {ruff_sync-0.1.6.dev2.dist-info → ruff_sync-0.1.6.dev3.dist-info}/METADATA +1 -1
- {ruff_sync-0.1.6.dev2.dist-info → ruff_sync-0.1.6.dev3.dist-info}/RECORD +6 -6
- {ruff_sync-0.1.6.dev2.dist-info → ruff_sync-0.1.6.dev3.dist-info}/WHEEL +0 -0
- {ruff_sync-0.1.6.dev2.dist-info → ruff_sync-0.1.6.dev3.dist-info}/entry_points.txt +0 -0
- {ruff_sync-0.1.6.dev2.dist-info → ruff_sync-0.1.6.dev3.dist-info}/licenses/LICENSE.md +0 -0
ruff_sync/validation.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import functools
|
|
6
|
+
import json
|
|
5
7
|
import logging
|
|
6
8
|
import pathlib
|
|
7
9
|
import re
|
|
@@ -109,6 +111,97 @@ def check_python_version_consistency(
|
|
|
109
111
|
return True
|
|
110
112
|
|
|
111
113
|
|
|
114
|
+
_RULE_LIST_KEYS: frozenset[str] = frozenset({"select", "extend-select", "ignore", "extend-ignore"})
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@functools.lru_cache(maxsize=1)
|
|
118
|
+
def _get_deprecated_rule_codes() -> frozenset[str]:
|
|
119
|
+
"""Return the set of deprecated rule codes reported by the installed Ruff version.
|
|
120
|
+
|
|
121
|
+
Returns an empty frozenset if ruff is not found or output cannot be parsed.
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
result = subprocess.run(
|
|
125
|
+
["ruff", "rule", "--all", "--output-format", "json"], # noqa: S607
|
|
126
|
+
capture_output=True,
|
|
127
|
+
text=True,
|
|
128
|
+
timeout=30,
|
|
129
|
+
check=False,
|
|
130
|
+
)
|
|
131
|
+
if result.returncode != 0:
|
|
132
|
+
return frozenset()
|
|
133
|
+
rules = json.loads(result.stdout)
|
|
134
|
+
return frozenset(r["code"] for r in rules if r.get("deprecated") is True)
|
|
135
|
+
except (
|
|
136
|
+
FileNotFoundError,
|
|
137
|
+
subprocess.TimeoutExpired,
|
|
138
|
+
json.JSONDecodeError,
|
|
139
|
+
KeyError,
|
|
140
|
+
TypeError,
|
|
141
|
+
):
|
|
142
|
+
return frozenset()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def check_deprecated_rules(
|
|
146
|
+
doc: TOMLDocument,
|
|
147
|
+
is_ruff_toml: bool = False,
|
|
148
|
+
strict: bool = False,
|
|
149
|
+
_deprecated_codes: frozenset[str] | None = None,
|
|
150
|
+
exclude: Iterable[str] = (),
|
|
151
|
+
) -> bool:
|
|
152
|
+
"""Warn if the merged config references any deprecated Ruff rules.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
doc: The merged TOML document.
|
|
156
|
+
is_ruff_toml: True if the document is a standalone ruff.toml.
|
|
157
|
+
strict: If True, treat deprecated rules as a failure.
|
|
158
|
+
_deprecated_codes: Optional set of deprecated codes to use (for testing).
|
|
159
|
+
exclude: List of keys excluded from the ruff configuration.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
True if no deprecated rules are found, or if strict=False.
|
|
163
|
+
False if strict=True and deprecated rules are found.
|
|
164
|
+
"""
|
|
165
|
+
deprecated_codes = (
|
|
166
|
+
_deprecated_codes if _deprecated_codes is not None else _get_deprecated_rule_codes()
|
|
167
|
+
)
|
|
168
|
+
if not deprecated_codes:
|
|
169
|
+
return True # Nothing to check (ruff not found or returned no deprecated rules)
|
|
170
|
+
|
|
171
|
+
if is_ruff_toml:
|
|
172
|
+
lint_section = doc.get("lint", {})
|
|
173
|
+
else:
|
|
174
|
+
lint_section = doc.get("tool", {}).get("ruff", {}).get("lint", {})
|
|
175
|
+
|
|
176
|
+
if not isinstance(lint_section, dict):
|
|
177
|
+
return True
|
|
178
|
+
|
|
179
|
+
found_deprecated = False
|
|
180
|
+
for key in _RULE_LIST_KEYS:
|
|
181
|
+
full_key = f"lint.{key}" if is_ruff_toml else f"tool.ruff.lint.{key}"
|
|
182
|
+
if key in exclude or full_key in exclude:
|
|
183
|
+
continue
|
|
184
|
+
|
|
185
|
+
rule_list = lint_section.get(key, [])
|
|
186
|
+
if not isinstance(rule_list, list):
|
|
187
|
+
continue
|
|
188
|
+
for rule_code in rule_list:
|
|
189
|
+
rule_str = str(rule_code).strip().upper()
|
|
190
|
+
if rule_str in deprecated_codes:
|
|
191
|
+
found_deprecated = True
|
|
192
|
+
msg = (
|
|
193
|
+
f"Upstream config uses deprecated rule '{rule_str}' "
|
|
194
|
+
f"(found in [{'lint' if is_ruff_toml else 'tool.ruff.lint'}].{key}). "
|
|
195
|
+
"This rule may be removed in a future Ruff version."
|
|
196
|
+
)
|
|
197
|
+
if strict:
|
|
198
|
+
LOGGER.error(f"❌ {msg}")
|
|
199
|
+
else:
|
|
200
|
+
LOGGER.warning(f"⚠️ {msg}")
|
|
201
|
+
|
|
202
|
+
return not (strict and found_deprecated)
|
|
203
|
+
|
|
204
|
+
|
|
112
205
|
def validate_toml_syntax(doc: TOMLDocument) -> bool:
|
|
113
206
|
"""Return True if the document serializes to valid TOML.
|
|
114
207
|
|
|
@@ -218,6 +311,13 @@ def validate_merged_config(
|
|
|
218
311
|
return False
|
|
219
312
|
if not validate_ruff_accepts_config(doc, is_ruff_toml=is_ruff_toml, strict=strict):
|
|
220
313
|
return False
|
|
314
|
+
|
|
315
|
+
version_ok = True
|
|
221
316
|
if not is_ruff_toml:
|
|
222
|
-
|
|
223
|
-
|
|
317
|
+
version_ok = check_python_version_consistency(doc, strict=strict, exclude=exclude)
|
|
318
|
+
|
|
319
|
+
deprecated_ok = check_deprecated_rules(
|
|
320
|
+
doc, is_ruff_toml=is_ruff_toml, strict=strict, exclude=exclude
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
return version_ok and deprecated_ok
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ruff-sync
|
|
3
|
-
Version: 0.1.6.
|
|
3
|
+
Version: 0.1.6.dev3
|
|
4
4
|
Summary: Synchronize Ruff linter configuration across projects
|
|
5
5
|
Project-URL: Homepage, https://github.com/Kilo59/ruff-sync
|
|
6
6
|
Project-URL: Documentation, https://kilo59.github.io/ruff-sync/
|
|
@@ -9,7 +9,7 @@ ruff_sync/formatters.py,sha256=A4p2XAyc-xnteUmdtRXbp63fIjT9MdyKF6qKvcyNMho,29908
|
|
|
9
9
|
ruff_sync/pre_commit.py,sha256=0ltXUkmocbrSwwf6cPbNc_K5K9n-gvou98xJy9YUhr0,5303
|
|
10
10
|
ruff_sync/system.py,sha256=vF9Jjb-Z9MuLwo3wiOqcCDxniNtjvo3O-aFt4NJf-2Y,5715
|
|
11
11
|
ruff_sync/types_.py,sha256=BejR6sgctR0qr5fKgRTtgHp2TqnvT8zTRo1NJi2VHLo,824
|
|
12
|
-
ruff_sync/validation.py,sha256=
|
|
12
|
+
ruff_sync/validation.py,sha256=OatdkWUKEyxw7CYTOFNpH6IRsbVfU5EHjt6Lu6nOO9U,11585
|
|
13
13
|
ruff_sync/tui/__init__.py,sha256=DcwvE70ETjBcC6pQeHpjrYtkJp8z4StGM8L3EuaVcIo,635
|
|
14
14
|
ruff_sync/tui/app.py,sha256=soq0fkFsLeB7ZxJWNZM_H6bNj7H8p6nEYyirVcskN54,9317
|
|
15
15
|
ruff_sync/tui/constants.py,sha256=fEPyp2k817QLluyiVHqDObzDONlHz_L3Ec0SYAUzzMs,267
|
|
@@ -17,8 +17,8 @@ ruff_sync/tui/screens.py,sha256=NVIlqNIr64JrFFWeec7usqJCb1x41NEmSfRZGeEcwuo,5557
|
|
|
17
17
|
ruff_sync/tui/themes.py,sha256=-x9u_8iZPa1XZuo8O_tWVHyCImN9Qs9F7xPhl0VLwZw,654
|
|
18
18
|
ruff_sync/tui/types_.py,sha256=poNUBJotgUso2IkUi3nXUuxz6wv1goFWZimj4VttdJE,8271
|
|
19
19
|
ruff_sync/tui/widgets.py,sha256=2m3gyH4xDBpM0CK-5eQmmUCZXYKJujrbyVkFTxqmHcg,9760
|
|
20
|
-
ruff_sync-0.1.6.
|
|
21
|
-
ruff_sync-0.1.6.
|
|
22
|
-
ruff_sync-0.1.6.
|
|
23
|
-
ruff_sync-0.1.6.
|
|
24
|
-
ruff_sync-0.1.6.
|
|
20
|
+
ruff_sync-0.1.6.dev3.dist-info/METADATA,sha256=e7qoBgxp2uvn3bzcVE_yKvoybrt5ciHLp1xvkpV90Xk,22706
|
|
21
|
+
ruff_sync-0.1.6.dev3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
22
|
+
ruff_sync-0.1.6.dev3.dist-info/entry_points.txt,sha256=QQ0pjxMIN0vp5EmNFkyb-1Yk8JOIkid8zAPN3IpAExA,78
|
|
23
|
+
ruff_sync-0.1.6.dev3.dist-info/licenses/LICENSE.md,sha256=RcCP8t8xyCx2cvMZSLjBrPqJfctciWC6q85ceQAcEfA,1080
|
|
24
|
+
ruff_sync-0.1.6.dev3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|