asset-release.py (2714B)
1 #!/usr/bin/env python3 2 """Determinism and invalidation tests for the complete release namespace.""" 3 import importlib.util 4 import json 5 from pathlib import Path 6 import sys 7 import tempfile 8 9 spec = importlib.util.spec_from_file_location('assets', sys.argv[1]) 10 assets = importlib.util.module_from_spec(spec) 11 spec.loader.exec_module(assets) 12 with tempfile.TemporaryDirectory() as temporary: 13 parent = Path(temporary) 14 entries = ['dist/app.js', 'dist/wasm-worker.js', 'dist/local-module-worker.js', 15 'dist/dependency.js', 'runtime/haskell/worker.mjs', 16 'runtime/haskell/shim/index.js', 'runtime/haskell/reactor.wasm', 17 'runtime/haskell/data/compiler.dag', 'catalogue.json', 'packages.json', 18 'compiler.json', 'environments.json', 'style.css', 'theme.js', 'images/icon.svg', 19 'reference/libraries/example.md', 'reference/libraries.md', 'reference/getting-started.md', 'reference/libraries.json', 'images/favicon.png', 'images/apple-touch-icon.png', 'images/preview.png'] 20 def build(number, changed=None, reverse=False): 21 root = parent / str(number) 22 root.mkdir() 23 (root / 'index.html').write_text('<link href="./style.css"><script src="./theme.js"></script><script type="module" src="./dist/app.js"></script>' + ''.join('<link href="./images/'+n+'">' for n in ['icon.svg','favicon.png','apple-touch-icon.png']) + '<meta content="https://arbori.cx/images/preview.png">') 24 for name in reversed(entries) if reverse else entries: 25 file = root / name 26 file.parent.mkdir(parents=True, exist_ok=True) 27 file.write_text(name + (' changed' if name == changed else '')) 28 (root / 'llms.txt').write_text('- [Guide](https://arbori.cx/reference/getting-started.md)\n- [Libraries](https://arbori.cx/reference/libraries.md)\n') 29 assets.freeze(root) 30 manifest = json.loads((root / 'assets.json').read_text()) 31 base = root / manifest['base'] 32 llms = (root / 'llms.txt').read_text() 33 for name in ['getting-started.md', 'libraries.md']: 34 assert f'https://arbori.cx/{manifest["base"]}reference/{name}' in llms 35 assert './reference/' not in llms 36 for name in entries: 37 assert (base / name).read_text() == name + (' changed' if name == changed else '') 38 assert not (root / name).is_file() 39 return manifest 40 first = build(0) 41 assert first == build(1, reverse=True), 'Creation order must not affect identity' 42 for i, name in enumerate(entries, 2): 43 assert build(i, name)['version'] != first['version'], name 44 print('PASS deterministic release identity; every asset kind invalidates the namespace')