Files
2026-05-20 16:19:28 -05:00

87 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Small wrapper around dpkg-buildpackage for Nala builds."""
from __future__ import annotations
import argparse
import os
import shutil
import subprocess
import tempfile
from pathlib import Path
ARTIFACT_PATTERNS = (
"*.deb",
"*.ddeb",
"*.changes",
"*.buildinfo",
"*.dsc",
"*.tar.*",
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Build Nala Debian artifacts")
mode = parser.add_mutually_exclusive_group()
mode.add_argument("--binary", action="store_const", const="binary", dest="mode")
mode.add_argument("--source", action="store_const", const="source", dest="mode")
mode.add_argument("--release", action="store_const", const="release", dest="mode")
parser.set_defaults(mode="binary")
parser.add_argument("--out-dir", default="dist/debian")
parser.add_argument("--no-clean", action="store_true", help="preserve build caches")
parser.add_argument("--nocheck", action="store_true", help="set DEB_BUILD_OPTIONS=nocheck")
parser.add_argument("--sign", action="store_true", help="sign build outputs")
parser.add_argument("--key-id", help="sign build outputs with this key")
return parser.parse_args()
def collect_artifacts(marker: Path, out_dir: Path) -> None:
out_dir.mkdir(parents=True, exist_ok=True)
for pattern in ARTIFACT_PATTERNS:
for artifact in Path("..").glob(pattern):
if artifact.is_file() and artifact.stat().st_mtime > marker.stat().st_mtime:
shutil.move(str(artifact), out_dir / artifact.name)
def build(kind: str, args: argparse.Namespace, out_dir: Path) -> None:
with tempfile.NamedTemporaryFile() as marker:
cmd = ["dpkg-buildpackage", "-S" if kind == "source" else "-b"]
if args.key_id:
cmd.append(f"--sign-keyid={args.key_id}")
elif not args.sign:
cmd.extend(("-us", "-uc"))
env = os.environ.copy()
env["DEB_DESTDIR"] = ".."
if args.no_clean:
env["NO_CLEAN"] = "1"
env.setdefault("CARGO_HOME", str(Path.home() / ".cargo"))
if args.nocheck:
options = env.get("DEB_BUILD_OPTIONS", "").split()
if "nocheck" not in options:
options.append("nocheck")
env["DEB_BUILD_OPTIONS"] = " ".join(options)
print(f"Building {kind} package...")
subprocess.run(cmd, check=True, env=env)
collect_artifacts(Path(marker.name), out_dir)
def main() -> None:
args = parse_args()
out_dir = Path(args.out_dir)
if args.mode == "release":
build("source", args, out_dir)
build("binary", args, out_dir)
else:
build(args.mode, args, out_dir)
print(f"Artifacts: {out_dir}")
if __name__ == "__main__":
main()