#!/usr/bin/env python3
"""Assemble index.html from the template, the inventory and the diagrams.
index.html is self-contained on purpose: it opens from the filesystem with no
server, and a browser at file:// refuses to fetch a sibling JSON. So the
inventory, every .mmd source and every rendered .svg are inlined here rather
than loaded at runtime.
Run it through docs/architecture/render.sh, which re-renders the SVGs first.
Running it alone rebuilds the viewer against whatever SVGs are already there.
"""
import json
import os
import yaml
HERE = os.path.dirname(os.path.abspath(__file__))
DIA = os.path.join(HERE, "diagrams")
CAPDIR = os.path.join(os.path.dirname(HERE), "capabilities")
def main() -> None:
arch = json.load(open(os.path.join(HERE, "maven-architecture.json")))
mermaid, svg = {}, {}
for name in sorted(os.listdir(DIA)):
path = os.path.join(DIA, name)
if name.endswith(".mmd"):
mermaid[name] = open(path).read()
elif name.endswith(".svg"):
svg[name] = open(path).read()
# The capability half. Generated beside this one and read here rather than
# re-derived: the ledger's build is the only thing allowed to decide a
# dimension, and a second derivation would drift from it silently.
ledger = yaml.safe_load(open(os.path.join(CAPDIR, "ledger.yaml")))
invariants = yaml.safe_load(
open(os.path.join(CAPDIR, "invariants.yaml")))["invariants"]
payload = (
"const ARCH = " + json.dumps(arch, ensure_ascii=False) + ";\n"
"const CAPS = " + json.dumps(ledger, ensure_ascii=False) + ";\n"
"const INV = " + json.dumps(invariants, ensure_ascii=False) + ";\n"
"const MERMAID = " + json.dumps(mermaid, ensure_ascii=False) + ";\n"
"const SVG = " + json.dumps(svg, ensure_ascii=False) + ";\n"
)
template = open(os.path.join(HERE, "viewer.template.html")).read()
if "/*__DATA__*/" not in template:
raise SystemExit("viewer.template.html has no /*__DATA__*/ marker")
out = os.path.join(HERE, "index.html")
open(out, "w").write(template.replace("/*__DATA__*/", payload))
print(
"index.html: %d bytes, %d components, %d relations, %d diagrams, "
"%d rendered, %d capabilities, %d invariants"
% (os.path.getsize(out), len(arch["components"]), len(arch["edges"]),
len(mermaid), len(svg), len(ledger["capabilities"]), len(invariants))
)
if __name__ == "__main__":
main()