scripts/check-site-url-consistency.py
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env python3
"""Verify that every tracked mention of the public site URL agrees with flint.toml.
``flint.toml``'s ``[project] site_url`` is the single source of truth for the
public FlintTrade domain. The literal URL still has to appear in the docs — a
reader pastes ``curl … | bash`` *before* cloning the repository, so the domain
cannot be resolved from config at read time — which is exactly why a moved
domain used to mean a manual hunt through two dozen files.
This checker is the other half of that contract (``scripts/apply-site-url.py``
is the rewrite half). It is the site-URL sibling of
``scripts/check-version-consistency.py`` and enforces four invariants:
1. ``[project] site_url`` exists and is a bare ``https://host`` origin.
2. Every file in :data:`SITE_URL_FILES` still spells that exact URL. A file that
drifted to an old domain no longer contains the canonical one and fails here.
3. No listed file names any other site-shaped origin. Legitimate non-site hosts
(GitHub, nodejs.org, loopback…) are allowlisted in :data:`NON_SITE_HOSTS`, so
a leftover ``https://old-domain.example/install.sh`` is reported by line.
4. No *unlisted* tracked file spells the canonical URL or serves one of the
canonical install routes from another host. This keeps
:data:`SITE_URL_FILES` complete: a new hardcoded mention must join the list,
so the scripted rewrite can never silently miss a file. This last invariant
needs ``git ls-files``; without git it degrades to the first three rather
than failing a checkout that has no work tree.
Usage:
python scripts/check-site-url-consistency.py
"""
from __future__ import annotations
import re
import shutil
import subprocess
import sys
import tomllib
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
# Tracked sources that spell the public site URL literally. Keep this list in
# step with reality — invariant 4 above fails the check when it drifts, and
# scripts/apply-site-url.py rewrites exactly these files.
SITE_URL_FILES = [
"packages/apps/terminal/src/lib/operatorProbeUrls.ts",
"packages/apps/terminal/src/tools/Settings/AboutSection.tsx",
"docs/DESKTOP.md",
"docs/USER_GUIDE.md",
"docs/setup/QUICKSTART.md",
"docs/setup/linux.md",
"docs/setup/macos.md",
"docs/setup/raspberry-pi.md",
"docs/setup/windows.md",
"infra/scripts/setup.sh",
"packages/apps/site/src/app/api/desktop-release/route.test.ts",
"packages/apps/site/src/app/download/page.tsx",
"packages/apps/site/src/app/layout.tsx",
"packages/apps/site/src/lib/desktop-copy.test.ts",
"packages/apps/site/src/lib/site-origin.test.ts",
"packages/apps/site/src/lib/site-origin.ts",
"packages/apps/site/src/lib/web-install-commands.ts",
"readme.md",
"scripts/install/flinttrade-install.ps1",
"scripts/install/flinttrade-install.sh",
"scripts/install/flinttrade-uninstall.sh",
"scripts/install/flinttrade-web-install.ps1",
"scripts/install/flinttrade-web-install.sh",
"tests/test_no_unhashed_pip_install.py",
"tests/test_pnpm_install_frozen.py",
"tests/test_web_install_scripts.py",
"tests/test_windows_command_docs.py",
]
# flint.toml holds the canonical value itself, so it is never a "mention".
SITE_URL_AUTHORITY = "flint.toml"
# This guard and its test necessarily spell example stale URLs — a docstring
# showing what a failure looks like, and fixtures proving the detector fires.
# They are exempt from the foreign-host scan only; every other rule still
# applies to them, so neither may quietly start naming the canonical URL.
SELF_REFERENTIAL_FILES = frozenset(
{
"scripts/check-site-url-consistency.py",
"tests/test_site_url_single_source.py",
}
)
# Paths the public site serves as the one-command bootstrap contract. A URL with
# one of these exact paths is a FlintTrade site URL whatever host precedes it,
# which is how a stale domain is recognised without knowing what it used to be.
SITE_ROUTES = (
"/web-install.sh",
"/web-install.ps1",
"/install.sh",
"/install.ps1",
"/uninstall.sh",
"/uninstall.ps1",
"/download",
"/api/desktop-release",
)
# Routes distinctive enough to identify a stale FlintTrade domain on sight. A
# foreign host serving one of these is almost certainly an un-rewritten old
# domain; a foreign host serving "/download" is almost certainly somebody else's
# download page, so that route is deliberately excluded here even though it is a
# real route of ours. Detection value without the false positives.
IDENTIFYING_ROUTES = frozenset(
{
"/web-install.sh",
"/web-install.ps1",
"/install.sh",
"/install.ps1",
"/uninstall.sh",
"/uninstall.ps1",
"/api/desktop-release",
}
)
# Hosts that legitimately appear alongside the site URL in the listed files.
# Anything else spelled there is treated as a competing site origin.
NON_SITE_HOSTS = frozenset(
{
"127.0.0.1",
"::1",
"api.github.com",
"codeload.github.com",
"git-scm.com",
"github.com",
"localhost",
"nodejs.org",
"python.org",
"raw.githubusercontent.com",
"registry.npmjs.org",
}
)
TEXT_SUFFIXES = frozenset(
{
".cjs",
".css",
".html",
".js",
".json",
".jsx",
".md",
".mdx",
".mjs",
".ps1",
".psm1",
".py",
".sh",
".toml",
".ts",
".tsx",
".txt",
".yaml",
".yml",
}
)
# A bare https origin: scheme + host, no path, no query, no trailing slash.
SITE_URL_PATTERN = re.compile(r"^https://[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?(?::\d{1,5})?$")
# Any URL in running text, including its path, stopping at shell/markup punctuation.
_URL_RE = re.compile(r"https?://([A-Za-z0-9._:-]*)((?:/[^\s'\"`)\]}>,;|\\]*)?)")
def read_site_url(root: Path = ROOT) -> str:
"""Return the canonical public site URL declared in flint.toml.
Args:
root: Repository root to read ``flint.toml`` from.
Returns:
The bare ``https://host`` origin, without a trailing slash.
Raises:
SystemExit: If the key is missing or is not a bare https origin.
"""
with (root / SITE_URL_AUTHORITY).open("rb") as handle:
data = tomllib.load(handle)
project = data.get("project")
site_url = project.get("site_url") if isinstance(project, dict) else None
if not isinstance(site_url, str) or not SITE_URL_PATTERN.match(site_url):
raise SystemExit(
f"{SITE_URL_AUTHORITY} [project] site_url must be a bare https origin "
f'(e.g. "https://example.dev"), got {site_url!r}'
)
return site_url
def site_host(site_url: str) -> str:
"""Return the host portion of *site_url* (scheme stripped)."""
return site_url.split("://", 1)[1]
def tracked_text_files(root: Path = ROOT) -> tuple[str, ...]:
"""Return every tracked repo-relative text path, or ``()`` when git is unusable.
Args:
root: Repository root to enumerate.
Returns:
Repo-relative POSIX paths of tracked files with a scannable text suffix.
"""
git = shutil.which("git")
if git is None:
return ()
result = subprocess.run(
[git, "ls-files", "-z"], cwd=root, capture_output=True, text=True, check=False
)
if result.returncode != 0:
return ()
return tuple(
entry
for entry in result.stdout.split("\0")
if entry and _is_scannable_text(root / entry)
)
def _is_scannable_text(path: Path) -> bool:
"""Return True when *path* is a tracked text file worth scanning.
Suffix alone is not enough: this repository tracks extensionless text files
(``notice``, ``LICENSE``, ``VERSION``) and an allowlist of suffixes silently
excused every one of them, which defeated the completeness invariant this
guard exists to hold. Anything not in :data:`TEXT_SUFFIXES` is therefore
sniffed instead of skipped — a NUL byte in the first block means binary.
Args:
path: Absolute path to a tracked entry.
Returns:
True when the file exists and reads as text.
"""
if not path.is_file():
return False
if path.suffix.lower() in TEXT_SUFFIXES:
return True
try:
return b"\0" not in path.read_bytes()[:8192]
except OSError:
return False
def foreign_site_urls(text: str, canonical_host: str) -> list[tuple[int, str]]:
"""Find URLs that serve a FlintTrade install route from the wrong host.
A stale domain betrays itself by serving one of *our* routes — ``/install.sh``,
``/web-install.ps1``, ``/download`` and friends. Any other third-party link is
none of this guard's business: an earlier revision flagged every host outside
:data:`NON_SITE_HOSTS`, which meant adding an ordinary reference link to the
readme or a setup page failed the build with a misleading "competing site
origin" message.
:data:`NON_SITE_HOSTS` is still consulted, for hosts that legitimately serve a
path of the same shape (``github.com/.../download``, for instance).
Args:
text: File contents to scan.
canonical_host: The host declared in flint.toml.
Returns:
``(line_number, matched_url)`` pairs, in file order.
"""
found: list[tuple[int, str]] = []
for match in _URL_RE.finditer(text):
# Trailing sentence punctuation is not part of the host ("…vercel.app.").
host = match.group(1).rstrip(".:-")
path = match.group(2)
bare_host = host.split(":", 1)[0]
if not bare_host or bare_host == canonical_host or host == canonical_host:
continue
if bare_host in NON_SITE_HOSTS:
continue
if path.rstrip("/") not in IDENTIFYING_ROUTES:
continue
found.append((text.count("\n", 0, match.start()) + 1, match.group(0)))
return found
def collect_failures(root: Path = ROOT) -> list[str]:
"""Return every site-URL disagreement, one human-readable line each.
Args:
root: Repository root to check.
Returns:
Failure descriptions naming the file (and line, where a stale literal was
located). An empty list means every tracked surface agrees with flint.toml.
"""
site_url = read_site_url(root)
canonical_host = site_host(site_url)
failures: list[str] = []
listed = set(SITE_URL_FILES)
for rel in SITE_URL_FILES:
path = root / rel
if not path.is_file():
failures.append(f"{rel}: listed in SITE_URL_FILES but missing from the repository")
continue
text = path.read_text(encoding="utf-8")
if site_url not in text:
failures.append(f"{rel}: does not mention the canonical site URL {site_url}")
for line, url in foreign_site_urls(text, canonical_host):
failures.append(f"{rel}:{line}: serves a canonical install route from {url} (expected {site_url})")
for rel in tracked_text_files(root):
if rel in listed or rel == SITE_URL_AUTHORITY:
continue
text = (root / rel).read_text(encoding="utf-8", errors="ignore")
if site_url in text:
line = text.count("\n", 0, text.index(site_url)) + 1
failures.append(
f"{rel}:{line}: spells the site URL but is absent from SITE_URL_FILES "
"(add it, or the scripted rewrite will skip this file)"
)
if rel in SELF_REFERENTIAL_FILES:
continue
for line, url in foreign_site_urls(text, canonical_host):
failures.append(f"{rel}:{line}: serves a canonical install route from {url} (expected {site_url})")
return failures
def main() -> int:
"""Print every disagreement and return a shell exit code."""
site_url = read_site_url()
failures = collect_failures()
if failures:
print("Site URL consistency check failed:")
for failure in failures:
print(f" - {failure}")
print(
"\nFor a domain move, run: python scripts/apply-site-url.py <new-url>"
f"\nOtherwise correct the file(s) above to {site_url} — re-running the apply "
"script with the URL already in flint.toml cannot repair a hand-edited file."
)
return 1
print(f"Site URL consistency check passed for {site_url}")
return 0
if __name__ == "__main__":
sys.exit(main())