Improve error message when a directory is not a flake

So you now get

  $ nix build
  error: path '.' is not a flake (because it does not reference a Git repository)

rather than

  $ nix build
  error: unsupported argument '.'
This commit is contained in:
Eelco Dolstra 2019-09-02 17:33:07 +02:00
parent 5ec2a1ed82
commit 61fdb16aac
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 39 additions and 20 deletions

View file

@ -145,10 +145,10 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
d.path = absPath(uri);
try {
if (!S_ISDIR(lstat(d.path).st_mode))
throw BadFlakeRef("path '%s' is not a flake (sub)directory");
throw MissingFlake("path '%s' is not a flake (sub)directory", d.path);
} catch (SysError & e) {
if (e.errNo == ENOENT || e.errNo == EISDIR)
throw BadFlakeRef("flake '%s' does not exist");
throw MissingFlake("flake '%s' does not exist", d.path);
throw;
}
while (true) {
@ -156,7 +156,7 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
subdir = baseNameOf(d.path) + (subdir.empty() ? "" : "/" + subdir);
d.path = dirOf(d.path);
if (d.path == "/")
throw BadFlakeRef("path '%s' does not reference a Git repository", uri);
throw MissingFlake("path '%s' is not a flake (because it does not reference a Git repository)", uri);
}
} else
d.path = canonPath(uri);

View file

@ -187,6 +187,7 @@ struct FlakeRef
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
MakeError(BadFlakeRef, Error);
MakeError(MissingFlake, BadFlakeRef);
std::optional<FlakeRef> parseFlakeRef(
const std::string & uri, bool allowRelative = false);

View file

@ -417,25 +417,43 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
Strings{"legacyPackages." + std::string(s, 8)}));
}
else if (auto flakeRef = parseFlakeRef(s, true))
result.push_back(std::make_shared<InstallableFlake>(*this, std::move(*flakeRef),
getDefaultFlakeAttrPaths()));
else {
else if ((colon = s.rfind(':')) != std::string::npos) {
auto flakeRef = std::string(s, 0, colon);
auto attrPath = std::string(s, colon + 1);
result.push_back(std::make_shared<InstallableFlake>(
*this,
FlakeRef(flakeRef, true),
attrPath,
getDefaultFlakeAttrPathPrefixes()));
std::exception_ptr flakeEx;
try {
auto flakeRef = FlakeRef(s, true);
result.push_back(std::make_shared<InstallableFlake>(
*this, std::move(flakeRef), getDefaultFlakeAttrPaths()));
continue;
} catch (MissingFlake &) {
/* 's' could be parsed as a flakeref, but it
references a local path that is not a flake. So
take note of that. */
flakeEx = std::current_exception();
} catch (BadFlakeRef &) {
}
if ((colon = s.rfind(':')) != std::string::npos) {
auto flakeRef = std::string(s, 0, colon);
auto attrPath = std::string(s, colon + 1);
result.push_back(std::make_shared<InstallableFlake>(
*this,
FlakeRef(flakeRef, true),
attrPath,
getDefaultFlakeAttrPathPrefixes()));
}
else if (s.find('/') != std::string::npos && (storePath = follow(s)))
result.push_back(std::make_shared<InstallableStorePath>(*storePath));
else {
if (flakeEx)
std::rethrow_exception(flakeEx);
else
throw Error("unsupported argument '%s'", s);
}
}
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);
}
}