From 20253329e4e6daebb2d2d090a16f04def870efdf Mon Sep 17 00:00:00 2001 From: Jarvis Prime Date: Wed, 4 Mar 2026 04:32:17 +0000 Subject: [PATCH] Add db migrations, update watch.sh for uv + idempotent runs - Schema versioned with migrations table - watch.sh runs db migrations on every pull - watch.sh uses uv run/sync instead of pip - Fixed parser.py reference in watch.sh --- db.py | 45 +++++++++++++++++++++++++++++++++++++++------ watch.sh | 18 +++++++++++------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/db.py b/db.py index 190dbfe..6429fb6 100644 --- a/db.py +++ b/db.py @@ -15,10 +15,10 @@ def get_db() -> sqlite3.Connection: return conn -def init_db(): - """Create tables if they don't exist.""" - conn = get_db() - conn.executescript(""" +SCHEMA_VERSION = 2 + +MIGRATIONS = { + 1: """ CREATE TABLE IF NOT EXISTS repos ( name TEXT PRIMARY KEY, url TEXT, @@ -34,7 +34,7 @@ def init_db(): language TEXT, documentation TEXT, prev_documentation TEXT, - functions TEXT, -- JSON array + functions TEXT, last_commit TEXT, staleness TEXT DEFAULT 'fresh', updated_at TEXT @@ -54,9 +54,42 @@ def init_db(): CREATE INDEX IF NOT EXISTS idx_files_staleness ON files(staleness); CREATE INDEX IF NOT EXISTS idx_rels_staleness ON relationships(staleness); CREATE INDEX IF NOT EXISTS idx_rels_to ON relationships(to_file); - """) + """, + 2: """ + CREATE TABLE IF NOT EXISTS schema_version ( + version INTEGER PRIMARY KEY + ); + """, +} + + +def init_db(): + """Create or migrate the database schema.""" + conn = get_db() + + # Check current version + try: + row = conn.execute("SELECT MAX(version) AS v FROM schema_version").fetchone() + current = row["v"] or 0 + except sqlite3.OperationalError: + current = 0 + + if current >= SCHEMA_VERSION: + conn.close() + return + + # Run pending migrations + for v in range(current + 1, SCHEMA_VERSION + 1): + if v in MIGRATIONS: + print(f" [db] Running migration v{v}...") + conn.executescript(MIGRATIONS[v]) + + # Ensure schema_version table exists and record version + conn.execute("CREATE TABLE IF NOT EXISTS schema_version (version INTEGER PRIMARY KEY)") + conn.execute("INSERT OR REPLACE INTO schema_version (version) VALUES (?)", (SCHEMA_VERSION,)) conn.commit() conn.close() + print(f" [db] Schema at v{SCHEMA_VERSION}") class GraphDB: diff --git a/watch.sh b/watch.sh index 8668d61..81befd3 100755 --- a/watch.sh +++ b/watch.sh @@ -33,7 +33,7 @@ start_mcp() { wait "$MCP_PID" 2>/dev/null || true fi echo "[watch] Starting MCP server..." - python mcp_server.py & + uv run python mcp_server.py & MCP_PID=$! echo "[watch] MCP server started (pid $MCP_PID)" } @@ -52,7 +52,7 @@ echo "" # Initial setup LAST_HASH=$(get_local_hash) -LAST_REQS=$(md5sum requirements.txt 2>/dev/null || echo "none") +LAST_REQS=$(md5sum requirements.txt pyproject.toml 2>/dev/null || echo "none") # Start MCP server if [ -f "devintel.db" ]; then @@ -82,19 +82,23 @@ while true; do git pull --ff-only origin master # Check if requirements changed - NEW_REQS=$(md5sum requirements.txt 2>/dev/null || echo "none") + NEW_REQS=$(md5sum requirements.txt pyproject.toml 2>/dev/null || echo "none") if [ "$NEW_REQS" != "$LAST_REQS" ]; then - echo "[watch] requirements.txt changed — reinstalling..." - pip install -r requirements.txt + echo "[watch] Dependencies changed — syncing..." + uv sync LAST_REQS="$NEW_REQS" fi + # Always run db migrations + echo "[watch] Running db migrations..." + uv run python -c "from db import init_db; init_db()" + # Check if ingestion code changed CHANGED_FILES=$(git diff --name-only "$LOCAL_HASH" "$REMOTE_HASH") NEEDS_REINGEST=false for f in $CHANGED_FILES; do case "$f" in - parser.py|docgen.py|ingest.py|db.py) + go_parser.py|docgen.py|ingest.py|db.py) NEEDS_REINGEST=true ;; esac @@ -102,7 +106,7 @@ while true; do if [ "$NEEDS_REINGEST" = true ] && [ -f "devintel.db" ]; then echo "[watch] Ingestion code changed. Re-running ingestion..." - python ingest.py + uv run python ingest.py fi # Always restart MCP server on any code change