buildenv: throw BuildEnvFileConflictError with more context

At the moment an Error is thrown that only holds an error message
regarding `nix-env` and `nix profile`. These tools make use of
builtins.buildEnv, but buildEnv is also used in other places. These
places are unrelated to Nix profiles, so the error shouldn't mention
these tools.

This generic error is now BuildEnvFileConflictError, which holds more
contextual information about the files that were conflicting while
building the environment.
This commit is contained in:
Bob van der Linden 2023-02-08 20:03:57 +01:00
parent 707ba52f2d
commit 3113b13df9
No known key found for this signature in database
GPG key ID: EEBE8E3EC4A31364
2 changed files with 31 additions and 7 deletions

View file

@ -92,13 +92,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
if (S_ISLNK(dstSt.st_mode)) { if (S_ISLNK(dstSt.st_mode)) {
auto prevPriority = state.priorities[dstFile]; auto prevPriority = state.priorities[dstFile];
if (prevPriority == priority) if (prevPriority == priority)
throw Error( throw BuildEnvFileConflictError(
"files '%1%' and '%2%' have the same priority %3%; " readLink(dstFile),
"use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' " srcFile,
"or type 'nix profile install --help' if using 'nix profile' to find out how " priority
"to change the priority of one of the conflicting packages" );
" (0 being the highest priority)",
srcFile, readLink(dstFile), priority);
if (prevPriority < priority) if (prevPriority < priority)
continue; continue;
if (unlink(dstFile.c_str()) == -1) if (unlink(dstFile.c_str()) == -1)

View file

@ -12,6 +12,32 @@ struct Package {
Package(const Path & path, bool active, int priority) : path{path}, active{active}, priority{priority} {} Package(const Path & path, bool active, int priority) : path{path}, active{active}, priority{priority} {}
}; };
class BuildEnvFileConflictError : public Error
{
public:
const Path fileA;
const Path fileB;
int priority;
BuildEnvFileConflictError(
const Path fileA,
const Path fileB,
int priority
)
: Error(
"Unable to build profile. There is a conflict for the following files:\n"
"\n"
" %1%\n"
" %2%",
fileA,
fileB
)
, fileA(fileA)
, fileB(fileB)
, priority(priority)
{}
};
typedef std::vector<Package> Packages; typedef std::vector<Package> Packages;
void buildProfile(const Path & out, Packages && pkgs); void buildProfile(const Path & out, Packages && pkgs);