Skip to content

Commit

Permalink
feat(back): fluidattacks#1101 globbed attrs
Browse files Browse the repository at this point in the history
- Collect attr paths using python globs
for initialization performance
- Pass them as attrPaths to evaluator
- Redefine evaluator logic for building outputs from attrs
- Initialization for universe takes less than 3 seconds now

Signed-off-by: Daniel Salazar <podany270895@gmail.com>
  • Loading branch information
dsalaza4 committed Jun 2, 2023
1 parent 1311f28 commit 0a6f245
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 29 deletions.
21 changes: 18 additions & 3 deletions src/cli/main/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from functools import (
partial,
)
from glob import (
glob,
)
from hashlib import (
sha256,
)
Expand Down Expand Up @@ -264,9 +267,16 @@ def _clone_src_cache_refresh(head: str, cache_key: str) -> None:
shutil.copytree(head, cached)


def _get_attr_paths(head: str) -> str:
abs_paths: list[str] = glob(f"{head}/**/main.nix", recursive=True)
rel_paths: list[str] = [path.replace(head, "") for path in abs_paths]
return "::".join(rel_paths)


def _nix_build(
*,
attr: str,
attr_paths: str,
cache: Optional[List[Dict[str, str]]],
head: str,
out: str = "",
Expand Down Expand Up @@ -298,6 +308,7 @@ def _nix_build(
*_if(not NIX_STABLE, "build"),
*_if(NIX_STABLE, "--argstr", "makesSrc", __MAKES_SRC__),
*_if(NIX_STABLE, "--argstr", "projectSrc", head),
*["--argstr", "attrPaths", attr_paths],
*_if(NIX_STABLE, "--attr", attr),
*["--option", "cores", "0"],
*_if(not NIX_STABLE, "--impure"),
Expand Down Expand Up @@ -400,7 +411,7 @@ class Config(NamedTuple):
cache: List[Dict[str, str]]


def _get_config(head: str) -> Config:
def _get_config(head: str, attr_paths: str) -> Config:
CON.out()
CON.rule("Building project configuration")
CON.out()
Expand All @@ -410,6 +421,7 @@ def _get_config(head: str) -> Config:
attr="config.configAsJson"
if NIX_STABLE
else f'{head}#__makes__."config:configAsJson"',
attr_paths=attr_paths,
cache=None,
head=head,
out=out,
Expand Down Expand Up @@ -566,7 +578,8 @@ def cli(args: List[str]) -> None:
_help_and_exit_base()

head: str = _get_head(src)
config: Config = _get_config(head)
attr_paths: str = _get_attr_paths(head)
config: Config = _get_config(head, attr_paths)

args, attr = _cli_get_args_and_attr(args, config.attrs, src)

Expand All @@ -575,7 +588,7 @@ def cli(args: List[str]) -> None:
MAKES_DIR,
f"provenance{attr.replace('/', '-')}.json",
)
code = _cli_build(attr, config, head, out, src)
code = _cli_build(attr, attr_paths, config, head, out, src)

if code == 0:
write_provenance(args, head, out, provenance, src)
Expand Down Expand Up @@ -603,6 +616,7 @@ def _cli_get_args_and_attr(

def _cli_build(
attr: str,
attr_paths: str,
config: Config,
head: str,
out: str,
Expand All @@ -623,6 +637,7 @@ def _cli_build(
attr=f'config.outputs."{attr}"'
if NIX_STABLE
else f'{head}#__makes__."config:outputs:{attr}"',
attr_paths=attr_paths,
cache=config.cache,
head=head,
out=out,
Expand Down
5 changes: 4 additions & 1 deletion src/evaluator/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# You better avoid changing this function signature...
# Ask a maintainer first.
{
# String containing complete list of main.nix files found within projectSrc
# in /path::/path::/path format
attrPaths,
# flake inputs to inject, if any
flakeInputs ? {},
# Source code of makes, can be overriden by the user.
Expand Down Expand Up @@ -56,7 +59,7 @@
"${makesSrcOverriden}/src/evaluator/modules/default.nix"
makesNix
];
specialArgs = args;
specialArgs = args // {inherit attrPaths;};
};
in
result
53 changes: 28 additions & 25 deletions src/evaluator/modules/default.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
attrsMapToList,
attrPaths,
config,
lib,
attrsOptional,
Expand Down Expand Up @@ -91,34 +91,37 @@
configAsJson = toFileJson "config.json" config.config;
outputs = let
# Load an attr set distributed across many files and directories
attrsFromPath = path: position:
attrs = let
pathInConfig = dir:
builtins.any
(makesDir: lib.hasInfix makesDir dir)
config.extendingMakesDirs;
pathExists = dir: builtins.pathExists (projectSrc + dir);
attrName = dir: let
makesDirsNoRoot = lib.remove "/" config.extendingMakesDirs;
from = makesDirsNoRoot ++ ["/main.nix"];
to = builtins.genList (_: "") ((builtins.length makesDirsNoRoot) + 1);
replaced = builtins.replaceStrings from to dir;
in
if replaced != ""
then replaced
else "/";
in
builtins.foldl'
lib.mergeAttrs
{}
(lib.lists.flatten
(attrsMapToList
(name: type:
if type == "directory"
then attrsFromPath "${path}/${name}" (position ++ [name])
else if name == "main.nix"
then {
"/${builtins.concatStringsSep "/" position}" =
import "${path}/main.nix" args;
}
else {})
(builtins.readDir path)));
(
builtins.map
(
dir:
attrsOptional
(pathInConfig dir && pathExists dir)
{"${attrName dir}" = import (projectSrc + dir) args;}
)
(lib.splitString "::" attrPaths)
);
in
(
builtins.foldl'
lib.mergeAttrs
{}
(builtins.map
(dir:
attrsOptional
(builtins.pathExists (projectSrc + dir))
(attrsFromPath (projectPath dir) []))
config.extendingMakesDirs)
)
attrs
// {
__all__ =
toFileJson "all"
Expand Down

0 comments on commit 0a6f245

Please sign in to comment.