feat: faster dependency computation
Co-authored-by: Raito Bezarius <raito@lix.systems> (just for wiring up things) Signed-off-by: Raito Bezarius <raito@lix.systems>
This commit is contained in:
parent
1aa37c4b80
commit
ab0767bedd
|
@ -7,7 +7,7 @@ import base64
|
|||
from collections.abc import Generator
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
import buildbot
|
||||
from buildbot.configurators import ConfiguratorBase
|
||||
|
@ -41,6 +41,12 @@ MasterLock = util.MasterLock
|
|||
|
||||
FLAKE_TARGET_ATTRIBUTE_FOR_JOBS = "hydraJobs"
|
||||
|
||||
class Job(NamedTuple):
|
||||
commit: str
|
||||
name: str
|
||||
expensive: bool
|
||||
deps: set[str] = set()
|
||||
|
||||
@dataclass
|
||||
class EvaluatorSettings:
|
||||
supported_systems: list[str]
|
||||
|
@ -425,12 +431,15 @@ class NixEvalCommand(buildstep.ShellMixin, steps.BuildStep):
|
|||
drv_show_log: StreamLog = yield self.getLog("stdio")
|
||||
all_deps = dict()
|
||||
|
||||
def closure_of(key, deps):
|
||||
r, size = set([key]), 0
|
||||
while len(r) != size:
|
||||
size = len(r)
|
||||
r.update(*[ deps[k] for k in r ])
|
||||
return r.difference([key])
|
||||
def find_deps(drv_info: dict[Any, Any]) -> dict[str, set[str]]:
|
||||
deps = {}
|
||||
for drv, info in drv_info.items():
|
||||
deps[drv] = set(info["inputDrvs"].keys())
|
||||
for n in graphlib.TopologicalSorter(deps).static_order():
|
||||
for d in tuple(deps[n]):
|
||||
deps[n].update(deps[d])
|
||||
return deps
|
||||
|
||||
|
||||
if succeeded_jobs:
|
||||
drv_show_log.addStdout(f"getting derivation infos for valid derivations\n")
|
||||
|
@ -449,11 +458,8 @@ class NixEvalCommand(buildstep.ShellMixin, steps.BuildStep):
|
|||
except json.JSONDecodeError as e:
|
||||
msg = f"Failed to parse `nix derivation show` output for {cmd.command}"
|
||||
raise BuildbotNixError(msg) from e
|
||||
for drv, info in drv_info.items():
|
||||
all_deps[drv] = set(info.get("inputDrvs").keys())
|
||||
|
||||
job_set = set(( drv for drv in ( job.get("drvPath") for job in filtered_jobs ) if drv ))
|
||||
all_deps = { k: list(closure_of(k, all_deps).intersection(job_set)) for k in job_set }
|
||||
all_deps = find_deps(drv_info)
|
||||
|
||||
self.build.addStepsAfterCurrentStep(
|
||||
[
|
||||
|
|
Loading…
Reference in a new issue