|
2 | 2 | """Simple linter to spot denylisted model usage within Django view modules.""" |
3 | 3 |
|
4 | 4 | import argparse |
| 5 | +import re |
5 | 6 | import sys |
6 | 7 | from dataclasses import dataclass |
7 | 8 | from pathlib import Path |
|
15 | 16 | "Symptom", |
16 | 17 | "BreastCancerHistoryItem", |
17 | 18 | ) |
18 | | -DENYLISTED_HELPERS = ("get_object_or_404(",) |
| 19 | +TARGETS = { |
| 20 | + "model.objects": re.compile(r"(?P<model_name>\w+)\.objects"), |
| 21 | + "model.get_object_or_404": re.compile(r"(?P<model_name>\w+)\.get_object_or_404"), |
| 22 | +} |
19 | 23 |
|
20 | 24 |
|
21 | 25 | @dataclass |
@@ -61,28 +65,23 @@ def find_view_modules(base_dir): |
61 | 65 |
|
62 | 66 |
|
63 | 67 | def find_matches(paths): |
64 | | - targets = { |
65 | | - f"{model_name}.objects": f"{model_name}.objects" |
66 | | - for model_name in DENYLISTED_MODELS |
67 | | - } |
68 | | - for helper in DENYLISTED_HELPERS: |
69 | | - targets[helper] = helper |
70 | | - |
71 | 68 | for path in paths: |
72 | 69 | try: |
73 | 70 | text = path.read_text(encoding="utf-8") |
74 | 71 | except UnicodeDecodeError: |
75 | 72 | continue |
76 | 73 |
|
77 | 74 | for line_number, line in enumerate(text.splitlines(), start=1): |
78 | | - for needle, label in targets.items(): |
79 | | - if needle in line: |
80 | | - yield Match( |
81 | | - path=path, |
82 | | - line_number=line_number, |
83 | | - target=label, |
84 | | - line=line.strip(), |
85 | | - ) |
| 75 | + for label, regex in TARGETS.items(): |
| 76 | + if match := regex.search(line): |
| 77 | + model_name = match.group("model_name") |
| 78 | + if model_name in DENYLISTED_MODELS: |
| 79 | + yield Match( |
| 80 | + path=path, |
| 81 | + line_number=line_number, |
| 82 | + target=label, |
| 83 | + line=line.strip(), |
| 84 | + ) |
86 | 85 |
|
87 | 86 |
|
88 | 87 | def main(): |
|
0 commit comments