feat(readTree): Add special here argument.

It's convenient for depending on sub-tree members of the current file as
well as gives access to siblings.

Change-Id: I74234cec6566177d88d3bc8507fa3f6ec789adb8
Reviewed-on: https://cl.snix.dev/c/snix/+/30098
Reviewed-by: adis bladis <adisbladis@gmail.com>
Tested-by: besadii
This commit is contained in:
vkryachko 2025-03-18 13:30:08 +00:00 committed by Vova Kryachko
parent 39b3e2c410
commit a04c73ca83
7 changed files with 39 additions and 15 deletions

View file

@ -84,9 +84,15 @@ the tree as empty nodes (`{}`).
imported files via `builtins.scopedImport`. This will forcefully imported files via `builtins.scopedImport`. This will forcefully
override the given values in the import scope, use with care! override the given values in the import scope, use with care!
The package headers in this repository follow the form `{ pkgs, ... }:` where The package headers in this repository follow the form
`pkgs` is a fixed-point of the entire package tree (see the `default.nix` at the `{depot, pkgs, lib, here, ... }:` where:
root of the depot).
* `depot` is a fixed-point of the entire package tree (see the `default.nix`
at the root of the depot).
* `pkgs` is the nixpkgs used in the repo, see `third_party/nixpkgs`
* `lib` is essentially a shortcut to `pkgs.lib` exposed for convenience
* `here` is a special argument that points to the current location in the
tree. Useful to avoid specifying dependencies from the very top of the `depot`
In theory `readTree` can pass arguments of different shapes, but I have found In theory `readTree` can pass arguments of different shapes, but I have found
this to be a good solution for the most part. this to be a good solution for the most part.

View file

@ -125,7 +125,7 @@ let
self = self =
if rootDir if rootDir
then { __readTree = [ ]; } then { __readTree = [ ]; }
else importFile args scopedArgs initPath parts argsFilter; else importFile (args // { here = result; }) scopedArgs initPath parts argsFilter;
# Import subdirectories of the current one, unless any skip # Import subdirectories of the current one, unless any skip
# instructions exist. # instructions exist.
@ -162,7 +162,7 @@ let
let let
p = joinChild (c + ".nix"); p = joinChild (c + ".nix");
childParts = parts ++ [ c ]; childParts = parts ++ [ c ];
imported = importFile args scopedArgs p childParts argsFilter; imported = importFile (args // { here = result; }) scopedArgs p childParts argsFilter;
in in
{ {
name = c; name = c;
@ -181,14 +181,16 @@ let
else nixChildren ++ children else nixChildren ++ children
); );
result =
if isAttrs nodeValue
then merge nodeValue (allChildren // (marker parts allChildren))
else nodeValue;
in in
if skipTree if skipTree
then { skip = true; } then { skip = true; }
else { else {
ok = ok = result;
if isAttrs nodeValue
then merge nodeValue (allChildren // (marker parts allChildren))
else nodeValue;
}; };
# Top-level implementation of readTree itself. # Top-level implementation of readTree itself.

View file

@ -134,6 +134,13 @@ let
(assertEq "default.nix drv is not changed by readTree" (assertEq "default.nix drv is not changed by readTree"
tree-tl.default-nix.can-be-drv tree-tl.default-nix.can-be-drv
(import ./test-tree-traversal/default-nix/can-be-drv/default.nix { })) (import ./test-tree-traversal/default-nix/can-be-drv/default.nix { }))
(assertEq "`here` argument represents the attrset a given file is part of"
(builtins.removeAttrs tree-tl.here-arg [ "__readTree" "__readTreeChildren" "subdir" ])
{
attr1 = "foo";
attr2 = "foo";
attr3 = "sibl1";
})
]; ];
# these each call readTree themselves because the throws have to happen inside assertThrows # these each call readTree themselves because the throws have to happen inside assertThrows

View file

@ -0,0 +1,6 @@
{ here, ... }: {
attr1 = "foo";
attr2 = here.attr1;
attr3 = here.subdir.sibl2;
}

View file

@ -0,0 +1 @@
{ ... }: "sibl1"

View file

@ -0,0 +1,2 @@
{ here, ... }:
here.sibl1

View file

@ -1,10 +1,10 @@
# Nix helpers for projects under //snix # Nix helpers for projects under //snix
{ pkgs, lib, depot, ... }: { pkgs, lib, depot, here, ... }:
let let
# Load the crate2nix crate tree. # Load the crate2nix crate tree.
crates = pkgs.callPackage ./Cargo.nix { crates = pkgs.callPackage ./Cargo.nix {
defaultCrateOverrides = depot.snix.utils.defaultCrateOverridesForPkgs pkgs; defaultCrateOverrides = here.utils.defaultCrateOverridesForPkgs pkgs;
}; };
# Cargo dependencies to be used with nixpkgs rustPlatform functions. # Cargo dependencies to be used with nixpkgs rustPlatform functions.
@ -30,9 +30,9 @@ let
protos = pkgs.symlinkJoin { protos = pkgs.symlinkJoin {
name = "snix-all-protos"; name = "snix-all-protos";
paths = [ paths = [
depot.snix.build.protos.protos here.build.protos.protos
depot.snix.castore.protos.protos here.castore.protos.protos
depot.snix.store.protos.protos here.store.protos.protos
]; ];
}; };
@ -112,7 +112,7 @@ in
crate2nix-check = crate2nix-check =
let let
crate2nix-check = depot.snix.utils.mkCrate2nixCheck ./Cargo.nix; crate2nix-check = here.utils.mkCrate2nixCheck ./Cargo.nix;
in in
crate2nix-check.command.overrideAttrs { crate2nix-check.command.overrideAttrs {
meta.ci.extraSteps = { meta.ci.extraSteps = {