Skip to content

Commit f18af84

Browse files
authored
Merge pull request #13170 from MattSturgeon/fix/call-flake/rel-path
Use correct parent `outPath` for relative path inputs
2 parents e7078d4 + 2922e30 commit f18af84

File tree

4 files changed

+117
-15
lines changed

4 files changed

+117
-15
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
synopsis: Non-flake inputs now contain a `sourceInfo` attribute
3+
issues: 13164
4+
prs: 13170
5+
---
6+
7+
Flakes have always a `sourceInfo` attribute which describes the source of the flake.
8+
The `sourceInfo.outPath` is often identical to the flake's `outPath`, however it can differ when the flake is located in a subdirectory of its source.
9+
10+
Non-flake inputs (i.e. inputs with `flake = false`) can also be located at some path _within_ a wider source.
11+
This usually happens when defining a relative path input within the same source as the parent flake, e.g. `inputs.foo.url = ./some-file.nix`.
12+
Such relative inputs will now inherit their parent's `sourceInfo`.
13+
14+
This also means it is now possible to use `?dir=subdir` on non-flake inputs.
15+
16+
This iterates on the work done in 2.26 to improve relative path support ([#10089](https://github.com/NixOS/nix/pull/10089)),
17+
and resolves a regression introduced in 2.28 relating to nested relative path inputs ([#13164](https://github.com/NixOS/nix/issues/13164)).

src/libflake/call-flake.nix

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,28 @@ let
3939
allNodes = mapAttrs (
4040
key: node:
4141
let
42+
hasOverride = overrides ? ${key};
43+
isRelative = node.locked.type or null == "path" && builtins.substring 0 1 node.locked.path != "/";
4244

4345
parentNode = allNodes.${getInputByPath lockFile.root node.parent};
4446

45-
flakeDir =
46-
let
47-
dir = overrides.${key}.dir or node.locked.path or "";
48-
parentDir = parentNode.flakeDir;
49-
in
50-
if node ? parent then parentDir + ("/" + dir) else dir;
51-
5247
sourceInfo =
53-
if overrides ? ${key} then
48+
if hasOverride then
5449
overrides.${key}.sourceInfo
55-
else if node.locked.type == "path" && builtins.substring 0 1 node.locked.path != "/" then
50+
else if isRelative then
5651
parentNode.sourceInfo
57-
// {
58-
outPath = parentNode.sourceInfo.outPath + ("/" + flakeDir);
59-
}
6052
else
6153
# FIXME: remove obsolete node.info.
6254
# Note: lock file entries are always final.
6355
fetchTreeFinal (node.info or { } // removeAttrs node.locked [ "dir" ]);
6456

6557
subdir = overrides.${key}.dir or node.locked.dir or "";
6658

67-
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
59+
outPath =
60+
if !hasOverride && isRelative then
61+
parentNode.outPath + (if node.locked.path == "" then "" else "/" + node.locked.path)
62+
else
63+
sourceInfo.outPath + (if subdir == "" then "" else "/" + subdir);
6864

6965
flake = import (outPath + "/flake.nix");
7066

@@ -99,9 +95,9 @@ let
9995
assert builtins.isFunction flake.outputs;
10096
result
10197
else
102-
sourceInfo;
98+
sourceInfo // { inherit sourceInfo outPath; };
10399

104-
inherit flakeDir sourceInfo;
100+
inherit outPath sourceInfo;
105101
}
106102
) lockFile.nodes;
107103

tests/functional/flakes/non-flake-inputs.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,20 @@ cat > "$flake3Dir/flake.nix" <<EOF
3737
url = "$nonFlakeDir/README.md";
3838
flake = false;
3939
};
40+
nonFlakeFile3 = {
41+
url = "$nonFlakeDir?dir=README.md";
42+
flake = false;
43+
};
44+
relativeNonFlakeFile = {
45+
url = ./config.nix;
46+
flake = false;
47+
};
4048
};
4149
4250
description = "Fnord";
4351
4452
outputs = inputs: rec {
53+
inherit inputs;
4554
packages.$system.xyzzy = inputs.flake2.packages.$system.bar;
4655
packages.$system.sth = inputs.flake1.packages.$system.foo;
4756
packages.$system.fnord =
@@ -88,6 +97,43 @@ mv "$flake2Dir.tmp" "$flake2Dir"
8897
mv "$nonFlakeDir.tmp" "$nonFlakeDir"
8998
nix build -o "$TEST_ROOT/result" flake3#xyzzy flake3#fnord
9099

100+
# Check non-flake inputs have a sourceInfo and an outPath
101+
#
102+
# This may look redundant, but the other checks below happen in a command
103+
# substitution subshell, so failures there will not exit this shell
104+
nix eval --raw flake3#inputs.nonFlake.outPath
105+
nix eval --raw flake3#inputs.nonFlake.sourceInfo.outPath
106+
nix eval --raw flake3#inputs.nonFlakeFile.outPath
107+
nix eval --raw flake3#inputs.nonFlakeFile.sourceInfo.outPath
108+
nix eval --raw flake3#inputs.nonFlakeFile2.outPath
109+
nix eval --raw flake3#inputs.nonFlakeFile2.sourceInfo.outPath
110+
nix eval --raw flake3#inputs.nonFlakeFile3.outPath
111+
nix eval --raw flake3#inputs.nonFlakeFile3.sourceInfo.outPath
112+
nix eval --raw flake3#inputs.relativeNonFlakeFile.outPath
113+
nix eval --raw flake3#inputs.relativeNonFlakeFile.sourceInfo.outPath
114+
115+
# Check non-flake file inputs have the expected outPaths
116+
[[
117+
$(nix eval --raw flake3#inputs.nonFlake.outPath) \
118+
= $(nix eval --raw flake3#inputs.nonFlake.sourceInfo.outPath)
119+
]]
120+
[[
121+
$(nix eval --raw flake3#inputs.nonFlakeFile.outPath) \
122+
= $(nix eval --raw flake3#inputs.nonFlakeFile.sourceInfo.outPath)
123+
]]
124+
[[
125+
$(nix eval --raw flake3#inputs.nonFlakeFile2.outPath) \
126+
= $(nix eval --raw flake3#inputs.nonFlakeFile2.sourceInfo.outPath)
127+
]]
128+
[[
129+
$(nix eval --raw flake3#inputs.nonFlakeFile3.outPath) \
130+
= $(nix eval --raw flake3#inputs.nonFlakeFile3.sourceInfo.outPath)/README.md
131+
]]
132+
[[
133+
$(nix eval --raw flake3#inputs.relativeNonFlakeFile.outPath) \
134+
= $(nix eval --raw flake3#inputs.relativeNonFlakeFile.sourceInfo.outPath)/config.nix
135+
]]
136+
91137
# Make branch "removeXyzzy" where flake3 doesn't have xyzzy anymore
92138
git -C "$flake3Dir" checkout -b removeXyzzy
93139
rm "$flake3Dir/flake.nix"

tests/functional/flakes/relative-paths.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,46 @@ EOF
131131
# would fail:
132132
nix eval .#ok
133133
)
134+
135+
# https://github.com/NixOS/nix/issues/13164
136+
mkdir -p "$TEST_ROOT/issue-13164/nested-flake1/nested-flake2"
137+
(
138+
cd "$TEST_ROOT/issue-13164"
139+
git init
140+
git config --global user.email "[email protected]"
141+
git config --global user.name "Your Name"
142+
cat >flake.nix <<EOF
143+
{
144+
inputs.nestedFlake1.url = "path:./nested-flake1";
145+
outputs = { self, nestedFlake1 }: {
146+
inherit nestedFlake1;
147+
};
148+
}
149+
EOF
150+
151+
cat >nested-flake1/flake.nix <<EOF
152+
{
153+
inputs.nestedFlake2.url = "path:./nested-flake2";
154+
155+
outputs = { self, nestedFlake2 }: {
156+
name = "nestedFlake1";
157+
inherit nestedFlake2;
158+
};
159+
}
160+
EOF
161+
162+
cat >nested-flake1/nested-flake2/flake.nix <<EOF
163+
{
164+
outputs = { self }: {
165+
name = "nestedFlake2";
166+
};
167+
}
168+
EOF
169+
170+
git add .
171+
git commit -m "Initial commit"
172+
173+
# I don't understand why two calls are necessary to reproduce the issue.
174+
nix eval --json .#nestedFlake1.nestedFlake2 --no-eval-cache
175+
nix eval --json .#nestedFlake1.nestedFlake2 --no-eval-cache
176+
)

0 commit comments

Comments
 (0)