python-qv 0.1.0__tar.gz → 0.1.2__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.2/.github/ISSUE_TEMPLATE/bug_report.yml +73 -0
- python_qv-0.1.2/.github/ISSUE_TEMPLATE/config.yml +8 -0
- python_qv-0.1.2/.github/ISSUE_TEMPLATE/feature_request.yml +43 -0
- python_qv-0.1.2/.github/ISSUE_TEMPLATE/rule_proposal.yml +56 -0
- python_qv-0.1.2/.github/pull_request_template.md +32 -0
- python_qv-0.1.2/.github/workflows/ci.yml +65 -0
- python_qv-0.1.2/.github/workflows/docs.yml +55 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/.github/workflows/publish.yml +57 -12
- {python_qv-0.1.0 → python_qv-0.1.2}/.gitignore +3 -0
- python_qv-0.1.2/.pre-commit-config.yaml +43 -0
- python_qv-0.1.2/.pre-commit-hooks.yaml +17 -0
- python_qv-0.1.2/.readthedocs.yaml +18 -0
- python_qv-0.1.2/CHANGELOG.md +44 -0
- python_qv-0.1.2/PKG-INFO +492 -0
- python_qv-0.1.2/README.md +452 -0
- python_qv-0.1.2/SECURITY.md +32 -0
- python_qv-0.1.2/action.yml +64 -0
- python_qv-0.1.2/docs/architecture.md +211 -0
- python_qv-0.1.2/docs/assets/favicon.svg +10 -0
- python_qv-0.1.2/docs/assets/logo.svg +17 -0
- python_qv-0.1.2/docs/ci_integration.md +120 -0
- python_qv-0.1.2/docs/cli_reference.md +196 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/docs/configuration.md +4 -4
- python_qv-0.1.2/docs/contributing.md +169 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/docs/getting_started.md +58 -22
- python_qv-0.1.2/docs/html_report.md +77 -0
- python_qv-0.1.2/docs/index.md +249 -0
- python_qv-0.1.2/docs/pre_commit.md +54 -0
- python_qv-0.1.2/docs/remediation.md +67 -0
- python_qv-0.1.2/docs/requirements.txt +3 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/docs/rules.md +27 -17
- python_qv-0.1.2/docs/tree.md +85 -0
- python_qv-0.1.2/docs/tui.md +92 -0
- python_qv-0.1.2/examples/README.md +102 -0
- python_qv-0.1.2/examples/all_in_one_unhealthy/Dockerfile +7 -0
- python_qv-0.1.2/examples/all_in_one_unhealthy/cycle_a.py +5 -0
- python_qv-0.1.2/examples/all_in_one_unhealthy/cycle_b.py +5 -0
- python_qv-0.1.2/examples/all_in_one_unhealthy/main.py +21 -0
- python_qv-0.1.2/examples/all_in_one_unhealthy/pyproject.toml +10 -0
- python_qv-0.1.2/examples/circular_imports/module_a.py +7 -0
- python_qv-0.1.2/examples/circular_imports/module_b.py +7 -0
- python_qv-0.1.2/examples/circular_imports/pyproject.toml +6 -0
- python_qv-0.1.2/examples/dead_modules/active_feature.py +5 -0
- python_qv-0.1.2/examples/dead_modules/main.py +11 -0
- python_qv-0.1.2/examples/dead_modules/pyproject.toml +6 -0
- python_qv-0.1.2/examples/dead_modules/unused_legacy_module.py +5 -0
- python_qv-0.1.2/examples/deprecated_stdlib/legacy_app.py +14 -0
- python_qv-0.1.2/examples/deprecated_stdlib/pyproject.toml +6 -0
- python_qv-0.1.2/examples/environment_drift/.github/workflows/ci.yml +19 -0
- python_qv-0.1.2/examples/environment_drift/Dockerfile +7 -0
- python_qv-0.1.2/examples/environment_drift/pyproject.toml +6 -0
- python_qv-0.1.2/examples/missing_dependencies/main.py +25 -0
- python_qv-0.1.2/examples/missing_dependencies/pyproject.toml +8 -0
- python_qv-0.1.2/examples/missing_metadata/pyproject.toml +5 -0
- python_qv-0.1.2/examples/unresolved_imports/pyproject.toml +6 -0
- python_qv-0.1.2/examples/unresolved_imports/service.py +9 -0
- python_qv-0.1.2/examples/unused_dependencies/app.py +12 -0
- python_qv-0.1.2/examples/unused_dependencies/pyproject.toml +10 -0
- python_qv-0.1.2/examples/vulnerable_dependencies/app.py +13 -0
- python_qv-0.1.2/examples/vulnerable_dependencies/pyproject.toml +8 -0
- python_qv-0.1.2/examples/vulnerable_dependencies/requirements.txt +1 -0
- python_qv-0.1.2/mkdocs.yml +87 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/pyproject.toml +20 -2
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/__init__.py +1 -1
- python_qv-0.1.2/src/qv/__main__.py +6 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/dependencies/analyzer.py +65 -4
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/environment/drift.py +75 -6
- python_qv-0.1.2/src/qv/analyzers/imports/analyzer.py +375 -0
- python_qv-0.1.2/src/qv/analyzers/security/__init__.py +13 -0
- python_qv-0.1.2/src/qv/analyzers/security/analyzer.py +113 -0
- python_qv-0.1.2/src/qv/analyzers/security/lockfile_parser.py +173 -0
- python_qv-0.1.2/src/qv/analyzers/security/osv_client.py +137 -0
- python_qv-0.1.2/src/qv/cli/main.py +583 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/config.py +4 -1
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/engine.py +2 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/models.py +16 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/project.py +111 -6
- python_qv-0.1.2/src/qv/remediation/__init__.py +6 -0
- python_qv-0.1.2/src/qv/remediation/engine.py +302 -0
- python_qv-0.1.2/src/qv/remediation/models.py +62 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/reporters/__init__.py +2 -0
- python_qv-0.1.2/src/qv/reporters/github_annotator.py +88 -0
- python_qv-0.1.2/src/qv/reporters/html_reporter.py +511 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/rules/registry.py +18 -0
- python_qv-0.1.2/src/qv/tui/__init__.py +5 -0
- python_qv-0.1.2/src/qv/tui/app.py +315 -0
- python_qv-0.1.2/src/qv/visualizers/__init__.py +5 -0
- python_qv-0.1.2/src/qv/visualizers/tree.py +209 -0
- python_qv-0.1.2/tests/analyzers/test_imports.py +175 -0
- python_qv-0.1.2/tests/analyzers/test_security.py +154 -0
- python_qv-0.1.2/tests/reporters/test_github_annotator.py +67 -0
- python_qv-0.1.2/tests/reporters/test_html.py +43 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/test_cli.py +2 -1
- python_qv-0.1.2/tests/test_examples.py +158 -0
- python_qv-0.1.2/tests/test_lockfile_parser.py +148 -0
- python_qv-0.1.2/tests/test_pre_commit_hooks.py +20 -0
- python_qv-0.1.2/tests/test_remediation.py +199 -0
- python_qv-0.1.2/tests/test_tree.py +68 -0
- python_qv-0.1.2/tests/test_tui.py +57 -0
- python_qv-0.1.2/tox.ini +43 -0
- python_qv-0.1.2/uv.lock +1355 -0
- python_qv-0.1.0/.github/workflows/ci.yml +0 -37
- python_qv-0.1.0/PKG-INFO +0 -281
- python_qv-0.1.0/README.md +0 -248
- python_qv-0.1.0/docs/ci_integration.md +0 -68
- python_qv-0.1.0/docs/cli_reference.md +0 -100
- python_qv-0.1.0/docs/contributing.md +0 -79
- python_qv-0.1.0/src/qv/analyzers/imports/analyzer.py +0 -160
- python_qv-0.1.0/src/qv/analyzers/security/__init__.py +0 -1
- python_qv-0.1.0/src/qv/cli/main.py +0 -253
- python_qv-0.1.0/tests/analyzers/test_imports.py +0 -69
- python_qv-0.1.0/uv.lock +0 -562
- {python_qv-0.1.0 → python_qv-0.1.2}/CONTRIBUTING.md +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/ci/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/dependencies/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/docker/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/environment/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/imports/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/packaging/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/analyzers/packaging/analyzer.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/cli/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/analyzer.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/core/context.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/frameworks/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/integrations/__init__.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/reporters/base.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/reporters/json_reporter.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/reporters/sarif.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/src/qv/reporters/terminal.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/analyzers/test_dependencies.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/analyzers/test_environment.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/analyzers/test_packaging.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/conftest.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/reporters/test_reporters.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/test_config.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/test_models.py +0 -0
- {python_qv-0.1.0 → python_qv-0.1.2}/tests/test_rules.py +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: 🐛 Bug Report
|
|
2
|
+
description: Report unexpected behavior, inaccurate diagnostics, or crashes in qv.
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to report an issue! Please search existing issues before filing a duplicate.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Bug Description
|
|
15
|
+
description: A clear and concise description of what the bug is.
|
|
16
|
+
placeholder: Describe the problem...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: reproduction
|
|
22
|
+
attributes:
|
|
23
|
+
label: Steps to Reproduce
|
|
24
|
+
description: Provide the command and minimal project layout to reproduce the issue.
|
|
25
|
+
placeholder: |
|
|
26
|
+
1. Run `qv scan` on a project with ...
|
|
27
|
+
2. Expected output: ...
|
|
28
|
+
3. Actual output: ...
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: command_output
|
|
34
|
+
attributes:
|
|
35
|
+
label: Command Output / Error Trace
|
|
36
|
+
description: Paste the output of `qv scan` or stack trace here.
|
|
37
|
+
render: text
|
|
38
|
+
validations:
|
|
39
|
+
required: false
|
|
40
|
+
|
|
41
|
+
- type: dropdown
|
|
42
|
+
id: package_manager
|
|
43
|
+
attributes:
|
|
44
|
+
label: Package Manager
|
|
45
|
+
description: Which package manager was used in the scanned project?
|
|
46
|
+
options:
|
|
47
|
+
- uv
|
|
48
|
+
- poetry
|
|
49
|
+
- pip / requirements.txt
|
|
50
|
+
- pdm
|
|
51
|
+
- pipenv
|
|
52
|
+
- Other / None
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
55
|
+
|
|
56
|
+
- type: input
|
|
57
|
+
id: environment
|
|
58
|
+
attributes:
|
|
59
|
+
label: Environment & Versions
|
|
60
|
+
description: Output of `qv version`, Python version, and OS.
|
|
61
|
+
placeholder: qv v0.1.0, Python 3.12.7, Ubuntu 24.04 / Windows 11 / macOS 14
|
|
62
|
+
validations:
|
|
63
|
+
required: true
|
|
64
|
+
|
|
65
|
+
- type: checkboxes
|
|
66
|
+
id: checkboxes
|
|
67
|
+
attributes:
|
|
68
|
+
label: Checklist
|
|
69
|
+
options:
|
|
70
|
+
- label: I have verified this is not a duplicate of an existing issue.
|
|
71
|
+
required: true
|
|
72
|
+
- label: I can reproduce this on the latest version of `qv`.
|
|
73
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: 📖 Documentation
|
|
4
|
+
url: https://qv.readthedocs.io/
|
|
5
|
+
about: Read the official documentation and guides.
|
|
6
|
+
- name: 💬 Discussions & Questions
|
|
7
|
+
url: https://github.com/inzamol/qv/discussions
|
|
8
|
+
about: Ask questions, share ideas, and discuss with the community.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: 💡 Feature Request
|
|
2
|
+
description: Suggest a new capability, visualizer, reporter, or CLI option for qv.
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Have an idea to make `qv` better? Tell us about your proposal!
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: problem
|
|
13
|
+
attributes:
|
|
14
|
+
label: Problem / Motivation
|
|
15
|
+
description: Is your feature request related to a specific pain point or workflow limitation?
|
|
16
|
+
placeholder: I'm always frustrated when...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: proposed_solution
|
|
22
|
+
attributes:
|
|
23
|
+
label: Proposed Solution
|
|
24
|
+
description: Describe the solution or new command/flag you'd like to see.
|
|
25
|
+
placeholder: Add a `--watch` flag to `qv scan` that...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: alternatives
|
|
31
|
+
attributes:
|
|
32
|
+
label: Considered Alternatives
|
|
33
|
+
description: Describe any alternative solutions or workarounds you've evaluated.
|
|
34
|
+
validations:
|
|
35
|
+
required: false
|
|
36
|
+
|
|
37
|
+
- type: checkboxes
|
|
38
|
+
id: willingness
|
|
39
|
+
attributes:
|
|
40
|
+
label: Contribution
|
|
41
|
+
options:
|
|
42
|
+
- label: I would be interested in submitting a Pull Request to implement this.
|
|
43
|
+
required: false
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: 📋 New Diagnostic Rule Proposal
|
|
2
|
+
description: Propose a new diagnostic check, code smell detection, or ecosystem drift rule.
|
|
3
|
+
title: "[Rule Proposal]: "
|
|
4
|
+
labels: ["rules", "enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Diagnostic rules in `qv` detect real ecosystem friction, configuration bugs, or runtime hazards.
|
|
10
|
+
|
|
11
|
+
- type: input
|
|
12
|
+
id: suggested_rule_id
|
|
13
|
+
attributes:
|
|
14
|
+
label: Proposed Rule Category & ID
|
|
15
|
+
description: e.g. `DEP-xxx` (Dependencies), `ENV-xxx` (Environment), `IMP-xxx` (Imports), `PKG-xxx` (Packaging)
|
|
16
|
+
placeholder: DEP-007
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: summary
|
|
22
|
+
attributes:
|
|
23
|
+
label: Rule Summary & Objective
|
|
24
|
+
description: What specific condition or bug does this rule identify?
|
|
25
|
+
placeholder: Detect when a requirement in pyproject.toml has an unpinned upper bound...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: dropdown
|
|
30
|
+
id: severity
|
|
31
|
+
attributes:
|
|
32
|
+
label: Default Severity
|
|
33
|
+
options:
|
|
34
|
+
- ERROR (Blocking hazard or broken project)
|
|
35
|
+
- WARNING (Sub-optimal or risky configuration)
|
|
36
|
+
- INFO (Advisory metric)
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
|
|
40
|
+
- type: textarea
|
|
41
|
+
id: evidence
|
|
42
|
+
attributes:
|
|
43
|
+
label: Deterministic Evidence Sources
|
|
44
|
+
description: Where does the evidence come from without making external network calls?
|
|
45
|
+
placeholder: AST import nodes, pyproject.toml table parsing, etc.
|
|
46
|
+
validations:
|
|
47
|
+
required: true
|
|
48
|
+
|
|
49
|
+
- type: textarea
|
|
50
|
+
id: remediation
|
|
51
|
+
attributes:
|
|
52
|
+
label: Remediation Strategy & Fix
|
|
53
|
+
description: What actionable command or edit will resolve the issue?
|
|
54
|
+
placeholder: Run `uv add ...` or update the manifest table.
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## 📝 Description
|
|
2
|
+
|
|
3
|
+
Briefly describe the changes introduced in this Pull Request, including the problem solved or feature added.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔗 Related Issues
|
|
8
|
+
|
|
9
|
+
- Fixes #(issue)
|
|
10
|
+
- Closes #(issue)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🧪 Type of Change
|
|
15
|
+
|
|
16
|
+
- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
|
|
17
|
+
- [ ] ✨ New feature / rule (non-breaking change which adds new diagnostic or visualizer)
|
|
18
|
+
- [ ] ⚡ Performance improvement
|
|
19
|
+
- [ ] 📖 Documentation update
|
|
20
|
+
- [ ] 🧹 Refactoring or code quality cleanup
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## ✅ Quality Checklist
|
|
25
|
+
|
|
26
|
+
- [ ] I have read the [Contributing Guidelines](https://github.com/inzamol/qv/blob/main/docs/contributing.md).
|
|
27
|
+
- [ ] My code adheres to strict type annotations and passes `uv run pyright`.
|
|
28
|
+
- [ ] My code passes linting and formatting via `uv run ruff check .` and `uv run ruff format --check .`.
|
|
29
|
+
- [ ] I have added comprehensive unit tests covering positive and negative cases under `tests/`.
|
|
30
|
+
- [ ] All tests pass locally with `uv run pytest`.
|
|
31
|
+
- [ ] Multi-environment matrix passes locally with `uv run tox`.
|
|
32
|
+
- [ ] If adding a new rule or CLI option, I have updated the relevant documentation in `docs/` and `README.md`.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
name: Test Matrix (Python ${{ matrix.python-version }})
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v5
|
|
27
|
+
with:
|
|
28
|
+
version: "latest"
|
|
29
|
+
|
|
30
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
31
|
+
run: uv python install ${{ matrix.python-version }}
|
|
32
|
+
|
|
33
|
+
- name: Install all dependencies
|
|
34
|
+
run: uv sync --all-extras
|
|
35
|
+
|
|
36
|
+
- name: Lint with Ruff
|
|
37
|
+
run: |
|
|
38
|
+
uv run ruff check .
|
|
39
|
+
uv run ruff format --check .
|
|
40
|
+
|
|
41
|
+
- name: Static Type Checking with Pyright
|
|
42
|
+
run: uv run pyright
|
|
43
|
+
|
|
44
|
+
- name: Run Test Suite
|
|
45
|
+
run: uv run pytest --cov=src/qv --cov-report=term-missing
|
|
46
|
+
|
|
47
|
+
- name: Self Health Scan (Dogfooding qv)
|
|
48
|
+
run: uv run qv scan --strict --ci --github-annotations
|
|
49
|
+
|
|
50
|
+
docs:
|
|
51
|
+
name: Build Documentation
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
|
|
56
|
+
- name: Install uv
|
|
57
|
+
uses: astral-sh/setup-uv@v5
|
|
58
|
+
with:
|
|
59
|
+
version: "latest"
|
|
60
|
+
|
|
61
|
+
- name: Install dependencies
|
|
62
|
+
run: uv sync --all-extras
|
|
63
|
+
|
|
64
|
+
- name: Build Docs in Strict Mode
|
|
65
|
+
run: uv run mkdocs build --strict
|
|
@@ -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
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
name: Publish to PyPI
|
|
1
|
+
name: Publish to PyPI & GitHub Release
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
4
|
push:
|
|
7
5
|
tags:
|
|
8
6
|
- "v[0-9]+.[0-9]+.[0-9]+"
|
|
9
7
|
- "v[0-9]+.[0-9]+.[0-9]+-*"
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
10
|
workflow_dispatch:
|
|
11
11
|
inputs:
|
|
12
12
|
target:
|
|
@@ -24,7 +24,7 @@ concurrency:
|
|
|
24
24
|
|
|
25
25
|
jobs:
|
|
26
26
|
validate:
|
|
27
|
-
name:
|
|
27
|
+
name: Validate Tag, Lint & Test Suite
|
|
28
28
|
runs-on: ubuntu-latest
|
|
29
29
|
strategy:
|
|
30
30
|
fail-fast: false
|
|
@@ -42,23 +42,59 @@ jobs:
|
|
|
42
42
|
- name: Set up Python ${{ matrix.python-version }}
|
|
43
43
|
run: uv python install ${{ matrix.python-version }}
|
|
44
44
|
|
|
45
|
-
- name: Install dependencies
|
|
46
|
-
run: uv sync --all-extras
|
|
45
|
+
- name: Install all dependencies
|
|
46
|
+
run: uv sync --all-extras
|
|
47
47
|
|
|
48
|
-
- name:
|
|
48
|
+
- name: Validate Git Tag vs Package Version
|
|
49
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
50
|
+
run: |
|
|
51
|
+
uv run python -c "
|
|
52
|
+
import os, sys
|
|
53
|
+
from pathlib import Path
|
|
54
|
+
try:
|
|
55
|
+
import tomllib
|
|
56
|
+
except ImportError:
|
|
57
|
+
import tomli as tomllib
|
|
58
|
+
|
|
59
|
+
tag = os.environ.get('GITHUB_REF_NAME', '')
|
|
60
|
+
if not tag.startswith('v'):
|
|
61
|
+
sys.exit(0)
|
|
62
|
+
tag_ver = tag.lstrip('v')
|
|
63
|
+
pyproject = tomllib.loads(Path('pyproject.toml').read_text(encoding='utf-8'))
|
|
64
|
+
toml_ver = pyproject.get('project', {}).get('version', '')
|
|
65
|
+
|
|
66
|
+
from qv import __version__ as code_ver
|
|
67
|
+
|
|
68
|
+
errors = []
|
|
69
|
+
if tag_ver != toml_ver:
|
|
70
|
+
errors.append(f'Git tag version ({tag_ver}) != pyproject.toml version ({toml_ver})')
|
|
71
|
+
if tag_ver != code_ver:
|
|
72
|
+
errors.append(f'Git tag version ({tag_ver}) != qv.__version__ ({code_ver})')
|
|
73
|
+
|
|
74
|
+
if errors:
|
|
75
|
+
for err in errors:
|
|
76
|
+
print(f'::error::{err}')
|
|
77
|
+
sys.exit(1)
|
|
78
|
+
print(f'✓ Tag {tag} strictly matches pyproject.toml and qv.__version__ ({tag_ver})')
|
|
79
|
+
"
|
|
80
|
+
|
|
81
|
+
- name: Lint and formatting checks
|
|
49
82
|
run: |
|
|
50
83
|
uv run ruff check .
|
|
51
84
|
uv run ruff format --check .
|
|
52
85
|
|
|
53
|
-
- name:
|
|
54
|
-
run: uv run
|
|
86
|
+
- name: Static type checking
|
|
87
|
+
run: uv run pyright
|
|
88
|
+
|
|
89
|
+
- name: Run test suite with coverage
|
|
90
|
+
run: uv run pytest --cov=src/qv --cov-report=term-missing
|
|
55
91
|
|
|
56
92
|
build:
|
|
57
|
-
name: Build &
|
|
93
|
+
name: Build, Attest & Release Assets
|
|
58
94
|
needs: [validate]
|
|
59
95
|
runs-on: ubuntu-latest
|
|
60
96
|
permissions:
|
|
61
|
-
contents:
|
|
97
|
+
contents: write
|
|
62
98
|
id-token: write
|
|
63
99
|
attestations: write
|
|
64
100
|
|
|
@@ -88,10 +124,19 @@ jobs:
|
|
|
88
124
|
path: dist/
|
|
89
125
|
if-no-files-found: error
|
|
90
126
|
|
|
127
|
+
- name: Create or Update GitHub Release with Notes
|
|
128
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
129
|
+
uses: softprops/action-gh-release@v2
|
|
130
|
+
with:
|
|
131
|
+
files: dist/*
|
|
132
|
+
generate_release_notes: true
|
|
133
|
+
draft: false
|
|
134
|
+
prerelease: contains(github.ref, '-')
|
|
135
|
+
|
|
91
136
|
publish-to-pypi:
|
|
92
137
|
name: Publish to PyPI
|
|
93
138
|
needs: [build]
|
|
94
|
-
if: (github.
|
|
139
|
+
if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
|
|
95
140
|
runs-on: ubuntu-latest
|
|
96
141
|
environment:
|
|
97
142
|
name: pypi
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: ruff-check
|
|
5
|
+
name: ruff check & fix
|
|
6
|
+
entry: uv run ruff check --fix .
|
|
7
|
+
language: system
|
|
8
|
+
pass_filenames: false
|
|
9
|
+
always_run: true
|
|
10
|
+
stages: [pre-commit]
|
|
11
|
+
|
|
12
|
+
- id: ruff-format
|
|
13
|
+
name: ruff format
|
|
14
|
+
entry: uv run ruff format .
|
|
15
|
+
language: system
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
always_run: true
|
|
18
|
+
stages: [pre-commit]
|
|
19
|
+
|
|
20
|
+
- id: qv-scan
|
|
21
|
+
name: qv health scan
|
|
22
|
+
entry: uv run qv scan
|
|
23
|
+
language: system
|
|
24
|
+
args: [--strict, --offline]
|
|
25
|
+
pass_filenames: false
|
|
26
|
+
always_run: true
|
|
27
|
+
stages: [pre-commit]
|
|
28
|
+
|
|
29
|
+
- id: pytest-check
|
|
30
|
+
name: pytest test suite
|
|
31
|
+
entry: uv run pytest
|
|
32
|
+
language: system
|
|
33
|
+
pass_filenames: false
|
|
34
|
+
always_run: true
|
|
35
|
+
stages: [pre-commit, pre-push]
|
|
36
|
+
|
|
37
|
+
- id: pyright-check
|
|
38
|
+
name: pyright typecheck
|
|
39
|
+
entry: uv run pyright
|
|
40
|
+
language: system
|
|
41
|
+
pass_filenames: false
|
|
42
|
+
always_run: true
|
|
43
|
+
stages: [pre-commit, pre-push]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
- id: qv-scan
|
|
2
|
+
name: qv scan
|
|
3
|
+
description: Diagnose Python project health, dependencies, and environment consistency
|
|
4
|
+
entry: qv scan
|
|
5
|
+
language: python
|
|
6
|
+
types_or: [python, toml, yaml, dockerfile]
|
|
7
|
+
pass_filenames: false
|
|
8
|
+
always_run: true
|
|
9
|
+
|
|
10
|
+
- id: qv-fix
|
|
11
|
+
name: qv fix
|
|
12
|
+
description: Automatically remediate safe Python project health issues
|
|
13
|
+
entry: qv fix -y
|
|
14
|
+
language: python
|
|
15
|
+
types_or: [python, toml]
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
always_run: true
|
|
@@ -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
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-10-01
|
|
11
|
+
|
|
12
|
+
Initial public release of `qv` — the proactive health diagnostics and remediation platform for Python projects.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- **Diagnostic Engine & Analyzers**:
|
|
16
|
+
- `DEP-001`: Dependency version constraint conflict detection.
|
|
17
|
+
- `DEP-002`: Missing undeclared package imports.
|
|
18
|
+
- `DEP-003`: Unused declared dependencies.
|
|
19
|
+
- `DEP-004`: Python target runtime incompatibility.
|
|
20
|
+
- `DEP-005`: Virtualenv vs declared pin drift.
|
|
21
|
+
- `DEP-006`: Known vulnerability/CVE reporting.
|
|
22
|
+
- `ENV-001`: Python interpreter version drift.
|
|
23
|
+
- `ENV-002`: Dockerfile base image Python version drift.
|
|
24
|
+
- `ENV-003`: CI matrix coverage drift.
|
|
25
|
+
- `IMP-001`: Circular import cycle detection with Tarjan's SCC algorithm.
|
|
26
|
+
- `IMP-002`: Unresolvable internal module imports.
|
|
27
|
+
- `IMP-003`: Orphan / dead internal modules.
|
|
28
|
+
- `IMP-004`: Deprecated / removed standard library modules (PEP 594).
|
|
29
|
+
- `PKG-001`: Missing PEP 621 packaging metadata.
|
|
30
|
+
- `PKG-002`: Invalid `pyproject.toml` syntax.
|
|
31
|
+
- **Reporting & Visualizers**:
|
|
32
|
+
- Interactive Terminal Explorer (TUI) with keyboard navigation (`qv inspect`, `qv ui`).
|
|
33
|
+
- Self-contained, single-file interactive HTML report generator (`qv scan --html`).
|
|
34
|
+
- Standard SARIF v2.1.0 report exporter (`qv scan --sarif`).
|
|
35
|
+
- Machine-readable JSON reporter (`qv scan --json`).
|
|
36
|
+
- Color-coded Rich terminal reporter with circular health score gauge.
|
|
37
|
+
- Dependency and import architecture visualizers (`qv tree`, `qv graph`).
|
|
38
|
+
- **Remediation**:
|
|
39
|
+
- Safe automated fix engine (`qv fix`) with dry-run previews, interactive confirmations, and package manager sync.
|
|
40
|
+
- **Ecosystem & CI/CD**:
|
|
41
|
+
- Native pre-commit hooks (`qv-scan`, `qv-fix`).
|
|
42
|
+
- Official GitHub Action (`action.yml`) with automated PR annotations and Step Summary markdown.
|
|
43
|
+
- Automated PyPI publishing workflow with SLSA build provenance attestations.
|
|
44
|
+
- Comprehensive documentation site built with MkDocs Material and configured for ReadTheDocs.
|