Infra
This commit is contained in:
1 parent
ea1afaf833
commit
e0db317146
12 files changed
+444
-56
No files matched your search
@@ -0,0 +1,69 @@
|
||||
"""Stamping for the service worker.
|
||||
|
||||
The dev server stamps sw.js on every request; the deploy stamps it once into
|
||||
the uploaded copy. Both import this, because a digest computed two different
|
||||
ways is a worker that thinks its caches are current when they are not.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
|
||||
WORKER = "sw.js"
|
||||
|
||||
VERSION_LINE = "const VERSION = 'dev';"
|
||||
LIBRARY_VERSION_LINE = "const LIBRARY_VERSION = 'dev';"
|
||||
LIBRARY_LINE = "const LIBRARY = [];"
|
||||
|
||||
CHUNK = 1 << 20
|
||||
|
||||
def walk(roots):
|
||||
found = {}
|
||||
for root in roots:
|
||||
for dirpath, _dirs, names in os.walk(root):
|
||||
for name in sorted(names):
|
||||
path = os.path.join(dirpath, name)
|
||||
rel = os.path.relpath(path, root).replace(os.sep, "/")
|
||||
found.setdefault(rel, path)
|
||||
return found
|
||||
|
||||
def digest(files):
|
||||
# Contents, not size and mtime: a checkout, a rebuild and a rsync all move
|
||||
# mtimes without changing a byte, and each one of those would otherwise
|
||||
# throw away every cache on every device for nothing.
|
||||
out = hashlib.sha256()
|
||||
for rel in sorted(files):
|
||||
out.update(rel.encode("utf-8") + b"\0")
|
||||
with open(files[rel], "rb") as fh:
|
||||
for chunk in iter(lambda: fh.read(CHUNK), b""):
|
||||
out.update(chunk)
|
||||
out.update(b"\0")
|
||||
return out.hexdigest()[:12]
|
||||
|
||||
def page_url(rel):
|
||||
if rel == "index.html":
|
||||
return "./"
|
||||
return "./" + (rel[:-len(".html")] if rel.endswith(".html") else rel)
|
||||
|
||||
def stamp_worker(roots):
|
||||
chrome = walk(roots[:1])
|
||||
library = {rel: path for rel, path in walk(roots).items() if rel not in chrome}
|
||||
|
||||
src = chrome.pop(WORKER, None)
|
||||
if src is None:
|
||||
return None
|
||||
with open(src, encoding="utf-8") as fh:
|
||||
body = fh.read()
|
||||
|
||||
for line, value in (
|
||||
(VERSION_LINE, "const VERSION = '%s';" % digest(chrome)),
|
||||
(LIBRARY_VERSION_LINE, "const LIBRARY_VERSION = '%s';" % digest(library)),
|
||||
(LIBRARY_LINE, "const LIBRARY = %s;"
|
||||
% json.dumps(sorted(page_url(rel) for rel in library), indent=2)),
|
||||
):
|
||||
if line not in body:
|
||||
raise RuntimeError("%s: expected to find %r to stamp" % (WORKER, line))
|
||||
body = body.replace(line, value, 1)
|
||||
return body.encode("utf-8")
|
||||
Reference in new issue
Block a user