Skip to content
Snippets Groups Projects
update-nixpkgs 1.8 KiB
Newer Older
#!/usr/bin/env python

import argparse
import json
from pathlib import Path

import httpx
from ps_tools import get_url_hash

# We pass this to builtins.fetchTarball which only supports sha256
HASH_TYPE = "sha256"

DEFAULT_CHANNEL = "nixos-21.05"
CHANNEL_URL_TEMPLATE = "https://channels.nixos.org/{channel}/nixexprs.tar.xz"


def get_nixos_channel_url(*, channel):
    """
    Get the URL for the current release of the given nixos channel.

    `https://channels.nixos.org/<channel>` redirects to the path on
    `https://releases.nixos.org` that corresponds to the current release
    of that channel. This captures that redirect, so we can pin against
    the release.
    """
    response = httpx.head(
        CHANNEL_URL_TEMPLATE.format(channel=channel), allow_redirects=False
    )
    response.raise_for_status()
    assert response.is_redirect
    return str(response.next_request.url)


def main():
    parser = argparse.ArgumentParser(description="Update a pinned nixos repository.")
    parser.add_argument(
        "repo_file",
        metavar="repo-file",
        nargs="?",
        default=Path(__file__).parent.with_name("nixpkgs-2105.json"),
        type=Path,
        help="JSON file with pinned configuration.",
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
    )
    parser.set_defaults(channel=DEFAULT_CHANNEL)
    args = parser.parse_args()

    repo_file = args.repo_file
    config = json.loads(repo_file.read_text())

    config["url"] = get_nixos_channel_url(channel=args.channel)
    hash_data = get_url_hash(HASH_TYPE, name=config["name"], url=config["url"])
    config["sha256"] = hash_data["outputHash"]

    output = json.dumps(config, indent=2)
    if args.dry_run:
        print(output)
    else:
        repo_file.write_text(output)


if __name__ == "__main__":
    main()