63 lines
3 KiB
Python
Executable file
63 lines
3 KiB
Python
Executable file
#!/usr/bin/python3
|
|
"""Construire les candidats locaux, sans installer ni signer ni accéder au réseau."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tarfile
|
|
import tempfile
|
|
import zipfile
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SOURCE = ROOT / "quickshell/.config/quickshell/labfy-sway"
|
|
|
|
|
|
# Explicit allowlist: no profile data or generated files enter the extension.
|
|
EXTENSION_FILES = ("manifest.json", "background.js")
|
|
|
|
|
|
def build_extension(output):
|
|
xpi = output / "labfy-session-v2-unsigned.xpi"
|
|
with zipfile.ZipFile(xpi, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
for name in EXTENSION_FILES:
|
|
info = zipfile.ZipInfo(name, date_time=(2026, 1, 1, 0, 0, 0))
|
|
info.compress_type = zipfile.ZIP_DEFLATED
|
|
archive.writestr(info, (ROOT / "firefox-extension/session-v2" / name).read_bytes())
|
|
return xpi
|
|
|
|
|
|
def build(output, extension_only=False):
|
|
output = Path(output).resolve()
|
|
if not output.is_relative_to(ROOT): raise ValueError("OUTPUT_MUST_BE_IN_ISOLATED_WORKTREE")
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
if extension_only:
|
|
xpi = build_extension(output)
|
|
manifest = {"signed": False, "installed": False, "files": {xpi.name: hashlib.sha256(xpi.read_bytes()).hexdigest()}}
|
|
(output / "extension-manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")
|
|
print(json.dumps(manifest))
|
|
return
|
|
binary = output / "labfy-v2-anchor"
|
|
flags = subprocess.check_output(["pkg-config", "--cflags", "--libs", "gtk+-3.0", "gdk-wayland-3.0"], text=True).split()
|
|
subprocess.run(["cc", "-std=c17", "-O2", "-Wall", "-Wextra", "-Werror", str(SOURCE / "session_v2/anchor_helper.c"), "-o", str(binary), *flags], check=True)
|
|
xpi = build_extension(output)
|
|
bundle = output / "labfy-session-v2-backend.tar.gz"
|
|
with tarfile.open(bundle, "w:gz") as archive:
|
|
for name in ("session-v2.py", "session-v2-native-host.py"):
|
|
archive.add(SOURCE / name, arcname=name)
|
|
for p in sorted((SOURCE / "session_v2").glob("*.py")): archive.add(p, arcname="session_v2/" + p.name)
|
|
archive.add(SOURCE / "session_v2/schema-v1.json", arcname="session_v2/schema-v1.json")
|
|
archive.add(binary, arcname="session_v2/libexec/labfy-v2-anchor")
|
|
archive.add(ROOT / "firefox-extension/session-v2/native-host.json.in", arcname="native-host.json.in")
|
|
manifest = {"signed": False, "installed": False, "files": {p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in (binary, xpi, bundle)}}
|
|
(output / "manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")
|
|
print(json.dumps(manifest))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("output", nargs="?", default=ROOT / "build/session-v2")
|
|
parser.add_argument("--extension-only", action="store_true", help="XPI seul, sans compilation GTK ni bundle backend")
|
|
args = parser.parse_args()
|
|
build(args.output, extension_only=args.extension_only)
|