Handle store symlinks in flake directories
E.g. 'nix path-info ./result' inside a flake directory now works again.
This commit is contained in:
parent
4f6a7c8621
commit
d132d057a8
5 changed files with 25 additions and 12 deletions
|
@ -143,6 +143,14 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
|
|||
IsPath d;
|
||||
if (allowRelative) {
|
||||
d.path = absPath(uri);
|
||||
try {
|
||||
if (!S_ISDIR(lstat(d.path).st_mode))
|
||||
throw BadFlakeRef("path '%s' is not a flake (sub)directory");
|
||||
} catch (SysError & e) {
|
||||
if (e.errNo == ENOENT || e.errNo == EISDIR)
|
||||
throw BadFlakeRef("flake '%s' does not exist");
|
||||
throw;
|
||||
}
|
||||
while (true) {
|
||||
if (pathExists(d.path + "/.git")) break;
|
||||
subdir = baseNameOf(d.path) + (subdir.empty() ? "" : "/" + subdir);
|
||||
|
|
|
@ -55,7 +55,7 @@ Path Store::followLinksToStore(const Path & _path) const
|
|||
path = absPath(target, dirOf(path));
|
||||
}
|
||||
if (!isInStore(path))
|
||||
throw Error(format("path '%1%' is not in the Nix store") % path);
|
||||
throw NotInStore("path '%1%' is not in the Nix store", path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ MakeError(InvalidPath, Error)
|
|||
MakeError(Unsupported, Error)
|
||||
MakeError(SubstituteGone, Error)
|
||||
MakeError(SubstituterDisabled, Error)
|
||||
MakeError(NotInStore, Error)
|
||||
|
||||
|
||||
struct BasicDerivation;
|
||||
|
|
|
@ -394,9 +394,18 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
|
|||
|
||||
} else {
|
||||
|
||||
auto follow = [&](const std::string & s) -> std::optional<Path> {
|
||||
try {
|
||||
return store->followLinksToStorePath(s);
|
||||
} catch (NotInStore &) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
for (auto & s : ss) {
|
||||
|
||||
size_t colon;
|
||||
std::optional<Path> storePath;
|
||||
|
||||
if (s.compare(0, 1, "(") == 0)
|
||||
result.push_back(std::make_shared<InstallableExpr>(*this, s));
|
||||
|
@ -422,17 +431,8 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
|
|||
getDefaultFlakeAttrPathPrefixes()));
|
||||
}
|
||||
|
||||
else if (s.find('/') != std::string::npos || s == ".") {
|
||||
Path storePath;
|
||||
try {
|
||||
storePath = store->toStorePath(store->followLinksToStore(s));
|
||||
} catch (Error) { }
|
||||
if (storePath != "")
|
||||
result.push_back(std::make_shared<InstallableStorePath>(storePath));
|
||||
else
|
||||
result.push_back(std::make_shared<InstallableFlake>(*this, FlakeRef(s, true),
|
||||
getDefaultFlakeAttrPaths()));
|
||||
}
|
||||
else if (s.find('/') != std::string::npos && (storePath = follow(s)))
|
||||
result.push_back(std::make_shared<InstallableStorePath>(*storePath));
|
||||
|
||||
else
|
||||
throw Error("unsupported argument '%s'", s);
|
||||
|
|
|
@ -149,6 +149,10 @@ nix build -o $TEST_ROOT/result --flake-registry $registry flake1
|
|||
nix build -o $TEST_ROOT/result --flake-registry $registry $flake1Dir
|
||||
nix build -o $TEST_ROOT/result --flake-registry $registry file://$flake1Dir
|
||||
|
||||
# CHeck that store symlinks inside a flake are not interpreted as flakes.
|
||||
nix build -o $flake1Dir/result --flake-registry $registry file://$flake1Dir
|
||||
nix path-info $flake1Dir/result
|
||||
|
||||
# Building a flake with an unlocked dependency should fail in pure mode.
|
||||
(! nix eval "(builtins.getFlake "$flake2Dir")")
|
||||
|
||||
|
|
Loading…
Reference in a new issue