Handle store symlinks in flake directories

E.g. 'nix path-info ./result' inside a flake directory now works
again.
This commit is contained in:
Eelco Dolstra 2019-06-21 15:29:05 +02:00
parent 4f6a7c8621
commit d132d057a8
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 25 additions and 12 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -26,6 +26,7 @@ MakeError(InvalidPath, Error)
MakeError(Unsupported, Error)
MakeError(SubstituteGone, Error)
MakeError(SubstituterDisabled, Error)
MakeError(NotInStore, Error)
struct BasicDerivation;

View file

@ -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);

View file

@ -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")")