refactor(db): extract shared DB module from duplicated patterns
Create tooling/db/common.py with resolve_db_path(), load_config(), get_connection(), and ensure_venv(). Update ticket, sprint, sqlite_connector.py, and decisions_sync.py to import from common instead of duplicating. Fixes pre-existing NameError in decisions_sync.py (missing import os). Add pyproject.toml with ruff config (ruff==0.15.9, CVE-clean) and dev dependencies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+9
-19
@@ -15,17 +15,16 @@ Usage:
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
|
||||
from common import WORKTREE_ROOT, get_connection, load_config # noqa: E402
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
TICKET_CLI = str(SCRIPT_DIR / "ticket")
|
||||
WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve()
|
||||
# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic.
|
||||
DB_PATH = Path(os.environ["SR_DB_PATH"]).resolve() if os.environ.get("SR_DB_PATH") else (WORKTREE_ROOT / ".." / "settledreach.db").resolve()
|
||||
PROJECT_ROOT = WORKTREE_ROOT
|
||||
|
||||
REMINDER = """---
|
||||
@@ -48,15 +47,6 @@ def run_ticket(*args):
|
||||
return {"ok": False, "error": f"Bad ticket output: {result.stdout[:200]}"}
|
||||
|
||||
|
||||
def get_connection():
|
||||
"""Direct DB connection for lifecycle mutations only."""
|
||||
conn = sqlite3.connect(str(DB_PATH))
|
||||
conn.execute("PRAGMA journal_mode=WAL;")
|
||||
conn.execute("PRAGMA foreign_keys=ON;")
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
|
||||
def parse_flags(args, known_flags):
|
||||
"""Parse --flag value pairs from args, return (flags_dict, positional_args)."""
|
||||
flags = {}
|
||||
@@ -325,7 +315,7 @@ def cmd_start(args):
|
||||
sys.exit(1)
|
||||
|
||||
# Activate
|
||||
conn = get_connection()
|
||||
conn = get_connection(load_config())
|
||||
conn.execute(
|
||||
"UPDATE sprints SET status='active', start_date=date('now') WHERE id=?",
|
||||
(sprint["id"],)
|
||||
@@ -369,7 +359,7 @@ def cmd_stop(args):
|
||||
picked_up = [t for t in incomplete if t["status"] in picked_up_statuses]
|
||||
auto_closed = []
|
||||
if picked_up:
|
||||
conn = get_connection()
|
||||
conn = get_connection(load_config())
|
||||
for t in picked_up:
|
||||
conn.execute("UPDATE tickets SET status='done' WHERE id=?", (t["id"],))
|
||||
auto_closed.append(t)
|
||||
@@ -380,7 +370,7 @@ def cmd_stop(args):
|
||||
incomplete = [t for t in incomplete if t["status"] not in picked_up_statuses]
|
||||
|
||||
# Complete the sprint
|
||||
conn = get_connection()
|
||||
conn = get_connection(load_config())
|
||||
conn.execute(
|
||||
"UPDATE sprints SET status='completed', end_date=date('now') WHERE id=?",
|
||||
(sprint["id"],)
|
||||
@@ -602,7 +592,7 @@ def cmd_prepare(args):
|
||||
|
||||
# Create sprint record if it doesn't exist
|
||||
if sprint.get("status") == "new":
|
||||
conn = get_connection()
|
||||
conn = get_connection(load_config())
|
||||
conn.execute(
|
||||
"INSERT INTO sprints (id, name, status) VALUES (?, ?, 'planning')",
|
||||
(sprint["id"], f"Sprint {sprint['id']}")
|
||||
@@ -664,7 +654,7 @@ def cmd_prepare(args):
|
||||
print()
|
||||
|
||||
# Decision coverage gaps
|
||||
conn = get_connection()
|
||||
conn = get_connection(load_config())
|
||||
cursor = conn.execute("""
|
||||
SELECT id, title FROM decisions
|
||||
WHERE type='confirmed' AND status='active'
|
||||
|
||||
Reference in New Issue
Block a user