python-qv 0.1.1__tar.gz → 0.1.3__tar.gz
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.
- python_qv-0.1.3/.github/workflows/docs.yml +55 -0
- python_qv-0.1.3/.readthedocs.yaml +18 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/PKG-INFO +11 -3
- {python_qv-0.1.1 → python_qv-0.1.3}/README.md +8 -1
- python_qv-0.1.3/docs/architecture.md +211 -0
- python_qv-0.1.3/docs/assets/favicon.svg +10 -0
- python_qv-0.1.3/docs/assets/logo.svg +17 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/ci_integration.md +7 -7
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/cli_reference.md +61 -26
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/configuration.md +4 -4
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/contributing.md +17 -16
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/getting_started.md +58 -22
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/html_report.md +10 -10
- python_qv-0.1.3/docs/index.md +249 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/pre_commit.md +6 -6
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/remediation.md +5 -5
- python_qv-0.1.3/docs/requirements.txt +3 -0
- python_qv-0.1.3/docs/rules.md +444 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/tree.md +6 -6
- {python_qv-0.1.1 → python_qv-0.1.3}/docs/tui.md +9 -8
- python_qv-0.1.3/examples/fastapi_issues/main.py +61 -0
- python_qv-0.1.3/examples/fastapi_issues/pyproject.toml +9 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/mkdocs.yml +32 -13
- {python_qv-0.1.1 → python_qv-0.1.3}/pyproject.toml +3 -2
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/__init__.py +1 -1
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/cli/main.py +84 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/engine.py +4 -0
- python_qv-0.1.3/src/qv/frameworks/__init__.py +19 -0
- python_qv-0.1.3/src/qv/frameworks/base.py +25 -0
- python_qv-0.1.3/src/qv/frameworks/fastapi.py +2219 -0
- python_qv-0.1.3/src/qv/frameworks/sqlalchemy.py +1580 -0
- python_qv-0.1.3/src/qv/rules/registry.py +783 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_cli.py +50 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_examples.py +17 -0
- python_qv-0.1.3/tests/test_fastapi.py +960 -0
- python_qv-0.1.3/tests/test_sqlalchemy.py +636 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/uv.lock +741 -737
- python_qv-0.1.1/.readthedocs.yaml +0 -16
- python_qv-0.1.1/docs/index.md +0 -60
- python_qv-0.1.1/docs/rules.md +0 -94
- python_qv-0.1.1/src/qv/frameworks/__init__.py +0 -1
- python_qv-0.1.1/src/qv/rules/registry.py +0 -169
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/ISSUE_TEMPLATE/rule_proposal.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/pull_request_template.md +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/workflows/ci.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.github/workflows/publish.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.gitignore +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.pre-commit-config.yaml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/.pre-commit-hooks.yaml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/CHANGELOG.md +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/CONTRIBUTING.md +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/SECURITY.md +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/action.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/README.md +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/all_in_one_unhealthy/Dockerfile +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/all_in_one_unhealthy/cycle_a.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/all_in_one_unhealthy/cycle_b.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/all_in_one_unhealthy/main.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/all_in_one_unhealthy/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/circular_imports/module_a.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/circular_imports/module_b.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/circular_imports/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/dead_modules/active_feature.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/dead_modules/main.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/dead_modules/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/dead_modules/unused_legacy_module.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/deprecated_stdlib/legacy_app.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/deprecated_stdlib/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/environment_drift/.github/workflows/ci.yml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/environment_drift/Dockerfile +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/environment_drift/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/missing_dependencies/main.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/missing_dependencies/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/missing_metadata/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/unresolved_imports/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/unresolved_imports/service.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/unused_dependencies/app.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/unused_dependencies/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/vulnerable_dependencies/app.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/vulnerable_dependencies/pyproject.toml +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/examples/vulnerable_dependencies/requirements.txt +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/__main__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/ci/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/dependencies/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/dependencies/analyzer.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/docker/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/environment/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/environment/drift.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/imports/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/imports/analyzer.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/packaging/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/packaging/analyzer.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/security/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/security/analyzer.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/security/lockfile_parser.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/analyzers/security/osv_client.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/cli/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/analyzer.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/config.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/context.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/models.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/core/project.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/integrations/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/remediation/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/remediation/engine.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/remediation/models.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/base.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/github_annotator.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/html_reporter.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/json_reporter.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/sarif.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/reporters/terminal.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/tui/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/tui/app.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/visualizers/__init__.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/src/qv/visualizers/tree.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/analyzers/test_dependencies.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/analyzers/test_environment.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/analyzers/test_imports.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/analyzers/test_packaging.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/analyzers/test_security.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/conftest.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/reporters/test_github_annotator.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/reporters/test_html.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/reporters/test_reporters.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_config.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_lockfile_parser.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_models.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_pre_commit_hooks.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_remediation.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_rules.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_tree.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tests/test_tui.py +0 -0
- {python_qv-0.1.1 → python_qv-0.1.3}/tox.ini +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: pages
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
name: Build Documentation
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repository
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v5
|
|
28
|
+
with:
|
|
29
|
+
version: "latest"
|
|
30
|
+
|
|
31
|
+
- name: Set up Python 3.12
|
|
32
|
+
run: uv python install 3.12
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: uv sync --all-extras
|
|
36
|
+
|
|
37
|
+
- name: Build MkDocs Site in Strict Mode
|
|
38
|
+
run: uv run mkdocs build --strict
|
|
39
|
+
|
|
40
|
+
- name: Upload artifact for GitHub Pages
|
|
41
|
+
uses: actions/upload-pages-artifact@v3
|
|
42
|
+
with:
|
|
43
|
+
path: site
|
|
44
|
+
|
|
45
|
+
deploy:
|
|
46
|
+
name: Deploy to GitHub Pages
|
|
47
|
+
environment:
|
|
48
|
+
name: github-pages
|
|
49
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
needs: build
|
|
52
|
+
steps:
|
|
53
|
+
- name: Deploy to GitHub Pages
|
|
54
|
+
id: deployment
|
|
55
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Read the Docs configuration file
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-24.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.12"
|
|
10
|
+
|
|
11
|
+
# Build documentation using MkDocs
|
|
12
|
+
mkdocs:
|
|
13
|
+
configuration: mkdocs.yml
|
|
14
|
+
|
|
15
|
+
# Install docs dependencies
|
|
16
|
+
python:
|
|
17
|
+
install:
|
|
18
|
+
- requirements: docs/requirements.txt
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-qv
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Diagnose why a Python project is unhealthy — explain root cause and suggest safe fixes.
|
|
5
5
|
Project-URL: Homepage, https://github.com/inzamol/qv
|
|
6
6
|
Project-URL: Repository, https://github.com/inzamol/qv
|
|
7
|
-
Project-URL: Documentation, https://
|
|
7
|
+
Project-URL: Documentation, https://inzamol.github.io/qv/
|
|
8
8
|
Project-URL: Issues, https://github.com/inzamol/qv/issues
|
|
9
9
|
Author: Inzamul Hoque
|
|
10
10
|
License-Expression: MIT
|
|
@@ -34,6 +34,7 @@ Requires-Dist: tox-uv>=1.7.0; extra == 'dev'
|
|
|
34
34
|
Requires-Dist: tox>=4.15.0; extra == 'dev'
|
|
35
35
|
Provides-Extra: docs
|
|
36
36
|
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
|
|
37
|
+
Requires-Dist: mkdocs<2.0.0,>=1.6.0; extra == 'docs'
|
|
37
38
|
Requires-Dist: pymdown-extensions>=10.7.0; extra == 'docs'
|
|
38
39
|
Description-Content-Type: text/markdown
|
|
39
40
|
|
|
@@ -198,8 +199,10 @@ Run `qv inspect` (or `qv ui`) for a full terminal dashboard:
|
|
|
198
199
|
| | `IMP-002` | Unresolved relative or internal module imports | `ERROR` |
|
|
199
200
|
| **Packaging** | `PKG-001` | Missing PEP 621 metadata (name, version, etc.) | `WARNING` |
|
|
200
201
|
| | `PKG-002` | Invalid syntax or malformed keys in `pyproject.toml` | `ERROR` |
|
|
202
|
+
| **FastAPI Doctor** | `FAP-001`–`FAP-038` | Async blocking calls, CPU starvation in endpoints, insecure CORS, missing timeouts, lifecycle anti-patterns, Pydantic v2 migrations | `ERROR` / `WARNING` |
|
|
203
|
+
| **SQL & Database** | `SQL-001`–`SQL-030` | N+1 queries in loops, session leaks, SQL injection, sync DB in async loop, missing eager loading, pool starvation, 2.0 syntax | `ERROR` / `WARNING` |
|
|
201
204
|
|
|
202
|
-
👉 *See
|
|
205
|
+
👉 *See all 80+ rules and remediation steps in the [Rules Catalog](docs/rules.md).*
|
|
203
206
|
|
|
204
207
|
---
|
|
205
208
|
|
|
@@ -330,6 +333,11 @@ qv environment
|
|
|
330
333
|
|
|
331
334
|
# Check AST & imports only (circular import loops, unresolvable modules)
|
|
332
335
|
qv architecture
|
|
336
|
+
|
|
337
|
+
# Check framework-specific issues (FastAPI, SQLAlchemy, SQLModel)
|
|
338
|
+
qv framework
|
|
339
|
+
qv framework --name fastapi
|
|
340
|
+
qv framework --name sqlalchemy
|
|
333
341
|
```
|
|
334
342
|
|
|
335
343
|
---
|
|
@@ -159,8 +159,10 @@ Run `qv inspect` (or `qv ui`) for a full terminal dashboard:
|
|
|
159
159
|
| | `IMP-002` | Unresolved relative or internal module imports | `ERROR` |
|
|
160
160
|
| **Packaging** | `PKG-001` | Missing PEP 621 metadata (name, version, etc.) | `WARNING` |
|
|
161
161
|
| | `PKG-002` | Invalid syntax or malformed keys in `pyproject.toml` | `ERROR` |
|
|
162
|
+
| **FastAPI Doctor** | `FAP-001`–`FAP-038` | Async blocking calls, CPU starvation in endpoints, insecure CORS, missing timeouts, lifecycle anti-patterns, Pydantic v2 migrations | `ERROR` / `WARNING` |
|
|
163
|
+
| **SQL & Database** | `SQL-001`–`SQL-030` | N+1 queries in loops, session leaks, SQL injection, sync DB in async loop, missing eager loading, pool starvation, 2.0 syntax | `ERROR` / `WARNING` |
|
|
162
164
|
|
|
163
|
-
👉 *See
|
|
165
|
+
👉 *See all 80+ rules and remediation steps in the [Rules Catalog](docs/rules.md).*
|
|
164
166
|
|
|
165
167
|
---
|
|
166
168
|
|
|
@@ -291,6 +293,11 @@ qv environment
|
|
|
291
293
|
|
|
292
294
|
# Check AST & imports only (circular import loops, unresolvable modules)
|
|
293
295
|
qv architecture
|
|
296
|
+
|
|
297
|
+
# Check framework-specific issues (FastAPI, SQLAlchemy, SQLModel)
|
|
298
|
+
qv framework
|
|
299
|
+
qv framework --name fastapi
|
|
300
|
+
qv framework --name sqlalchemy
|
|
294
301
|
```
|
|
295
302
|
|
|
296
303
|
---
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Architecture & Internal Design
|
|
2
|
+
|
|
3
|
+
`qv` is built as an offline-first, modular diagnostic engine designed to analyze Python project ecosystems in sub-second execution time.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. System Overview
|
|
8
|
+
|
|
9
|
+
Traditional linters inspect only individual source files (AST), while package managers typically only inspect lockfiles. `qv` bridges this gap by unifying four distinct layers of the Python ecosystem into an immutable diagnostic model:
|
|
10
|
+
|
|
11
|
+
1. **Manifests**: `pyproject.toml`, `requirements.txt`, `setup.cfg`, `Pipfile`.
|
|
12
|
+
2. **Active Environment**: `sys.executable`, `site-packages`, `importlib.metadata` distributions, and installed version constraints.
|
|
13
|
+
3. **Source Code AST**: Module import references, circular call loops, and orphan files.
|
|
14
|
+
4. **Runtime & Infrastructure**: `Dockerfile`, `docker-compose.yml`, and `.github/workflows/` CI matrices.
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
CLI / TUI (click + rich)
|
|
18
|
+
│
|
|
19
|
+
Project Discovery
|
|
20
|
+
│
|
|
21
|
+
ProjectContext (Immutable)
|
|
22
|
+
│
|
|
23
|
+
┌───────────────┬──────────────┴───────────────┬────────────────┐
|
|
24
|
+
Dependencies Environment Imports Packaging
|
|
25
|
+
Analyzer Analyzer Analyzer Analyzer
|
|
26
|
+
└───────────────┼──────────────────────────────┴────────────────┘
|
|
27
|
+
│
|
|
28
|
+
AnalysisEngine
|
|
29
|
+
│
|
|
30
|
+
Diagnostic Model
|
|
31
|
+
│
|
|
32
|
+
Root Cause Correlator
|
|
33
|
+
│
|
|
34
|
+
┌──────────────┬─────────────┼─────────────┬──────────────┬──────────────┐
|
|
35
|
+
Terminal JSON SARIF HTML GitHub Actions Interactive
|
|
36
|
+
Reporter Reporter Reporter Reporter Annotator TUI Dashboard
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 2. End-to-End Diagnostic Pipeline
|
|
42
|
+
|
|
43
|
+
The diagram below illustrates the complete lifecycle from project path discovery through multi-channel report generation:
|
|
44
|
+
|
|
45
|
+
```mermaid
|
|
46
|
+
flowchart TD
|
|
47
|
+
subgraph Discovery["1. Discovery & Context Ingestion"]
|
|
48
|
+
A["<b>File System Scanner</b><br/>Walks project root, excludes ignored paths"]
|
|
49
|
+
B["<b>Manifest Parser</b><br/>Parses PEP 621, Poetry, Flit, setuptools, requirements"]
|
|
50
|
+
C["<b>Environment Inspector</b><br/>Inspects active virtualenv & installed distributions"]
|
|
51
|
+
D["<b>AST Module Parser</b><br/>Extracts import statements & relative import trees"]
|
|
52
|
+
E["<b>Infrastructure Parser</b><br/>Extracts Docker base images & CI matrix versions"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
subgraph Context["2. Immutable Context"]
|
|
56
|
+
CTX["<b>ProjectContext</b><br/>Frozen snapshot of project metadata, AST, and environment"]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
subgraph Analyzers["3. Subsystem Analyzers"]
|
|
60
|
+
F1["<b>Dependencies Analyzer</b><br/>Conflict resolution, undeclared/unused packages"]
|
|
61
|
+
F2["<b>Environment Analyzer</b><br/>Python interpreter, Docker, and CI drift"]
|
|
62
|
+
F3["<b>Imports Analyzer</b><br/>Tarjan's cycle algorithm & unresolvable modules"]
|
|
63
|
+
F4["<b>Packaging Analyzer</b><br/>PEP 621 compliance & schema validation"]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
subgraph Correlation["4. Correlation & Scoring"]
|
|
67
|
+
G["<b>Analysis Engine & Correlator</b><br/>Aggregates findings, deduplicates evidence"]
|
|
68
|
+
H["<b>Health Score Calculator</b><br/>Applies severity penalties (0–100 score)"]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
subgraph Reporters["5. Reporting & Remediation"]
|
|
72
|
+
R1["<b>Terminal Reporter</b><br/>Colorized Rich tables & boxes"]
|
|
73
|
+
R2["<b>Interactive TUI</b><br/>Live dashboard with keyboard navigation"]
|
|
74
|
+
R3["<b>Self-Contained HTML</b><br/>Single-file interactive report with SVG gauges"]
|
|
75
|
+
R4["<b>SARIF v2.1.0 & JSON</b><br/>GitHub Security & CI integration"]
|
|
76
|
+
R5["<b>Remediation Engine</b><br/>Safe diff generator & sync coordinator"]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
Discovery --> CTX
|
|
80
|
+
CTX --> Analyzers
|
|
81
|
+
Analyzers --> Correlation
|
|
82
|
+
Correlation --> Reporters
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. Subsystem Analyzers
|
|
88
|
+
|
|
89
|
+
All diagnostic checks are implemented as independent analyzers under `src/qv/analyzers/`. Each analyzer accepts the immutable `ProjectContext` and yields structured `Diagnostic` instances.
|
|
90
|
+
|
|
91
|
+
### 3.1 Dependencies Analyzer (`src/qv/analyzers/dependencies/`)
|
|
92
|
+
- **Constraint Conflict Engine**: Validates installed package versions against declared PEP 508 version specifiers.
|
|
93
|
+
- **Missing Dependency Detection**: Identifies third-party packages imported in source code that are missing from `pyproject.toml` or requirements files.
|
|
94
|
+
- **Unused Dependency Detection**: Pinpoints direct declared dependencies that are never referenced across project source files.
|
|
95
|
+
- **Standard Library Awareness**: Includes exhaustive Python 3.10–3.13 stdlib catalogs (accounting for PEP 594 removals).
|
|
96
|
+
|
|
97
|
+
### 3.2 Environment & Drift Analyzer (`src/qv/analyzers/environment/`)
|
|
98
|
+
- **Python Version Drift**: Compares the active virtualenv interpreter version against `requires-python` or target runtime.
|
|
99
|
+
- **Container Drift**: Scans `Dockerfile` and `compose.yml` for base image Python version tags that diverge from project targets.
|
|
100
|
+
- **CI Matrix Drift**: Verifies that GitHub Actions matrix definitions cover the Python versions declared in project manifests.
|
|
101
|
+
|
|
102
|
+
### 3.3 Imports & AST Analyzer (`src/qv/analyzers/imports/`)
|
|
103
|
+
- **Circular Import Cycle Detection**: Constructs a directed module dependency graph and uses **Tarjan's Strongly Connected Components (SCC)** algorithm to identify recursive import loops.
|
|
104
|
+
- **Unresolved Local Imports**: Flags imports that reference non-existent local packages or missing `__init__.py` files.
|
|
105
|
+
- **Orphan / Dead File Detection**: Identifies Python modules that are never imported by any other module, test file, or console script entry point.
|
|
106
|
+
|
|
107
|
+
### 3.4 Packaging Analyzer (`src/qv/analyzers/packaging/`)
|
|
108
|
+
- **PEP 621 Schema Validation**: Ensures required tables (`[project]`, `name`, `version`) are present and syntactically valid.
|
|
109
|
+
- **Build Backend Consistency**: Verifies configuration compatibility with standard build tools (`setuptools`, `flit_core`, `hatchling`, `poetry.core`, `pdm.backend`).
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 4. Immutable Core Models
|
|
114
|
+
|
|
115
|
+
All state within `qv` flows through immutable, strictly typed dataclasses defined in `src/qv/core/`:
|
|
116
|
+
|
|
117
|
+
### 4.1 `ProjectContext`
|
|
118
|
+
A frozen snapshot of discovered project assets:
|
|
119
|
+
- `root_dir`: Absolute project path.
|
|
120
|
+
- `manifest`: Parsed `pyproject.toml` or requirements metadata.
|
|
121
|
+
- `environment`: Active Python interpreter version, virtualenv path, and installed distributions.
|
|
122
|
+
- `source_files`: Parsed AST trees and imported module sets.
|
|
123
|
+
- `config`: User configuration loaded from `[tool.qv]`.
|
|
124
|
+
|
|
125
|
+
### 4.2 `Diagnostic`
|
|
126
|
+
A structured diagnostic finding:
|
|
127
|
+
- `rule_id`: Stable identifier (e.g. `DEP-001`, `IMP-001`).
|
|
128
|
+
- `title`: Short human-readable summary.
|
|
129
|
+
- `severity`: `ERROR`, `WARNING`, `INFO`.
|
|
130
|
+
- `message`: Specific description of the root cause.
|
|
131
|
+
- `location`: Optional file path and line number.
|
|
132
|
+
- `evidence`: Bulleted list of facts discovered during analysis.
|
|
133
|
+
- `suggestions`: Recommended CLI commands or code modifications.
|
|
134
|
+
- `fix_action`: Optional automated remediation plan.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 5. Root Cause Engine & Health Scoring
|
|
139
|
+
|
|
140
|
+
`qv` scores project health on a scale from **0 to 100**:
|
|
141
|
+
|
|
142
|
+
$$\text{Health Score} = \max\left(0, 100 - \sum \text{Severity Penalties}\right)$$
|
|
143
|
+
|
|
144
|
+
### 5.1 Severity Penalties
|
|
145
|
+
|
|
146
|
+
| Finding Severity | Base Penalty | Behavior in Strict / CI Mode |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| **`ERROR`** | **-15 points** | Fails scan immediately (exit code 1). |
|
|
149
|
+
| **`WARNING`** | **-5 points** | Fails scan if `--strict` or `--ci` is enabled. |
|
|
150
|
+
| **`INFO`** | **-1 point** | Non-blocking advisory finding. |
|
|
151
|
+
|
|
152
|
+
### 5.2 Score Color Thresholds
|
|
153
|
+
- **Green (Healthy)**: $80 \le \text{Score} \le 100$
|
|
154
|
+
- **Yellow (Degraded)**: $50 \le \text{Score} \le 79$
|
|
155
|
+
- **Red (Critical)**: $0 \le \text{Score} \le 49$
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 6. Safe Automated Remediation Engine
|
|
160
|
+
|
|
161
|
+
The remediation engine (`src/qv/remediation/`) adheres to strict safety guarantees:
|
|
162
|
+
|
|
163
|
+
1. **Non-Destructive AST/TOML Editing**: Modifications to `pyproject.toml` preserve existing formatting, comments, and unrelated tables.
|
|
164
|
+
2. **Dry-Run Diff Generation**: All proposed fixes can be inspected in advance via `qv fix --dry-run`.
|
|
165
|
+
3. **Reversible Fix Actions**: Fixes are scoped to specific files with atomic writes.
|
|
166
|
+
4. **Package Manager Auto-Sync**: When `--sync` is passed, `qv` automatically invokes the project's native tool (`uv sync`, `poetry install`, `pip install`) to update the virtualenv.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 7. Multi-Channel Reporting Pipeline
|
|
171
|
+
|
|
172
|
+
Diagnostics can be formatted and routed to multiple consumers:
|
|
173
|
+
|
|
174
|
+
- **Terminal Reporter**: Human-readable colorized output with evidence boxes and suggestion snippets.
|
|
175
|
+
- **Interactive TUI Dashboard (`qv inspect`)**: Rich terminal interface with dual panes, scrolling, keyboard shortcuts, and live dependency tree toggling.
|
|
176
|
+
- **Standalone HTML Report (`qv scan --html`)**: Single-file HTML dashboard with SVG health score meters, real-time client-side search, severity filters, and light/dark theme toggle.
|
|
177
|
+
- **SARIF v2.1.0 Reporter**: Standard OASIS SARIF format for GitHub Advanced Security and Code Scanning alerts.
|
|
178
|
+
- **JSON Reporter**: Machine-readable output for custom scripts and dashboard ingestion.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 8. Codebase Directory Map
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
src/qv/
|
|
186
|
+
├── __init__.py # Package version and public exports
|
|
187
|
+
├── cli.py # Click CLI entry point and subcommands
|
|
188
|
+
├── core/
|
|
189
|
+
│ ├── config.py # [tool.qv] configuration loader
|
|
190
|
+
│ ├── context.py # ProjectContext discovery & data ingestion
|
|
191
|
+
│ ├── models.py # Diagnostic, Severity, ScanResult dataclasses
|
|
192
|
+
│ └── rules.py # RuleCatalog registry
|
|
193
|
+
├── analyzers/
|
|
194
|
+
│ ├── dependencies/ # DEP-001 through DEP-006 analyzers
|
|
195
|
+
│ ├── environment/ # ENV-001 through ENV-003 analyzers
|
|
196
|
+
│ ├── imports/ # IMP-001 through IMP-004 analyzers
|
|
197
|
+
│ └── packaging/ # PKG-001 and PKG-002 analyzers
|
|
198
|
+
├── remediation/
|
|
199
|
+
│ ├── engine.py # Remediation planner and fix executor
|
|
200
|
+
│ └── actions.py # Atomic manifest & TOML fix handlers
|
|
201
|
+
├── reporters/
|
|
202
|
+
│ ├── terminal.py # Rich console output formatting
|
|
203
|
+
│ ├── html.py # Standalone HTML report generator
|
|
204
|
+
│ ├── sarif.py # SARIF v2.1.0 generator
|
|
205
|
+
│ ├── json.py # JSON exporter
|
|
206
|
+
│ └── github.py # GitHub Actions PR annotation emitter
|
|
207
|
+
├── tui/
|
|
208
|
+
│ └── dashboard.py # Interactive Rich terminal explorer
|
|
209
|
+
└── visualizers/
|
|
210
|
+
└── tree.py # Dependency & circular import visualizer
|
|
211
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
+
<rect width="64" height="64" rx="14" fill="#09090B" stroke="#27272A" stroke-width="1.5" />
|
|
3
|
+
|
|
4
|
+
<!-- 'q' glyph -->
|
|
5
|
+
<circle cx="23" cy="29" r="9" fill="none" stroke="#FFFFFF" stroke-width="4.2" />
|
|
6
|
+
<path d="M32 20 L32 44" stroke="#FFFFFF" stroke-width="4.2" stroke-linecap="round" />
|
|
7
|
+
|
|
8
|
+
<!-- 'v' glyph -->
|
|
9
|
+
<path d="M37 23 L44 39 L51 23" fill="none" stroke="#E4E4E7" stroke-width="4.2" stroke-linecap="round" stroke-linejoin="round" />
|
|
10
|
+
</svg>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="100%" height="100%">
|
|
2
|
+
<!-- Background Badge / Squircle -->
|
|
3
|
+
<rect x="8" y="8" width="104" height="104" rx="26" fill="#09090B" stroke="#27272A" stroke-width="2" />
|
|
4
|
+
|
|
5
|
+
<!-- Subtle inner ambient frame -->
|
|
6
|
+
<rect x="14" y="14" width="92" height="92" rx="20" fill="none" stroke="#18181B" stroke-width="1" />
|
|
7
|
+
|
|
8
|
+
<!-- 'q' glyph -->
|
|
9
|
+
<circle cx="44" cy="54" r="16" fill="none" stroke="#FFFFFF" stroke-width="7" />
|
|
10
|
+
<path d="M60 38 L60 80" stroke="#FFFFFF" stroke-width="7" stroke-linecap="round" />
|
|
11
|
+
|
|
12
|
+
<!-- 'v' glyph -->
|
|
13
|
+
<path d="M68 42 L80 72 L92 42" fill="none" stroke="#E4E4E7" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" />
|
|
14
|
+
|
|
15
|
+
<!-- Diagnostic focal dot -->
|
|
16
|
+
<circle cx="94" cy="34" r="3" fill="#A1A1AA" />
|
|
17
|
+
</svg>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Official GitHub Action (`inzamol/qv`)
|
|
7
|
+
## 1. Official GitHub Action (`inzamol/qv`)
|
|
8
8
|
|
|
9
9
|
Use the official composite GitHub Action to run `qv` with automated PR annotations and step summaries:
|
|
10
10
|
|
|
@@ -28,9 +28,9 @@ jobs:
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
## Custom CI Configuration
|
|
31
|
+
## 2. Custom CI Configuration
|
|
32
32
|
|
|
33
|
-
### Basic CI Check
|
|
33
|
+
### 2.1 Basic CI Check
|
|
34
34
|
|
|
35
35
|
Add a step to your `.github/workflows/ci.yml`:
|
|
36
36
|
|
|
@@ -52,7 +52,7 @@ jobs:
|
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
55
|
-
### GitHub Code Scanning with SARIF
|
|
55
|
+
### 2.2 GitHub Code Scanning with SARIF
|
|
56
56
|
|
|
57
57
|
`qv` supports emitting findings in **SARIF v2.1.0** format for GitHub Advanced Security and Code Scanning:
|
|
58
58
|
|
|
@@ -84,7 +84,7 @@ jobs:
|
|
|
84
84
|
|
|
85
85
|
---
|
|
86
86
|
|
|
87
|
-
## Pre-commit Integration
|
|
87
|
+
## 3. Pre-commit Integration
|
|
88
88
|
|
|
89
89
|
`qv` provides native pre-commit hooks via `.pre-commit-hooks.yaml`.
|
|
90
90
|
|
|
@@ -103,7 +103,7 @@ repos:
|
|
|
103
103
|
# - id: qv-fix
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
### Available Hooks
|
|
106
|
+
### 3.1 Available Hooks
|
|
107
107
|
|
|
108
108
|
| Hook ID | Description | Default Command |
|
|
109
109
|
|---|---|---|
|
|
@@ -112,7 +112,7 @@ repos:
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
-
## Exit Codes for CI Pipelines
|
|
115
|
+
## 4. Exit Codes for CI Pipelines
|
|
116
116
|
|
|
117
117
|
- `0`: Success — no blocking findings.
|
|
118
118
|
- `1`: Failure — errors found (or warnings in `--strict` / `--ci` mode).
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Global Options
|
|
7
|
+
## 1. Global Options
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
qv --help
|
|
@@ -13,7 +13,27 @@ qv --version
|
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
## `qv
|
|
16
|
+
## 2. `qv init`
|
|
17
|
+
|
|
18
|
+
Generates or updates the `[tool.qv]` configuration block in your `pyproject.toml` without overwriting existing settings.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
qv init [PATH]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Initialize [tool.qv] in current directory
|
|
28
|
+
qv init
|
|
29
|
+
|
|
30
|
+
# Initialize in a specific project path
|
|
31
|
+
qv init ./services/backend
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. `qv scan`
|
|
17
37
|
|
|
18
38
|
Runs full diagnostic analysis on the specified directory.
|
|
19
39
|
|
|
@@ -21,13 +41,13 @@ Runs full diagnostic analysis on the specified directory.
|
|
|
21
41
|
qv scan [PATH] [OPTIONS]
|
|
22
42
|
```
|
|
23
43
|
|
|
24
|
-
### Arguments
|
|
44
|
+
### 3.1 Arguments
|
|
25
45
|
|
|
26
46
|
| Argument | Description | Default |
|
|
27
47
|
|---|---|---|
|
|
28
48
|
| `PATH` | Path to the project root directory | `.` (current directory) |
|
|
29
49
|
|
|
30
|
-
### Options
|
|
50
|
+
### 3.2 Options
|
|
31
51
|
|
|
32
52
|
| Option | Description |
|
|
33
53
|
|---|---|
|
|
@@ -40,7 +60,7 @@ qv scan [PATH] [OPTIONS]
|
|
|
40
60
|
| `--offline` | Disables remote vulnerability/CVE queries (airgapped mode) |
|
|
41
61
|
| `--output`, `-o <FILE>` | Writes output directly to a file |
|
|
42
62
|
|
|
43
|
-
### Exit Codes
|
|
63
|
+
### 3.3 Exit Codes
|
|
44
64
|
|
|
45
65
|
| Exit Code | Meaning |
|
|
46
66
|
|---|---|
|
|
@@ -51,7 +71,7 @@ qv scan [PATH] [OPTIONS]
|
|
|
51
71
|
|
|
52
72
|
---
|
|
53
73
|
|
|
54
|
-
## `qv inspect` (alias: `qv ui`)
|
|
74
|
+
## 4. `qv inspect` (alias: `qv ui`)
|
|
55
75
|
|
|
56
76
|
Launches an interactive terminal dashboard (TUI) to navigate findings, expand evidence, view dependency trees, and apply fixes interactively with keyboard shortcuts.
|
|
57
77
|
|
|
@@ -60,7 +80,7 @@ qv inspect [PATH] [OPTIONS]
|
|
|
60
80
|
qv ui [PATH] [OPTIONS]
|
|
61
81
|
```
|
|
62
82
|
|
|
63
|
-
### Controls
|
|
83
|
+
### 4.1 Controls
|
|
64
84
|
|
|
65
85
|
| Key | Action |
|
|
66
86
|
|---|---|
|
|
@@ -73,7 +93,7 @@ qv ui [PATH] [OPTIONS]
|
|
|
73
93
|
|
|
74
94
|
---
|
|
75
95
|
|
|
76
|
-
## `qv fix`
|
|
96
|
+
## 5. `qv fix`
|
|
77
97
|
|
|
78
98
|
Safely and automatically fixes detectable diagnostic health issues (e.g., adding missing dependencies to `pyproject.toml`, removing unused dependencies, initializing packaging metadata).
|
|
79
99
|
|
|
@@ -81,7 +101,7 @@ Safely and automatically fixes detectable diagnostic health issues (e.g., adding
|
|
|
81
101
|
qv fix [PATH] [OPTIONS]
|
|
82
102
|
```
|
|
83
103
|
|
|
84
|
-
### Options
|
|
104
|
+
### 5.1 Options
|
|
85
105
|
|
|
86
106
|
| Option | Description |
|
|
87
107
|
|---|---|
|
|
@@ -102,7 +122,7 @@ qv fix -y
|
|
|
102
122
|
|
|
103
123
|
---
|
|
104
124
|
|
|
105
|
-
## `qv tree` / `qv graph`
|
|
125
|
+
## 6. `qv tree` / `qv graph`
|
|
106
126
|
|
|
107
127
|
Visualizes direct vs transitive package dependencies and internal source module import architecture (with circular import cycles highlighted).
|
|
108
128
|
|
|
@@ -110,7 +130,7 @@ Visualizes direct vs transitive package dependencies and internal source module
|
|
|
110
130
|
qv tree [PATH] [OPTIONS]
|
|
111
131
|
```
|
|
112
132
|
|
|
113
|
-
### Options
|
|
133
|
+
### 6.1 Options
|
|
114
134
|
|
|
115
135
|
| Option | Description |
|
|
116
136
|
|---|---|
|
|
@@ -134,7 +154,7 @@ qv tree -d -L 2
|
|
|
134
154
|
|
|
135
155
|
---
|
|
136
156
|
|
|
137
|
-
## `qv explain`
|
|
157
|
+
## 7. `qv explain`
|
|
138
158
|
|
|
139
159
|
Displays detailed explanations, evidence requirements, and remediation instructions for a rule.
|
|
140
160
|
|
|
@@ -150,37 +170,52 @@ qv explain DEP-002
|
|
|
150
170
|
|
|
151
171
|
---
|
|
152
172
|
|
|
153
|
-
##
|
|
154
|
-
|
|
155
|
-
Generates or updates the `[tool.qv]` configuration block in your `pyproject.toml`.
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
qv init [PATH]
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Targeted Subsystem Commands
|
|
173
|
+
## 8. Targeted Subsystem Commands
|
|
164
174
|
|
|
165
175
|
Run focused checks on specific areas without executing the full scan:
|
|
166
176
|
|
|
167
|
-
### `qv dependency`
|
|
177
|
+
### 8.1 `qv dependency`
|
|
168
178
|
Scans for dependency conflicts, missing imports, unused packages, and version mismatches.
|
|
169
179
|
|
|
170
180
|
```bash
|
|
171
181
|
qv dependency [PATH]
|
|
172
182
|
```
|
|
173
183
|
|
|
174
|
-
### `qv environment`
|
|
184
|
+
### 8.2 `qv environment`
|
|
175
185
|
Checks for Python runtime drift between local environment, Dockerfiles, and CI matrices.
|
|
176
186
|
|
|
177
187
|
```bash
|
|
178
188
|
qv environment [PATH]
|
|
179
189
|
```
|
|
180
190
|
|
|
181
|
-
### `qv architecture`
|
|
191
|
+
### 8.3 `qv architecture`
|
|
182
192
|
Scans source code for circular imports and unresolved internal modules.
|
|
183
193
|
|
|
184
194
|
```bash
|
|
185
195
|
qv architecture [PATH]
|
|
186
196
|
```
|
|
197
|
+
|
|
198
|
+
### 8.4 `qv framework` (alias: `qv frameworks`)
|
|
199
|
+
Runs framework-specific diagnostic rules (e.g. FastAPI async blocking calls, SQLAlchemy N+1 queries, unclosed sessions, SQL injection, pool leaks).
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
qv framework [PATH] [OPTIONS]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Options:
|
|
206
|
+
- `-n, --name [fastapi|sqlalchemy|sql|all]`: Filter analysis to a specific framework (default: all detected frameworks).
|
|
207
|
+
- `--json`: Output framework scan results as structured JSON.
|
|
208
|
+
- `--sarif`: Output framework scan results in SARIF v2.1.0 format.
|
|
209
|
+
|
|
210
|
+
Example:
|
|
211
|
+
```bash
|
|
212
|
+
# Scan current project for all framework issues
|
|
213
|
+
qv framework
|
|
214
|
+
|
|
215
|
+
# Scan specifically for FastAPI issues
|
|
216
|
+
qv framework --name fastapi
|
|
217
|
+
|
|
218
|
+
# Scan specifically for SQLAlchemy / SQL database issues
|
|
219
|
+
qv framework --name sqlalchemy
|
|
220
|
+
```
|
|
221
|
+
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## Example `pyproject.toml`
|
|
7
|
+
## 1. Example `pyproject.toml`
|
|
8
8
|
|
|
9
9
|
```toml
|
|
10
10
|
[tool.qv]
|
|
@@ -38,7 +38,7 @@ python = "3.12"
|
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
-
## Severity Overrides
|
|
41
|
+
## 2. Severity Overrides
|
|
42
42
|
|
|
43
43
|
You can adjust how strictly any rule is treated:
|
|
44
44
|
|
|
@@ -51,7 +51,7 @@ You can adjust how strictly any rule is treated:
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
## Ignore Rules
|
|
54
|
+
## 3. Ignore Rules
|
|
55
55
|
|
|
56
56
|
To suppress rules that are not applicable to your workflow, list them under `[tool.qv.ignore]`:
|
|
57
57
|
|
|
@@ -62,7 +62,7 @@ rules = ["DEP-003", "ENV-002"]
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
-
## Precedence Order
|
|
65
|
+
## 4. Precedence Order
|
|
66
66
|
|
|
67
67
|
When resolving configuration, `qv` follows this precedence:
|
|
68
68
|
|