migration: preserve frontend shell pages and styles
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
ORIGINAL_ROOT = APP_ROOT.parent
|
||||
FRONTEND_ROOT = APP_ROOT / "frontend"
|
||||
ORIGINAL_STATIC = ORIGINAL_ROOT / "static"
|
||||
|
||||
SOURCE_RANGE = re.compile(
|
||||
r"/\* PRESERVATION-SOURCE-BEGIN app\.js:(\d+)-(\d+) \*/\n"
|
||||
r"(.*?)"
|
||||
r"/\* PRESERVATION-SOURCE-END app\.js:\1-\2 \*/\n?",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def reassembled_frontend_runtime() -> str:
|
||||
chunks: dict[tuple[int, int], str] = {}
|
||||
for path in FRONTEND_ROOT.rglob("*.js"):
|
||||
for match in SOURCE_RANGE.finditer(path.read_text(encoding="utf-8")):
|
||||
source_range = (int(match.group(1)), int(match.group(2)))
|
||||
if source_range in chunks:
|
||||
raise AssertionError(f"duplicate app.js source range: {source_range}")
|
||||
chunks[source_range] = match.group(3)
|
||||
|
||||
assembled: list[str] = []
|
||||
next_line = 1
|
||||
for (start, end), content in sorted(chunks.items()):
|
||||
if start != next_line:
|
||||
raise AssertionError(
|
||||
f"app.js source coverage gap: expected line {next_line}, got {start}"
|
||||
)
|
||||
if len(content.splitlines(keepends=True)) != end - start + 1:
|
||||
raise AssertionError(f"app.js line count changed in range {start}-{end}")
|
||||
assembled.append(content)
|
||||
next_line = end + 1
|
||||
|
||||
original_line_count = len(
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8").splitlines()
|
||||
)
|
||||
if next_line != original_line_count + 1:
|
||||
raise AssertionError(
|
||||
f"app.js source coverage ended at {next_line - 1}, expected {original_line_count}"
|
||||
)
|
||||
return "".join(assembled)
|
||||
|
||||
|
||||
def assert_moved_asset_matches(
|
||||
testcase,
|
||||
original_relative: str,
|
||||
frontend_relative: str | None = None,
|
||||
) -> None:
|
||||
target_relative = frontend_relative or original_relative
|
||||
testcase.assertEqual(
|
||||
sha256(FRONTEND_ROOT / target_relative),
|
||||
sha256(ORIGINAL_STATIC / original_relative),
|
||||
original_relative,
|
||||
)
|
||||
|
||||
|
||||
def assert_page_prefix_matches(testcase, page_relative: str) -> None:
|
||||
original = (ORIGINAL_STATIC / page_relative).read_text(encoding="utf-8")
|
||||
migrated = (FRONTEND_ROOT / page_relative).read_text(encoding="utf-8")
|
||||
testcase.assertTrue(
|
||||
migrated.startswith(original.rstrip("\n") + "\n\n"),
|
||||
page_relative,
|
||||
)
|
||||
Reference in New Issue
Block a user