sql-code-graph 1.34.0__py3-none-any.whl → 1.34.1__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.
- {sql_code_graph-1.34.0.dist-info → sql_code_graph-1.34.1.dist-info}/METADATA +1 -1
- {sql_code_graph-1.34.0.dist-info → sql_code_graph-1.34.1.dist-info}/RECORD +7 -7
- sqlcg/__init__.py +1 -1
- sqlcg/cli/commands/git.py +46 -17
- sqlcg/cli/commands/reindex.py +65 -0
- {sql_code_graph-1.34.0.dist-info → sql_code_graph-1.34.1.dist-info}/WHEEL +0 -0
- {sql_code_graph-1.34.0.dist-info → sql_code_graph-1.34.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sql-code-graph
|
|
3
|
-
Version: 1.34.
|
|
3
|
+
Version: 1.34.1
|
|
4
4
|
Summary: SQL code graph analyzer and lineage tracer
|
|
5
5
|
Project-URL: Homepage, https://github.com/Warhorze/sql-code-graph
|
|
6
6
|
Project-URL: Repository, https://github.com/Warhorze/sql-code-graph
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
sqlcg/__init__.py,sha256=
|
|
1
|
+
sqlcg/__init__.py,sha256=41PZf0zcZBhUQbwRo78_ftWrsT-lF8uXFf2sQm3NIKc,116
|
|
2
2
|
sqlcg/__main__.py,sha256=1YoFLcqEgTwYq1J3TbUwpkdG0zeeLIf2fJvwWI-CLFU,109
|
|
3
3
|
sqlcg/cli/__init__.py,sha256=W8fD0LpMq2xm_5WKGNMvJh2WBL1ho5E8hUeAqXQYT1g,28
|
|
4
4
|
sqlcg/cli/coverage.py,sha256=Xm9ITzZDHv2mJ70Q5jCacVuhDStVrE3gq12_-Ypvtd8,43823
|
|
@@ -9,11 +9,11 @@ sqlcg/cli/commands/catalog.py,sha256=xCIWp_9xcDPHIMUB0xrZR3-G0WMvKbfq4yMwe2sDT2g
|
|
|
9
9
|
sqlcg/cli/commands/db.py,sha256=QEDPs0boeFe8ETE8BWe7I2JLSXROUI571SHXMTUqxh8,7982
|
|
10
10
|
sqlcg/cli/commands/find.py,sha256=uMdG08bU-AvB9RqsTKPfdVnJet7b3Ebj0xbsjqTclYA,2678
|
|
11
11
|
sqlcg/cli/commands/gain.py,sha256=PQCWjlisjUY4Gz_MkppXPI1_w8xsB4DPlN7uAxx0GvY,10149
|
|
12
|
-
sqlcg/cli/commands/git.py,sha256=
|
|
12
|
+
sqlcg/cli/commands/git.py,sha256=IB6Pypo_0RYd8rsKQLdP73OnlZUidZJ8_czQe1SNdOc,8857
|
|
13
13
|
sqlcg/cli/commands/index.py,sha256=KGy0vPlvFcMetBjT5wIEvEcy9MEcLt7lhNaKfRWUkgU,19502
|
|
14
14
|
sqlcg/cli/commands/install.py,sha256=4aZzvDNdl2Ea5v-ufR8Oj1qq30oGS_9jX17etYpoan8,10148
|
|
15
15
|
sqlcg/cli/commands/mcp.py,sha256=drh5udcroZFddmJAG3q9JWxekDqTO9H4xC-oIqiis-Y,14871
|
|
16
|
-
sqlcg/cli/commands/reindex.py,sha256=
|
|
16
|
+
sqlcg/cli/commands/reindex.py,sha256=6j1QL3TjrsnWaFSIKvpGJ3LF8CoCjAbue0UFtmk9FS0,22704
|
|
17
17
|
sqlcg/cli/commands/report.py,sha256=JU0qjyMxwOukE7bN3XvvIzOI7zMg_Gsnvk_8F6pKNpA,4915
|
|
18
18
|
sqlcg/cli/commands/uninstall.py,sha256=WrA1FnINxnd6mmE4-_QBK0aHBnibstJeAT8swnQKG4M,8962
|
|
19
19
|
sqlcg/cli/commands/watch.py,sha256=_OvUQ4m_Pp2lAzI_f9UX2Gwb56zbsaSC4Tj8h51uciA,2806
|
|
@@ -65,7 +65,7 @@ sqlcg/utils/__init__.py,sha256=--iqt5ThTXmT8Wz7da8hs3n0zDfYPl8P-z5OgRJ_77E,154
|
|
|
65
65
|
sqlcg/utils/hashing.py,sha256=H25-sYfxHKb3_IERFnHyAIYNiXN470Oqo5sJT_D3YOA,438
|
|
66
66
|
sqlcg/utils/ignore.py,sha256=6__DfiYgynI2b8nH52O2BzI1EZcZ_LRazhqEOJVGGcE,1955
|
|
67
67
|
sqlcg/utils/logging.py,sha256=u0fCmYsLj9o81vawm3xZTHaw68GQYVm7JxG-gP81u8A,840
|
|
68
|
-
sql_code_graph-1.34.
|
|
69
|
-
sql_code_graph-1.34.
|
|
70
|
-
sql_code_graph-1.34.
|
|
71
|
-
sql_code_graph-1.34.
|
|
68
|
+
sql_code_graph-1.34.1.dist-info/METADATA,sha256=UtXmf-S4GYLSS7MuPpYJxhaJ7fOmbZwSR54RnSyVGPw,17791
|
|
69
|
+
sql_code_graph-1.34.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
70
|
+
sql_code_graph-1.34.1.dist-info/entry_points.txt,sha256=Wfe49sVzV9p4eVFGo5RxcV-frr3HOP0yzzst8JBxQLQ,46
|
|
71
|
+
sql_code_graph-1.34.1.dist-info/RECORD,,
|
sqlcg/__init__.py
CHANGED
sqlcg/cli/commands/git.py
CHANGED
|
@@ -23,6 +23,29 @@ class _HookSpec(NamedTuple):
|
|
|
23
23
|
# Hook script templates — use {sqlcg_bin} as the placeholder for the resolved binary.
|
|
24
24
|
# The sentinel comments (e.g. "# sqlcg post-checkout hook") must stay byte-for-byte
|
|
25
25
|
# unchanged so R9 idempotency is preserved: _install_single_hook matches them verbatim.
|
|
26
|
+
#
|
|
27
|
+
# Run-time binary resolution (#126 + #1): the hook no longer trusts the single embedded
|
|
28
|
+
# absolute literal to stay valid forever (a venv rebuild or tool upgrade makes the
|
|
29
|
+
# install-time path stale and the resync would then run a wrong/missing binary). Instead
|
|
30
|
+
# the shared _RESOLVE_PREAMBLE resolves the binary at *run time* with a hybrid order:
|
|
31
|
+
# 1. the preferred path rendered in at install time ({sqlcg_bin}, normally the stable
|
|
32
|
+
# user-base binary from _resolve_sqlcg_bin) — the fast path, used if still executable;
|
|
33
|
+
# 2. `command -v sqlcg` on $PATH — covers uv-tool, user-base-on-PATH, and active-venv;
|
|
34
|
+
# 3. neither resolves → print a loud stderr error and exit non-zero (never silent).
|
|
35
|
+
# The shell never recomputes getuserbase() — the preferred path is rendered in by Python.
|
|
36
|
+
# It exports SQLCG_BIN for the hook body to invoke.
|
|
37
|
+
_RESOLVE_PREAMBLE = (
|
|
38
|
+
'if [ -x "{sqlcg_bin}" ]; then\n'
|
|
39
|
+
' SQLCG_BIN="{sqlcg_bin}"\n'
|
|
40
|
+
"elif command -v sqlcg >/dev/null 2>&1; then\n"
|
|
41
|
+
' SQLCG_BIN="$(command -v sqlcg)"\n'
|
|
42
|
+
"else\n"
|
|
43
|
+
" echo \"sqlcg: cannot find the sqlcg binary (tried '{sqlcg_bin}' and \\$PATH)"
|
|
44
|
+
" -- run 'sqlcg git install-hooks' to repoint this hook\" >&2\n"
|
|
45
|
+
" exit 1\n"
|
|
46
|
+
"fi\n"
|
|
47
|
+
)
|
|
48
|
+
|
|
26
49
|
_HOOKS: list[_HookSpec] = [
|
|
27
50
|
_HookSpec(
|
|
28
51
|
filename="post-checkout",
|
|
@@ -32,7 +55,8 @@ _HOOKS: list[_HookSpec] = [
|
|
|
32
55
|
"# sqlcg post-checkout hook — incremental resync after branch switch\n"
|
|
33
56
|
"# $3 == 1 means branch checkout (not file checkout); skip file checkouts\n"
|
|
34
57
|
'[ "$3" = "1" ] || exit 0\n'
|
|
35
|
-
|
|
58
|
+
+ _RESOLVE_PREAMBLE
|
|
59
|
+
+ '"$SQLCG_BIN" reindex --from "$1" --to "$2"'
|
|
36
60
|
' "$(git rev-parse --show-toplevel)" --dialect auto --quiet --notify'
|
|
37
61
|
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
38
62
|
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
@@ -41,22 +65,27 @@ _HOOKS: list[_HookSpec] = [
|
|
|
41
65
|
_HookSpec(
|
|
42
66
|
filename="post-merge",
|
|
43
67
|
sentinel="# sqlcg post-merge hook",
|
|
44
|
-
script_template=
|
|
45
|
-
#!/bin/sh
|
|
46
|
-
# sqlcg post-merge hook — incremental resync after pull/merge
|
|
47
|
-
# git sets ORIG_HEAD to the pre-merge HEAD; pass it as --from so --notify
|
|
48
|
-
# through a running server (same path as post-checkout). If
|
|
49
|
-
# first-ever merge / gc'd), fall back to the
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|| echo "sqlcg: graph not updated (reindex failed)
|
|
58
|
-
|
|
59
|
-
""
|
|
68
|
+
script_template=(
|
|
69
|
+
"#!/bin/sh\n"
|
|
70
|
+
"# sqlcg post-merge hook — incremental resync after pull/merge\n"
|
|
71
|
+
"# git sets ORIG_HEAD to the pre-merge HEAD; pass it as --from so --notify\n"
|
|
72
|
+
"# can route through a running server (same path as post-checkout). If\n"
|
|
73
|
+
"# ORIG_HEAD is unset (e.g. first-ever merge / gc'd), fall back to the\n"
|
|
74
|
+
"# standalone stored-SHA delta (direct write).\n"
|
|
75
|
+
+ _RESOLVE_PREAMBLE
|
|
76
|
+
+ "PREV=$(git rev-parse --verify --quiet ORIG_HEAD)\n"
|
|
77
|
+
"TOP=$(git rev-parse --show-toplevel)\n"
|
|
78
|
+
'if [ -n "$PREV" ]; then\n'
|
|
79
|
+
' "$SQLCG_BIN" reindex --from "$PREV" --to HEAD "$TOP" --dialect auto'
|
|
80
|
+
" --quiet --notify \\\n"
|
|
81
|
+
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
82
|
+
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
83
|
+
"else\n"
|
|
84
|
+
' "$SQLCG_BIN" reindex "$TOP" --dialect auto --quiet --notify \\\n'
|
|
85
|
+
' || echo "sqlcg: graph not updated (reindex failed)'
|
|
86
|
+
" -- run 'sqlcg mcp status'\" >&2\n"
|
|
87
|
+
"fi\n"
|
|
88
|
+
),
|
|
60
89
|
),
|
|
61
90
|
]
|
|
62
91
|
|
sqlcg/cli/commands/reindex.py
CHANGED
|
@@ -129,6 +129,11 @@ def reindex_cmd( # noqa: B008
|
|
|
129
129
|
# below) and return to git immediately. The respawn guard env var prevents
|
|
130
130
|
# the detached child from detaching again.
|
|
131
131
|
if _is_hook_path and os.environ.get(_HOOK_DETACHED_ENV) != "1":
|
|
132
|
+
# #1 — loud foreground preflight BEFORE detaching. The detached child's
|
|
133
|
+
# schema gate (below) writes its Exit(1) to the hook-resync log, invisible
|
|
134
|
+
# to the user, so a stale-binary schema skew dies silently (exit 0 to git).
|
|
135
|
+
# Surface a real mismatch in the foreground, where git's terminal can see it.
|
|
136
|
+
_hook_preflight_schema_check()
|
|
132
137
|
_spawn_detached_hook_resync(path)
|
|
133
138
|
return
|
|
134
139
|
|
|
@@ -291,6 +296,66 @@ def _spawn_detached_hook_resync(path: Path) -> None:
|
|
|
291
296
|
console.print(f"sqlcg: resyncing graph in background (log: {log_path})")
|
|
292
297
|
|
|
293
298
|
|
|
299
|
+
def _hook_preflight_schema_check() -> None:
|
|
300
|
+
"""Surface a stale-binary schema/version skew in the FOREGROUND hook process (#1).
|
|
301
|
+
|
|
302
|
+
On the hook path the resync is detached (#77), so the existing schema gate
|
|
303
|
+
(``reindex_cmd`` at ~:150) runs in the detached child whose stdout/stderr go to
|
|
304
|
+
``hook-resync.log`` — its ``Exit(1)`` never reaches the user's terminal and the
|
|
305
|
+
graph silently never refreshes. This preflight runs *before* the detach and, on a
|
|
306
|
+
REAL mismatch, prints a visible, actionable stderr message and exits non-zero
|
|
307
|
+
without detaching.
|
|
308
|
+
|
|
309
|
+
Git runs post-checkout/post-merge AFTER the operation and ignores the hook exit
|
|
310
|
+
status, so the **stderr message** is the load-bearing part (not the exit code).
|
|
311
|
+
|
|
312
|
+
BOUNDED, FAIL-SOFT open (plan-review B1 — MANDATED). DuckDB takes an exclusive
|
|
313
|
+
file lock: per ``config.py`` ``get_backend`` docstring, a second process cannot
|
|
314
|
+
open the DB at all (even read-only) while another holds it — it raises
|
|
315
|
+
``duckdb.IOException`` (#63). On rapid successive checkouts a prior detached
|
|
316
|
+
resync still holds the lock, so this open WILL contend. We therefore do a SINGLE
|
|
317
|
+
open attempt (NOT ``_open_backend_with_lock_retry``'s ~31 s retry, which would
|
|
318
|
+
stall ``git checkout`` — a #77-class regression) and, on ``IOException`` (lock
|
|
319
|
+
held ⇒ a resync is already in flight), treat it as "cannot determine — fall
|
|
320
|
+
through to the existing detach path unchanged": never block, never emit a
|
|
321
|
+
schema-mismatch error. Only a SUCCESSFUL read showing a real mismatch triggers
|
|
322
|
+
the loud exit. The backend is opened read-only and released before returning so
|
|
323
|
+
the detached child can still acquire the lock.
|
|
324
|
+
"""
|
|
325
|
+
import duckdb
|
|
326
|
+
|
|
327
|
+
from sqlcg.core.config import get_backend
|
|
328
|
+
from sqlcg.core.schema import SCHEMA_VERSION
|
|
329
|
+
|
|
330
|
+
try:
|
|
331
|
+
backend = get_backend(read_only=True)
|
|
332
|
+
except duckdb.IOException:
|
|
333
|
+
# Lock held by an in-flight resync — cannot determine; fall through to detach.
|
|
334
|
+
return
|
|
335
|
+
|
|
336
|
+
try:
|
|
337
|
+
with backend:
|
|
338
|
+
stored_version = backend.get_schema_version()
|
|
339
|
+
if stored_version is None or stored_version == SCHEMA_VERSION:
|
|
340
|
+
# Matches (or no stored version yet on a fresh graph) — detach as today.
|
|
341
|
+
return
|
|
342
|
+
indexed_tool_version = backend.get_indexed_version()
|
|
343
|
+
except duckdb.IOException:
|
|
344
|
+
# Lock raced after the open (e.g. closed-then-reopened by the writer);
|
|
345
|
+
# fail soft exactly as the open-time IOException path.
|
|
346
|
+
return
|
|
347
|
+
|
|
348
|
+
skew = f" (graph last indexed by sqlcg {indexed_tool_version})" if indexed_tool_version else ""
|
|
349
|
+
print(
|
|
350
|
+
f"sqlcg: graph schema is v{stored_version} but this tool needs "
|
|
351
|
+
f"v{SCHEMA_VERSION}{skew} — the hook binary is stale. "
|
|
352
|
+
"Run 'sqlcg git install-hooks' to repoint the hook, then "
|
|
353
|
+
"'sqlcg db reset && sqlcg index <root>'.",
|
|
354
|
+
file=sys.stderr,
|
|
355
|
+
)
|
|
356
|
+
raise typer.Exit(1)
|
|
357
|
+
|
|
358
|
+
|
|
294
359
|
def _open_backend_with_lock_retry() -> "GraphBackend":
|
|
295
360
|
"""Open the DuckDB backend, retrying with backoff if it is locked.
|
|
296
361
|
|
|
File without changes
|
|
File without changes
|