introduce compression to build script
This commit is contained in:
@@ -1,40 +1,99 @@
|
|||||||
#!/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 git
|
import git
|
||||||
|
import magic
|
||||||
|
from compression import gzip, zstd
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
SOURCES_DIR = "src"
|
SOURCES_DIR = "src"
|
||||||
DIST_DIR = "dist"
|
DIST_DIR = "dist"
|
||||||
|
COMPR_THRESHOLD = 512
|
||||||
|
|
||||||
|
# mostly taken from https://caddyserver.com/docs/caddyfile/directives/encode
|
||||||
|
COMPR_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/otf",
|
||||||
|
"font/ttf",
|
||||||
|
"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):
|
||||||
|
with open(path, "rb") as reader, open(path + ".zst", "wb") as zstd_writer, open(path + ".gz", "wb") as gzip_writer:
|
||||||
|
content = reader.read()
|
||||||
|
zstd_compressed = zstd.compress(content, level=15)
|
||||||
|
_ = zstd_writer.write(zstd_compressed)
|
||||||
|
gzip_compressed = gzip.compress(content, compresslevel=9)
|
||||||
|
_ = gzip_writer.write(gzip_compressed)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with contextlib.suppress(FileNotFoundError):
|
with contextlib.suppress(FileNotFoundError):
|
||||||
shutil.rmtree(DIST_DIR)
|
shutil.rmtree(DIST_DIR)
|
||||||
|
|
||||||
env = Environment(
|
env = Environment(loader=FileSystemLoader(SOURCES_DIR), autoescape=True)
|
||||||
loader=FileSystemLoader(SOURCES_DIR),
|
|
||||||
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)
|
||||||
@@ -46,11 +105,17 @@ 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 >= COMPR_THRESHOLD:
|
||||||
|
compress(dist_path)
|
||||||
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) >= COMPR_THRESHOLD:
|
||||||
|
m = mime.from_file(dist_path)
|
||||||
|
if any(m.startswith(prefix) for prefix in COMPR_MIME_PREFIXES):
|
||||||
|
compress(dist_path)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user