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 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
- console.print(json.dumps([tr.to_dict() for tr in tool_results], indent=2))
177
+ print(json.dumps([tr.to_dict() for tr in tool_results], indent=2))
166
178
  elif output == OutputMode.RAW:
167
- console.print(json.dumps([tr.raw.to_dict() for tr in tool_results], indent=2))
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
- with_flags = " ".join(f"--with {dep}" for dep in tool_config.extra_deps)
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.11
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
  [![CI](https://img.shields.io/github/actions/workflow/status/rhiza-fr/py-cq/ci.yml?label=CI)](https://github.com/rhiza-fr/py-cq/actions/workflows/ci.yml)
33
33
  [![codecov](https://codecov.io/gh/rhiza-fr/py-cq/graph/badge.svg)](https://codecov.io/gh/rhiza-fr/py-cq)
34
- [![PyPI version](https://img.shields.io/pypi/v/python-code-quality)](https://pypi.org/project/python-code-quality/)
35
- [![Python versions](https://img.shields.io/pypi/pyversions/python-code-quality)](https://pypi.org/project/python-code-quality/)
34
+ [![PyPI version](https://img.shields.io/pypi/v/python-code-quality?)](https://pypi.org/project/python-code-quality/)
35
+ [![Python versions](https://img.shields.io/pypi/pyversions/python-code-quality?)](https://pypi.org/project/python-code-quality/)
36
36
  [![License](https://img.shields.io/github/license/rhiza-fr/py-cq)](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=wu1GlxSDxS835i9-mO4-xmyBLfr6puU-ES-26T7Mty0,11007
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=tgNGFOO3h-EyetCEzC_RS2K-b9OkOFpOwGwrEAHIpZA,7477
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.11.dist-info/WHEEL,sha256=Y4JtJkdCWKLnDS7bvHXqjUWSsYTnJMN9TTubfHSxAyo,80
31
- python_code_quality-0.1.11.dist-info/entry_points.txt,sha256=cfWbTw7eYO6Trv1-Z_odL6Zta9CqYU6Vk9lAHdfB60Q,40
32
- python_code_quality-0.1.11.dist-info/METADATA,sha256=jFwxqdRuW0FKdFkS9rhUnJ7Olv2ablFvnF20Wk_s1Eo,12091
33
- python_code_quality-0.1.11.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.11.0
2
+ Generator: uv 0.11.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any