generated from coulomb/repo-seed
feat(repos): multi-machine path support via host_paths
Adds a JSONB column `host_paths` to managed_repos mapping
hostname → absolute local path. Fixes the consistency-checker
failure when the same repo lives at different paths on different
machines (e.g. /home/worsch/marki-docx on the workstation vs
/home/tegwick/marki-docx on custodiancore).
Changes:
- Migration g4b5c6d7e8f9: adds host_paths JSONB (default {})
- Model: host_paths Mapped[dict] column
- Schemas: host_paths in RepoRead; new RepoPathRegister schema
- Router: POST /repos/{slug}/paths/ — merges one host entry
- consistency_check.py: resolve_repo_path() prefers host_paths
[hostname] over local_path; --repo-path CLI override added
- MCP: update_repo_path(slug, path, host?) tool
- Makefile: register-path target; REPO_PATH passthrough on
check-consistency and fix-consistency targets
- TOOLS.md: documents update_repo_path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
@@ -294,7 +295,22 @@ def _api_post(api_base: str, path: str, body: dict) -> Any:
|
||||
# Core check engine
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def check_repo(api_base: str, repo_slug: str) -> ConsistencyReport:
|
||||
def resolve_repo_path(repo: dict, override: str | None = None) -> str:
|
||||
"""Resolve the local filesystem path for a repo on the current machine.
|
||||
|
||||
Priority:
|
||||
1. Explicit --repo-path CLI override
|
||||
2. host_paths[current_hostname] — per-machine path registered via POST /repos/{slug}/paths/
|
||||
3. local_path — legacy single-path field (backward compat)
|
||||
"""
|
||||
if override:
|
||||
return override
|
||||
hostname = socket.gethostname()
|
||||
host_paths = repo.get("host_paths") or {}
|
||||
return host_paths.get(hostname) or repo.get("local_path") or ""
|
||||
|
||||
|
||||
def check_repo(api_base: str, repo_slug: str, repo_path_override: str | None = None) -> ConsistencyReport:
|
||||
"""Run all consistency checks for a registered repo."""
|
||||
repo = _api_get(api_base, f"/repos/{repo_slug}")
|
||||
if repo is None:
|
||||
@@ -307,7 +323,7 @@ def check_repo(api_base: str, repo_slug: str) -> ConsistencyReport:
|
||||
return report
|
||||
|
||||
repo_id: str = repo["id"]
|
||||
repo_path: str = repo.get("local_path") or ""
|
||||
repo_path: str = resolve_repo_path(repo, repo_path_override)
|
||||
report = ConsistencyReport(repo_slug=repo_slug, repo_path=repo_path)
|
||||
|
||||
if not repo_path:
|
||||
@@ -607,9 +623,9 @@ def _check_orphan_db(
|
||||
# Fix engine
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def fix_repo(api_base: str, repo_slug: str) -> ConsistencyReport:
|
||||
def fix_repo(api_base: str, repo_slug: str, repo_path_override: str | None = None) -> ConsistencyReport:
|
||||
"""Run checks then apply all auto-fixable issues. Returns updated report."""
|
||||
report = check_repo(api_base, repo_slug)
|
||||
report = check_repo(api_base, repo_slug, repo_path_override)
|
||||
fixable = [i for i in report.issues if i.fixable]
|
||||
|
||||
for issue in fixable:
|
||||
@@ -866,6 +882,9 @@ def main() -> None:
|
||||
help="Run checks against all registered repos with local_path")
|
||||
parser.add_argument("--fix", action="store_true",
|
||||
help="Apply auto-fixable issues (status drift, repo mismatch, etc.)")
|
||||
parser.add_argument("--repo-path", metavar="PATH", default=None,
|
||||
help="Override the local repo path (useful when the DB has a different "
|
||||
"machine's path). Takes priority over host_paths and local_path.")
|
||||
parser.add_argument("--api-base", default="http://127.0.0.1:8000",
|
||||
help="State Hub API base URL")
|
||||
parser.add_argument("--json", action="store_true", dest="as_json",
|
||||
@@ -887,7 +906,9 @@ def main() -> None:
|
||||
repo_slugs = [args.repo]
|
||||
|
||||
runner = fix_repo if args.fix else check_repo
|
||||
reports = [runner(args.api_base, slug) for slug in repo_slugs]
|
||||
# --repo-path only applies to single-repo runs; silently ignored with --all
|
||||
path_override = args.repo_path if not args.all else None
|
||||
reports = [runner(args.api_base, slug, path_override) for slug in repo_slugs]
|
||||
|
||||
if args.as_json:
|
||||
output = (
|
||||
|
||||
Reference in New Issue
Block a user