2024-02-05 15:43:08 +00:00
|
|
|
#!/usr/bin/env nix-shell
|
2024-03-26 18:09:34 +00:00
|
|
|
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.beautifulsoup4 ps.click ps.httpx ps.jinja2 ps.pyyaml ])"
|
2024-02-05 15:43:08 +00:00
|
|
|
import base64
|
|
|
|
import binascii
|
|
|
|
import json
|
|
|
|
import pathlib
|
2024-03-12 18:12:35 +00:00
|
|
|
from typing import Optional
|
2024-02-05 15:43:08 +00:00
|
|
|
from urllib.parse import urlparse
|
|
|
|
|
|
|
|
import bs4
|
|
|
|
import click
|
|
|
|
import httpx
|
|
|
|
import jinja2
|
|
|
|
|
|
|
|
import utils
|
|
|
|
|
|
|
|
|
|
|
|
LEAF_TEMPLATE = jinja2.Template('''
|
2024-09-20 05:56:56 +00:00
|
|
|
{ mkKdeDerivation }:
|
2024-02-05 15:43:08 +00:00
|
|
|
mkKdeDerivation {
|
|
|
|
pname = "{{ pname }}";
|
|
|
|
}
|
|
|
|
'''.strip())
|
|
|
|
|
|
|
|
ROOT_TEMPLATE = jinja2.Template('''
|
2024-10-08 10:39:19 +00:00
|
|
|
{ callPackage }:
|
|
|
|
{
|
2024-02-05 15:43:08 +00:00
|
|
|
{%- for p in packages %}
|
2024-09-20 05:56:56 +00:00
|
|
|
{{ p }} = callPackage ./{{ p }} { };
|
2024-02-05 15:43:08 +00:00
|
|
|
{%- 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
|
|
|
|
)
|
2024-03-12 18:12:35 +00:00
|
|
|
@click.option(
|
|
|
|
"--sources-url",
|
|
|
|
type=str,
|
|
|
|
default=None,
|
|
|
|
)
|
|
|
|
def main(set: str, version: str, nixpkgs: pathlib.Path, sources_url: Optional[str]):
|
2024-02-05 15:43:08 +00:00
|
|
|
root_dir = nixpkgs / "pkgs/kde"
|
|
|
|
set_dir = root_dir / set
|
|
|
|
generated_dir = root_dir / "generated"
|
|
|
|
metadata = utils.KDERepoMetadata.from_json(generated_dir)
|
|
|
|
|
2024-03-12 18:12:35 +00:00
|
|
|
if sources_url is None:
|
|
|
|
set_url = {
|
|
|
|
"frameworks": "kf",
|
|
|
|
"gear": "releases",
|
|
|
|
"plasma": "plasma",
|
|
|
|
}[set]
|
2024-09-12 13:35:02 +00:00
|
|
|
sources_url = f"https://kde.org/info/sources/source-{set_url}-{version}/"
|
2024-02-05 15:43:08 +00:00
|
|
|
|
2024-03-12 18:12:35 +00:00
|
|
|
sources = httpx.get(sources_url)
|
2024-02-05 15:43:08 +00:00
|
|
|
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:
|
2024-03-06 06:47:17 +00:00
|
|
|
fd.write(ROOT_TEMPLATE.render(packages=sorted(results.keys())) + "\n")
|
2024-02-05 15:43:08 +00:00
|
|
|
|
|
|
|
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
|