From 904a107d16b69f28b9d61c677eb27b953d421a54 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 9 Feb 2023 22:10:30 +0100 Subject: [PATCH 1/3] flakes: Ensure that `self.outPath == ./.` Users expect `self` to refer to the directory where the `flake.nix` file resides. --- src/libexpr/flake/call-flake.nix | 8 +++- tests/flakes/inputs.sh | 79 ++++++++++++++++++++++++++++++++ tests/local.mk | 1 + 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tests/flakes/inputs.sh diff --git a/src/libexpr/flake/call-flake.nix b/src/libexpr/flake/call-flake.nix index 8061db3df..7dc03e7f5 100644 --- a/src/libexpr/flake/call-flake.nix +++ b/src/libexpr/flake/call-flake.nix @@ -9,14 +9,18 @@ let (key: node: let - sourceInfo = + rawSourceInfo = if key == lockFile.root then rootSrc else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]); subdir = if key == lockFile.root then rootSubdir else node.locked.dir or ""; - flake = import (sourceInfo + (if subdir != "" then "/" else "") + subdir + "/flake.nix"); + outPath = rawSourceInfo + ((if subdir == "" then "" else "/") + subdir); + + sourceInfo = rawSourceInfo // { inherit outPath; }; + + flake = import (outPath + "/flake.nix"); inputs = builtins.mapAttrs (inputName: inputSpec: allNodes.${resolveInput inputSpec}) diff --git a/tests/flakes/inputs.sh b/tests/flakes/inputs.sh new file mode 100644 index 000000000..d6269fc59 --- /dev/null +++ b/tests/flakes/inputs.sh @@ -0,0 +1,79 @@ +source ./common.sh + +requireGit + + +test_subdir_self_path() { + baseDir=$TEST_ROOT/$RANDOM + flakeDir=$baseDir/b-low + mkdir -p $flakeDir + writeSimpleFlake $baseDir + writeSimpleFlake $flakeDir + + echo all good > $flakeDir/message + cat > $flakeDir/flake.nix < $flakeDir/message + cat > $flakeDir/flake.nix < $clientDir/flake.nix < Date: Wed, 22 Feb 2023 03:28:30 +0100 Subject: [PATCH 2/3] flakes: Differentiate `self.outPath` and `self.sourceInfo.outPath` It would be incorrect to say that the `sourceInfo` has an `outPath` that isn't the root. `sourceInfo` is about the root, whereas only the flake may not be about the root. Thanks Eelco for pointing that out. --- src/libexpr/flake/call-flake.nix | 22 +++++++++++++++++----- tests/flakes/inputs.sh | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libexpr/flake/call-flake.nix b/src/libexpr/flake/call-flake.nix index 7dc03e7f5..4beb0b0fe 100644 --- a/src/libexpr/flake/call-flake.nix +++ b/src/libexpr/flake/call-flake.nix @@ -9,16 +9,14 @@ let (key: node: let - rawSourceInfo = + sourceInfo = if key == lockFile.root then rootSrc else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]); subdir = if key == lockFile.root then rootSubdir else node.locked.dir or ""; - outPath = rawSourceInfo + ((if subdir == "" then "" else "/") + subdir); - - sourceInfo = rawSourceInfo // { inherit outPath; }; + outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir); flake = import (outPath + "/flake.nix"); @@ -47,7 +45,21 @@ let outputs = flake.outputs (inputs // { self = result; }); - result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; }; + result = + outputs + # We add the sourceInfo attribute for its metadata, as they are + # relevant metadata for the flake. However, the outPath of the + # sourceInfo does not necessarily match the outPath of the flake, + # as the flake may be in a subdirectory of a source. + # This is shadowed in the next // + // sourceInfo + // { + # This shadows the sourceInfo.outPath + inherit outPath; + + inherit inputs; inherit outputs; inherit sourceInfo; _type = "flake"; + }; + in if node.flake or true then assert builtins.isFunction flake.outputs; diff --git a/tests/flakes/inputs.sh b/tests/flakes/inputs.sh index d6269fc59..80620488a 100644 --- a/tests/flakes/inputs.sh +++ b/tests/flakes/inputs.sh @@ -46,6 +46,7 @@ test_git_subdir_self_path() { default = assert builtins.readFile ./message == "all good\n"; assert builtins.readFile (inputs.self + "/message") == "all good\n"; + assert inputs.self.outPath == inputs.self.sourceInfo.outPath + "/b-low"; import ./simple.nix; }; }; From e76619a40275faa08dac36dee89c0f8508cfe146 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sun, 26 Feb 2023 14:41:23 +0100 Subject: [PATCH 3/3] rl-next: Describe fixed flake outPath semantics The reference documentation already implies the correct semantics. --- doc/manual/src/release-notes/rl-next.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 7e8344e63..a38305fde 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -3,6 +3,12 @@ * A new function `builtins.readFileType` is available. It is similar to `builtins.readDir` but acts on a single file or directory. +* In flakes, the `.outPath` attribute of a flake now always refers to the + directory containing the `flake.nix`. This was not the case for when + `flake.nix` was in a subdirectory of e.g. a git repository. + The root of the source of a flake in a subdirectory is still available in + `.sourceInfo.outPath`. + * The `builtins.readDir` function has been optimized when encountering not-yet-known file types from POSIX's `readdir`. In such cases the type of each file is/was discovered by making multiple syscalls. This change makes these operations