45 lines
1.8 KiB
Python
45 lines
1.8 KiB
Python
"""The shared git-source resolver (phase 35, task 03).
|
|
|
|
One function, two callers: the in-app Sync pipeline
|
|
(``app/api/sync.py::_run_sync``) and the CLI
|
|
(``scripts/import_docs.py::_resolve_sources``) — both resolve the repo
|
|
URLs to clone/pull through :func:`effective_git_sources`, so the
|
|
admin-managed ``git_sources`` table is what actually gets cloned and
|
|
indexed from either entry point (the API's ``GET /api/git-sources``
|
|
fallback list is the only other place that reads the env list — task 02).
|
|
|
|
Precedence (the phase's locked decision — the env var is demoted, not
|
|
removed): ``git_sources`` DB rows win, in ``(added_at, id)`` order;
|
|
``BOR_GIT_SOURCES`` is a fallback only while the table is empty; both
|
|
empty → ``([], "env")`` and each caller keeps its existing fail-loud
|
|
behavior (sync: ``GitSyncError``; CLI: the legacy ``DEFAULT_SOURCES``
|
|
fallback).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Literal
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.config import get_settings
|
|
from app.models import GitSource
|
|
|
|
|
|
def effective_git_sources(db: Session) -> tuple[list[str], Literal["db", "env"]]:
|
|
"""``(urls, origin)`` — the repo URLs to clone, and where they came from.
|
|
|
|
``"db"``: the ``git_sources`` rows in ``(added_at, id)`` order (oldest
|
|
first, id tie-break for same-timestamp inserts) — once the table has
|
|
any row, ``BOR_GIT_SOURCES`` is ignored entirely.
|
|
``"env"``: the ``BOR_GIT_SOURCES`` list — ``Settings.git_source_list``,
|
|
the phase-28 CSV parse, reused not re-implemented — used only while
|
|
the table is empty; both empty → ``([], "env")``.
|
|
"""
|
|
rows = db.scalars(
|
|
select(GitSource).order_by(GitSource.added_at.asc(), GitSource.id.asc())
|
|
).all()
|
|
if rows:
|
|
return [row.url for row in rows], "db"
|
|
return list(get_settings().git_source_list), "env"
|