diff --git a/nix/readTree/README.md b/nix/readTree/README.md index 5d430d1cf..36af46286 100644 --- a/nix/readTree/README.md +++ b/nix/readTree/README.md @@ -84,9 +84,15 @@ the tree as empty nodes (`{}`). imported files via `builtins.scopedImport`. This will forcefully override the given values in the import scope, use with care! -The package headers in this repository follow the form `{ pkgs, ... }:` where -`pkgs` is a fixed-point of the entire package tree (see the `default.nix` at the -root of the depot). +The package headers in this repository follow the form +`{depot, pkgs, lib, here, ... }:` where: + +* `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 this to be a good solution for the most part. diff --git a/nix/readTree/default.nix b/nix/readTree/default.nix index 829e699b9..9771e6862 100644 --- a/nix/readTree/default.nix +++ b/nix/readTree/default.nix @@ -125,7 +125,7 @@ let self = if rootDir 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 # instructions exist. @@ -162,7 +162,7 @@ let let p = joinChild (c + ".nix"); childParts = parts ++ [ c ]; - imported = importFile args scopedArgs p childParts argsFilter; + imported = importFile (args // { here = result; }) scopedArgs p childParts argsFilter; in { name = c; @@ -181,14 +181,16 @@ let else nixChildren ++ children ); + result = + if isAttrs nodeValue + then merge nodeValue (allChildren // (marker parts allChildren)) + else nodeValue; + in if skipTree then { skip = true; } else { - ok = - if isAttrs nodeValue - then merge nodeValue (allChildren // (marker parts allChildren)) - else nodeValue; + ok = result; }; # Top-level implementation of readTree itself. diff --git a/nix/readTree/tests/default.nix b/nix/readTree/tests/default.nix index 6b58175a4..0865d9e7e 100644 --- a/nix/readTree/tests/default.nix +++ b/nix/readTree/tests/default.nix @@ -134,6 +134,13 @@ let (assertEq "default.nix drv is not changed by readTree" tree-tl.default-nix.can-be-drv (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 diff --git a/nix/readTree/tests/test-tree-traversal/here-arg/default.nix b/nix/readTree/tests/test-tree-traversal/here-arg/default.nix new file mode 100644 index 000000000..9072f55ae --- /dev/null +++ b/nix/readTree/tests/test-tree-traversal/here-arg/default.nix @@ -0,0 +1,6 @@ +{ here, ... }: { + attr1 = "foo"; + attr2 = here.attr1; + + attr3 = here.subdir.sibl2; +} diff --git a/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl1.nix b/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl1.nix new file mode 100644 index 000000000..964bdaa34 --- /dev/null +++ b/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl1.nix @@ -0,0 +1 @@ +{ ... }: "sibl1" diff --git a/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl2.nix b/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl2.nix new file mode 100644 index 000000000..37fb4d8c3 --- /dev/null +++ b/nix/readTree/tests/test-tree-traversal/here-arg/subdir/sibl2.nix @@ -0,0 +1,2 @@ +{ here, ... }: +here.sibl1 diff --git a/snix/default.nix b/snix/default.nix index f9ba8b48d..fbc7ddb24 100644 --- a/snix/default.nix +++ b/snix/default.nix @@ -1,10 +1,10 @@ # Nix helpers for projects under //snix -{ pkgs, lib, depot, ... }: +{ pkgs, lib, depot, here, ... }: let # Load the crate2nix crate tree. 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. @@ -30,9 +30,9 @@ let protos = pkgs.symlinkJoin { name = "snix-all-protos"; paths = [ - depot.snix.build.protos.protos - depot.snix.castore.protos.protos - depot.snix.store.protos.protos + here.build.protos.protos + here.castore.protos.protos + here.store.protos.protos ]; }; @@ -112,7 +112,7 @@ in crate2nix-check = let - crate2nix-check = depot.snix.utils.mkCrate2nixCheck ./Cargo.nix; + crate2nix-check = here.utils.mkCrate2nixCheck ./Cargo.nix; in crate2nix-check.command.overrideAttrs { meta.ci.extraSteps = {