Skip to content

Commit

Permalink
WIP: opt-out, inputs.self.outPathIsString = true;
Browse files Browse the repository at this point in the history
  • Loading branch information
roberth committed Aug 8, 2024
1 parent e21e54e commit 23d8c06
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 17 deletions.
45 changes: 29 additions & 16 deletions src/libexpr/flake/call-flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,42 @@ let
builtins.mapAttrs
(key: node:
let

sourceInfo =
# FIXME: remove obsolete node.info.
tree0 =
if overrides ? ${key}
then
overrides.${key}.sourceInfo
else
# FIXME: remove obsolete node.info.
let
tree =
fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
in tree // {
# TODO: return the path value without fetching to the store?
# removing this will improve performance, but may break
# one or two flakes, that rely on
# `builtins.typeOf outPath` for some reason, or perhaps
# something more subtle than that, despite our conservative
# choice of lazy path semantics.
outPath = "${tree.outPath}";
};
fetchTree (node.info or {} // removeAttrs node.locked [
# attributes that are applied after fetching
"dir"
"outPathIsString"
]);

# TODO: split this logic into stand-alone functions
getSourceInfo = coerceOutPathToString:
tree0 // {
# TODO: return the path value without fetching to the store?
# removing this will improve performance, but may break
# one or two flakes, that rely on
# `builtins.typeOf outPath` for some reason, or perhaps
# something more subtle than that, despite our conservative
# choice of lazy path semantics.
outPath = if coerceOutPathToString then "${tree0.outPath}" else tree0.outPath;
};

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

outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
getOutPath = coerceOutPathToString:
getSourceInfo coerceOutPathToString + ((if subdir == "" then "" else "/") + subdir);

outPath = getOutPath outPathIsString;
sourceInfo = getSourceInfo outPathIsString;

flake0 = import (getOutPath false + "/flake.nix");

# Users can opt in to the legacy behavior of outPath being a string.
outPathIsString = flake0.inputs.self.outPathIsString or false;

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

Expand Down
13 changes: 12 additions & 1 deletion src/libexpr/flake/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ static FlakeInput parseFlakeInput(
}
else {
attrs.erase("url");
// TODO: if (isRoot) ...
attrs.erase("outPathIsString");
if (!attrs.empty())
throw Error("unexpected flake input attribute '%s', at %s", attrs.begin()->first, state.positions[pos]);
if (url)
Expand Down Expand Up @@ -411,7 +413,16 @@ LockedFlake lockFlake(
from what's in the lock file). */
for (auto & [id, input2] : flakeInputs) {
auto inputPath(inputPathPrefix);
inputPath.push_back(id);
if (id == "self") {
// TODO validate that it only has `outPathIsString` (for now)
// TODO accept hints for fetching schemas such as `git` or `github`
// so that the fetching of the flake can be customized as
// needed in the flake itself.
// TODO allow certain schemas to be rejected, e.g. inputs.self.hints."github" = throw "this flake must be fetch with the `git:` scheme in order to load submodules";
continue;
} else {
inputPath.push_back(id);
}
auto inputPathS = printInputPath(inputPath);
debug("computing input '%s'", inputPathS);

Expand Down

0 comments on commit 23d8c06

Please sign in to comment.