mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-29 09:06:15 +02:00
Merge branch 'master' of github.com:NixOS/nix
This commit is contained in:
commit
39e8aad446
12 changed files with 178 additions and 112 deletions
|
@ -1184,11 +1184,11 @@ static void derivationStrictInternal(
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
/* !!! Check whether j is a valid attribute
|
/* !!! Check whether j is a valid attribute
|
||||||
name. */
|
name. */
|
||||||
/* Derivations cannot be named ‘drv’, because
|
/* Derivations cannot be named ‘drvPath’, because
|
||||||
then we'd have an attribute ‘drvPath’ in
|
we already have an attribute ‘drvPath’ in
|
||||||
the resulting set. */
|
the resulting set (see state.sDrvPath). */
|
||||||
if (j == "drv")
|
if (j == "drvPath")
|
||||||
state.error<EvalError>("invalid derivation output name 'drv'")
|
state.error<EvalError>("invalid derivation output name 'drvPath'")
|
||||||
.atPos(v)
|
.atPos(v)
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
outputs.insert(j);
|
outputs.insert(j);
|
||||||
|
|
|
@ -342,7 +342,8 @@ struct GitInputScheme : InputScheme
|
||||||
logger->pause();
|
logger->pause();
|
||||||
Finally restoreLogger([]() { logger->resume(); });
|
Finally restoreLogger([]() { logger->resume(); });
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-m", *commitMsg });
|
{ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-F", "-" },
|
||||||
|
*commitMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (type == std::filesystem::file_type::unknown)
|
if (type == std::filesystem::file_type::unknown)
|
||||||
type = getFileType(path);
|
type = std::filesystem::symlink_status(path).type();
|
||||||
|
|
||||||
if (type == std::filesystem::file_type::directory) {
|
if (type == std::filesystem::file_type::directory) {
|
||||||
for (auto & i : std::filesystem::directory_iterator{path})
|
for (auto & i : std::filesystem::directory_iterator{path})
|
||||||
|
|
|
@ -12,7 +12,7 @@ void IndirectRootStore::makeSymlink(const Path & link, const Path & target)
|
||||||
createSymlink(target, tempLink);
|
createSymlink(target, tempLink);
|
||||||
|
|
||||||
/* Atomically replace the old one. */
|
/* Atomically replace the old one. */
|
||||||
renameFile(tempLink, link);
|
std::filesystem::rename(tempLink, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path IndirectRootStore::addPermRoot(const StorePath & storePath, const Path & _gcRoot)
|
Path IndirectRootStore::addPermRoot(const StorePath & storePath, const Path & _gcRoot)
|
||||||
|
|
|
@ -64,7 +64,7 @@ protected:
|
||||||
AutoDelete del(tmp, false);
|
AutoDelete del(tmp, false);
|
||||||
StreamToSourceAdapter source(istream);
|
StreamToSourceAdapter source(istream);
|
||||||
writeFile(tmp, source);
|
writeFile(tmp, source);
|
||||||
renameFile(tmp, path2);
|
std::filesystem::rename(tmp, path2);
|
||||||
del.cancel();
|
del.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1779,7 +1779,7 @@ void LocalStore::addBuildLog(const StorePath & drvPath, std::string_view log)
|
||||||
|
|
||||||
writeFile(tmpFile, compress("bzip2", log));
|
writeFile(tmpFile, compress("bzip2", log));
|
||||||
|
|
||||||
renameFile(tmpFile, logPath);
|
std::filesystem::rename(tmpFile, logPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> LocalStore::getVersion()
|
std::optional<std::string> LocalStore::getVersion()
|
||||||
|
|
|
@ -783,7 +783,7 @@ static void movePath(const Path & src, const Path & dst)
|
||||||
if (changePerm)
|
if (changePerm)
|
||||||
chmod_(src, st.st_mode | S_IWUSR);
|
chmod_(src, st.st_mode | S_IWUSR);
|
||||||
|
|
||||||
renameFile(src, dst);
|
std::filesystem::rename(src, dst);
|
||||||
|
|
||||||
if (changePerm)
|
if (changePerm)
|
||||||
chmod_(dst, st.st_mode);
|
chmod_(dst, st.st_mode);
|
||||||
|
|
|
@ -285,7 +285,7 @@ static void movePath(const Path & src, const Path & dst)
|
||||||
if (changePerm)
|
if (changePerm)
|
||||||
chmod_(src, st.st_mode | S_IWUSR);
|
chmod_(src, st.st_mode | S_IWUSR);
|
||||||
|
|
||||||
renameFile(src, dst);
|
std::filesystem::rename(src, dst);
|
||||||
|
|
||||||
if (changePerm)
|
if (changePerm)
|
||||||
chmod_(dst, st.st_mode);
|
chmod_(dst, st.st_mode);
|
||||||
|
@ -372,7 +372,7 @@ bool LocalDerivationGoal::cleanupDecideWhetherDiskFull()
|
||||||
if (buildMode != bmCheck && status.known->isValid()) continue;
|
if (buildMode != bmCheck && status.known->isValid()) continue;
|
||||||
auto p = worker.store.toRealPath(status.known->path);
|
auto p = worker.store.toRealPath(status.known->path);
|
||||||
if (pathExists(chrootRootDir + p))
|
if (pathExists(chrootRootDir + p))
|
||||||
renameFile((chrootRootDir + p), p);
|
std::filesystem::rename((chrootRootDir + p), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return diskFull;
|
return diskFull;
|
||||||
|
@ -421,7 +421,9 @@ static void doBind(const Path & source, const Path & target, bool optional = fal
|
||||||
} else if (S_ISLNK(st.st_mode)) {
|
} else if (S_ISLNK(st.st_mode)) {
|
||||||
// Symlinks can (apparently) not be bind-mounted, so just copy it
|
// Symlinks can (apparently) not be bind-mounted, so just copy it
|
||||||
createDirs(dirOf(target));
|
createDirs(dirOf(target));
|
||||||
copyFile(source, target, /* andDelete */ false);
|
copyFile(
|
||||||
|
std::filesystem::path(source),
|
||||||
|
std::filesystem::path(target), false);
|
||||||
} else {
|
} else {
|
||||||
createDirs(dirOf(target));
|
createDirs(dirOf(target));
|
||||||
writeFile(target, "");
|
writeFile(target, "");
|
||||||
|
@ -2568,8 +2570,11 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
|
||||||
// Replace the output by a fresh copy of itself to make sure
|
// Replace the output by a fresh copy of itself to make sure
|
||||||
// that there's no stale file descriptor pointing to it
|
// that there's no stale file descriptor pointing to it
|
||||||
Path tmpOutput = actualPath + ".tmp";
|
Path tmpOutput = actualPath + ".tmp";
|
||||||
copyFile(actualPath, tmpOutput, true);
|
copyFile(
|
||||||
renameFile(tmpOutput, actualPath);
|
std::filesystem::path(actualPath),
|
||||||
|
std::filesystem::path(tmpOutput), true);
|
||||||
|
|
||||||
|
std::filesystem::rename(tmpOutput, actualPath);
|
||||||
|
|
||||||
auto newInfo0 = newInfoFromCA(DerivationOutput::CAFloating {
|
auto newInfo0 = newInfoFromCA(DerivationOutput::CAFloating {
|
||||||
.method = dof.ca.method,
|
.method = dof.ca.method,
|
||||||
|
|
|
@ -27,7 +27,7 @@ void builtinUnpackChannel(
|
||||||
|
|
||||||
if (fileCount != 1)
|
if (fileCount != 1)
|
||||||
throw Error("channel tarball '%s' contains more than one file", src);
|
throw Error("channel tarball '%s' contains more than one file", src);
|
||||||
renameFile(fileName, (out + "/" + channelName));
|
std::filesystem::rename(fileName, (out + "/" + channelName));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,12 +222,6 @@ Path readLink(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fs::file_type getFileType(const Path & path)
|
|
||||||
{
|
|
||||||
return fs::symlink_status(path).type();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string readFile(const Path & path)
|
std::string readFile(const Path & path)
|
||||||
{
|
{
|
||||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY
|
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY
|
||||||
|
@ -574,7 +568,7 @@ void replaceSymlink(const Path & target, const Path & link)
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
renameFile(tmp, link);
|
std::filesystem::rename(tmp, link);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -597,29 +591,29 @@ static void setWriteTime(const fs::path & p, const struct stat & st)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void copy(const fs::directory_entry & from, const fs::path & to, bool andDelete)
|
void copyFile(const fs::path & from, const fs::path & to, bool andDelete)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// TODO: Rewrite the `is_*` to use `symlink_status()`
|
// TODO: Rewrite the `is_*` to use `symlink_status()`
|
||||||
auto statOfFrom = lstat(from.path().c_str());
|
auto statOfFrom = lstat(from.c_str());
|
||||||
#endif
|
#endif
|
||||||
auto fromStatus = from.symlink_status();
|
auto fromStatus = fs::symlink_status(from);
|
||||||
|
|
||||||
// Mark the directory as writable so that we can delete its children
|
// Mark the directory as writable so that we can delete its children
|
||||||
if (andDelete && fs::is_directory(fromStatus)) {
|
if (andDelete && fs::is_directory(fromStatus)) {
|
||||||
fs::permissions(from.path(), fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow);
|
fs::permissions(from, fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fs::is_symlink(fromStatus) || fs::is_regular_file(fromStatus)) {
|
if (fs::is_symlink(fromStatus) || fs::is_regular_file(fromStatus)) {
|
||||||
fs::copy(from.path(), to, fs::copy_options::copy_symlinks | fs::copy_options::overwrite_existing);
|
fs::copy(from, to, fs::copy_options::copy_symlinks | fs::copy_options::overwrite_existing);
|
||||||
} else if (fs::is_directory(fromStatus)) {
|
} else if (fs::is_directory(fromStatus)) {
|
||||||
fs::create_directory(to);
|
fs::create_directory(to);
|
||||||
for (auto & entry : fs::directory_iterator(from.path())) {
|
for (auto & entry : fs::directory_iterator(from)) {
|
||||||
copy(entry, to / entry.path().filename(), andDelete);
|
copyFile(entry, to / entry.path().filename(), andDelete);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Error("file '%s' has an unsupported type", from.path());
|
throw Error("file '%s' has an unsupported type", from);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -627,25 +621,15 @@ void copy(const fs::directory_entry & from, const fs::path & to, bool andDelete)
|
||||||
#endif
|
#endif
|
||||||
if (andDelete) {
|
if (andDelete) {
|
||||||
if (!fs::is_symlink(fromStatus))
|
if (!fs::is_symlink(fromStatus))
|
||||||
fs::permissions(from.path(), fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow);
|
fs::permissions(from, fs::perms::owner_write, fs::perm_options::add | fs::perm_options::nofollow);
|
||||||
fs::remove(from.path());
|
fs::remove(from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyFile(const Path & oldPath, const Path & newPath, bool andDelete)
|
|
||||||
{
|
|
||||||
return copy(fs::directory_entry(fs::path(oldPath)), fs::path(newPath), andDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
void renameFile(const Path & oldName, const Path & newName)
|
|
||||||
{
|
|
||||||
fs::rename(oldName, newName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void moveFile(const Path & oldName, const Path & newName)
|
void moveFile(const Path & oldName, const Path & newName)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
renameFile(oldName, newName);
|
std::filesystem::rename(oldName, newName);
|
||||||
} catch (fs::filesystem_error & e) {
|
} catch (fs::filesystem_error & e) {
|
||||||
auto oldPath = fs::path(oldName);
|
auto oldPath = fs::path(oldName);
|
||||||
auto newPath = fs::path(newName);
|
auto newPath = fs::path(newName);
|
||||||
|
@ -659,8 +643,8 @@ void moveFile(const Path & oldName, const Path & newName)
|
||||||
if (e.code().value() == EXDEV) {
|
if (e.code().value() == EXDEV) {
|
||||||
fs::remove(newPath);
|
fs::remove(newPath);
|
||||||
warn("Can’t rename %s as %s, copying instead", oldName, newName);
|
warn("Can’t rename %s as %s, copying instead", oldName, newName);
|
||||||
copy(fs::directory_entry(oldPath), tempCopyTarget, true);
|
copyFile(oldPath, tempCopyTarget, true);
|
||||||
renameFile(
|
std::filesystem::rename(
|
||||||
os_string_to_string(PathViewNG { tempCopyTarget }),
|
os_string_to_string(PathViewNG { tempCopyTarget }),
|
||||||
os_string_to_string(PathViewNG { newPath }));
|
os_string_to_string(PathViewNG { newPath }));
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,8 +122,6 @@ Path readLink(const Path & path);
|
||||||
*/
|
*/
|
||||||
Descriptor openDirectory(const std::filesystem::path & path);
|
Descriptor openDirectory(const std::filesystem::path & path);
|
||||||
|
|
||||||
std::filesystem::file_type getFileType(const Path & path);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the contents of a file into a string.
|
* Read the contents of a file into a string.
|
||||||
*/
|
*/
|
||||||
|
@ -171,8 +169,6 @@ void createSymlink(const Path & target, const Path & link);
|
||||||
*/
|
*/
|
||||||
void replaceSymlink(const Path & target, const Path & link);
|
void replaceSymlink(const Path & target, const Path & link);
|
||||||
|
|
||||||
void renameFile(const Path & src, const Path & dst);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to 'renameFile', but fallback to a copy+remove if `src` and `dst`
|
* Similar to 'renameFile', but fallback to a copy+remove if `src` and `dst`
|
||||||
* are on a different filesystem.
|
* are on a different filesystem.
|
||||||
|
@ -188,7 +184,7 @@ void moveFile(const Path & src, const Path & dst);
|
||||||
* with the guaranty that the destination will be “fresh”, with no stale inode
|
* with the guaranty that the destination will be “fresh”, with no stale inode
|
||||||
* or file descriptor pointing to it).
|
* or file descriptor pointing to it).
|
||||||
*/
|
*/
|
||||||
void copyFile(const Path & oldPath, const Path & newPath, bool andDelete);
|
void copyFile(const std::filesystem::path & from, const std::filesystem::path & to, bool andDelete);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatic cleanup of resources.
|
* Automatic cleanup of resources.
|
||||||
|
|
|
@ -102,6 +102,74 @@ namespace nix {
|
||||||
, type \
|
, type \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#define ASSERT_TRACE3(args, type, message, context1, context2) \
|
||||||
|
ASSERT_THROW( \
|
||||||
|
std::string expr(args); \
|
||||||
|
std::string name = expr.substr(0, expr.find(" ")); \
|
||||||
|
try { \
|
||||||
|
Value v = eval("builtins." args); \
|
||||||
|
state.forceValueDeep(v); \
|
||||||
|
} catch (BaseError & e) { \
|
||||||
|
ASSERT_EQ(PrintToString(e.info().msg), \
|
||||||
|
PrintToString(message)); \
|
||||||
|
ASSERT_EQ(e.info().traces.size(), 3) << "while testing " args << std::endl << e.what(); \
|
||||||
|
auto trace = e.info().traces.rbegin(); \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(context1)); \
|
||||||
|
++trace; \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(context2)); \
|
||||||
|
++trace; \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(HintFmt("while calling the '%s' builtin", name))); \
|
||||||
|
throw; \
|
||||||
|
} \
|
||||||
|
, type \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define ASSERT_TRACE4(args, type, message, context1, context2, context3) \
|
||||||
|
ASSERT_THROW( \
|
||||||
|
std::string expr(args); \
|
||||||
|
std::string name = expr.substr(0, expr.find(" ")); \
|
||||||
|
try { \
|
||||||
|
Value v = eval("builtins." args); \
|
||||||
|
state.forceValueDeep(v); \
|
||||||
|
} catch (BaseError & e) { \
|
||||||
|
ASSERT_EQ(PrintToString(e.info().msg), \
|
||||||
|
PrintToString(message)); \
|
||||||
|
ASSERT_EQ(e.info().traces.size(), 4) << "while testing " args << std::endl << e.what(); \
|
||||||
|
auto trace = e.info().traces.rbegin(); \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(context1)); \
|
||||||
|
++trace; \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(context2)); \
|
||||||
|
++trace; \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(context3)); \
|
||||||
|
++trace; \
|
||||||
|
ASSERT_EQ(PrintToString(trace->hint), \
|
||||||
|
PrintToString(HintFmt("while calling the '%s' builtin", name))); \
|
||||||
|
throw; \
|
||||||
|
} \
|
||||||
|
, type \
|
||||||
|
)
|
||||||
|
|
||||||
|
// We assume that expr starts with "builtins.derivationStrict { name =",
|
||||||
|
// otherwise the name attribute position (1, 29) would be invalid.
|
||||||
|
#define DERIVATION_TRACE_HINTFMT(name) \
|
||||||
|
HintFmt("while evaluating derivation '%s'\n" \
|
||||||
|
" whose name attribute is located at %s", \
|
||||||
|
name, Pos(1, 29, Pos::String{.source = make_ref<std::string>(expr)}))
|
||||||
|
|
||||||
|
// To keep things simple, we also assume that derivation name is "foo".
|
||||||
|
#define ASSERT_DERIVATION_TRACE1(args, type, message) \
|
||||||
|
ASSERT_TRACE2(args, type, message, DERIVATION_TRACE_HINTFMT("foo"))
|
||||||
|
#define ASSERT_DERIVATION_TRACE2(args, type, message, context) \
|
||||||
|
ASSERT_TRACE3(args, type, message, context, DERIVATION_TRACE_HINTFMT("foo"))
|
||||||
|
#define ASSERT_DERIVATION_TRACE3(args, type, message, context1, context2) \
|
||||||
|
ASSERT_TRACE4(args, type, message, context1, context2, DERIVATION_TRACE_HINTFMT("foo"))
|
||||||
|
|
||||||
TEST_F(ErrorTraceTest, genericClosure) {
|
TEST_F(ErrorTraceTest, genericClosure) {
|
||||||
ASSERT_TRACE2("genericClosure 1",
|
ASSERT_TRACE2("genericClosure 1",
|
||||||
TypeError,
|
TypeError,
|
||||||
|
@ -1185,7 +1253,6 @@ namespace nix {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* // Needs different ASSERTs
|
|
||||||
TEST_F(ErrorTraceTest, derivationStrict) {
|
TEST_F(ErrorTraceTest, derivationStrict) {
|
||||||
ASSERT_TRACE2("derivationStrict \"\"",
|
ASSERT_TRACE2("derivationStrict \"\"",
|
||||||
TypeError,
|
TypeError,
|
||||||
|
@ -1197,102 +1264,115 @@ namespace nix {
|
||||||
HintFmt("attribute '%s' missing", "name"),
|
HintFmt("attribute '%s' missing", "name"),
|
||||||
HintFmt("in the attrset passed as argument to builtins.derivationStrict"));
|
HintFmt("in the attrset passed as argument to builtins.derivationStrict"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = 1; }",
|
ASSERT_TRACE3("derivationStrict { name = 1; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a string but found %s: %s", "an integer", "1"),
|
HintFmt("expected a string but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the `name` attribute passed to builtins.derivationStrict"));
|
HintFmt("while evaluating the `name` attribute passed to builtins.derivationStrict"),
|
||||||
|
HintFmt("while evaluating the derivation attribute 'name'"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; }",
|
ASSERT_DERIVATION_TRACE1("derivationStrict { name = \"foo\"; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("required attribute 'builder' missing"),
|
HintFmt("required attribute 'builder' missing"));
|
||||||
HintFmt("while evaluating derivation 'foo'"));
|
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __structuredAttrs = 15; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __structuredAttrs = 15; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a Boolean but found %s: %s", "an integer", "15"),
|
HintFmt("expected a Boolean but found %s: %s", "an integer", Uncolored(ANSI_CYAN "15" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the `__structuredAttrs` attribute passed to builtins.derivationStrict"));
|
HintFmt("while evaluating the `__structuredAttrs` attribute passed to builtins.derivationStrict"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __ignoreNulls = 15; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; __ignoreNulls = 15; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a Boolean but found %s: %s", "an integer", "15"),
|
HintFmt("expected a Boolean but found %s: %s", "an integer", Uncolored(ANSI_CYAN "15" ANSI_NORMAL)),
|
||||||
HintFmt("while evaluating the `__ignoreNulls` attribute passed to builtins.derivationStrict"));
|
HintFmt("while evaluating the `__ignoreNulls` attribute passed to builtins.derivationStrict"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = 15; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = 15; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("invalid value '15' for 'outputHashMode' attribute"),
|
HintFmt("invalid value '%s' for 'outputHashMode' attribute", "15"),
|
||||||
HintFmt("while evaluating the attribute 'outputHashMode' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputHashMode", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = \"custom\"; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; outputHashMode = \"custom\"; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("invalid value 'custom' for 'outputHashMode' attribute"),
|
HintFmt("invalid value '%s' for 'outputHashMode' attribute", "custom"),
|
||||||
HintFmt("while evaluating the attribute 'outputHashMode' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputHashMode", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = {}; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
HintFmt("cannot coerce %s to a string: { }", "a set"),
|
||||||
HintFmt("while evaluating the attribute 'system' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "system", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = {}; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
HintFmt("cannot coerce %s to a string: { }", "a set"),
|
||||||
HintFmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"drv\"; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"drvPath\"; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("invalid derivation output name 'drv'"),
|
HintFmt("invalid derivation output name 'drvPath'"),
|
||||||
HintFmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = []; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; outputs = \"out\"; __structuredAttrs = true; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
|
HintFmt("expected a list but found %s: %s", "a string", "\"out\""),
|
||||||
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = []; }",
|
||||||
|
EvalError,
|
||||||
HintFmt("derivation cannot have an empty set of outputs"),
|
HintFmt("derivation cannot have an empty set of outputs"),
|
||||||
HintFmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"drv\" ]; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"drvPath\" ]; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("invalid derivation output name 'drv'"),
|
HintFmt("invalid derivation output name 'drvPath'"),
|
||||||
HintFmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"out\" \"out\" ]; }",
|
ASSERT_DERIVATION_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = [ \"out\" \"out\" ]; }",
|
||||||
TypeError,
|
EvalError,
|
||||||
HintFmt("duplicate derivation output 'out'"),
|
HintFmt("duplicate derivation output '%s'", "out"),
|
||||||
HintFmt("while evaluating the attribute 'outputs' of derivation 'foo'"));
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "outputs", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __contentAddressed = \"true\"; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __contentAddressed = \"true\"; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
||||||
HintFmt("while evaluating the attribute '__contentAddressed' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "__contentAddressed", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
||||||
HintFmt("while evaluating the attribute '__impure' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "__impure", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; __impure = \"true\"; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
HintFmt("expected a Boolean but found %s: %s", "a string", "\"true\""),
|
||||||
HintFmt("while evaluating the attribute '__impure' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "__impure", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = \"foo\"; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = \"foo\"; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("expected a list but found %s: %s", "a string", "\"foo\""),
|
HintFmt("expected a list but found %s: %s", "a string", "\"foo\""),
|
||||||
HintFmt("while evaluating the attribute 'args' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "args", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ {} ]; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ {} ]; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
HintFmt("cannot coerce %s to a string: { }", "a set"),
|
||||||
HintFmt("while evaluating an element of the argument list"));
|
HintFmt("while evaluating an element of the argument list"),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "args", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ \"a\" {} ]; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; args = [ \"a\" {} ]; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
HintFmt("cannot coerce %s to a string: { }", "a set"),
|
||||||
HintFmt("while evaluating an element of the argument list"));
|
HintFmt("while evaluating an element of the argument list"),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "args", "foo"));
|
||||||
|
|
||||||
ASSERT_TRACE2("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; FOO = {}; }",
|
ASSERT_DERIVATION_TRACE3("derivationStrict { name = \"foo\"; builder = 1; system = 1; outputs = \"out\"; FOO = {}; }",
|
||||||
TypeError,
|
TypeError,
|
||||||
HintFmt("cannot coerce %s to a string: %s", "a set", "{ }"),
|
HintFmt("cannot coerce %s to a string: { }", "a set"),
|
||||||
HintFmt("while evaluating the attribute 'FOO' of derivation 'foo'"));
|
HintFmt(""),
|
||||||
|
HintFmt("while evaluating attribute '%s' of derivation '%s'", "FOO", "foo"));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
} /* namespace nix */
|
} /* namespace nix */
|
||||||
|
|
Loading…
Reference in a new issue