1
0
Fork 1
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-09 09:36:20 +09:00

maintainers/scripts/update.nix: Fix reverse toposort with independent packages

When updating GNOME packages in reverse topological order using the following command:

    nix-shell maintainers/scripts/update.nix --arg predicate '(path: pkg: builtins.any (team: team.shortName == "GNOME") pkg.meta.teams or [])' --argstr order reverse-topological

the `update.py` script would crash with `ValueError` on calling `ordered.index("adwaita-fonts")`.

This happened because the `adwaita-fonts` does not depend on any other GNOME package, nor it is depended upon by one.
As a result, it had been discarded by the `reverse_edges` function.

Co-authored-by: Philip Taron <philip.taron@gmail.com>
This commit is contained in:
Jan Tojnar 2025-05-01 17:26:02 +02:00
parent 4b62180ead
commit 2e0c34649b

View file

@ -1,6 +1,6 @@
from graphlib import TopologicalSorter
from pathlib import Path
from typing import Any, Generator, Literal
from typing import Any, Final, Generator, Literal
import argparse
import asyncio
import contextlib
@ -15,6 +15,11 @@ import tempfile
Order = Literal["arbitrary", "reverse-topological", "topological"]
FAKE_DEPENDENCY_FOR_INDEPENDENT_PACKAGES: Final[str] = (
"::fake_dependency_for_independent_packages"
)
class CalledProcessError(Exception):
process: asyncio.subprocess.Process
stderr: bytes | None
@ -116,10 +121,14 @@ def requisites_to_attrs(
def reverse_edges(graph: dict[str, set[str]]) -> dict[str, set[str]]:
"""
Flips the edges of a directed graph.
Packages without any dependency relation in the updated set
will be added to `FAKE_DEPENDENCY_FOR_INDEPENDENT_PACKAGES` node.
"""
reversed_graph: dict[str, set[str]] = {}
for dependent, dependencies in graph.items():
dependencies = dependencies or {FAKE_DEPENDENCY_FOR_INDEPENDENT_PACKAGES}
for dependency in dependencies:
reversed_graph.setdefault(dependency, set()).add(dependent)
@ -413,6 +422,8 @@ async def populate_queue(
ready_packages = list(sorter.get_ready())
eprint(f"Enqueuing group of {len(ready_packages)} packages")
for package in ready_packages:
if package == FAKE_DEPENDENCY_FOR_INDEPENDENT_PACKAGES:
continue
await packages_to_update.put(attr_packages[package])
await packages_to_update.join()
sorter.done(*ready_packages)