Skip to content

Commit d08a448

Browse files
authored
Merge pull request #13403 from NixOS/mergify/bp/2.28-maintenance/pr-13170
Use correct parent `outPath` for relative path inputs (backport #13170)
2 parents decc0bf + 3206585 commit d08a448

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

0 commit comments

Comments
 (0)