nixpkgs/maintainers/scripts/kde/generate-sources.py

122 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.beautifulsoup4 ps.click ps.httpx ps.jinja2 ps.pyyaml ])"
import base64
import binascii
import json
import pathlib
from typing import Optional
from urllib.parse import urlparse
import bs4
import click
import httpx
import jinja2
import utils
LEAF_TEMPLATE = jinja2.Template('''
{mkKdeDerivation}:
mkKdeDerivation {
pname = "{{ pname }}";
}
'''.strip())
ROOT_TEMPLATE = jinja2.Template('''
{callPackage}: {
{%- for p in packages %}
{{ p }} = callPackage ./{{ p }} {};
{%- endfor %}
}
'''.strip());
def to_sri(hash):
raw = binascii.unhexlify(hash)
b64 = base64.b64encode(raw).decode()
return f"sha256-{b64}"
@click.command
@click.argument(
"set",
type=click.Choice(["frameworks", "gear", "plasma"]),
required=True
)
@click.argument(
"version",
type=str,
required=True
)
@click.option(
"--nixpkgs",
type=click.Path(
exists=True,
file_okay=False,
resolve_path=True,
writable=True,
path_type=pathlib.Path,
),
default=pathlib.Path(__file__).parent.parent.parent.parent
)
@click.option(
"--sources-url",
type=str,
default=None,
)
def main(set: str, version: str, nixpkgs: pathlib.Path, sources_url: Optional[str]):
root_dir = nixpkgs / "pkgs/kde"
set_dir = root_dir / set
generated_dir = root_dir / "generated"
metadata = utils.KDERepoMetadata.from_json(generated_dir)
if sources_url is None:
set_url = {
"frameworks": "kf",
"gear": "releases",
"plasma": "plasma",
}[set]
sources_url = f"https://kde.org/info/sources/source-{set_url}-{version}.html"
sources = httpx.get(sources_url)
sources.raise_for_status()
bs = bs4.BeautifulSoup(sources.text, features="html.parser")
results = {}
for item in bs.select("tr")[1:]:
link = item.select_one("td:nth-child(1) a")
assert link
hash = item.select_one("td:nth-child(3) tt")
assert hash
project_name, version = link.text.rsplit("-", maxsplit=1)
if project_name not in metadata.projects_by_name:
print(f"Warning: unknown tarball: {project_name}")
results[project_name] = {
"version": version,
"url": "mirror://kde" + urlparse(link.attrs["href"]).path,
"hash": to_sri(hash.text)
}
pkg_dir = set_dir / project_name
pkg_file = pkg_dir / "default.nix"
if not pkg_file.exists():
print(f"Generated new package: {set}/{project_name}")
pkg_dir.mkdir(parents=True, exist_ok=True)
with pkg_file.open("w") as fd:
fd.write(LEAF_TEMPLATE.render(pname=project_name) + "\n")
set_dir.mkdir(parents=True, exist_ok=True)
with (set_dir / "default.nix").open("w") as fd:
fd.write(ROOT_TEMPLATE.render(packages=sorted(results.keys())) + "\n")
sources_dir = generated_dir / "sources"
sources_dir.mkdir(parents=True, exist_ok=True)
with (sources_dir / f"{set}.json").open("w") as fd:
json.dump(results, fd, indent=2)
if __name__ == "__main__":
main() # type: ignore