"""Build a minimal, offline, hand-rolled npm package and its registry metadata document, for integration-testing the `npm` module of id-configurator. No network access and no build backend (npm/node) is used: the tarball is a plain gzipped tar assembled with the standard library only, so this script can run in a minimal Python image with nothing installed. """ from __future__ import annotations import base64 import hashlib import io import json import pathlib import tarfile PACKAGE = "idconfiguratortestpkg" VERSION = "0.0.1" TARBALL_NAME = f"{PACKAGE}-{VERSION}.tgz" OUT_DIR = pathlib.Path("/srv") PACKAGE_JSON = json.dumps({"name": PACKAGE, "version": VERSION}) MARKER = "test-only package served by the id-configurator integration tests\n" def _add_file(archive: tarfile.TarFile, name: str, content: bytes) -> None: info = tarfile.TarInfo(name=f"package/{name}") info.size = len(content) archive.addfile(info, io.BytesIO(content)) def build_tarball() -> bytes: buffer = io.BytesIO() with tarfile.open(fileobj=buffer, mode="w:gz") as archive: _add_file(archive, "package.json", PACKAGE_JSON.encode("utf-8")) _add_file(archive, "marker.txt", MARKER.encode("utf-8")) return buffer.getvalue() def write_registry_metadata(out_dir: pathlib.Path, tarball: bytes) -> None: # npm requires a fully-qualified tarball URL, so this bakes in a # placeholder that nginx's sub_filter rewrites to the real # https:/// at request time (see # npm-repo.nginx.conf) - the host and port this fixture is actually # reached on aren't known at image-build time. sha1 = hashlib.sha1(tarball).hexdigest() # nosec B324 sha512_b64 = base64.b64encode(hashlib.sha512(tarball).digest()).decode("ascii") metadata = { "name": PACKAGE, "dist-tags": {"latest": VERSION}, "versions": { VERSION: { "name": PACKAGE, "version": VERSION, "dist": { "shasum": sha1, "integrity": f"sha512-{sha512_b64}", "tarball": f"__BASE_URL__/{TARBALL_NAME}", }, } }, } (out_dir / PACKAGE).write_text(json.dumps(metadata, indent=2), encoding="utf-8") def main() -> None: OUT_DIR.mkdir(parents=True, exist_ok=True) tarball = build_tarball() (OUT_DIR / TARBALL_NAME).write_bytes(tarball) write_registry_metadata(OUT_DIR, tarball) if __name__ == "__main__": main()