python-code-quality 0.1.11__py3-none-any.whl → 0.1.13__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.
- py_cq/cli.py +14 -2
- py_cq/execution_engine.py +15 -1
- {python_code_quality-0.1.11.dist-info → python_code_quality-0.1.13.dist-info}/METADATA +15 -3
- {python_code_quality-0.1.11.dist-info → python_code_quality-0.1.13.dist-info}/RECORD +6 -6
- {python_code_quality-0.1.11.dist-info → python_code_quality-0.1.13.dist-info}/WHEEL +1 -1
- {python_code_quality-0.1.11.dist-info → python_code_quality-0.1.13.dist-info}/entry_points.txt +0 -0
py_cq/cli.py
CHANGED
|
@@ -125,6 +125,12 @@ def check(
|
|
|
125
125
|
language: str | None = typer.Option(
|
|
126
126
|
None, "--language", "-l", help="Override language detection (e.g. python, typescript, rust)"
|
|
127
127
|
),
|
|
128
|
+
only: str | None = typer.Option(
|
|
129
|
+
None, "--only", help="Comma-separated tool IDs to run (e.g. ruff,ty,pytest)"
|
|
130
|
+
),
|
|
131
|
+
skip: str | None = typer.Option(
|
|
132
|
+
None, "--skip", help="Comma-separated tool IDs to skip (e.g. bandit,vulture)"
|
|
133
|
+
),
|
|
128
134
|
):
|
|
129
135
|
"""Feed the results from 11+ code quality tools to an LLM. Try: cq check . -o llm""" # --help
|
|
130
136
|
path_obj = Path(path)
|
|
@@ -153,6 +159,12 @@ def check(
|
|
|
153
159
|
user_cfg = load_user_config(path_obj)
|
|
154
160
|
context_lines: int = int(user_cfg.get("context_lines", 15))
|
|
155
161
|
effective_registry = _apply_user_config(tool_registry, user_cfg)
|
|
162
|
+
if only:
|
|
163
|
+
keep = set(only.split(","))
|
|
164
|
+
effective_registry = {k: v for k, v in effective_registry.items() if k in keep}
|
|
165
|
+
if skip:
|
|
166
|
+
drop = set(skip.split(","))
|
|
167
|
+
effective_registry = {k: v for k, v in effective_registry.items() if k not in drop}
|
|
156
168
|
if clear_cache:
|
|
157
169
|
tool_cache.clear()
|
|
158
170
|
tool_results = run_tools(effective_registry.values(), path, workers, early_exit=(output == OutputMode.LLM))
|
|
@@ -162,9 +174,9 @@ def check(
|
|
|
162
174
|
if output == OutputMode.SCORE:
|
|
163
175
|
console.print(combined_metrics.score)
|
|
164
176
|
elif output == OutputMode.JSON:
|
|
165
|
-
|
|
177
|
+
print(json.dumps([tr.to_dict() for tr in tool_results], indent=2))
|
|
166
178
|
elif output == OutputMode.RAW:
|
|
167
|
-
|
|
179
|
+
print(json.dumps([tr.raw.to_dict() for tr in tool_results], indent=2))
|
|
168
180
|
elif output == OutputMode.LLM:
|
|
169
181
|
# log.setLevel("CRITICAL")
|
|
170
182
|
from py_cq.llm_formatter import format_for_llm
|
py_cq/execution_engine.py
CHANGED
|
@@ -41,6 +41,18 @@ def _find_project_root(path: Path) -> Path | None:
|
|
|
41
41
|
return None
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
def _dep_in_venv(dep: str, project_root: Path) -> bool:
|
|
45
|
+
"""Return True if `dep` is installed in the project's .venv."""
|
|
46
|
+
venv = project_root / ".venv"
|
|
47
|
+
if not venv.exists():
|
|
48
|
+
return False
|
|
49
|
+
for subdir in ("Scripts", "bin"):
|
|
50
|
+
for suffix in ("", ".exe", ".cmd"):
|
|
51
|
+
if (venv / subdir / f"{dep}{suffix}").exists():
|
|
52
|
+
return True
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
|
|
44
56
|
def run_tool(tool_config: ToolConfig, context_path: str) -> RawResult:
|
|
45
57
|
"""Runs a tool defined by its configuration and returns the execution result.
|
|
46
58
|
|
|
@@ -72,7 +84,9 @@ def run_tool(tool_config: ToolConfig, context_path: str) -> RawResult:
|
|
|
72
84
|
project_root = _find_project_root(resolved)
|
|
73
85
|
abs_dir = str(project_root) if project_root else str(resolved.parent)
|
|
74
86
|
path = str(resolved)
|
|
75
|
-
|
|
87
|
+
project_root_path = Path(abs_dir)
|
|
88
|
+
missing_deps = [d for d in tool_config.extra_deps if not _dep_in_venv(d, project_root_path)]
|
|
89
|
+
with_flags = " ".join(f"--with {dep}" for dep in missing_deps)
|
|
76
90
|
python = f'"{uv}" run --directory "{abs_dir}" {with_flags}'.rstrip()
|
|
77
91
|
abs_context_path = str(Path(context_path).resolve())
|
|
78
92
|
input_path_posix = Path(context_path).as_posix().rstrip("/")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-code-quality
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: Python Code Quality Analysis Tool - feed the results from 11 CQ tools straight into an LLM. Minimal tokens.
|
|
5
5
|
Author: Chris Kilner
|
|
6
6
|
Author-email: Chris Kilner <chris@rhiza.fr>
|
|
@@ -31,8 +31,8 @@ Description-Content-Type: text/markdown
|
|
|
31
31
|
|
|
32
32
|
[](https://github.com/rhiza-fr/py-cq/actions/workflows/ci.yml)
|
|
33
33
|
[](https://codecov.io/gh/rhiza-fr/py-cq)
|
|
34
|
-
[](https://pypi.org/project/python-code-quality/)
|
|
35
|
-
[](https://pypi.org/project/python-code-quality/)
|
|
34
|
+
[](https://pypi.org/project/python-code-quality/)
|
|
35
|
+
[](https://pypi.org/project/python-code-quality/)
|
|
36
36
|
[](LICENSE)
|
|
37
37
|
|
|
38
38
|
Feed the results from 11+ code quality tools to an LLM. Minimal tokens.
|
|
@@ -112,6 +112,8 @@ cq check . -o score # Numeric score only for CI
|
|
|
112
112
|
cq check . -o json # Detailed parsed JSON output for jq
|
|
113
113
|
cq check . -o raw # Raw tool output for debug
|
|
114
114
|
cq check path/to/file.py # Just one file (skips pytest and coverage)
|
|
115
|
+
cq check . --only ruff,ty # Run only specific tools
|
|
116
|
+
cq check . --skip bandit # Skip specific tools
|
|
115
117
|
cq check . --workers 1 # Run sequentially if you like things slow
|
|
116
118
|
cq check . --clear-cache # Clear cached results before running (rarely needed)
|
|
117
119
|
cq config path/to/project/ # Show effective tool configuration
|
|
@@ -231,6 +233,16 @@ Then invoke it with `/cq-fix` in Claude Code. The `$(...)` embeds the live `cq`
|
|
|
231
233
|
]
|
|
232
234
|
```
|
|
233
235
|
|
|
236
|
+
Both `json` and `raw` output pipe cleanly to `jq`:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Get the coverage section
|
|
240
|
+
cq check . -o raw | jq '.[] | select(.tool_name == "coverage")'
|
|
241
|
+
|
|
242
|
+
# Get parsed coverage metrics only
|
|
243
|
+
cq check . -o json | jq '.[] | select(.tool_name == "coverage") | .metrics'
|
|
244
|
+
```
|
|
245
|
+
|
|
234
246
|
## Configuration
|
|
235
247
|
|
|
236
248
|
Add a `[tool.cq]` section to your project's `pyproject.toml`:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
py_cq/__init__.py,sha256=rS7kf1RU1zZskvJlkbZaMqEpdRYPspwDPAFbxzF3tXg,373
|
|
2
|
-
py_cq/cli.py,sha256=
|
|
2
|
+
py_cq/cli.py,sha256=x4BZTZVFTbSCqcdvF17Ed_WEJ5n3aQtODL7mLHzF_3s,11528
|
|
3
3
|
py_cq/config/__init__.py,sha256=f0wc51O_3kGDTZUnCbGv8_zWnC5yYGl4NWcf2buSImQ,670
|
|
4
4
|
py_cq/config/config.yaml,sha256=R8CjZH8erBQSbJFKgHt-CCwD1Mgj6ZCGQ3OtWH0Ebig,2402
|
|
5
5
|
py_cq/context_hash.py,sha256=h-i7Rhd7AUfLv9SkQvE79bjJvTsm_ZwoVwSmUKXWmfM,2977
|
|
6
|
-
py_cq/execution_engine.py,sha256=
|
|
6
|
+
py_cq/execution_engine.py,sha256=lA9HAX5iIxxIaOjTNxSak1qZUuETGKlNdsOMAdY2sQo,8012
|
|
7
7
|
py_cq/language_detector.py,sha256=6av5HaimcZ54RkN69xQmGgC0mxtTvGzPV3SL8NGG8Uc,1116
|
|
8
8
|
py_cq/llm_formatter.py,sha256=l74O5iqNWMR16789Xncoi93xOqgQJhW5IQK9_OyA9mE,1632
|
|
9
9
|
py_cq/localtypes.py,sha256=jCX1ZuwTixQooEk2N1Gi1XRuDcdBc2NlOdQBKysEybk,6128
|
|
@@ -27,7 +27,7 @@ py_cq/parsers/typarser.py,sha256=zrI0KS65MUGPxYPP74B6BRyTbjcPhKyQPjH2KZIyxN0,249
|
|
|
27
27
|
py_cq/parsers/vultureparser.py,sha256=U6zC7P0ATA_N4SB90BahKF5QHMITf_z-NsOgrh_Q5rA,1995
|
|
28
28
|
py_cq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
py_cq/tool_registry.py,sha256=oMEkFHkU3gg5UpeGD4zHtynOYmWieRgDN5kTwZ5KsE8,1584
|
|
30
|
-
python_code_quality-0.1.
|
|
31
|
-
python_code_quality-0.1.
|
|
32
|
-
python_code_quality-0.1.
|
|
33
|
-
python_code_quality-0.1.
|
|
30
|
+
python_code_quality-0.1.13.dist-info/WHEEL,sha256=M4DeIjVCA49okfALADZoWX5JOGwnmHb-JOpQHtI-1c0,80
|
|
31
|
+
python_code_quality-0.1.13.dist-info/entry_points.txt,sha256=cfWbTw7eYO6Trv1-Z_odL6Zta9CqYU6Vk9lAHdfB60Q,40
|
|
32
|
+
python_code_quality-0.1.13.dist-info/METADATA,sha256=jxjtkNG-hBU_o6lXwddPF_ZIXrMFEwd9FrLc4l0Cwz8,12463
|
|
33
|
+
python_code_quality-0.1.13.dist-info/RECORD,,
|
{python_code_quality-0.1.11.dist-info → python_code_quality-0.1.13.dist-info}/entry_points.txt
RENAMED
|
File without changes
|