pycode-kg 0.23.0__tar.gz → 0.24.0__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.
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/PKG-INFO +9 -9
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/README.md +4 -4
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/pyproject.toml +31 -8
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/__init__.py +1 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/analysis/bridge.py +0 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/analysis/centrality.py +0 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/analysis/framework_detector.py +0 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_hooks.py +52 -11
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_init.py +4 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_quilt.py +0 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_snapshot.py +4 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/pycodekg.py +0 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/pycodekg_thorough_analysis.py +266 -73
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/report.py +39 -2
- pycode_kg-0.24.0/src/pycode_kg/resolution.py +211 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/scene3d.py +5 -51
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/snapshots.py +16 -1
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/viz3d.py +45 -47
- pycode_kg-0.23.0/src/pycode_kg/resolution.py +0 -95
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/LICENSE +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/.DS_Store +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/__main__.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/analysis/__init__.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/app.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/architecture.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/__init__.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_analyze.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_architecture.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_bridges.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_build.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_build_full.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_centrality.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_explain.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_framework_nodes.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_mcp.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_model.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_query.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/cmd_viz.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/main.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/cli/options.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/config.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/explain.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/graph.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/graph_html.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/index.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/kg.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/layout3d.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/mcp_server.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/module/__init__.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/module/base.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/module/extractor.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/module/types.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/ranking/__init__.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/ranking/cli_rank.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/ranking/coderank.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/render.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/store.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/theme.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/utils.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/visitor.py +0 -0
- {pycode_kg-0.23.0 → pycode_kg-0.24.0}/src/pycode_kg/viz3d_timeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycode-kg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.0
|
|
4
4
|
Summary: A tool to build a searchable knowledge graph from Python repositories
|
|
5
5
|
License-Expression: Elastic-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -21,8 +21,8 @@ Provides-Extra: viz3d
|
|
|
21
21
|
Requires-Dist: PyQt5 (>=5.15.0) ; extra == "all"
|
|
22
22
|
Requires-Dist: PyQt5 (>=5.15.0) ; extra == "viz3d"
|
|
23
23
|
Requires-Dist: click (>=8.1.0,<9)
|
|
24
|
-
Requires-Dist: kgmodule-utils[semantic,viz3d] (>=0.
|
|
25
|
-
Requires-Dist: kgmodule-utils[viz3d-render] (>=0.
|
|
24
|
+
Requires-Dist: kgmodule-utils[semantic,viz3d] (>=0.18.0)
|
|
25
|
+
Requires-Dist: kgmodule-utils[viz3d-qt,viz3d-render] (>=0.18.0) ; extra == "viz3d"
|
|
26
26
|
Requires-Dist: markdown (>=3.6) ; extra == "all"
|
|
27
27
|
Requires-Dist: markdown (>=3.6) ; extra == "viz3d"
|
|
28
28
|
Requires-Dist: mcp (>=1.0.0,<2)
|
|
@@ -38,8 +38,8 @@ Requires-Dist: pyvis (>=0.3.2) ; extra == "viz"
|
|
|
38
38
|
Requires-Dist: pyvista (>=0.44.0) ; extra == "all"
|
|
39
39
|
Requires-Dist: pyvistaqt (>=0.11.0) ; extra == "all"
|
|
40
40
|
Requires-Dist: pyvistaqt (>=0.11.0) ; extra == "viz3d"
|
|
41
|
-
Requires-Dist: quiltwright (>=0.
|
|
42
|
-
Requires-Dist: quiltwright (>=0.
|
|
41
|
+
Requires-Dist: quiltwright (>=0.8.0) ; extra == "all"
|
|
42
|
+
Requires-Dist: quiltwright (>=0.8.0) ; extra == "viz3d"
|
|
43
43
|
Requires-Dist: rich (>=14.3.3,<15)
|
|
44
44
|
Requires-Dist: sentence-transformers (>=5.4.1)
|
|
45
45
|
Requires-Dist: sqlite-vec (==0.1.9)
|
|
@@ -60,7 +60,7 @@ Description-Content-Type: text/markdown
|
|
|
60
60
|
|
|
61
61
|
[](https://www.python.org/)
|
|
62
62
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
63
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
64
64
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
65
65
|
[](https://python-poetry.org/)
|
|
66
66
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
@@ -255,7 +255,7 @@ src/pycode_kg/
|
|
|
255
255
|
└── viz3d_timeline.py # Metric history timeline
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
-
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.
|
|
258
|
+
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.24.0.md](docs/analysis_v0.24.0.md), produced (of course) by `pycodekg analyze` against this very repo.
|
|
259
259
|
|
|
260
260
|
---
|
|
261
261
|
|
|
@@ -282,13 +282,13 @@ If you use PyCodeKG in your research or project, please cite it:
|
|
|
282
282
|
|
|
283
283
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
284
284
|
|
|
285
|
-
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.
|
|
285
|
+
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.24.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19737993
|
|
286
286
|
|
|
287
287
|
```bibtex
|
|
288
288
|
@software{suchanek_pycode_kg,
|
|
289
289
|
author = {Suchanek, Eric G.},
|
|
290
290
|
title = {{PyCodeKG}: A Knowledge Graph for Python Codebases},
|
|
291
|
-
version = {0.
|
|
291
|
+
version = {0.24.0},
|
|
292
292
|
year = {2026},
|
|
293
293
|
publisher = {Flux-Frontiers},
|
|
294
294
|
url = {https://github.com/Flux-Frontiers/pycode_kg},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
8
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
9
9
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
10
10
|
[](https://python-poetry.org/)
|
|
11
11
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
@@ -200,7 +200,7 @@ src/pycode_kg/
|
|
|
200
200
|
└── viz3d_timeline.py # Metric history timeline
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.
|
|
203
|
+
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.24.0.md](docs/analysis_v0.24.0.md), produced (of course) by `pycodekg analyze` against this very repo.
|
|
204
204
|
|
|
205
205
|
---
|
|
206
206
|
|
|
@@ -227,13 +227,13 @@ If you use PyCodeKG in your research or project, please cite it:
|
|
|
227
227
|
|
|
228
228
|
[](https://zenodo.org/badge/latestdoi/1202379010)
|
|
229
229
|
|
|
230
|
-
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.
|
|
230
|
+
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.24.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19737993
|
|
231
231
|
|
|
232
232
|
```bibtex
|
|
233
233
|
@software{suchanek_pycode_kg,
|
|
234
234
|
author = {Suchanek, Eric G.},
|
|
235
235
|
title = {{PyCodeKG}: A Knowledge Graph for Python Codebases},
|
|
236
|
-
version = {0.
|
|
236
|
+
version = {0.24.0},
|
|
237
237
|
year = {2026},
|
|
238
238
|
publisher = {Flux-Frontiers},
|
|
239
239
|
url = {https://github.com/Flux-Frontiers/pycode_kg},
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# pyproject.toml — PyCodeKG package configuration (PEP 621)
|
|
2
2
|
#
|
|
3
3
|
# Author: Eric G. Suchanek, PhD
|
|
4
|
-
# Last Revision: 2026-08-15
|
|
5
4
|
#
|
|
6
5
|
# Build system : Poetry 2.x with PEP 621 [project] table
|
|
7
6
|
#
|
|
@@ -71,7 +70,7 @@ torch = [
|
|
|
71
70
|
# ---------------------------------------------------------------------------
|
|
72
71
|
[project]
|
|
73
72
|
name = "pycode-kg"
|
|
74
|
-
version = "0.
|
|
73
|
+
version = "0.24.0"
|
|
75
74
|
description = "A tool to build a searchable knowledge graph from Python repositories"
|
|
76
75
|
readme = "README.md"
|
|
77
76
|
license = "Elastic-2.0"
|
|
@@ -137,7 +136,21 @@ dependencies = [
|
|
|
137
136
|
# Its only dependency is numpy, which `[semantic]` already pulls, so it adds
|
|
138
137
|
# nothing to the install — it just declares what layout3d actually imports.
|
|
139
138
|
# Unlike `[viz]`, there is no pyvis to leak into a bare install.
|
|
140
|
-
|
|
139
|
+
# Floor is 0.13.x rather than 0.12.1 because that is where SnapshotManager
|
|
140
|
+
# stops writing absolute paths into snapshot JSON. This package ships
|
|
141
|
+
# `pycodekg snapshot save`, and those snapshots get committed to the
|
|
142
|
+
# user's repo — against an older kgmodule-utils the command writes their
|
|
143
|
+
# home directory and username into version control.
|
|
144
|
+
#
|
|
145
|
+
# 0.13.2 specifically, never 0.13.1: that release carried the path fix but
|
|
146
|
+
# also made `repo_root` a read-only property, which breaks every subclass
|
|
147
|
+
# that assigns it. 0.13.2 keeps the fix and restores the plain attribute.
|
|
148
|
+
#
|
|
149
|
+
# 0.15.0 because the `viz3d` extra below needs kg_utils.viz3d.qt, and this
|
|
150
|
+
# repo's own rule is one floor per package — a lower floor here would leave
|
|
151
|
+
# a reader working out which constraint actually binds. Nothing in the core
|
|
152
|
+
# install needs 0.15.0 functionally; it is a superset of 0.14.0.
|
|
153
|
+
"kgmodule-utils[semantic,viz3d]>=0.18.0",
|
|
141
154
|
]
|
|
142
155
|
|
|
143
156
|
[project.optional-dependencies]
|
|
@@ -154,12 +167,22 @@ viz3d = [
|
|
|
154
167
|
# and smooth_paths live there. The main dependency above stays on plain
|
|
155
168
|
# [viz3d] (numpy only) so the nine repos that take pycode-kg do not acquire
|
|
156
169
|
# VTK for a layout import; rendering stays opt-in, here.
|
|
157
|
-
|
|
170
|
+
# Same floor as the core declaration above — one package, one floor, so a
|
|
171
|
+
# reader does not have to work out which constraint actually binds.
|
|
172
|
+
# [viz3d-qt] (new in 0.15.0) adds kg_utils.viz3d.qt — the Qt machinery a
|
|
173
|
+
# viewer needs to cast: the render lifecycle and cast_scene_to_looking_glass,
|
|
174
|
+
# which this module's "Cast to LG" button now drives instead of open-coding
|
|
175
|
+
# the four-step build/render/write/cast itself. It subsumes [viz3d-render]
|
|
176
|
+
# (it declares pyvista too), but both are named so the dependency reads as
|
|
177
|
+
# what it is rather than as a side effect.
|
|
178
|
+
"kgmodule-utils[viz3d-render,viz3d-qt]>=0.18.0",
|
|
158
179
|
"pyvistaqt>=0.11.0",
|
|
159
180
|
"trame-vtk>=2.0.0",
|
|
160
181
|
# Looking Glass quilts. 0.4.0 supplies depth_report() and widened
|
|
161
|
-
# requires-python to <3.14, which retires the old marker gate.
|
|
162
|
-
|
|
182
|
+
# requires-python to <3.14, which retires the old marker gate. 0.6.0 adds
|
|
183
|
+
# QuiltSpec.scaled(), which replaces the tile-grid rounding this repo used
|
|
184
|
+
# to open-code, and save_and_cast_quilt() underneath the SDK cast helper.
|
|
185
|
+
"quiltwright>=0.8.0",
|
|
163
186
|
]
|
|
164
187
|
|
|
165
188
|
# Cross-KG sibling packages (doc-kg, pycode-kg, agent-kg, kg-rag) are NOT
|
|
@@ -184,7 +207,7 @@ all = [
|
|
|
184
207
|
"pyvis>=0.3.2",
|
|
185
208
|
"pyvista>=0.44.0",
|
|
186
209
|
"pyvistaqt>=0.11.0",
|
|
187
|
-
"quiltwright>=0.
|
|
210
|
+
"quiltwright>=0.8.0",
|
|
188
211
|
"streamlit>=1.56.0",
|
|
189
212
|
"trame-vtk>=2.0.0",
|
|
190
213
|
]
|
|
@@ -226,7 +249,7 @@ ty = ">=0.0.41"
|
|
|
226
249
|
optional = true
|
|
227
250
|
|
|
228
251
|
[tool.poetry.group.kg.dependencies]
|
|
229
|
-
doc-kg = ">=0.
|
|
252
|
+
doc-kg = ">=0.22.0"
|
|
230
253
|
|
|
231
254
|
[project.urls]
|
|
232
255
|
Homepage = "https://github.com/Flux-Frontiers/pycode_kg"
|
|
@@ -6,7 +6,6 @@ CLI command for installing PyCodeKG git hooks:
|
|
|
6
6
|
install-hooks — install the pre-commit snapshot hook into .git/hooks/
|
|
7
7
|
|
|
8
8
|
Author: Eric G. Suchanek, PhD
|
|
9
|
-
Last Revision: 2026-08-11 19:32:52
|
|
10
9
|
|
|
11
10
|
Author: Eric G. Suchanek, PhD
|
|
12
11
|
|
|
@@ -29,10 +28,33 @@ from pycode_kg.cli.main import cli
|
|
|
29
28
|
|
|
30
29
|
_PRE_COMMIT_HOOK = """\
|
|
31
30
|
#!/usr/bin/env bash
|
|
32
|
-
# PyCodeKG pre-commit hook — runs quality checks
|
|
33
|
-
#
|
|
31
|
+
# PyCodeKG pre-commit hook — runs quality checks. The index rebuild and metrics
|
|
32
|
+
# snapshot are opt-in and OFF by default; see "Why snapshots are off" below.
|
|
34
33
|
# Installed by: pycodekg install-hooks
|
|
35
|
-
#
|
|
34
|
+
#
|
|
35
|
+
# PYCODEKG_SNAPSHOT=1 git commit ... opt in to a per-commit snapshot
|
|
36
|
+
# PYCODEKG_SKIP_SNAPSHOT=1 git commit ... force snapshots off (wins)
|
|
37
|
+
#
|
|
38
|
+
# Note that PYCODEKG_SKIP_SNAPSHOT no longer skips the quality checks. It used
|
|
39
|
+
# to short-circuit the whole hook, so a variable named "skip snapshot" also
|
|
40
|
+
# silently skipped ruff, ty and pytest. It now gates only what it names.
|
|
41
|
+
#
|
|
42
|
+
# Why snapshots are off by default (2026-08-18)
|
|
43
|
+
# ---------------------------------------------
|
|
44
|
+
# A per-commit snapshot records `git write-tree` and is then itself staged into
|
|
45
|
+
# that same commit. Staging changes the index, so the recorded hash can never
|
|
46
|
+
# equal the tree it claims to describe — and manifest.json carries a
|
|
47
|
+
# `last_update` timestamp, so the `git add` is never a no-op. The drift is
|
|
48
|
+
# guaranteed by construction, not caused by formatting, and reordering does not
|
|
49
|
+
# fix it: the `git add` lands after the hash either way.
|
|
50
|
+
#
|
|
51
|
+
# An audit of 605 snapshots across 29 fleet manifests found 63 (10.4%) keyed to
|
|
52
|
+
# a tree any commit actually has. `snapshot diff` between adjacent entries has
|
|
53
|
+
# therefore been comparing states that never existed.
|
|
54
|
+
#
|
|
55
|
+
# The fix is to snapshot at release, keyed on the tag rather than on an
|
|
56
|
+
# ephemeral pre-commit tree. See kgrag_priv/docs/SNAPSHOT_STRATEGY.md. Until
|
|
57
|
+
# that lands, this hook runs quality checks only.
|
|
36
58
|
#
|
|
37
59
|
# Order matters, and it is deliberately checks-then-index:
|
|
38
60
|
#
|
|
@@ -46,8 +68,6 @@ _PRE_COMMIT_HOOK = """\
|
|
|
46
68
|
# commit that ruff/ty/pytest is about to reject.
|
|
47
69
|
set -euo pipefail
|
|
48
70
|
|
|
49
|
-
[ "${PYCODEKG_SKIP_SNAPSHOT:-0}" = "1" ] && exit 0
|
|
50
|
-
|
|
51
71
|
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
52
72
|
|
|
53
73
|
cd "$REPO_ROOT"
|
|
@@ -63,12 +83,27 @@ elif command -v pre-commit &>/dev/null; then
|
|
|
63
83
|
pre-commit run || exit 1
|
|
64
84
|
fi
|
|
65
85
|
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
86
|
+
# ---------------------------------------------------------------------------
|
|
87
|
+
# Opt-in index rebuild + snapshot. Everything below is skipped unless
|
|
88
|
+
# PYCODEKG_SNAPSHOT=1 is set, and is skipped regardless if
|
|
89
|
+
# PYCODEKG_SKIP_SNAPSHOT=1.
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
[ "${PYCODEKG_SNAPSHOT:-0}" = "1" ] || exit 0
|
|
92
|
+
[ "${PYCODEKG_SKIP_SNAPSHOT:-0}" = "1" ] && exit 0
|
|
93
|
+
|
|
94
|
+
# Captured after the checks so nothing further modifies the working tree. Note
|
|
95
|
+
# the caveat above: this still cannot match the committed tree, because the
|
|
96
|
+
# `git add` below changes the index after this point.
|
|
69
97
|
TREE_HASH=$(git write-tree)
|
|
70
98
|
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
71
99
|
|
|
100
|
+
# Snapshots are default-branch history. On any other branch, stop here —
|
|
101
|
+
# feature-branch commits (and the PRs/CI built from them) stay free of
|
|
102
|
+
# generated snapshot files, and skip the 60-90s rebuild along the way.
|
|
103
|
+
DEFAULT_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null || true)
|
|
104
|
+
DEFAULT_BRANCH="${DEFAULT_BRANCH#origin/}"
|
|
105
|
+
[ "$BRANCH" != "${DEFAULT_BRANCH:-main}" ] && exit 0
|
|
106
|
+
|
|
72
107
|
# Rebuild the local index to keep it in sync with staged content.
|
|
73
108
|
"$REPO_ROOT/.venv/bin/pycodekg" build --repo "$REPO_ROOT" || exit 1
|
|
74
109
|
|
|
@@ -104,11 +139,14 @@ exit 0
|
|
|
104
139
|
def install_hooks(repo: str, force: bool) -> None:
|
|
105
140
|
"""Install the PyCodeKG pre-commit git hook.
|
|
106
141
|
|
|
107
|
-
After installation, before each commit:
|
|
142
|
+
After installation, before each commit on the default branch:
|
|
108
143
|
1. Rebuilds the local PyCodeKG index (full wipe)
|
|
109
144
|
2. Captures a metrics snapshot, keyed by tree hash
|
|
110
145
|
3. Stages the snapshot directory
|
|
111
146
|
|
|
147
|
+
On any other branch the quality checks still run but the rebuild and
|
|
148
|
+
snapshot are skipped, so feature-branch commits carry no generated files.
|
|
149
|
+
|
|
112
150
|
This keeps the index in sync and ensures snapshots reflect the state of
|
|
113
151
|
the knowledge graph at commit time. The hook only ever touches its own
|
|
114
152
|
repository — sibling KG repos install their own hooks.
|
|
@@ -137,5 +175,8 @@ def install_hooks(repo: str, force: bool) -> None:
|
|
|
137
175
|
hook_path.chmod(mode)
|
|
138
176
|
|
|
139
177
|
click.echo(f"OK Installed pre-commit hook: {hook_path}")
|
|
140
|
-
click.echo("
|
|
178
|
+
click.echo(" Quality checks run on every commit.")
|
|
179
|
+
click.echo(" Snapshots are OFF by default - see kgrag_priv/docs/SNAPSHOT_STRATEGY.md.")
|
|
180
|
+
click.echo(" Opt in with: PYCODEKG_SNAPSHOT=1 git commit ...")
|
|
181
|
+
click.echo(" Force off: PYCODEKG_SKIP_SNAPSHOT=1 git commit ...")
|
|
141
182
|
click.echo(" Run 'pycodekg build' first if you haven't built the graph yet.")
|
|
@@ -253,6 +253,8 @@ def init(
|
|
|
253
253
|
|
|
254
254
|
docstring_cov = analysis.get("docstring_coverage", {})
|
|
255
255
|
coverage = docstring_cov.get("coverage_pct", 0.0) / 100.0 if docstring_cov else 0.0
|
|
256
|
+
coverage_documented = docstring_cov.get("with_doc", 0)
|
|
257
|
+
coverage_total = docstring_cov.get("total", 0)
|
|
256
258
|
critical_issues = len(analysis.get("issues", []))
|
|
257
259
|
|
|
258
260
|
fn_metrics = analysis.get("function_metrics", {})
|
|
@@ -276,6 +278,8 @@ def init(
|
|
|
276
278
|
branch=branch,
|
|
277
279
|
graph_stats_dict=stats,
|
|
278
280
|
coverage=coverage,
|
|
281
|
+
coverage_documented=coverage_documented,
|
|
282
|
+
coverage_total=coverage_total,
|
|
279
283
|
critical_issues=critical_issues,
|
|
280
284
|
complexity_median=complexity_median,
|
|
281
285
|
hotspots=hotspots,
|
|
@@ -111,6 +111,8 @@ def save_snapshot(
|
|
|
111
111
|
# Extract metrics from analysis results
|
|
112
112
|
docstring_cov = analysis.get("docstring_coverage", {})
|
|
113
113
|
coverage = docstring_cov.get("coverage_pct", 0.0) / 100.0 if docstring_cov else 0.0
|
|
114
|
+
coverage_documented = docstring_cov.get("with_doc", 0)
|
|
115
|
+
coverage_total = docstring_cov.get("total", 0)
|
|
114
116
|
issue_strings = analysis.get("issues", [])
|
|
115
117
|
critical_issues = len(issue_strings)
|
|
116
118
|
|
|
@@ -140,6 +142,8 @@ def save_snapshot(
|
|
|
140
142
|
branch=branch,
|
|
141
143
|
graph_stats_dict=stats,
|
|
142
144
|
coverage=coverage,
|
|
145
|
+
coverage_documented=coverage_documented,
|
|
146
|
+
coverage_total=coverage_total,
|
|
143
147
|
critical_issues=critical_issues,
|
|
144
148
|
complexity_median=complexity_median,
|
|
145
149
|
hotspots=hotspots,
|