introduce brotli compression to build script

This commit is contained in:
nelsbrock committed 2026-08-15 16:39:05 +02:00
1 parent dd95c144f3
commit 4bdc5faf33
1 file changed
+69 -6
+69 -6
View File
@@ -1,31 +1,84 @@
#!/usr/bin/env python #!/usr/bin/env python
import contextlib import contextlib
from io import BufferedWriter, FileIO
import os import os
import shutil import shutil
from io import BufferedWriter, FileIO
import brotli
import git import git
import magic
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
SOURCES_DIR = "src" SOURCES_DIR = "src"
DIST_DIR = "dist" DIST_DIR = "dist"
BROTLI_THRESHOLD = 1024
# taken from https://caddyserver.com/docs/caddyfile/directives/encode
BROTLI_MIME_PREFIXES = [
"application/atom+xml",
"application/eot",
"application/font",
"application/geo+json",
"application/graphql+json",
"application/javascript",
"application/json",
"application/ld+json",
"application/manifest+json",
"application/opentype",
"application/otf",
"application/rss+xml",
"application/truetype",
"application/ttf",
"application/vnd.api+json",
"application/vnd.ms-fontobject",
"application/wasm",
"application/x-httpd-cgi",
"application/x-javascript",
"application/x-opentype",
"application/x-otf",
"application/x-perl",
"application/x-protobuf",
"application/x-ttf",
"application/xhtml+xml",
"application/xml",
"font/",
"image/svg+xml",
"image/vnd.microsoft.icon",
"image/x-icon",
"multipart/bag",
"multipart/mixed",
"text/",
]
def latest_git_commit_year() -> int: def latest_git_commit_year() -> int:
return git.Repo(".").head.commit.authored_datetime.year return git.Repo(".").head.commit.authored_datetime.year
def build_template(env: Environment, src_path: str): def build_template(env: Environment, src_path: str) -> tuple[str, int]:
rel_path = os.path.relpath(src_path, SOURCES_DIR) rel_path = os.path.relpath(src_path, SOURCES_DIR)
dist_path = os.path.splitext(os.path.join(DIST_DIR, rel_path))[0] dist_path = os.path.splitext(os.path.join(DIST_DIR, rel_path))[0]
template = env.get_template(rel_path) template = env.get_template(rel_path)
rendered_text = template.render(copyright_year = latest_git_commit_year()) rendered_text = template.render(copyright_year = latest_git_commit_year())
size = 0
with BufferedWriter(FileIO(dist_path, "wb")) as writer: with BufferedWriter(FileIO(dist_path, "wb")) as writer:
for line in rendered_text.splitlines(): for line in rendered_text.splitlines():
line = line.strip() line = line.strip()
if len(line) > 0: if len(line) > 0:
writer.write(line.encode()) line_b = line.encode()
writer.write(b"\n") size += len(line_b) + 1
_ = writer.write(line.encode())
_ = writer.write(b"\n")
return dist_path, size
def compress(path: str, mode):
with open(path, "rb") as reader, open(path + ".br", "wb") as writer:
content = reader.read()
compressed = brotli.compress(content, mode)
writer.write(compressed)
def main(): def main():
with contextlib.suppress(FileNotFoundError): with contextlib.suppress(FileNotFoundError):
@@ -36,6 +89,8 @@ def main():
autoescape=True autoescape=True
) )
mime = magic.Magic(mime=True)
for root, _, files in os.walk(SOURCES_DIR): for root, _, files in os.walk(SOURCES_DIR):
rel_dir_path = os.path.relpath(root, SOURCES_DIR) rel_dir_path = os.path.relpath(root, SOURCES_DIR)
dist_root = os.path.join(DIST_DIR, rel_dir_path) dist_root = os.path.join(DIST_DIR, rel_dir_path)
@@ -46,11 +101,19 @@ def main():
if src_name.endswith(".jinja"): if src_name.endswith(".jinja"):
if not src_name.startswith("_"): if not src_name.startswith("_"):
build_template(env, src_path) dist_path, size = build_template(env, src_path)
if size > BROTLI_THRESHOLD:
compress(dist_path, brotli.MODE_TEXT)
else: else:
dist_path = os.path.join(dist_root, src_name) dist_path = os.path.join(dist_root, src_name)
shutil.copy(src_path, dist_path) shutil.copy(src_path, dist_path)
if os.path.getsize(dist_path) > BROTLI_THRESHOLD:
mimetype = mime.from_file(dist_path)
if any(mimetype.startswith(prefix) for prefix in BROTLI_MIME_PREFIXES):
mode = brotli.MODE_FONT if mimetype == "font/woff2" else brotli.MODE_GENERIC
compress(dist_path, mode)
if __name__ == '__main__': if __name__ == '__main__':
main() main()