Skip to content

Commit

Permalink
Try and help if a file is missing at eval time
Browse files Browse the repository at this point in the history
When evaluating a local git flake, if a file a missing at eval-time but
present in the source directory, tell the user that he probably forgot
to check it out

Fix #4507
  • Loading branch information
thufschmitt committed Jul 7, 2021
1 parent bfd6c55 commit cce7972
Showing 1 changed file with 34 additions and 15 deletions.
49 changes: 34 additions & 15 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -535,26 +535,45 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
auto cache = openEvalCache(*state, lockedFlake);
auto root = cache->getRoot();

for (auto & attrPath : getActualAttrPaths()) {
auto attr = root->findAlongAttrPath(
parseAttrPath(*state, attrPath),
true
);
try {
for (auto & attrPath : getActualAttrPaths()) {
auto attr = root->findAlongAttrPath(
parseAttrPath(*state, attrPath),
true
);

if (!attr) continue;
if (!attr) continue;

if (!attr->isDerivation())
throw Error("flake output attribute '%s' is not a derivation", attrPath);
if (!attr->isDerivation())
throw Error("flake output attribute '%s' is not a derivation", attrPath);

auto drvPath = attr->forceDerivation();
auto drvPath = attr->forceDerivation();

auto drvInfo = DerivationInfo{
std::move(drvPath),
state->store->maybeParseStorePath(attr->getAttr(state->sOutPath)->getString()),
attr->getAttr(state->sOutputName)->getString()
};
auto drvInfo = DerivationInfo{
std::move(drvPath),
state->store->maybeParseStorePath(attr->getAttr(state->sOutPath)->getString()),
attr->getAttr(state->sOutputName)->getString()
};

return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)};
return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)};
}
} catch (FileError & e) {
if (e.errNo != ENOENT) throw;
if (!state->store->isInStore(e.path)) throw;
auto resolvedInput = lockedFlake->flake.resolvedRef.input;
auto [sourceStorePath, relPath] = state->store->toStorePath(e.path);
if (sourceStorePath != lockedFlake->flake.lockedRef.input.computeStorePath(*state->store)) throw;
if (fetchers::maybeGetStrAttr(resolvedInput.attrs, "type").value_or("") != "git") throw;
if (auto repositoryPath = resolvedInput.getSourcePath()) {
auto sourcePath = *repositoryPath + "/" + relPath;
if (pathExists(sourcePath))
e.addTrace(
noPos,
"The file is present in '%s'. "
"Did you forget to track it in Git?",
*repositoryPath);
}
throw;
}

throw Error("flake '%s' does not provide attribute %s",
Expand Down

0 comments on commit cce7972

Please sign in to comment.