Files
mail/scripts/stage-linux-metadata.py
T

59 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Stage Linux desktop and AppStream metadata using the Cargo package version."""
import argparse
import os
import re
import tomllib
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from pathlib import Path
def stage(project: Path, destination: Path, *, flatpak: bool = False) -> str:
with (project / "Cargo.toml").open("rb") as stream:
version = tomllib.load(stream)["package"]["version"]
if not re.fullmatch(r"\d+\.\d+\.\d+(?:-(?:alpha|beta|rc)\.[1-9]\d*)?", version):
raise ValueError(f"Unsupported release version: {version}")
# Reproducible builds can supply an epoch; otherwise use the UTC build date.
epoch = os.environ.get("SOURCE_DATE_EPOCH")
release_date = (
datetime.fromtimestamp(int(epoch), timezone.utc)
if epoch is not None else datetime.now(timezone.utc)
).date().isoformat()
resources = project / "resources"
desktop = (resources / "com.flectar.mail.desktop").read_text(encoding="utf-8")
desktop, count = re.subn(
r"^X-AppImage-Version=.*$", f"X-AppImage-Version={version}", desktop,
flags=re.MULTILINE,
)
if count != 1:
raise ValueError("Expected one X-AppImage-Version field in the desktop template")
if flatpak:
desktop = re.sub(r"^X-AppImage-[^\n]*\n?", "", desktop, flags=re.MULTILINE)
parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))
metainfo = ET.parse(resources / "com.flectar.mail.metainfo.xml", parser=parser)
# The first release describes the build being packaged. Retain older entries.
release = metainfo.find("./releases/release")
if release is None:
raise ValueError("Missing current release in the AppStream template")
release.set("version", version)
release.set("date", release_date)
release.set("type", "development" if "-" in version else "stable")
release.attrib.pop("timestamp", None)
desktop_path = destination / "usr/share/applications/com.flectar.mail.desktop"
metainfo_path = destination / "usr/share/metainfo/com.flectar.mail.metainfo.xml"
desktop_path.parent.mkdir(parents=True, exist_ok=True)
metainfo_path.parent.mkdir(parents=True, exist_ok=True)
desktop_path.write_text(desktop, encoding="utf-8")
metainfo.write(metainfo_path, encoding="utf-8", xml_declaration=True)
return version
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--flatpak", action="store_true", help="omit AppImage-only desktop keys")
parser.add_argument("destination", type=Path, help="AppDir or Debian package root")
args = parser.parse_args()
print(stage(Path(__file__).resolve().parent.parent, args.destination, flatpak=args.flatpak))