From 3d5b1032a193419cfa7406f0e42a7621994d70af Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 17 Apr 2020 15:07:44 -0600 Subject: logError, logWarning; Logger functions; switch to Verbosity enum --- src/error-demo/error-demo.cc | 67 ++++++++++++++++++++++---------------------- src/libstore/daemon.cc | 4 +++ src/libutil/error.cc | 50 ++++++++++++++++++++++++--------- src/libutil/error.hh | 19 +++++++------ src/libutil/logging.cc | 18 ++++++++++++ src/libutil/logging.hh | 30 +++++++++++++------- src/nix/progress-bar.cc | 6 ++++ 7 files changed, 128 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index a9ff6057c..b7dd4cc22 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -1,4 +1,4 @@ -#include "error.hh" +#include "logging.hh" #include "nixexpr.hh" #include @@ -8,24 +8,25 @@ int main() { using namespace nix; + std::unique_ptr logger(makeDefaultLogger()); + + verbosity = lvlError; + // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); // Error in a program; no hint and no nix code. - printErrorInfo( - ErrorInfo { .level = elError, - .name = "name", + logError( + ErrorInfo { .name = "name", .description = "error description", }); // Warning with name, description, and hint. // The hintfmt function makes all the substituted text yellow. - printErrorInfo( - ErrorInfo { .level = elWarning, - .name = "name", + logWarning( + ErrorInfo { .name = "name", .description = "error description", - .hint = std::optional( - hintfmt("there was a %1%", "warning")), + .hint = hintfmt("there was a %1%", "warning"), }); @@ -34,32 +35,32 @@ int main() SymbolTable testTable; auto problem_file = testTable.create("myfile.nix"); - printErrorInfo( - ErrorInfo{ - .level = elWarning, - .name = "warning name", - .description = "warning description", - .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::nullopt, - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::nullopt - }}); + logWarning( + ErrorInfo { .name = "warning name", + .description = "warning description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::nullopt, + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::nullopt + }}); // Error with previous and next lines of code. - printErrorInfo( - ErrorInfo{ - .level = elError, - .name = "error name", - .description = "error description", - .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::optional("previous line of code"), - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::optional("next line of code"), - }}); + logError( + ErrorInfo { .name = "error name", + .description = "error description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::optional("previous line of code"), + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::optional("next line of code"), + }}); return 0; diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 8e9f9d71b..c8daef57c 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -73,6 +73,10 @@ struct TunnelLogger : public Logger enqueueMsg(*buf.s); } + void logEI(const ErrorInfo & ei) override + { + } + /* startWork() means that we're starting an operation for which we want to send out stderr to the client. */ void startWork() diff --git a/src/libutil/error.cc b/src/libutil/error.cc index a5571d4ec..779f519c0 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -2,6 +2,7 @@ #include #include +#include "serialise.hh" namespace nix { @@ -66,25 +67,45 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) } } -void printErrorInfo(const ErrorInfo &einfo) +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; string levelString; switch (einfo.level) { - case ErrLevel::elError: { + case Verbosity::lvlError: { levelString = ANSI_RED; levelString += "error:"; levelString += ANSI_NORMAL; break; } - case ErrLevel::elWarning: { + case Verbosity::lvlWarn: { levelString = ANSI_YELLOW; levelString += "warning:"; levelString += ANSI_NORMAL; break; } + case Verbosity::lvlInfo: { + levelString = ANSI_YELLOW; + levelString += "info:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlTalkative: + case Verbosity::lvlChatty: + case Verbosity::lvlVomit: { + levelString = ANSI_GREEN; + levelString += "info:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlDebug: { + levelString = ANSI_YELLOW; + levelString += "debug:"; + levelString += ANSI_NORMAL; + break; + } default: { levelString = fmt("invalid error level: %1%", einfo.level); break; @@ -99,7 +120,7 @@ void printErrorInfo(const ErrorInfo &einfo) dashes.append("-"); // divider. - std::cout << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, + out << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, prefix, levelString, "---", @@ -115,32 +136,33 @@ void printErrorInfo(const ErrorInfo &einfo) ? string(" ") + showErrPos(einfo.nixCode->errPos) : ""; - std::cout << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, + out << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, prefix, einfo.nixCode->errPos.nixFile, eline) << std::endl; - std::cout << prefix << std::endl; + out << prefix << std::endl; } else { - std::cout << fmt("%1%from command line argument", prefix) << std::endl; - std::cout << prefix << std::endl; + out << fmt("%1%from command line argument", prefix) << std::endl; + out << prefix << std::endl; } } // description - std::cout << prefix << einfo.description << std::endl; - std::cout << prefix << std::endl; + out << prefix << einfo.description << std::endl; + out << prefix << std::endl; // lines of code. if (einfo.nixCode->errLineOfCode != "") { printCodeLines(prefix, *einfo.nixCode); - std::cout << prefix << std::endl; + out << prefix << std::endl; } // hint if (einfo.hint.has_value()) { - std::cout << prefix << *einfo.hint << std::endl; - std::cout << prefix << std::endl; + out << prefix << *einfo.hint << std::endl; + out << prefix << std::endl; } -} + return out; +} } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index f402b692e..0419a1b52 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -11,9 +11,14 @@ namespace nix { typedef enum { - elWarning, - elError -} ErrLevel; + lvlError = 0, + lvlWarn, + lvlInfo, + lvlTalkative, + lvlChatty, + lvlDebug, + lvlVomit +} Verbosity; struct ErrPos { @@ -101,7 +106,7 @@ inline hintformat hintfmt(const std::string & fs, const Args & ... args) // ErrorInfo. struct ErrorInfo { - ErrLevel level; + Verbosity level; string name; string description; std::optional hint; @@ -110,11 +115,7 @@ struct ErrorInfo static std::optional programName; }; -// -------------------------------------------------------- -// error printing - -// just to cout for now. -void printErrorInfo(const ErrorInfo &einfo); +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index fa5c84a27..98f500a65 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -3,6 +3,7 @@ #include #include +#include namespace nix { @@ -57,6 +58,14 @@ public: writeToStderr(prefix + filterANSIEscapes(fs.s, !tty) + "\n"); } + void logEI(const ErrorInfo & ei) override + { + std::stringstream oss; + oss << ei; + + log(ei.level, oss.str()); + } + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) override @@ -135,6 +144,15 @@ struct JSONLogger : Logger write(json); } + void logEI(const ErrorInfo & ei) override + { + // nlohmann::json json; + // json["action"] = "msg"; + // json["level"] = lvl; + // json["msg"] = fs.s; + // write(json); + } + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) override { diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index beb5e6b64..ba6f39ac9 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -1,19 +1,10 @@ #pragma once #include "types.hh" +#include "error.hh" namespace nix { -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - typedef enum { actUnknown = 0, actCopyPath = 100, @@ -70,6 +61,13 @@ public: log(lvlInfo, fs); } + virtual void logEI(const ErrorInfo &ei) = 0; + + void logEI(Verbosity lvl, ErrorInfo ei) { + ei.level = lvl; + logEI(ei); + } + virtual void warn(const std::string & msg); virtual void startActivity(ActivityId act, Verbosity lvl, ActivityType type, @@ -157,6 +155,18 @@ extern Verbosity verbosity; /* suppress msgs > this */ #define debug(args...) printMsg(lvlDebug, args) #define vomit(args...) printMsg(lvlVomit, args) +#define logErrorInfo(level, errorInfo...) \ + do { \ + if (level <= nix::verbosity) { \ + logger->logEI(level, errorInfo); \ + } \ + } while (0) + +#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo) +#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo) + + + template inline void warn(const std::string & fs, const Args & ... args) { diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc index 26631416c..41f3d4cd7 100644 --- a/src/nix/progress-bar.cc +++ b/src/nix/progress-bar.cc @@ -124,6 +124,12 @@ public: log(*state, lvl, fs.s); } + void logEI(const ErrorInfo &ei) override + { + auto state(state_.lock()); + // log(*state, lvl, ei.as_str()); + } + void log(State & state, Verbosity lvl, const std::string & s) { if (state.active) { -- cgit v1.2.3 From 4697552948b4d9b958b0e8f8ff1b68b5e9608e4e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 17 Apr 2020 15:50:46 -0600 Subject: demoing other error levels than warn/error; rename line and file fields in errPos --- src/error-demo/error-demo.cc | 37 ++++++++++++++++++++++++++++++-- src/libutil/error.cc | 50 ++++++++++++++++++++++++++------------------ src/libutil/error.hh | 8 +++---- src/libutil/logging.cc | 39 +++++++++++++++++++++++++++++----- 4 files changed, 103 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index b7dd4cc22..14027278d 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -8,13 +8,46 @@ int main() { using namespace nix; - std::unique_ptr logger(makeDefaultLogger()); + makeDefaultLogger(); - verbosity = lvlError; + verbosity = lvlVomit; // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); + // For completeness sake, info through vomit levels. + // But this is maybe a heavy format for those. + logger->logEI( + ErrorInfo { .level = lvlInfo, + .name = "Info name", + .description = "Info description", + }); + + logger->logEI( + ErrorInfo { .level = lvlTalkative, + .name = "Talkative name", + .description = "Talkative description", + }); + + logger->logEI( + ErrorInfo { .level = lvlChatty, + .name = "Chatty name", + .description = "Chatty description", + }); + + logger->logEI( + ErrorInfo { .level = lvlDebug, + .name = "Debug name", + .description = "Debug description", + }); + + logger->logEI( + ErrorInfo { .level = lvlVomit, + .name = "Vomit name", + .description = "Vomit description", + }); + + // Error in a program; no hint and no nix code. logError( ErrorInfo { .name = "name", diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 779f519c0..0e07c0d98 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -17,9 +17,9 @@ std::ostream& operator<<(std::ostream &os, const hintformat &hf) string showErrPos(const ErrPos &errPos) { if (errPos.column > 0) { - return fmt("(%1%:%2%)", errPos.lineNumber, errPos.column); + return fmt("(%1%:%2%)", errPos.line, errPos.column); } else { - return fmt("(%1%)", errPos.lineNumber); + return fmt("(%1%)", errPos.line); }; } @@ -29,7 +29,7 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) if (nixCode.prevLineOfCode.has_value()) { std::cout << fmt("%1% %|2$5d|| %3%", prefix, - (nixCode.errPos.lineNumber - 1), + (nixCode.errPos.line - 1), *nixCode.prevLineOfCode) << std::endl; } @@ -37,7 +37,7 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) // line of code containing the error.%2$+5d% std::cout << fmt("%1% %|2$5d|| %3%", prefix, - (nixCode.errPos.lineNumber), + (nixCode.errPos.line), nixCode.errLineOfCode) << std::endl; @@ -61,7 +61,7 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) if (nixCode.nextLineOfCode.has_value()) { std::cout << fmt("%1% %|2$5d|| %3%", prefix, - (nixCode.errPos.lineNumber + 1), + (nixCode.errPos.line + 1), *nixCode.nextLineOfCode) << std::endl; } @@ -87,16 +87,26 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) break; } case Verbosity::lvlInfo: { - levelString = ANSI_YELLOW; + levelString = ANSI_GREEN; levelString += "info:"; levelString += ANSI_NORMAL; break; } - case Verbosity::lvlTalkative: - case Verbosity::lvlChatty: + case Verbosity::lvlTalkative: { + levelString = ANSI_GREEN; + levelString += "talk:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlChatty: { + levelString = ANSI_GREEN; + levelString += "chat:"; + levelString += ANSI_NORMAL; + break; + } case Verbosity::lvlVomit: { levelString = ANSI_GREEN; - levelString += "info:"; + levelString += "vomit:"; levelString += ANSI_NORMAL; break; } @@ -121,25 +131,25 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) // divider. out << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, - prefix, - levelString, - "---", - einfo.name, - dashes, - einfo.programName.value_or("")) - << std::endl; + prefix, + levelString, + "---", + einfo.name, + dashes, + einfo.programName.value_or("")) + << std::endl; // filename. if (einfo.nixCode.has_value()) { - if (einfo.nixCode->errPos.nixFile != "") { + if (einfo.nixCode->errPos.file != "") { string eline = einfo.nixCode->errLineOfCode != "" ? string(" ") + showErrPos(einfo.nixCode->errPos) : ""; out << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, - prefix, - einfo.nixCode->errPos.nixFile, - eline) << std::endl; + prefix, + einfo.nixCode->errPos.file, + eline) << std::endl; out << prefix << std::endl; } else { out << fmt("%1%from command line argument", prefix) << std::endl; diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 0419a1b52..63778ebda 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -22,16 +22,16 @@ typedef enum { struct ErrPos { - int lineNumber; + int line; int column; - string nixFile; + string file; template ErrPos& operator=(const P &pos) { - lineNumber = pos.line; + line = pos.line; column = pos.column; - nixFile = pos.file; + file = pos.file; return *this; } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 98f500a65..4a8b98640 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -146,11 +146,40 @@ struct JSONLogger : Logger void logEI(const ErrorInfo & ei) override { - // nlohmann::json json; - // json["action"] = "msg"; - // json["level"] = lvl; - // json["msg"] = fs.s; - // write(json); + // add fields like Pos info and etc? + std::ostringstream oss; + oss << ei; + + nlohmann::json json; + json["action"] = "msg"; + json["level"] = ei.level; + json["msg"] = oss.str(); + + // Extra things that COULD go into json. Useful? + // TODO: decide if useful. + // TODO: make a json obj that goes into json["msg"]? + json["name"] = ei.name; + json["description"] = ei.description; + if (ei.hint.has_value()) + { + json["hint"] = ei.hint->str(); + } + if (ei.nixCode.has_value()) + { + if (ei.nixCode->errPos.line != 0) + json["line"] = ei.nixCode->errPos.line; + if (ei.nixCode->errPos.column != 0) + json["column"] = ei.nixCode->errPos.column; + if (ei.nixCode->errPos.file != "") + json["file"] = ei.nixCode->errPos.file; + if (ei.nixCode->prevLineOfCode.has_value()) + json["prevLineOfCode"] = *ei.nixCode->prevLineOfCode; + json["errLineOfCode"] = ei.nixCode->errLineOfCode; + if (ei.nixCode->nextLineOfCode.has_value()) + json["nextLineOfCode"] = *ei.nixCode->nextLineOfCode; + } + + write(json); } void startActivity(ActivityId act, Verbosity lvl, ActivityType type, -- cgit v1.2.3 From 15e9564fd1e11b3797f0188a494aa66d4622dfb0 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 19 Apr 2020 17:16:51 -0600 Subject: logEI for tunnelLogger and progressbar --- src/libstore/daemon.cc | 8 ++++++++ src/nix/progress-bar.cc | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index c8daef57c..d985f151b 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -75,6 +75,14 @@ struct TunnelLogger : public Logger void logEI(const ErrorInfo & ei) override { + if (ei.level > verbosity) return; + + std::stringstream oss; + oss << ei; + + StringSink buf; + buf << STDERR_NEXT << oss.str() << "\n"; // (fs.s + "\n"); + enqueueMsg(*buf.s); } /* startWork() means that we're starting an operation for which we diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc index 41f3d4cd7..b1226d550 100644 --- a/src/nix/progress-bar.cc +++ b/src/nix/progress-bar.cc @@ -127,7 +127,11 @@ public: void logEI(const ErrorInfo &ei) override { auto state(state_.lock()); - // log(*state, lvl, ei.as_str()); + + std::stringstream oss; + oss << ei; + + log(*state, ei.level, oss.str()); } void log(State & state, Verbosity lvl, const std::string & s) -- cgit v1.2.3 From d3052197feababc312fd874e08ae48050d985eb3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 21 Apr 2020 13:25:41 -0600 Subject: add ErrorInfo to BaseError --- src/libutil/error.cc | 2 +- src/libutil/error.hh | 122 ----------------------------------------------- src/libutil/fmt.hh | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ src/libutil/logging.hh | 1 - src/libutil/types.hh | 125 ++++++++++++++++++++++++------------------------ src/libutil/util.hh | 1 - 6 files changed, 192 insertions(+), 186 deletions(-) delete mode 100644 src/libutil/error.hh create mode 100644 src/libutil/fmt.hh (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 0e07c0d98..41595b0df 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -1,4 +1,4 @@ -#include "error.hh" +#include "types.hh" #include #include diff --git a/src/libutil/error.hh b/src/libutil/error.hh deleted file mode 100644 index 63778ebda..000000000 --- a/src/libutil/error.hh +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef error_hh -#define error_hh - -#include "ansicolor.hh" -#include -#include -#include -#include "types.hh" - -namespace nix -{ - -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - -struct ErrPos -{ - int line; - int column; - string file; - - template - ErrPos& operator=(const P &pos) - { - line = pos.line; - column = pos.column; - file = pos.file; - return *this; - } - - template - ErrPos(const P &p) - { - *this = p; - } -}; - -struct NixCode -{ - ErrPos errPos; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; -}; - -// ---------------------------------------------------------------- -// format function for hints. same as fmt, except templated values -// are always in yellow. - -template -struct yellowify -{ - yellowify(T &s) : value(s) {} - T &value; -}; - -template -std::ostream& operator<<(std::ostream &out, const yellowify &y) -{ - return out << ANSI_YELLOW << y.value << ANSI_NORMAL; -} - -class hintformat -{ -public: - hintformat(string format) :fmt(format) - { - fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - } - template - hintformat& operator%(const T &value) - { - fmt % yellowify(value); - return *this; - } - - std::string str() const - { - return fmt.str(); - } - - template - friend class AddHint; -private: - format fmt; -}; - -std::ostream& operator<<(std::ostream &os, const hintformat &hf); - -template -inline hintformat hintfmt(const std::string & fs, const Args & ... args) -{ - hintformat f(fs); - formatHelper(f, args...); - return f; -} - -// ------------------------------------------------- -// ErrorInfo. -struct ErrorInfo -{ - Verbosity level; - string name; - string description; - std::optional hint; - std::optional nixCode; - - static std::optional programName; -}; - -std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); - -} - -#endif diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh new file mode 100644 index 000000000..08edffee0 --- /dev/null +++ b/src/libutil/fmt.hh @@ -0,0 +1,127 @@ +#pragma once + +#include +#include +#include "ansicolor.hh" + + +namespace nix { + + +/* Inherit some names from other namespaces for convenience. */ +using std::string; +using boost::format; + + +/* A variadic template that does nothing. Useful to call a function + for all variadic arguments but ignoring the result. */ +struct nop { template nop(T...) {} }; + + +struct FormatOrString +{ + string s; + FormatOrString(const string & s) : s(s) { }; + template + FormatOrString(const F & f) : s(f.str()) { }; + FormatOrString(const char * s) : s(s) { }; +}; + + +/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is + equivalent to ‘boost::format(format) % a_0 % ... % + ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion + takes place). */ + +template +inline void formatHelper(F & f) +{ +} + +template +inline void formatHelper(F & f, const T & x, const Args & ... args) +{ + formatHelper(f % x, args...); +} + +inline std::string fmt(const std::string & s) +{ + return s; +} + +inline std::string fmt(const char * s) +{ + return s; +} + +inline std::string fmt(const FormatOrString & fs) +{ + return fs.s; +} + +template +inline std::string fmt(const std::string & fs, const Args & ... args) +{ + boost::format f(fs); + f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + formatHelper(f, args...); + return f.str(); +} + +// ----------------------------------------------------------------------------- +// format function for hints in errors. same as fmt, except templated values +// are always in yellow. + +template +struct yellowify +{ + yellowify(T &s) : value(s) {} + T &value; +}; + +template +std::ostream& operator<<(std::ostream &out, const yellowify &y) +{ + return out << ANSI_YELLOW << y.value << ANSI_NORMAL; +} + +class hintformat +{ +public: + hintformat(const string &format) :fmt(format) + { + fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); + } + template + hintformat& operator%(const T &value) + { + fmt % yellowify(value); + return *this; + } + hintformat(const hintformat &hf) + : fmt(hf.fmt) + {} + + + std::string str() const + { + return fmt.str(); + } + + template + friend class AddHint; +private: + format fmt; +}; + +std::ostream& operator<<(std::ostream &os, const hintformat &hf); + +template +inline hintformat hintfmt(const std::string & fs, const Args & ... args) +{ + hintformat f(fs); + formatHelper(f, args...); + return f; +} + +} diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index ba6f39ac9..8269e2e1a 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -1,7 +1,6 @@ #pragma once #include "types.hh" -#include "error.hh" namespace nix { diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 981af528b..633c6bdf7 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -3,13 +3,13 @@ #include "ref.hh" -#include #include #include #include #include +#include -#include +#include "fmt.hh" /* Before 4.7, gcc's std::exception uses empty throw() specifiers for * its (virtual) destructor and what() in c++11 mode, in violation of spec @@ -20,73 +20,66 @@ #endif #endif - namespace nix { - -/* Inherit some names from other namespaces for convenience. */ -using std::string; using std::list; using std::set; using std::vector; -using boost::format; - - -/* A variadic template that does nothing. Useful to call a function - for all variadic arguments but ignoring the result. */ -struct nop { template nop(T...) {} }; - -struct FormatOrString +typedef enum { + lvlError = 0, + lvlWarn, + lvlInfo, + lvlTalkative, + lvlChatty, + lvlDebug, + lvlVomit +} Verbosity; + +struct ErrPos { - string s; - FormatOrString(const string & s) : s(s) { }; - template - FormatOrString(const F & f) : s(f.str()) { }; - FormatOrString(const char * s) : s(s) { }; -}; - - -/* A helper for formatting strings. ‘fmt(format, a_0, ..., a_n)’ is - equivalent to ‘boost::format(format) % a_0 % ... % - ... a_n’. However, ‘fmt(s)’ is equivalent to ‘s’ (so no %-expansion - takes place). */ + int line; + int column; + string file; -template -inline void formatHelper(F & f) -{ -} - -template -inline void formatHelper(F & f, const T & x, const Args & ... args) -{ - formatHelper(f % x, args...); -} + template + ErrPos& operator=(const P &pos) + { + line = pos.line; + column = pos.column; + file = pos.file; + return *this; + } -inline std::string fmt(const std::string & s) -{ - return s; -} + template + ErrPos(const P &p) + { + *this = p; + } +}; -inline std::string fmt(const char * s) +struct NixCode { - return s; -} + ErrPos errPos; + std::optional prevLineOfCode; + string errLineOfCode; + std::optional nextLineOfCode; +}; -inline std::string fmt(const FormatOrString & fs) +// ------------------------------------------------- +// ErrorInfo. +struct ErrorInfo { - return fs.s; -} + Verbosity level; + string name; + string description; + std::optional hint; + std::optional nixCode; -template -inline std::string fmt(const std::string & fs, const Args & ... args) -{ - boost::format f(fs); - f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - formatHelper(f, args...); - return f.str(); -} + static std::optional programName; +}; +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); /* BaseError should generally not be caught, as it has Interrupted as a subclass. Catch Error instead. */ @@ -94,33 +87,42 @@ class BaseError : public std::exception { protected: string prefix_; // used for location traces etc. - string err; + ErrorInfo err; public: unsigned int status = 1; // exit status template BaseError(unsigned int status, const Args & ... args) - : err(fmt(args...)) + : err(hintfmt(args...)) , status(status) { } template BaseError(const Args & ... args) - : err(fmt(args...)) + : err { .level = lvlError, + .hint = hintfmt(args...) + } + { + } + + BaseError(ErrorInfo e) + : err(e) { } #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() const throw () { return err.c_str(); } + const char * what() const throw () { return err.description.c_str(); } #else - const char * what() const noexcept { return err.c_str(); } + const char * what() const noexcept { return err.description.c_str(); } #endif - const string & msg() const { return err; } + const string & msg() const { return err.description; } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); + + const ErrorInfo & info() const { return err; } }; #define MakeError(newClass, superClass) \ @@ -139,7 +141,8 @@ public: template SysError(const Args & ... args) - : Error(addErrno(fmt(args...))) + : Error(args...) // TODO addErrNo for hintfmt + // : Error(addErrno(hintfmt(args...))) { } private: diff --git a/src/libutil/util.hh b/src/libutil/util.hh index fb9a7ed38..636f3ba6c 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -3,7 +3,6 @@ #include "types.hh" #include "logging.hh" #include "ansicolor.hh" -#include "error.hh" #include #include -- cgit v1.2.3 From e4fb9a38493a041861fe5c75bc8ddd129a2e5262 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 21 Apr 2020 17:07:07 -0600 Subject: remove 'format' from Error constructor calls --- src/libexpr/attr-path.cc | 16 ++-- src/libexpr/eval-inline.hh | 6 +- src/libexpr/eval.cc | 23 +++--- src/libexpr/nixexpr.cc | 2 +- src/libexpr/nixexpr.hh | 4 +- src/libexpr/parser.y | 32 ++++---- src/libexpr/primops.cc | 124 +++++++++++++++---------------- src/libexpr/primops/fetchGit.cc | 2 +- src/libexpr/primops/fetchMercurial.cc | 2 +- src/libexpr/value-to-json.cc | 4 +- src/libmain/shared.cc | 10 +-- src/libmain/shared.hh | 6 +- src/libstore/binary-cache-store.cc | 8 +- src/libstore/build.cc | 98 ++++++++++++------------ src/libstore/builtins/buildenv.cc | 10 +-- src/libstore/builtins/fetchurl.cc | 4 +- src/libstore/daemon.cc | 2 +- src/libstore/derivations.cc | 6 +- src/libstore/download.cc | 6 +- src/libstore/download.hh | 6 +- src/libstore/gc.cc | 44 +++++------ src/libstore/local-binary-cache-store.cc | 2 +- src/libstore/local-fs-store.cc | 6 +- src/libstore/local-store.cc | 48 ++++++------ src/libstore/nar-accessor.cc | 6 +- src/libstore/nar-info.cc | 2 +- src/libstore/optimise-store.cc | 24 +++--- src/libstore/pathlocks.cc | 8 +- src/libstore/profiles.cc | 8 +- src/libstore/references.cc | 2 +- src/libstore/remote-fs-accessor.cc | 2 +- src/libstore/remote-store.cc | 4 +- src/libstore/s3-binary-cache-store.cc | 8 +- src/libstore/sqlite.cc | 2 +- src/libstore/store-api.cc | 4 +- src/libutil/archive.cc | 19 ++--- src/libutil/args.cc | 9 ++- src/libutil/compression.cc | 2 +- src/libutil/fmt.hh | 6 +- src/libutil/types.hh | 4 +- src/libutil/util.cc | 50 ++++++------- src/nix-channel/nix-channel.cc | 30 +++++--- src/nix-daemon/nix-daemon.cc | 43 ++++++----- src/nix-env/nix-env.cc | 55 +++++++------- src/nix-instantiate/nix-instantiate.cc | 4 +- src/nix-prefetch-url/nix-prefetch-url.cc | 10 +-- src/nix-store/nix-store.cc | 38 +++++----- src/nix/cat.cc | 4 +- src/nix/hash.cc | 2 +- src/nix/ls.cc | 2 +- src/nix/repl.cc | 8 +- src/nix/run.cc | 4 +- 52 files changed, 424 insertions(+), 407 deletions(-) (limited to 'src') diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index 76d101b98..9a9531a3f 100644 --- a/src/libexpr/attr-path.cc +++ b/src/libexpr/attr-path.cc @@ -19,7 +19,7 @@ static Strings parseAttrPath(const string & s) ++i; while (1) { if (i == s.end()) - throw Error(format("missing closing quote in selection path '%1%'") % s); + throw Error("missing closing quote in selection path '%1%'", s); if (*i == '"') break; cur.push_back(*i++); } @@ -60,11 +60,11 @@ std::pair findAlongAttrPath(EvalState & state, const string & attr if (v->type != tAttrs) throw TypeError( - format("the expression selected by the selection path '%1%' should be a set but is %2%") - % attrPath % showType(*v)); - + "the expression selected by the selection path '%1%' should be a set but is %2%", + attrPath, + showType(*v)); if (attr.empty()) - throw Error(format("empty attribute name in selection path '%1%'") % attrPath); + throw Error("empty attribute name in selection path '%1%'", attrPath); Bindings::iterator a = v->attrs->find(state.symbols.create(attr)); if (a == v->attrs->end()) @@ -77,9 +77,9 @@ std::pair findAlongAttrPath(EvalState & state, const string & attr if (!v->isList()) throw TypeError( - format("the expression selected by the selection path '%1%' should be a list but is %2%") - % attrPath % showType(*v)); - + "the expression selected by the selection path '%1%' should be a list but is %2%", + attrPath, + showType(*v)); if (attrIndex >= v->listSize()) throw AttrPathNotFound("list index %1% in selection path '%2%' is out of range", attrIndex, attrPath); diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index c27116e3b..4d82ccf09 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -9,18 +9,18 @@ namespace nix { LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos)) { - throw EvalError(format(s) % pos); + throw EvalError(s, pos); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) { - throw TypeError(format(s) % showType(v)); + throw TypeError(s, showType(v)); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos)) { - throw TypeError(format(s) % showType(v) % pos); + throw TypeError(s, showType(v), pos); } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index dac32b6f5..516c25b02 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -493,52 +493,52 @@ Value & EvalState::getBuiltin(const string & name) LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2)) { - throw EvalError(format(s) % s2); + throw EvalError(s, s2); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos)) { - throw EvalError(format(s) % s2 % pos); + throw EvalError(s, s2, pos); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3)) { - throw EvalError(format(s) % s2 % s3); + throw EvalError(s, s2, s3); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos)) { - throw EvalError(format(s) % s2 % s3 % pos); + throw EvalError(s, s2, s3, pos); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) { - throw EvalError(format(s) % sym % p1 % p2); + throw EvalError(s, sym, p1, p2); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos)) { - throw TypeError(format(s) % pos); + throw TypeError(s, pos); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) { - throw TypeError(format(s) % s1); + throw TypeError(s, s1); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos)) { - throw TypeError(format(s) % fun.showNamePos() % s2 % pos); + throw TypeError(s, fun.showNamePos(), s2, pos); } LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos)) { - throw AssertionError(format(s) % s1 % pos); + throw AssertionError(s, s1, pos); } LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos)) { - throw UndefinedVarError(format(s) % s1 % pos); + throw UndefinedVarError(s, s1, pos); } LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2)) @@ -1883,8 +1883,7 @@ void EvalState::printStats() string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const { - throw TypeError(format("cannot coerce %1% to a string, at %2%") % - showType() % pos); + throw TypeError("cannot coerce %1% to a string, at %2%", showType(), pos); } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 63cbef1dd..a9955f6df 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -267,7 +267,7 @@ void ExprVar::bindVars(const StaticEnv & env) /* Otherwise, the variable must be obtained from the nearest enclosing `with'. If there is no `with', then we can issue an "undefined variable" error now. */ - if (withLevel == -1) throw UndefinedVarError(format("undefined variable '%1%' at %2%") % name % pos); + if (withLevel == -1) throw UndefinedVarError("undefined variable '%1%' at %2%", name, pos); fromWith = true; this->level = withLevel; diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index f7e9105a4..79e3f90e5 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -234,9 +234,7 @@ struct ExprLambda : Expr : pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body) { if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end()) - throw ParseError(format("duplicate formal function argument '%1%' at %2%") - % arg % pos); - }; + throw ParseError("duplicate formal function argument '%1%' at %2%", arg, pos); }; void setName(Symbol & name); string showNamePos() const; COMMON_METHODS diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 9c769e803..3767532d5 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -64,15 +64,15 @@ namespace nix { static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos) { - throw ParseError(format("attribute '%1%' at %2% already defined at %3%") - % showAttrPath(attrPath) % pos % prevPos); + throw ParseError("attribute '%1%' at %2% already defined at %3%", + showAttrPath(attrPath), pos, prevPos); } static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos) { - throw ParseError(format("attribute '%1%' at %2% already defined at %3%") - % attr % pos % prevPos); + throw ParseError("attribute '%1%' at %2% already defined at %3%", + attr, pos, prevPos); } @@ -140,8 +140,8 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, static void addFormal(const Pos & pos, Formals * formals, const Formal & formal) { if (!formals->argNames.insert(formal.name).second) - throw ParseError(format("duplicate formal function argument '%1%' at %2%") - % formal.name % pos); + throw ParseError("duplicate formal function argument '%1%' at %2%", + formal.name, pos); formals->formals.push_front(formal); } @@ -327,8 +327,7 @@ expr_function { $$ = new ExprWith(CUR_POS, $2, $4); } | LET binds IN expr_function { if (!$2->dynamicAttrs.empty()) - throw ParseError(format("dynamic attributes not allowed in let at %1%") - % CUR_POS); + throw ParseError("dynamic attributes not allowed in let at %1%", CUR_POS); $$ = new ExprLet($2, $4); } | expr_if @@ -475,8 +474,8 @@ attrs $$->push_back(AttrName(str->s)); delete str; } else - throw ParseError(format("dynamic attributes not allowed in inherit at %1%") - % makeCurPos(@2, data)); + throw ParseError("dynamic attributes not allowed in inherit at %1%", + makeCurPos(@2, data)); } | { $$ = new AttrPath; } ; @@ -670,11 +669,10 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos Path res = r.second + suffix; if (pathExists(res)) return canonPath(res); } - format f = format( + string f = "file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)" - + string(pos ? ", at %2%" : "")); - f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); - throw ThrownError(f % path % pos); + + string(pos ? ", at %2%" : ""); + throw ThrownError(f, path, pos); } @@ -691,7 +689,8 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl request.unpack = true; res = { true, getDownloader()->downloadCached(store, request).path }; } catch (DownloadError & e) { - printError(format("warning: Nix search path entry '%1%' cannot be downloaded, ignoring") % elem.second); + // TODO: change to warn()? + printError("warning: Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second); res = { false, "" }; } } else { @@ -699,7 +698,8 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl if (pathExists(path)) res = { true, path }; else { - printError(format("warning: Nix search path entry '%1%' does not exist, ignoring") % elem.second); + // TODO: change to warn()? + printError("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second); res = { false, "" }; } } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 8de234951..13eb1ba58 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -94,8 +94,8 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%", + path, e.path, pos); } Path realPath = state.checkSourcePath(state.toRealPath(path, context)); @@ -171,8 +171,8 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format("cannot import '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%" + , path, e.path, pos); } path = state.checkSourcePath(path); @@ -181,17 +181,17 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value void *handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); if (!handle) - throw EvalError(format("could not open '%1%': %2%") % path % dlerror()); + throw EvalError("could not open '%1%': %2%", path, dlerror()); dlerror(); ValueInitializer func = (ValueInitializer) dlsym(handle, sym.c_str()); if(!func) { char *message = dlerror(); if (message) - throw EvalError(format("could not load symbol '%1%' from '%2%': %3%") % sym % path % message); + throw EvalError("could not load symbol '%1%' from '%2%': %3%", sym, path, message); else - throw EvalError(format("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected") - % sym % path); + throw EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected" + , sym, path); } (func)(state, v); @@ -207,7 +207,7 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) auto elems = args[0]->listElems(); auto count = args[0]->listSize(); if (count == 0) { - throw EvalError(format("at least one argument to 'exec' required, at %1%") % pos); + throw EvalError("at least one argument to 'exec' required, at %1%", pos); } PathSet context; auto program = state.coerceToString(pos, *elems[0], context, false, false); @@ -218,8 +218,8 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format("cannot execute '%1%', since path '%2%' is not valid, at %3%") - % program % e.path % pos); + throw EvalError("cannot execute '%1%', since path '%2%' is not valid, at %3%" + , program, e.path, pos); } auto output = runProgram(program, true, commandArgs); @@ -227,13 +227,13 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) try { parsed = state.parseExprFromString(output, pos.file); } catch (Error & e) { - e.addPrefix(format("While parsing the output from '%1%', at %2%\n") % program % pos); + e.addPrefix(fmt("While parsing the output from '%1%', at %2%\n", program, pos)); throw; } try { state.eval(parsed, v); } catch (Error & e) { - e.addPrefix(format("While evaluating the output from '%1%', at %2%\n") % program % pos); + e.addPrefix(fmt("While evaluating the output from '%1%', at %2%\n", program, pos)); throw; } } @@ -339,7 +339,7 @@ struct CompareValues if (v1->type == tInt && v2->type == tFloat) return v1->integer < v2->fpoint; if (v1->type != v2->type) - throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) % showType(*v2)); + throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2)); switch (v1->type) { case tInt: return v1->integer < v2->integer; @@ -350,7 +350,7 @@ struct CompareValues case tPath: return strcmp(v1->path, v2->path) < 0; default: - throw EvalError(format("cannot compare %1% with %2%") % showType(*v1) % showType(*v2)); + throw EvalError("cannot compare %1% with %2%", showType(*v1), showType(*v2)); } } }; @@ -371,7 +371,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator startSet = args[0]->attrs->find(state.symbols.create("startSet")); if (startSet == args[0]->attrs->end()) - throw EvalError(format("attribute 'startSet' required, at %1%") % pos); + throw EvalError("attribute 'startSet' required, at %1%", pos); state.forceList(*startSet->value, pos); ValueList workSet; @@ -382,7 +382,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator op = args[0]->attrs->find(state.symbols.create("operator")); if (op == args[0]->attrs->end()) - throw EvalError(format("attribute 'operator' required, at %1%") % pos); + throw EvalError("attribute 'operator' required, at %1%", pos); state.forceValue(*op->value); /* Construct the closure by applying the operator to element of @@ -401,7 +401,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator key = e->attrs->find(state.symbols.create("key")); if (key == e->attrs->end()) - throw EvalError(format("attribute 'key' required, at %1%") % pos); + throw EvalError("attribute 'key' required, at %1%", pos); state.forceValue(*key->value); if (!doneKeys.insert(key->value).second) continue; @@ -431,7 +431,7 @@ static void prim_abort(EvalState & state, const Pos & pos, Value * * args, Value { PathSet context; string s = state.coerceToString(pos, *args[0], context); - throw Abort(format("evaluation aborted with the following error message: '%1%'") % s); + throw Abort("evaluation aborted with the following error message: '%1%'", s); } @@ -506,9 +506,9 @@ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value { state.forceValue(*args[0]); if (args[0]->type == tString) - printError(format("trace: %1%") % args[0]->string.s); + printError("trace: %1%", args[0]->string.s); else - printError(format("trace: %1%") % *args[0]); + printError("trace: %1%", *args[0]); state.forceValue(*args[1]); v = *args[1]; } @@ -533,13 +533,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Figure out the name first (for stack backtraces). */ Bindings::iterator attr = args[0]->attrs->find(state.sName); if (attr == args[0]->attrs->end()) - throw EvalError(format("required attribute 'name' missing, at %1%") % pos); + throw EvalError("required attribute 'name' missing, at %1%", pos); string drvName; Pos & posDrvName(*attr->pos); try { drvName = state.forceStringNoCtx(*attr->value, pos); } catch (Error & e) { - e.addPrefix(format("while evaluating the derivation attribute 'name' at %1%:\n") % posDrvName); + e.addPrefix(fmt("while evaluating the derivation attribute 'name' at %1%:\n", posDrvName)); throw; } @@ -583,18 +583,18 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * outputs.clear(); for (auto & j : ss) { if (outputs.find(j) != outputs.end()) - throw EvalError(format("duplicate derivation output '%1%', at %2%") % j % posDrvName); + throw EvalError("duplicate derivation output '%1%', at %2%", j, posDrvName); /* !!! Check whether j is a valid attribute name. */ /* Derivations cannot be named ‘drv’, because then we'd have an attribute ‘drvPath’ in the resulting set. */ if (j == "drv") - throw EvalError(format("invalid derivation output name 'drv', at %1%") % posDrvName); + throw EvalError("invalid derivation output name 'drv', at %1%", posDrvName); outputs.insert(j); } if (outputs.empty()) - throw EvalError(format("derivation cannot have an empty set of outputs, at %1%") % posDrvName); + throw EvalError("derivation cannot have an empty set of outputs, at %1%", posDrvName); }; try { @@ -706,9 +706,9 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Do we have all required attributes? */ if (drv.builder == "") - throw EvalError(format("required attribute 'builder' missing, at %1%") % posDrvName); + throw EvalError("required attribute 'builder' missing, at %1%", posDrvName); if (drv.platform == "") - throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName); + throw EvalError("required attribute 'system' missing, at %1%", posDrvName); /* Check whether the derivation name is valid. */ if (isDerivation(drvName)) @@ -717,7 +717,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * if (outputHash) { /* Handle fixed-output derivations. */ if (outputs.size() != 1 || *(outputs.begin()) != "out") - throw Error(format("multiple outputs are not supported in fixed-output derivations, at %1%") % posDrvName); + throw Error("multiple outputs are not supported in fixed-output derivations, at %1%", posDrvName); HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); Hash h(*outputHash, ht); @@ -818,7 +818,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V e.g. nix-push does the right thing. */ if (!state.store->isStorePath(path)) path = canonPath(path, true); if (!state.store->isInStore(path)) - throw EvalError(format("path '%1%' is not in the Nix store, at %2%") % path % pos); + throw EvalError("path '%1%' is not in the Nix store, at %2%", path, pos); Path path2 = state.store->toStorePath(path); if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(path2)); @@ -834,9 +834,9 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format( - "cannot check the existence of '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError( + "cannot check the existence of '%1%', since path '%2%' is not valid, at %3%", + path, e.path, pos); } try { @@ -879,12 +879,12 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%" + , path, e.path, pos); } string s = readFile(state.checkSourcePath(state.toRealPath(path, context))); if (s.find((char) 0) != string::npos) - throw Error(format("the contents of the file '%1%' cannot be represented as a Nix string") % path); + throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path); mkString(v, s.c_str()); } @@ -908,7 +908,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va i = v2.attrs->find(state.symbols.create("path")); if (i == v2.attrs->end()) - throw EvalError(format("attribute 'path' missing, at %1%") % pos); + throw EvalError("attribute 'path' missing, at %1%", pos); PathSet context; string path = state.coerceToString(pos, *i->value, context, false, false); @@ -916,8 +916,8 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError(format("cannot find '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError("cannot find '%1%', since path '%2%' is not valid, at %3%", + path, e.path, pos); } searchPath.emplace_back(prefix, path); @@ -934,7 +934,7 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error(format("unknown hash type '%1%', at %2%") % type % pos); + throw Error("unknown hash type '%1%', at %2%", type, pos); PathSet context; // discarded Path p = state.coerceToPath(pos, *args[1], context); @@ -950,8 +950,8 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val try { state.realiseContext(ctx); } catch (InvalidPathError & e) { - throw EvalError(format("cannot read '%1%', since path '%2%' is not valid, at %3%") - % path % e.path % pos); + throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%", + path, e.path, pos); } DirEntries entries = readDirectory(state.checkSourcePath(path)); @@ -1021,7 +1021,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu for (auto path : context) { if (path.at(0) != '/') - throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos); + throw EvalError("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%", name, pos); refs.insert(state.store->parseStorePath(path)); } @@ -1089,11 +1089,11 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args PathSet context; Path path = state.coerceToPath(pos, *args[1], context); if (!context.empty()) - throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % pos); + throw EvalError("string '%1%' cannot refer to other paths, at %2%", path, pos); state.forceValue(*args[0]); if (args[0]->type != tLambda) - throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos); + throw TypeError("first argument in call to 'filterSource' is not a function but %1%, at %2%", showType(*args[0]), pos); addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v); } @@ -1113,7 +1113,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value PathSet context; path = state.coerceToPath(*attr.pos, *attr.value, context); if (!context.empty()) - throw EvalError(format("string '%1%' cannot refer to other paths, at %2%") % path % *attr.pos); + throw EvalError("string '%1%' cannot refer to other paths, at %2%", path, *attr.pos); } else if (attr.name == state.sName) name = state.forceStringNoCtx(*attr.value, *attr.pos); else if (n == "filter") { @@ -1124,10 +1124,10 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value else if (n == "sha256") expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); else - throw EvalError(format("unsupported argument '%1%' to 'addPath', at %2%") % attr.name % *attr.pos); + throw EvalError("unsupported argument '%1%' to 'addPath', at %2%", attr.name, *attr.pos); } if (path.empty()) - throw EvalError(format("'path' required, at %1%") % pos); + throw EvalError("'path' required, at %1%", pos); if (name.empty()) name = baseNameOf(path); @@ -1185,7 +1185,7 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) // !!! Should we create a symbol here or just do a lookup? Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); if (i == args[1]->attrs->end()) - throw EvalError(format("attribute '%1%' missing, at %2%") % attr % pos); + throw EvalError("attribute '%1%' missing, at %2%", attr, pos); // !!! add to stack trace? if (state.countCalls && i->pos) state.attrSelects[*i->pos]++; state.forceValue(*i->value); @@ -1265,14 +1265,14 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, Bindings::iterator j = v2.attrs->find(state.sName); if (j == v2.attrs->end()) - throw TypeError(format("'name' attribute missing in a call to 'listToAttrs', at %1%") % pos); + throw TypeError("'name' attribute missing in a call to 'listToAttrs', at %1%", pos); string name = state.forceStringNoCtx(*j->value, pos); Symbol sym = state.symbols.create(name); if (seen.insert(sym).second) { Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue)); if (j2 == v2.attrs->end()) - throw TypeError(format("'value' attribute missing in a call to 'listToAttrs', at %1%") % pos); + throw TypeError("'value' attribute missing in a call to 'listToAttrs', at %1%", pos); v.attrs->push_back(Attr(sym, j2->value, j2->pos)); } @@ -1346,7 +1346,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args { state.forceValue(*args[0]); if (args[0]->type != tLambda) - throw TypeError(format("'functionArgs' requires a function, at %1%") % pos); + throw TypeError("'functionArgs' requires a function, at %1%", pos); if (!args[0]->lambda.fun->matchAttrs) { state.mkAttrs(v, 0); @@ -1396,7 +1396,7 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu { state.forceList(list, pos); if (n < 0 || (unsigned int) n >= list.listSize()) - throw Error(format("list index %1% is out of bounds, at %2%") % n % pos); + throw Error("list index %1% is out of bounds, at %2%", n, pos); state.forceValue(*list.listElems()[n]); v = *list.listElems()[n]; } @@ -1423,7 +1423,7 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value { state.forceList(*args[0], pos); if (args[0]->listSize() == 0) - throw Error(format("'tail' called on an empty list, at %1%") % pos); + throw Error("'tail' called on an empty list, at %1%", pos); state.mkList(v, args[0]->listSize() - 1); for (unsigned int n = 0; n < v.listSize(); ++n) v.listElems()[n] = args[0]->listElems()[n + 1]; @@ -1564,7 +1564,7 @@ static void prim_genList(EvalState & state, const Pos & pos, Value * * args, Val auto len = state.forceInt(*args[1], pos); if (len < 0) - throw EvalError(format("cannot create list of size %1%, at %2%") % len % pos); + throw EvalError("cannot create list of size %1%, at %2%", len, pos); state.mkList(v, len); @@ -1722,7 +1722,7 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & state.forceValue(*args[1], pos); NixFloat f2 = state.forceFloat(*args[1], pos); - if (f2 == 0) throw EvalError(format("division by zero, at %1%") % pos); + if (f2 == 0) throw EvalError("division by zero, at %1%", pos); if (args[0]->type == tFloat || args[1]->type == tFloat) { mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos)); @@ -1731,7 +1731,7 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & NixInt i2 = state.forceInt(*args[1], pos); /* Avoid division overflow as it might raise SIGFPE. */ if (i1 == std::numeric_limits::min() && i2 == -1) - throw EvalError(format("overflow in integer division, at %1%") % pos); + throw EvalError("overflow in integer division, at %1%", pos); mkInt(v, i1 / i2); } } @@ -1787,7 +1787,7 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V PathSet context; string s = state.coerceToString(pos, *args[2], context); - if (start < 0) throw EvalError(format("negative start position in 'substring', at %1%") % pos); + if (start < 0) throw EvalError("negative start position in 'substring', at %1%", pos); mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context); } @@ -1807,7 +1807,7 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error(format("unknown hash type '%1%', at %2%") % type % pos); + throw Error("unknown hash type '%1%', at %2%", type, pos); PathSet context; // discarded string s = state.forceString(*args[1], context, pos); @@ -1950,7 +1950,7 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar state.forceList(*args[0], pos); state.forceList(*args[1], pos); if (args[0]->listSize() != args[1]->listSize()) - throw EvalError(format("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%") % pos); + throw EvalError("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%", pos); vector from; from.reserve(args[0]->listSize()); @@ -2072,11 +2072,11 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, else if (n == "name") request.name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError(format("unsupported argument '%1%' to '%2%', at %3%") % attr.name % who % attr.pos); + throw EvalError("unsupported argument '%1%' to '%2%', at %3%", attr.name, who, attr.pos); } if (request.uri.empty()) - throw EvalError(format("'url' argument required, at %1%") % pos); + throw EvalError("'url' argument required, at %1%", pos); } else request.uri = state.forceStringNoCtx(*args[0], pos); diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 4aee1073e..480cc1adc 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -221,7 +221,7 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va } if (url.empty()) - throw EvalError(format("'url' argument required, at %1%") % pos); + throw EvalError("'url' argument required, at %1%", pos); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index db274fa4f..76029f548 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -191,7 +191,7 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar } if (url.empty()) - throw EvalError(format("'url' argument required, at %1%") % pos); + throw EvalError("'url' argument required, at %1%", pos); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc index 5fe8570ad..6ec8315ba 100644 --- a/src/libexpr/value-to-json.cc +++ b/src/libexpr/value-to-json.cc @@ -79,7 +79,7 @@ void printValueAsJSON(EvalState & state, bool strict, break; default: - throw TypeError(format("cannot convert %1% to JSON") % showType(v)); + throw TypeError("cannot convert %1% to JSON", showType(v)); } } @@ -93,7 +93,7 @@ void printValueAsJSON(EvalState & state, bool strict, void ExternalValueBase::printValueAsJSON(EvalState & state, bool strict, JSONPlaceholder & out, PathSet & context) const { - throw TypeError(format("cannot convert %1% to JSON") % showType()); + throw TypeError("cannot convert %1% to JSON", showType()); } diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index d41e772e9..f7ab56271 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -75,7 +75,7 @@ string getArg(const string & opt, Strings::iterator & i, const Strings::iterator & end) { ++i; - if (i == end) throw UsageError(format("'%1%' requires an argument") % opt); + if (i == end) throw UsageError("'%1%' requires an argument", opt); return *i; } @@ -229,7 +229,7 @@ bool LegacyArgs::processArgs(const Strings & args, bool finish) Strings ss(args); auto pos = ss.begin(); if (!parseArg(pos, ss.end())) - throw UsageError(format("unexpected argument '%1%'") % args.front()); + throw UsageError("unexpected argument '%1%'", args.front()); return true; } @@ -273,7 +273,7 @@ void showManPage(const string & name) restoreSignals(); setenv("MANPATH", settings.nixManDir.c_str(), 1); execlp("man", "man", name.c_str(), nullptr); - throw SysError(format("command 'man %1%' failed") % name.c_str()); + throw SysError("command 'man %1%' failed", name.c_str()); } @@ -301,7 +301,7 @@ int handleExceptions(const string & programName, std::function fun) % e.what() % programName); return 1; } catch (BaseError & e) { - printError(format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); + printError(error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); if (e.prefix() != "" && !settings.showTrace) printError("(use '--show-trace' to show detailed location information)"); return e.status; @@ -338,7 +338,7 @@ RunPager::RunPager() execlp("pager", "pager", nullptr); execlp("less", "less", nullptr); execlp("more", "more", nullptr); - throw SysError(format("executing '%1%'") % pager); + throw SysError("executing '%1%'", pager); }); pid.setKillSignal(SIGINT); diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index b49574652..f558247c0 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -56,7 +56,7 @@ template N getIntArg(const string & opt, Strings::iterator & i, const Strings::iterator & end, bool allowUnit) { ++i; - if (i == end) throw UsageError(format("'%1%' requires an argument") % opt); + if (i == end) throw UsageError("'%1%' requires an argument", opt); string s = *i; N multiplier = 1; if (allowUnit && !s.empty()) { @@ -66,13 +66,13 @@ template N getIntArg(const string & opt, else if (u == 'M') multiplier = 1ULL << 20; else if (u == 'G') multiplier = 1ULL << 30; else if (u == 'T') multiplier = 1ULL << 40; - else throw UsageError(format("invalid unit specifier '%1%'") % u); + else throw UsageError("invalid unit specifier '%1%'", u); s.resize(s.size() - 1); } } N n; if (!string2Int(s, n)) - throw UsageError(format("'%1%' requires an integer argument") % opt); + throw UsageError("'%1%' requires an integer argument", opt); return n * multiplier; } diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 3a2d84861..4b7385c6b 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -40,14 +40,14 @@ void BinaryCacheStore::init() upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n", "text/x-nix-cache-info"); } else { for (auto & line : tokenizeString(*cacheInfo, "\n")) { - size_t colon = line.find(':'); - if (colon == std::string::npos) continue; + size_t colon= line.find(':'); + if (colon ==std::string::npos) continue; auto name = line.substr(0, colon); auto value = trim(line.substr(colon + 1, std::string::npos)); if (name == "StoreDir") { if (value != storeDir) - throw Error(format("binary cache '%s' is for Nix stores with prefix '%s', not '%s'") - % getUri() % value % storeDir); + throw Error("binary cache '%s' is for Nix stores with prefix '%s', not '%s'", + getUri(), value, storeDir); } else if (name == "WantMassQuery") { wantMassQuery.setDefault(value == "1" ? "true" : "false"); } else if (name == "Priority") { diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 527d7ac42..2301adb16 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -453,7 +453,7 @@ static void commonChildInit(Pipe & logPipe) that e.g. ssh cannot open /dev/tty) and it doesn't receive terminal signals. */ if (setsid() == -1) - throw SysError(format("creating a new session")); + throw SysError("creating a new session"); /* Dup the write side of the logger pipe into stderr. */ if (dup2(logPipe.writeSide.get(), STDERR_FILENO) == -1) @@ -466,7 +466,7 @@ static void commonChildInit(Pipe & logPipe) /* Reroute stdin to /dev/null. */ int fdDevNull = open(pathNullDevice.c_str(), O_RDWR); if (fdDevNull == -1) - throw SysError(format("cannot open '%1%'") % pathNullDevice); + throw SysError("cannot open '%1%'", pathNullDevice); if (dup2(fdDevNull, STDIN_FILENO) == -1) throw SysError("cannot dup null device into stdin"); close(fdDevNull); @@ -488,7 +488,7 @@ void handleDiffHook( auto diffRes = runProgram(diffHookOptions); if (!statusOk(diffRes.first)) - throw ExecError(diffRes.first, fmt("diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first))); + throw ExecError(diffRes.first, "diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first)); if (diffRes.second != "") printError(chomp(diffRes.second)); @@ -534,8 +534,8 @@ UserLock::UserLock() /* Get the members of the build-users-group. */ struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); if (!gr) - throw Error(format("the group '%1%' specified in 'build-users-group' does not exist") - % settings.buildUsersGroup); + throw Error("the group '%1%' specified in 'build-users-group' does not exist", + settings.buildUsersGroup); gid = gr->gr_gid; /* Copy the result of getgrnam. */ @@ -546,8 +546,8 @@ UserLock::UserLock() } if (users.empty()) - throw Error(format("the build users group '%1%' has no members") - % settings.buildUsersGroup); + throw Error("the build users group '%1%' has no members", + settings.buildUsersGroup); /* Find a user account that isn't currently in use for another build. */ @@ -556,8 +556,8 @@ UserLock::UserLock() struct passwd * pw = getpwnam(i.c_str()); if (!pw) - throw Error(format("the user '%1%' in the group '%2%' does not exist") - % i % settings.buildUsersGroup); + throw Error("the user '%1%' in the group '%2%' does not exist", + i, settings.buildUsersGroup); createDirs(settings.nixStateDir + "/userpool"); @@ -565,7 +565,7 @@ UserLock::UserLock() AutoCloseFD fd = open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600); if (!fd) - throw SysError(format("opening user lock '%1%'") % fnUserLock); + throw SysError("opening user lock '%1%'", fnUserLock); if (lockFile(fd.get(), ltWrite, false)) { fdUserLock = std::move(fd); @@ -574,8 +574,8 @@ UserLock::UserLock() /* Sanity check... */ if (uid == getuid() || uid == geteuid()) - throw Error(format("the Nix user should not be a member of '%1%'") - % settings.buildUsersGroup); + throw Error("the Nix user should not be a member of '%1%'", + settings.buildUsersGroup); #if __linux__ /* Get the list of supplementary groups of this build user. This @@ -585,7 +585,7 @@ UserLock::UserLock() int err = getgrouplist(pw->pw_name, pw->pw_gid, supplementaryGIDs.data(), &ngroups); if (err == -1) - throw Error(format("failed to get list of supplementary groups for '%1%'") % pw->pw_name); + throw Error("failed to get list of supplementary groups for '%1%'", pw->pw_name); supplementaryGIDs.resize(ngroups); #endif @@ -594,9 +594,9 @@ UserLock::UserLock() } } - throw Error(format("all build users are currently in use; " - "consider creating additional users and adding them to the '%1%' group") - % settings.buildUsersGroup); + throw Error("all build users are currently in use; " + "consider creating additional users and adding them to the '%1%' group", + settings.buildUsersGroup); } @@ -1985,7 +1985,7 @@ void DerivationGoal::startBuilder() string s = get(drv->env, "exportReferencesGraph").value_or(""); Strings ss = tokenizeString(s); if (ss.size() % 2 != 0) - throw BuildError(format("odd number of tokens in 'exportReferencesGraph': '%1%'") % s); + throw BuildError("odd number of tokens in 'exportReferencesGraph': '%1%'", s); for (Strings::iterator i = ss.begin(); i != ss.end(); ) { string fileName = *i++; static std::regex regex("[A-Za-z_][A-Za-z0-9_.-]*"); @@ -2034,7 +2034,7 @@ void DerivationGoal::startBuilder() worker.store.computeFSClosure(worker.store.parseStorePath(worker.store.toStorePath(i.second.source)), closure); } catch (InvalidPath & e) { } catch (Error & e) { - throw Error(format("while processing 'sandbox-paths': %s") % e.what()); + throw Error("while processing 'sandbox-paths': %s", e.what()); } for (auto & i : closure) { auto p = worker.store.printStorePath(i); @@ -2081,10 +2081,10 @@ void DerivationGoal::startBuilder() printMsg(lvlChatty, format("setting up chroot environment in '%1%'") % chrootRootDir); if (mkdir(chrootRootDir.c_str(), 0750) == -1) - throw SysError(format("cannot create '%1%'") % chrootRootDir); + throw SysError("cannot create '%1%'", chrootRootDir); if (buildUser && chown(chrootRootDir.c_str(), 0, buildUser->getGID()) == -1) - throw SysError(format("cannot change ownership of '%1%'") % chrootRootDir); + throw SysError("cannot change ownership of '%1%'", chrootRootDir); /* Create a writable /tmp in the chroot. Many builders need this. (Of course they should really respect $TMPDIR @@ -2128,7 +2128,7 @@ void DerivationGoal::startBuilder() chmod_(chrootStoreDir, 01775); if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1) - throw SysError(format("cannot change ownership of '%1%'") % chrootStoreDir); + throw SysError("cannot change ownership of '%1%'", chrootStoreDir); for (auto & i : inputPaths) { auto p = worker.store.printStorePath(i); @@ -2161,7 +2161,7 @@ void DerivationGoal::startBuilder() if (needsHashRewrite()) { if (pathExists(homeDir)) - throw Error(format("directory '%1%' exists; please remove it") % homeDir); + throw Error("directory '%1%' exists; please remove it", homeDir); /* We're not doing a chroot build, but we have some valid output paths. Since we can't just overwrite or delete @@ -2206,8 +2206,7 @@ void DerivationGoal::startBuilder() if (line == "extra-sandbox-paths" || line == "extra-chroot-dirs") { state = stExtraChrootDirs; } else { - throw Error(format("unknown pre-build hook command '%1%'") - % line); + throw Error("unknown pre-build hook command '%1%'", line); } } else if (state == stExtraChrootDirs) { if (line == "") { @@ -2967,7 +2966,7 @@ void DerivationGoal::chownToBuilder(const Path & path) { if (!buildUser) return; if (chown(path.c_str(), buildUser->getUID(), buildUser->getGID()) == -1) - throw SysError(format("cannot change ownership of '%1%'") % path); + throw SysError("cannot change ownership of '%1%'", path); } @@ -3104,7 +3103,7 @@ void DerivationGoal::runChild() /* Bind-mount chroot directory to itself, to treat it as a different filesystem from /, as needed for pivot_root. */ if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1) - throw SysError(format("unable to bind mount '%1%'") % chrootRootDir); + throw SysError("unable to bind mount '%1%'", chrootRootDir); /* Bind-mount the sandbox's Nix store onto itself so that we can mark it as a "shared" subtree, allowing bind @@ -3238,16 +3237,16 @@ void DerivationGoal::runChild() /* Do the chroot(). */ if (chdir(chrootRootDir.c_str()) == -1) - throw SysError(format("cannot change directory to '%1%'") % chrootRootDir); + throw SysError("cannot change directory to '%1%'", chrootRootDir); if (mkdir("real-root", 0) == -1) throw SysError("cannot create real-root directory"); if (pivot_root(".", "real-root") == -1) - throw SysError(format("cannot pivot old root directory onto '%1%'") % (chrootRootDir + "/real-root")); + throw SysError("cannot pivot old root directory onto '%1%'", (chrootRootDir + "/real-root")); if (chroot(".") == -1) - throw SysError(format("cannot change root directory to '%1%'") % chrootRootDir); + throw SysError("cannot change root directory to '%1%'", chrootRootDir); if (umount2("real-root", MNT_DETACH) == -1) throw SysError("cannot unmount real root filesystem"); @@ -3268,7 +3267,7 @@ void DerivationGoal::runChild() #endif if (chdir(tmpDirInSandbox.c_str()) == -1) - throw SysError(format("changing into '%1%'") % tmpDir); + throw SysError("changing into '%1%'", tmpDir); /* Close all other file descriptors. */ closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}); @@ -3407,9 +3406,9 @@ void DerivationGoal::runChild() sandboxProfile += "(allow file-read* file-write* process-exec\n"; for (auto & i : dirsInChroot) { if (i.first != i.second.source) - throw Error(format( - "can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin") - % i.first % i.second.source); + throw Error( + "can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin", + i.first, i.second.source); string path = i.first; struct stat st; @@ -3500,7 +3499,7 @@ void DerivationGoal::runChild() else if (drv->builder == "builtin:unpack-channel") builtinUnpackChannel(drv2); else - throw Error(format("unsupported builtin function '%1%'") % string(drv->builder, 8)); + throw Error("unsupported builtin function '%1%'", string(drv->builder, 8)); _exit(0); } catch (std::exception & e) { writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n"); @@ -3510,7 +3509,7 @@ void DerivationGoal::runChild() execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data()); - throw SysError(format("executing '%1%'") % drv->builder); + throw SysError("executing '%1%'", drv->builder); } catch (std::exception & e) { writeFull(STDERR_FILENO, "\1while setting up the build environment: " + string(e.what()) + "\n"); @@ -3595,7 +3594,7 @@ void DerivationGoal::registerOutputs() replaceValidPath(path, actualPath); else if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1) - throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path); + throw SysError("moving build output '%1%' from the sandbox to the Nix store", path); } if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path); } @@ -3616,13 +3615,13 @@ void DerivationGoal::registerOutputs() user. */ if ((!S_ISLNK(st.st_mode) && (st.st_mode & (S_IWGRP | S_IWOTH))) || (buildUser && st.st_uid != buildUser->getUID())) - throw BuildError(format("suspicious ownership or permission on '%1%'; rejecting this build output") % path); + throw BuildError("suspicious ownership or permission on '%1%'; rejecting this build output", path); #endif /* Apply hash rewriting if necessary. */ bool rewritten = false; if (!outputRewrites.empty()) { - printError(format("warning: rewriting hashes in '%1%'; cross fingers") % path); + printError("warning: rewriting hashes in '%1%'; cross fingers", path); /* Canonicalise first. This ensures that the path we're rewriting doesn't contain a hard link to /etc/shadow or @@ -3654,7 +3653,8 @@ void DerivationGoal::registerOutputs() /* The output path should be a regular file without execute permission. */ if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0) throw BuildError( - format("output path '%1%' should be a non-executable regular file") % path); + "output path '%1%' should be a non-executable regular file", + path); } /* Check the hash. In hash mode, move the path produced by @@ -3715,7 +3715,7 @@ void DerivationGoal::registerOutputs() Path dst = worker.store.toRealPath(path + checkSuffix); deletePath(dst); if (rename(actualPath.c_str(), dst.c_str())) - throw SysError(format("renaming '%1%' to '%2%'") % actualPath % dst); + throw SysError("renaming '%1%' to '%2%'", actualPath, dst); handleDiffHook( buildUser ? buildUser->getUID() : getuid(), @@ -4014,7 +4014,7 @@ Path DerivationGoal::openLogFile() settings.compressLog ? ".bz2" : ""); fdLogFile = open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666); - if (!fdLogFile) throw SysError(format("creating log file '%1%'") % logFileName); + if (!fdLogFile) throw SysError("creating log file '%1%'", logFileName); logFileSink = std::make_shared(fdLogFile.get()); @@ -4522,7 +4522,6 @@ void SubstitutionGoal::handleEOF(int fd) if (fd == outPipe.readSide.get()) worker.wakeUp(shared_from_this()); } - ////////////////////////////////////////////////////////////////////// @@ -4739,9 +4738,9 @@ void Worker::run(const Goals & _topGoals) if (!children.empty() || !waitingForAWhile.empty()) waitForInput(); else { - if (awake.empty() && 0 == settings.maxBuildJobs) throw Error( - "unable to start any build; either increase '--max-jobs' " - "or enable remote builds"); + if (awake.empty() && 0 == settings.maxBuildJobs) + throw Error("unable to start any build; either increase '--max-jobs' " + "or enable remote builds"); assert(!awake.empty()); } } @@ -4754,7 +4753,6 @@ void Worker::run(const Goals & _topGoals) assert(!settings.keepGoing || children.empty()); } - void Worker::waitForInput() { printMsg(lvlVomit, "waiting for children"); @@ -4895,6 +4893,9 @@ void Worker::waitForInput() } + + + unsigned int Worker::exitStatus() { /* @@ -4994,7 +4995,6 @@ void LocalStore::buildPaths(const std::vector & drvPaths, throw Error(worker.exitStatus(), "build of %s failed", showPaths(failed)); } - BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv, BuildMode buildMode) { @@ -5055,4 +5055,8 @@ void LocalStore::repairPath(const StorePath & path) } + } + + + diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index 1b802d908..000769094 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -72,15 +72,15 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, if (!S_ISDIR(lstat(target).st_mode)) throw Error("collision between '%1%' and non-directory '%2%'", srcFile, target); if (unlink(dstFile.c_str()) == -1) - throw SysError(format("unlinking '%1%'") % dstFile); + throw SysError("unlinking '%1%'", dstFile); if (mkdir(dstFile.c_str(), 0755) == -1) - throw SysError(format("creating directory '%1%'")); + throw SysError("creating directory '%1%'", dstFile); createLinks(state, target, dstFile, state.priorities[dstFile]); createLinks(state, srcFile, dstFile, priority); continue; } } else if (errno != ENOENT) - throw SysError(format("getting status of '%1%'") % dstFile); + throw SysError("getting status of '%1%'", dstFile); } else { @@ -99,11 +99,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, if (prevPriority < priority) continue; if (unlink(dstFile.c_str()) == -1) - throw SysError(format("unlinking '%1%'") % dstFile); + throw SysError("unlinking '%1%'", dstFile); } else if (S_ISDIR(dstSt.st_mode)) throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile); } else if (errno != ENOENT) - throw SysError(format("getting status of '%1%'") % dstFile); + throw SysError("getting status of '%1%'", dstFile); } createSymlink(srcFile, dstFile); diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc index f6ae5d2e6..223ed1fba 100644 --- a/src/libstore/builtins/fetchurl.cc +++ b/src/libstore/builtins/fetchurl.cc @@ -18,7 +18,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData) auto getAttr = [&](const string & name) { auto i = drv.env.find(name); - if (i == drv.env.end()) throw Error(format("attribute '%s' missing") % name); + if (i == drv.env.end()) throw Error("attribute '%s' missing", name); return i->second; }; @@ -54,7 +54,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData) auto executable = drv.env.find("executable"); if (executable != drv.env.end() && executable->second == "1") { if (chmod(storePath.c_str(), 0755) == -1) - throw SysError(format("making '%1%' executable") % storePath); + throw SysError("making '%1%' executable", storePath); } }; diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index d985f151b..f8b449e5e 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -747,7 +747,7 @@ static void performOp(TunnelLogger * logger, ref store, } default: - throw Error(format("invalid operation %1%") % op); + throw Error("invalid operation %1%", op); } } diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 973ddc86a..f35b8cc43 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -87,7 +87,7 @@ static void expect(std::istream & str, const string & s) char s2[s.size()]; str.read(s2, s.size()); if (string(s2, s.size()) != s) - throw FormatError(format("expected string '%1%'") % s); + throw FormatError("expected string '%1%'", s); } @@ -114,7 +114,7 @@ static Path parsePath(std::istream & str) { string s = parseString(str); if (s.size() == 0 || s[0] != '/') - throw FormatError(format("bad path '%1%' in derivation") % s); + throw FormatError("bad path '%1%' in derivation", s); return s; } @@ -196,7 +196,7 @@ Derivation readDerivation(const Store & store, const Path & drvPath) try { return parseDerivation(store, readFile(drvPath)); } catch (FormatError & e) { - throw Error(format("error parsing derivation '%1%': %2%") % drvPath % e.msg()); + throw Error("error parsing derivation '%1%': %2%", drvPath, e.msg()); } } diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 5967d0425..7d0cb449b 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -113,7 +113,7 @@ struct CurlDownloader : public Downloader if (requestHeaders) curl_slist_free_all(requestHeaders); try { if (!done) - fail(DownloadError(Interrupted, format("download of '%s' was interrupted") % request.uri)); + fail(DownloadError(Interrupted, "download of '%s' was interrupted", request.uri)); } catch (...) { ignoreException(); } @@ -518,7 +518,7 @@ struct CurlDownloader : public Downloader int running; CURLMcode mc = curl_multi_perform(curlm, &running); if (mc != CURLM_OK) - throw nix::Error(format("unexpected error from curl_multi_perform(): %s") % curl_multi_strerror(mc)); + throw nix::Error("unexpected error from curl_multi_perform(): %s", curl_multi_strerror(mc)); /* Set the promises of any finished requests. */ CURLMsg * msg; @@ -548,7 +548,7 @@ struct CurlDownloader : public Downloader vomit("download thread waiting for %d ms", sleepTimeMs); mc = curl_multi_wait(curlm, extraFDs, 1, sleepTimeMs, &numfds); if (mc != CURLM_OK) - throw nix::Error(format("unexpected error from curl_multi_wait(): %s") % curl_multi_strerror(mc)); + throw nix::Error("unexpected error from curl_multi_wait(): %s", curl_multi_strerror(mc)); nextWakeup = std::chrono::steady_clock::time_point(); diff --git a/src/libstore/download.hh b/src/libstore/download.hh index 5a131c704..8141928d2 100644 --- a/src/libstore/download.hh +++ b/src/libstore/download.hh @@ -128,8 +128,10 @@ class DownloadError : public Error { public: Downloader::Error error; - DownloadError(Downloader::Error error, const FormatOrString & fs) - : Error(fs), error(error) + + template + DownloadError(Downloader::Error error, const Args & ... args) + : Error(args...), error(error) { } }; diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 0c3d89611..27bd3f3e9 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -38,7 +38,7 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) AutoCloseFD fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600); if (!fdGCLock) - throw SysError(format("opening global GC lock '%1%'") % fnGCLock); + throw SysError("opening global GC lock '%1%'", fnGCLock); if (!lockFile(fdGCLock.get(), lockType, false)) { printError(format("waiting for the big garbage collector lock...")); @@ -65,8 +65,8 @@ static void makeSymlink(const Path & link, const Path & target) /* Atomically replace the old one. */ if (rename(tempLink.c_str(), link.c_str()) == -1) - throw SysError(format("cannot rename '%1%' to '%2%'") - % tempLink % link); + throw SysError("cannot rename '%1%' to '%2%'", + tempLink , link); } @@ -91,15 +91,15 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, Path gcRoot(canonPath(_gcRoot)); if (isInStore(gcRoot)) - throw Error(format( + throw Error( "creating a garbage collector root (%1%) in the Nix store is forbidden " - "(are you running nix-build inside the store?)") % gcRoot); + "(are you running nix-build inside the store?)", gcRoot); if (indirect) { /* Don't clobber the link if it already exists and doesn't point to the Nix store. */ if (pathExists(gcRoot) && (!isLink(gcRoot) || !isInStore(readLink(gcRoot)))) - throw Error(format("cannot create symlink '%1%'; already exists") % gcRoot); + throw Error("cannot create symlink '%1%'; already exists", gcRoot); makeSymlink(gcRoot, printStorePath(storePath)); addIndirectRoot(gcRoot); } @@ -109,10 +109,10 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, Path rootsDir = canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str()); if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") - throw Error(format( + throw Error( "path '%1%' is not a valid garbage collector root; " - "it's not in the directory '%2%'") - % gcRoot % rootsDir); + "it's not in the directory '%2%'", + gcRoot, rootsDir); } if (baseNameOf(gcRoot) == std::string(storePath.to_string())) @@ -170,7 +170,7 @@ void LocalStore::addTempRoot(const StorePath & path) way. */ struct stat st; if (fstat(state->fdTempRoots.get(), &st) == -1) - throw SysError(format("statting '%1%'") % fnTempRoots); + throw SysError("statting '%1%'", fnTempRoots); if (st.st_size == 0) break; /* The garbage collector deleted this file before we could @@ -211,7 +211,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor) if (!*fd) { /* It's okay if the file has disappeared. */ if (errno == ENOENT) continue; - throw SysError(format("opening temporary roots file '%1%'") % path); + throw SysError("opening temporary roots file '%1%'", path); } /* This should work, but doesn't, for some reason. */ @@ -222,7 +222,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor) only succeed if the owning process has died. In that case we don't care about its temporary roots. */ if (lockFile(fd->get(), ltWrite, false)) { - printError(format("removing stale temporary roots file '%1%'") % path); + printError("removing stale temporary roots file '%1%'", path); unlink(path.c_str()); writeFull(fd->get(), "d"); continue; @@ -398,7 +398,7 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor) if (!fdDir) { if (errno == ENOENT || errno == EACCES) continue; - throw SysError(format("opening %1%") % fdStr); + throw SysError("opening %1%", fdStr); } struct dirent * fd_ent; while (errno = 0, fd_ent = readdir(fdDir.get())) { @@ -408,7 +408,7 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor) if (errno) { if (errno == ESRCH) continue; - throw SysError(format("iterating /proc/%1%/fd") % ent->d_name); + throw SysError("iterating /proc/%1%/fd", ent->d_name); } fdDir.reset(); @@ -536,7 +536,7 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path) struct stat st; if (lstat(realPath.c_str(), &st)) { if (errno == ENOENT) return; - throw SysError(format("getting status of %1%") % realPath); + throw SysError("getting status of %1%", realPath); } printInfo(format("deleting '%1%'") % path); @@ -554,10 +554,10 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path) // size. try { if (chmod(realPath.c_str(), st.st_mode | S_IWUSR) == -1) - throw SysError(format("making '%1%' writable") % realPath); + throw SysError("making '%1%' writable", realPath); Path tmp = trashDir + "/" + std::string(baseNameOf(path)); if (rename(realPath.c_str(), tmp.c_str())) - throw SysError(format("unable to rename '%1%' to '%2%'") % realPath % tmp); + throw SysError("unable to rename '%1%' to '%2%'", realPath, tmp); state.bytesInvalidated += size; } catch (SysError & e) { if (e.errNo == ENOSPC) { @@ -676,7 +676,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path) void LocalStore::removeUnusedLinks(const GCState & state) { AutoCloseDir dir(opendir(linksDir.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % linksDir); + if (!dir) throw SysError("opening directory '%1%'", linksDir); long long actualSize = 0, unsharedSize = 0; @@ -689,7 +689,7 @@ void LocalStore::removeUnusedLinks(const GCState & state) struct stat st; if (lstat(path.c_str(), &st) == -1) - throw SysError(format("statting '%1%'") % path); + throw SysError("statting '%1%'", path); if (st.st_nlink != 1) { actualSize += st.st_size; @@ -700,14 +700,14 @@ void LocalStore::removeUnusedLinks(const GCState & state) printMsg(lvlTalkative, format("deleting unused link '%1%'") % path); if (unlink(path.c_str()) == -1) - throw SysError(format("deleting '%1%'") % path); + throw SysError("deleting '%1%'", path); state.results.bytesFreed += st.st_size; } struct stat st; if (stat(linksDir.c_str(), &st) == -1) - throw SysError(format("statting '%1%'") % linksDir); + throw SysError("statting '%1%'", linksDir); long long overhead = st.st_blocks * 512ULL; printInfo(format("note: currently hard linking saves %.2f MiB") @@ -801,7 +801,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) try { AutoCloseDir dir(opendir(realStoreDir.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % realStoreDir); + if (!dir) throw SysError("opening directory '%1%'", realStoreDir); /* Read the store and immediately delete all paths that aren't valid. When using --max-freed etc., deleting diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 363be1443..48aca478c 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -74,7 +74,7 @@ static void atomicWrite(const Path & path, const std::string & s) AutoDelete del(tmp, false); writeFile(tmp, s); if (rename(tmp.c_str(), path.c_str())) - throw SysError(format("renaming '%1%' to '%2%'") % tmp % path); + throw SysError("renaming '%1%' to '%2%'", tmp, path); del.cancel(); } diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index aa5abd835..2d564a0d7 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -22,7 +22,7 @@ struct LocalStoreAccessor : public FSAccessor { Path storePath = store->toStorePath(path); if (!store->isValidPath(store->parseStorePath(storePath))) - throw InvalidPath(format("path '%1%' is not a valid store path") % storePath); + throw InvalidPath("path '%1%' is not a valid store path", storePath); return store->getRealStoreDir() + std::string(path, store->storeDir.size()); } @@ -33,11 +33,11 @@ struct LocalStoreAccessor : public FSAccessor struct stat st; if (lstat(realPath.c_str(), &st)) { if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false}; - throw SysError(format("getting status of '%1%'") % path); + throw SysError("getting status of '%1%'", path); } if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode)) - throw Error(format("file '%1%' has unsupported type") % path); + throw Error("file '%1%' has unsupported type", path); return { S_ISREG(st.st_mode) ? Type::tRegular : diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index ae7513ad8..db5a3b53c 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -92,13 +92,13 @@ LocalStore::LocalStore(const Params & params) else { struct stat st; if (stat(realStoreDir.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % realStoreDir); + throw SysError("getting attributes of path '%1%'", realStoreDir); if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) { if (chown(realStoreDir.c_str(), 0, gr->gr_gid) == -1) - throw SysError(format("changing ownership of path '%1%'") % realStoreDir); + throw SysError("changing ownership of path '%1%'", realStoreDir); if (chmod(realStoreDir.c_str(), perm) == -1) - throw SysError(format("changing permissions on path '%1%'") % realStoreDir); + throw SysError("changing permissions on path '%1%'", realStoreDir); } } } @@ -109,12 +109,12 @@ LocalStore::LocalStore(const Params & params) struct stat st; while (path != "/") { if (lstat(path.c_str(), &st)) - throw SysError(format("getting status of '%1%'") % path); + throw SysError("getting status of '%1%'", path); if (S_ISLNK(st.st_mode)) - throw Error(format( + throw Error( "the path '%1%' is a symlink; " - "this is not allowed for the Nix store and its parent directories") - % path); + "this is not allowed for the Nix store and its parent directories", + path); path = dirOf(path); } } @@ -155,8 +155,8 @@ LocalStore::LocalStore(const Params & params) upgrade. */ int curSchema = getSchema(); if (curSchema > nixSchemaVersion) - throw Error(format("current Nix store schema is version %1%, but I only support %2%") - % curSchema % nixSchemaVersion); + throw Error("current Nix store schema is version %1%, but I only support %2%", + curSchema, nixSchemaVersion); else if (curSchema == 0) { /* new store */ curSchema = nixSchemaVersion; @@ -284,7 +284,7 @@ int LocalStore::getSchema() if (pathExists(schemaPath)) { string s = readFile(schemaPath); if (!string2Int(s, curSchema)) - throw Error(format("'%1%' is corrupt") % schemaPath); + throw Error("'%1%' is corrupt", schemaPath); } return curSchema; } @@ -293,7 +293,7 @@ int LocalStore::getSchema() void LocalStore::openDB(State & state, bool create) { if (access(dbDir.c_str(), R_OK | W_OK)) - throw SysError(format("Nix database directory '%1%' is not writable") % dbDir); + throw SysError("Nix database directory '%1%' is not writable", dbDir); /* Open the Nix database. */ string dbPath = dbDir + "/db.sqlite"; @@ -367,7 +367,7 @@ void LocalStore::makeStoreWritable() throw SysError("setting up a private mount namespace"); if (mount(0, realStoreDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) - throw SysError(format("remounting %1% writable") % realStoreDir); + throw SysError("remounting %1% writable", realStoreDir); } #endif } @@ -388,7 +388,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct | 0444 | (st.st_mode & S_IXUSR ? 0111 : 0); if (chmod(path.c_str(), mode) == -1) - throw SysError(format("changing mode of '%1%' to %2$o") % path % mode); + throw SysError("changing mode of '%1%' to %2$o", path, mode); } } @@ -406,7 +406,7 @@ static void canonicaliseTimestampAndPermissions(const Path & path, const struct #else if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1) #endif - throw SysError(format("changing modification time of '%1%'") % path); + throw SysError("changing modification time of '%1%'", path); } } @@ -415,7 +415,7 @@ void canonicaliseTimestampAndPermissions(const Path & path) { struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); canonicaliseTimestampAndPermissions(path, st); } @@ -430,17 +430,17 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe setattrlist() to remove other attributes as well. */ if (lchflags(path.c_str(), 0)) { if (errno != ENOTSUP) - throw SysError(format("clearing flags of path '%1%'") % path); + throw SysError("clearing flags of path '%1%'", path); } #endif struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); /* Really make sure that the path is of a supported type. */ if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))) - throw Error(format("file '%1%' has an unsupported type") % path); + throw Error("file '%1%' has an unsupported type", path); #if __linux__ /* Remove extended attributes / ACLs. */ @@ -474,7 +474,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe if (fromUid != (uid_t) -1 && st.st_uid != fromUid) { assert(!S_ISDIR(st.st_mode)); if (inodesSeen.find(Inode(st.st_dev, st.st_ino)) == inodesSeen.end()) - throw BuildError(format("invalid ownership on file '%1%'") % path); + throw BuildError("invalid ownership on file '%1%'", path); mode_t mode = st.st_mode & ~S_IFMT; assert(S_ISLNK(st.st_mode) || (st.st_uid == geteuid() && (mode == 0444 || mode == 0555) && st.st_mtime == mtimeStore)); return; @@ -498,8 +498,8 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe if (!S_ISLNK(st.st_mode) && chown(path.c_str(), geteuid(), getegid()) == -1) #endif - throw SysError(format("changing owner of '%1%' to %2%") - % path % geteuid()); + throw SysError("changing owner of '%1%' to %2%", + path, geteuid()); } if (S_ISDIR(st.st_mode)) { @@ -518,11 +518,11 @@ void canonicalisePathMetaData(const Path & path, uid_t fromUid, InodesSeen & ino be a symlink, since we can't change its ownership. */ struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); if (st.st_uid != geteuid()) { assert(S_ISLNK(st.st_mode)); - throw Error(format("wrong ownership of top-level store path '%1%'") % path); + throw Error("wrong ownership of top-level store path '%1%'", path); } } @@ -1392,7 +1392,7 @@ static void makeMutable(const Path & path) AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC); if (fd == -1) { if (errno == ELOOP) return; // it's a symlink - throw SysError(format("opening file '%1%'") % path); + throw SysError("opening file '%1%'", path); } unsigned int flags = 0, old; diff --git a/src/libstore/nar-accessor.cc b/src/libstore/nar-accessor.cc index b74480684..ca663d837 100644 --- a/src/libstore/nar-accessor.cc +++ b/src/libstore/nar-accessor.cc @@ -184,7 +184,7 @@ struct NarAccessor : public FSAccessor auto i = get(path); if (i.type != FSAccessor::Type::tDirectory) - throw Error(format("path '%1%' inside NAR file is not a directory") % path); + throw Error("path '%1%' inside NAR file is not a directory", path); StringSet res; for (auto & child : i.children) @@ -197,7 +197,7 @@ struct NarAccessor : public FSAccessor { auto i = get(path); if (i.type != FSAccessor::Type::tRegular) - throw Error(format("path '%1%' inside NAR file is not a regular file") % path); + throw Error("path '%1%' inside NAR file is not a regular file", path); if (getNarBytes) return getNarBytes(i.start, i.size); @@ -209,7 +209,7 @@ struct NarAccessor : public FSAccessor { auto i = get(path); if (i.type != FSAccessor::Type::tSymlink) - throw Error(format("path '%1%' inside NAR file is not a symlink") % path); + throw Error("path '%1%' inside NAR file is not a symlink", path); return i.target; } }; diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 1375094b5..fbdcd7786 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -7,7 +7,7 @@ NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & : ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack { auto corrupt = [&]() { - throw Error(format("NAR info file '%1%' is corrupt") % whence); + throw Error("NAR info file '%1%' is corrupt", whence); }; auto parseHashField = [&](const string & s) { diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index 8ac382e9d..f9cf2bb6b 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -19,9 +19,9 @@ static void makeWritable(const Path & path) { struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); if (chmod(path.c_str(), st.st_mode | S_IWUSR) == -1) - throw SysError(format("changing writability of '%1%'") % path); + throw SysError("changing writability of '%1%'", path); } @@ -47,7 +47,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash() InodeHash inodeHash; AutoCloseDir dir(opendir(linksDir.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % linksDir); + if (!dir) throw SysError("opening directory '%1%'", linksDir); struct dirent * dirent; while (errno = 0, dirent = readdir(dir.get())) { /* sic */ @@ -55,7 +55,7 @@ LocalStore::InodeHash LocalStore::loadInodeHash() // We don't care if we hit non-hash files, anything goes inodeHash.insert(dirent->d_ino); } - if (errno) throw SysError(format("reading directory '%1%'") % linksDir); + if (errno) throw SysError("reading directory '%1%'", linksDir); printMsg(lvlTalkative, format("loaded %1% hash inodes") % inodeHash.size()); @@ -68,7 +68,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa Strings names; AutoCloseDir dir(opendir(path.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % path); + if (!dir) throw SysError("opening directory '%1%'", path); struct dirent * dirent; while (errno = 0, dirent = readdir(dir.get())) { /* sic */ @@ -83,7 +83,7 @@ Strings LocalStore::readDirectoryIgnoringInodes(const Path & path, const InodeHa if (name == "." || name == "..") continue; names.push_back(name); } - if (errno) throw SysError(format("reading directory '%1%'") % path); + if (errno) throw SysError("reading directory '%1%'", path); return names; } @@ -96,7 +96,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); #if __APPLE__ /* HFS/macOS has some undocumented security feature disabling hardlinking for @@ -130,7 +130,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, NixOS (example: $fontconfig/var/cache being modified). Skip those files. FIXME: check the modification time. */ if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { - printError(format("skipping suspicious writable file '%1%'") % path); + printError("skipping suspicious writable file '%1%'", path); return; } @@ -186,7 +186,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, current file with a hard link to that file. */ struct stat stLink; if (lstat(linkPath.c_str(), &stLink)) - throw SysError(format("getting attributes of path '%1%'") % linkPath); + throw SysError("getting attributes of path '%1%'", linkPath); if (st.st_ino == stLink.st_ino) { debug(format("'%1%' is already linked to '%2%'") % path % linkPath); @@ -194,7 +194,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, } if (st.st_size != stLink.st_size) { - printError(format("removing corrupted link '%1%'") % linkPath); + printError("removing corrupted link '%1%'", linkPath); unlink(linkPath.c_str()); goto retry; } @@ -229,7 +229,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, /* Atomically replace the old file with the new hard link. */ if (rename(tempLink.c_str(), path.c_str()) == -1) { if (unlink(tempLink.c_str()) == -1) - printError(format("unable to unlink '%1%'") % tempLink); + printError("unable to unlink '%1%'", tempLink); if (errno == EMLINK) { /* Some filesystems generate too many links on the rename, rather than on the original link. (Probably it @@ -238,7 +238,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, debug("'%s' has reached maximum number of links", linkPath); return; } - throw SysError(format("cannot rename '%1%' to '%2%'") % tempLink % path); + throw SysError("cannot rename '%1%' to '%2%'", tempLink, path); } stats.filesLinked++; diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index 2635e3940..52d430ffd 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -20,7 +20,7 @@ AutoCloseFD openLockFile(const Path & path, bool create) fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600); if (!fd && (create || errno != ENOENT)) - throw SysError(format("opening lock file '%1%'") % path); + throw SysError("opening lock file '%1%'", path); return fd; } @@ -51,7 +51,7 @@ bool lockFile(int fd, LockType lockType, bool wait) while (flock(fd, type) != 0) { checkInterrupt(); if (errno != EINTR) - throw SysError(format("acquiring/releasing lock")); + throw SysError("acquiring/releasing lock"); else return false; } @@ -60,7 +60,7 @@ bool lockFile(int fd, LockType lockType, bool wait) checkInterrupt(); if (errno == EWOULDBLOCK) return false; if (errno != EINTR) - throw SysError(format("acquiring/releasing lock")); + throw SysError("acquiring/releasing lock"); } } @@ -124,7 +124,7 @@ bool PathLocks::lockPaths(const PathSet & paths, hasn't been unlinked). */ struct stat st; if (fstat(fd.get(), &st) == -1) - throw SysError(format("statting lock file '%1%'") % lockPath); + throw SysError("statting lock file '%1%'", lockPath); if (st.st_size != 0) /* This lock file has been unlinked, so we're holding a lock on a deleted file. This means that other diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 2bef51878..6cfe393a4 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -50,7 +50,7 @@ Generations findGenerations(Path profile, int & curGen) gen.number = n; struct stat st; if (lstat(gen.path.c_str(), &st) != 0) - throw SysError(format("statting '%1%'") % gen.path); + throw SysError("statting '%1%'", gen.path); gen.creationTime = st.st_mtime; gens.push_back(gen); } @@ -117,7 +117,7 @@ Path createGeneration(ref store, Path profile, Path outPath) static void removeFile(const Path & path) { if (remove(path.c_str()) == -1) - throw SysError(format("cannot unlink '%1%'") % path); + throw SysError("cannot unlink '%1%'", path); } @@ -149,7 +149,7 @@ void deleteGenerations(const Path & profile, const std::set & gens Generations gens = findGenerations(profile, curGen); if (gensToDelete.find(curGen) != gensToDelete.end()) - throw Error(format("cannot delete current generation of profile %1%'") % profile); + throw Error("cannot delete current generation of profile %1%'", profile); for (auto & i : gens) { if (gensToDelete.find(i.number) == gensToDelete.end()) continue; @@ -226,7 +226,7 @@ void deleteGenerationsOlderThan(const Path & profile, const string & timeSpec, b int days; if (!string2Int(strDays, days) || days < 1) - throw Error(format("invalid number of days specifier '%1%'") % timeSpec); + throw Error("invalid number of days specifier '%1%'", timeSpec); time_t oldTime = curTime - days * 24 * 3600; diff --git a/src/libstore/references.cc b/src/libstore/references.cc index 102e15921..a10d536a3 100644 --- a/src/libstore/references.cc +++ b/src/libstore/references.cc @@ -92,7 +92,7 @@ PathSet scanForReferences(const string & path, auto baseName = std::string(baseNameOf(i)); string::size_type pos = baseName.find('-'); if (pos == string::npos) - throw Error(format("bad reference '%1%'") % i); + throw Error("bad reference '%1%'", i); string s = string(baseName, 0, pos); assert(s.size() == refLength); assert(backMap.find(s) == backMap.end()); diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc index 5a2d103b9..9277a8e6b 100644 --- a/src/libstore/remote-fs-accessor.cc +++ b/src/libstore/remote-fs-accessor.cc @@ -51,7 +51,7 @@ std::pair, Path> RemoteFSAccessor::fetch(const Path & path_) std::string restPath = std::string(path, storePath.size()); if (!store->isValidPath(store->parseStorePath(storePath))) - throw InvalidPath(format("path '%1%' is not a valid store path") % storePath); + throw InvalidPath("path '%1%' is not a valid store path", storePath); auto i = nars.find(storePath); if (i != nars.end()) return {i->second, restPath}; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 8c55da268..0f8126aee 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -116,11 +116,11 @@ ref UDSRemoteStore::openConnection() struct sockaddr_un addr; addr.sun_family = AF_UNIX; if (socketPath.size() + 1 >= sizeof(addr.sun_path)) - throw Error(format("socket path '%1%' is too long") % socketPath); + throw Error("socket path '%1%' is too long", socketPath); strcpy(addr.sun_path, socketPath.c_str()); if (::connect(conn->fd.get(), (struct sockaddr *) &addr, sizeof(addr)) == -1) - throw SysError(format("cannot connect to daemon at '%1%'") % socketPath); + throw SysError("cannot connect to daemon at '%1%'", socketPath); conn->from.fd = conn->fd.get(); conn->to.fd = conn->fd.get(); diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index f2e4b63e0..0326821f6 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -32,8 +32,10 @@ namespace nix { struct S3Error : public Error { Aws::S3::S3Errors err; - S3Error(Aws::S3::S3Errors err, const FormatOrString & fs) - : Error(fs), err(err) { }; + + template + S3Error(Aws::S3::S3Errors err, const Args & ... args) + : Error(args...), err(err) { }; }; /* Helper: given an Outcome, return R in case of success, or @@ -249,7 +251,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore // If bucket listing is disabled, 404s turn into 403s || error.GetErrorType() == Aws::S3::S3Errors::ACCESS_DENIED) return false; - throw Error(format("AWS error fetching '%s': %s") % path % error.GetMessage()); + throw Error("AWS error fetching '%s': %s", path, error.GetMessage()); } return true; diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index eb1daafc5..3407e5826 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -29,7 +29,7 @@ SQLite::SQLite(const Path & path, bool create) { if (sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK) - throw Error(format("cannot open SQLite database '%s'") % path); + throw Error("cannot open SQLite database '%s'", path); if (sqlite3_busy_timeout(db, 60 * 60 * 1000) != SQLITE_OK) throwSQLiteError(db, "setting timeout"); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index b9e894a9a..a04d5013e 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -22,7 +22,7 @@ bool Store::isInStore(const Path & path) const Path Store::toStorePath(const Path & path) const { if (!isInStore(path)) - throw Error(format("path '%1%' is not in the Nix store") % path); + throw Error("path '%1%' is not in the Nix store", path); Path::size_type slash = path.find('/', storeDir.size() + 1); if (slash == Path::npos) return path; @@ -40,7 +40,7 @@ Path Store::followLinksToStore(std::string_view _path) const path = absPath(target, dirOf(path)); } if (!isInStore(path)) - throw Error(format("path '%1%' is not in the Nix store") % path); + throw Error("path '%1%' is not in the Nix store", path); return path; } diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index db544a212..6a8484705 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -46,7 +46,7 @@ static void dumpContents(const Path & path, size_t size, sink << "contents" << size; AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (!fd) throw SysError(format("opening file '%1%'") % path); + if (!fd) throw SysError("opening file '%1%'", path); std::vector buf(65536); size_t left = size; @@ -68,7 +68,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter) struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting attributes of path '%1%'") % path); + throw SysError("getting attributes of path '%1%'", path); sink << "("; @@ -94,8 +94,9 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter) name.erase(pos); } if (unhacked.find(name) != unhacked.end()) - throw Error(format("file name collision in between '%1%' and '%2%'") - % (path + "/" + unhacked[name]) % (path + "/" + i.name)); + throw Error("file name collision in between '%1%' and '%2%'", + (path + "/" + unhacked[name]), + (path + "/" + i.name)); unhacked[name] = i.name; } else unhacked[i.name] = i.name; @@ -111,7 +112,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter) else if (S_ISLNK(st.st_mode)) sink << "type" << "symlink" << "target" << readLink(path); - else throw Error(format("file '%1%' has an unsupported type") % path); + else throw Error("file '%1%' has an unsupported type", path); sink << ")"; } @@ -247,7 +248,7 @@ static void parse(ParseSink & sink, Source & source, const Path & path) } else if (s == "name") { name = readString(source); if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos) - throw Error(format("NAR contains invalid file name '%1%'") % name); + throw Error("NAR contains invalid file name '%1%'", name); if (name <= prevName) throw Error("NAR directory is not sorted"); prevName = name; @@ -303,14 +304,14 @@ struct RestoreSink : ParseSink { Path p = dstPath + path; if (mkdir(p.c_str(), 0777) == -1) - throw SysError(format("creating directory '%1%'") % p); + throw SysError("creating directory '%1%'", p); }; void createRegularFile(const Path & path) { Path p = dstPath + path; fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666); - if (!fd) throw SysError(format("creating file '%1%'") % p); + if (!fd) throw SysError("creating file '%1%'", p); } void isExecutable() @@ -332,7 +333,7 @@ struct RestoreSink : ParseSink OpenSolaris). Since preallocation is just an optimisation, ignore it. */ if (errno && errno != EINVAL && errno != EOPNOTSUPP && errno != ENOSYS) - throw SysError(format("preallocating file of %1% bytes") % len); + throw SysError("preallocating file of %1% bytes", len); } #endif } diff --git a/src/libutil/args.cc b/src/libutil/args.cc index ba15ea571..4e705dd64 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -47,7 +47,7 @@ void Args::parseCmdline(const Strings & _cmdline) } else if (!dashDash && std::string(arg, 0, 1) == "-") { if (!processFlag(pos, cmdline.end())) - throw UsageError(format("unrecognised flag '%1%'") % arg); + throw UsageError("unrecognised flag '%1%'", arg); } else { pendingArgs.push_back(*pos++); @@ -104,8 +104,9 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end) for (size_t n = 0 ; n < flag.arity; ++n) { if (pos == end) { if (flag.arity == ArityAny) break; - throw UsageError(format("flag '%1%' requires %2% argument(s)") - % name % flag.arity); + throw UsageError("flag '%1%' requires %2% argument(s)", + name, + flag.arity); } args.push_back(*pos++); } @@ -133,7 +134,7 @@ bool Args::processArgs(const Strings & args, bool finish) { if (expectedArgs.empty()) { if (!args.empty()) - throw UsageError(format("unexpected argument '%1%'") % args.front()); + throw UsageError("unexpected argument '%1%'", args.front()); return true; } diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc index 860b04adb..a117ddc72 100644 --- a/src/libutil/compression.cc +++ b/src/libutil/compression.cc @@ -481,7 +481,7 @@ ref makeCompressionSink(const std::string & method, Sink & next else if (method == "br") return make_ref(nextSink); else - throw UnknownCompressionMethod(format("unknown compression method '%s'") % method); + throw UnknownCompressionMethod("unknown compression method '%s'", method); } ref compress(const std::string & method, const std::string & in, const bool parallel) diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh index 08edffee0..d65215063 100644 --- a/src/libutil/fmt.hh +++ b/src/libutil/fmt.hh @@ -92,15 +92,15 @@ public: { fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); } + hintformat(const hintformat &hf) + : fmt(hf.fmt) + {} template hintformat& operator%(const T &value) { fmt % yellowify(value); return *this; } - hintformat(const hintformat &hf) - : fmt(hf.fmt) - {} std::string str() const diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 633c6bdf7..2261adb82 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -93,7 +93,9 @@ public: template BaseError(unsigned int status, const Args & ... args) - : err(hintfmt(args...)) + : err { .level = lvlError, + .hint = hintfmt(args...) + } , status(status) { } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 332c1c43a..bffcbcccf 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -129,7 +129,7 @@ Path canonPath(const Path & path, bool resolveSymlinks) string s; if (path[0] != '/') - throw Error(format("not an absolute path: '%1%'") % path); + throw Error("not an absolute path: '%1%'", path); string::const_iterator i = path.begin(), end = path.end(); string temp; @@ -165,7 +165,7 @@ Path canonPath(const Path & path, bool resolveSymlinks) the symlink target might contain new symlinks). */ if (resolveSymlinks && isLink(s)) { if (++followCount >= maxFollow) - throw Error(format("infinite symlink recursion in path '%1%'") % path); + throw Error("infinite symlink recursion in path '%1%'", path); temp = absPath(readLink(s), dirOf(s)) + string(i, end); i = temp.begin(); /* restart */ @@ -226,7 +226,7 @@ struct stat lstat(const Path & path) { struct stat st; if (lstat(path.c_str(), &st)) - throw SysError(format("getting status of '%1%'") % path); + throw SysError("getting status of '%1%'", path); return st; } @@ -238,7 +238,7 @@ bool pathExists(const Path & path) res = lstat(path.c_str(), &st); if (!res) return true; if (errno != ENOENT && errno != ENOTDIR) - throw SysError(format("getting status of %1%") % path); + throw SysError("getting status of %1%", path); return false; } @@ -274,7 +274,7 @@ DirEntries readDirectory(const Path & path) entries.reserve(64); AutoCloseDir dir(opendir(path.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % path); + if (!dir) throw SysError("opening directory '%1%'", path); struct dirent * dirent; while (errno = 0, dirent = readdir(dir.get())) { /* sic */ @@ -289,7 +289,7 @@ DirEntries readDirectory(const Path & path) #endif ); } - if (errno) throw SysError(format("reading directory '%1%'") % path); + if (errno) throw SysError("reading directory '%1%'", path); return entries; } @@ -322,7 +322,7 @@ string readFile(const Path & path, bool drain) { AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); if (!fd) - throw SysError(format("opening file '%1%'") % path); + throw SysError("opening file '%1%'", path); return drain ? drainFD(fd.get()) : readFile(fd.get()); } @@ -339,7 +339,7 @@ void writeFile(const Path & path, const string & s, mode_t mode) { AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode); if (!fd) - throw SysError(format("opening file '%1%'") % path); + throw SysError("opening file '%1%'", path); writeFull(fd.get(), s); } @@ -348,7 +348,7 @@ void writeFile(const Path & path, Source & source, mode_t mode) { AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode); if (!fd) - throw SysError(format("opening file '%1%'") % path); + throw SysError("opening file '%1%'", path); std::vector buf(64 * 1024); @@ -396,7 +396,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) struct stat st; if (lstat(path.c_str(), &st) == -1) { if (errno == ENOENT) return; - throw SysError(format("getting status of '%1%'") % path); + throw SysError("getting status of '%1%'", path); } if (!S_ISDIR(st.st_mode) && st.st_nlink == 1) @@ -407,7 +407,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR; if ((st.st_mode & PERM_MASK) != PERM_MASK) { if (chmod(path.c_str(), st.st_mode | PERM_MASK) == -1) - throw SysError(format("chmod '%1%'") % path); + throw SysError("chmod '%1%'", path); } for (auto & i : readDirectory(path)) @@ -416,7 +416,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) if (remove(path.c_str()) == -1) { if (errno == ENOENT) return; - throw SysError(format("cannot unlink '%1%'") % path); + throw SysError("cannot unlink '%1%'", path); } } @@ -468,12 +468,12 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix, "wheel", then "tar" will fail to unpack archives that have the setgid bit set on directories. */ if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0) - throw SysError(format("setting group of directory '%1%'") % tmpDir); + throw SysError("setting group of directory '%1%'", tmpDir); #endif return tmpDir; } if (errno != EEXIST) - throw SysError(format("creating directory '%1%'") % tmpDir); + throw SysError("creating directory '%1%'", tmpDir); } } @@ -555,15 +555,15 @@ Paths createDirs(const Path & path) if (lstat(path.c_str(), &st) == -1) { created = createDirs(dirOf(path)); if (mkdir(path.c_str(), 0777) == -1 && errno != EEXIST) - throw SysError(format("creating directory '%1%'") % path); + throw SysError("creating directory '%1%'", path); st = lstat(path); created.push_back(path); } if (S_ISLNK(st.st_mode) && stat(path.c_str(), &st) == -1) - throw SysError(format("statting symlink '%1%'") % path); + throw SysError("statting symlink '%1%'", path); - if (!S_ISDIR(st.st_mode)) throw Error(format("'%1%' is not a directory") % path); + if (!S_ISDIR(st.st_mode)) throw Error("'%1%' is not a directory", path); return created; } @@ -572,7 +572,7 @@ Paths createDirs(const Path & path) void createSymlink(const Path & target, const Path & link) { if (symlink(target.c_str(), link.c_str())) - throw SysError(format("creating symlink from '%1%' to '%2%'") % link % target); + throw SysError("creating symlink from '%1%' to '%2%'", link, target); } @@ -589,7 +589,7 @@ void replaceSymlink(const Path & target, const Path & link) } if (rename(tmp.c_str(), link.c_str()) != 0) - throw SysError(format("renaming '%1%' to '%2%'") % tmp % link); + throw SysError("renaming '%1%' to '%2%'", tmp, link); break; } @@ -694,7 +694,7 @@ AutoDelete::~AutoDelete() deletePath(path); else { if (remove(path.c_str()) == -1) - throw SysError(format("cannot unlink '%1%'") % path); + throw SysError("cannot unlink '%1%'", path); } } } catch (...) { @@ -760,7 +760,7 @@ void AutoCloseFD::close() if (fd != -1) { if (::close(fd) == -1) /* This should never happen. */ - throw SysError(format("closing file descriptor %1%") % fd); + throw SysError("closing file descriptor %1%", fd); } } @@ -920,7 +920,7 @@ void killUser(uid_t uid) #endif if (errno == ESRCH) break; /* no more processes */ if (errno != EINTR) - throw SysError(format("cannot kill processes for uid '%1%'") % uid); + throw SysError("cannot kill processes for uid '%1%'", uid); } _exit(0); @@ -928,7 +928,7 @@ void killUser(uid_t uid) int status = pid.wait(); if (status != 0) - throw Error(format("cannot kill processes for uid '%1%': %2%") % uid % statusToString(status)); + throw Error("cannot kill processes for uid '%1%': %2%", uid, statusToString(status)); /* !!! We should really do some check to make sure that there are no processes left running under `uid', but there is no portable @@ -1322,7 +1322,7 @@ void ignoreException() try { throw; } catch (std::exception & e) { - printError(format("error (ignored): %1%") % e.what()); + printError("error (ignored): %1%", e.what()); } } @@ -1440,7 +1440,7 @@ void callFailure(const std::function & failure, st try { failure(exc); } catch (std::exception & e) { - printError(format("uncaught exception: %s") % e.what()); + printError("uncaught exception: %s", e.what()); abort(); } } diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index a2639579d..c403e3780 100755 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -37,7 +37,8 @@ static void writeChannels() { auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)}; if (!channelsFD) - throw SysError(format("opening '%1%' for writing") % channelsList); + throw Error(""); + // throw SysError("opening '%1%' for writing", channelsList); for (const auto & channel : channels) writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n"); } @@ -46,9 +47,11 @@ static void writeChannels() static void addChannel(const string & url, const string & name) { if (!regex_search(url, std::regex("^(file|http|https)://"))) - throw Error(format("invalid channel URL '%1%'") % url); + throw Error(""); + // throw Error("invalid channel URL '%1%'", url); if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$"))) - throw Error(format("invalid channel identifier '%1%'") % name); + throw Error(""); + // throw Error("invalid channel identifier '%1%'", name); readChannels(); channels[name] = url; writeChannels(); @@ -140,9 +143,11 @@ static void update(const StringSet & channelNames) if (S_ISLNK(st.st_mode)) // old-skool ~/.nix-defexpr if (unlink(nixDefExpr.c_str()) == -1) - throw SysError(format("unlinking %1%") % nixDefExpr); + throw Error(""); + // throw SysError("unlinking %1%", nixDefExpr); } else if (errno != ENOENT) { - throw SysError(format("getting status of %1%") % nixDefExpr); + throw Error(""); + // throw SysError("getting status of %1%", nixDefExpr); } createDirs(nixDefExpr); auto channelLink = nixDefExpr + "/channels"; @@ -194,10 +199,12 @@ static int _main(int argc, char ** argv) switch (cmd) { case cNone: - throw UsageError("no command specified"); + throw Error(""); + // throw UsageError("no command specified"); case cAdd: if (args.size() < 1 || args.size() > 2) - throw UsageError("'--add' requires one or two arguments"); + throw Error(""); + // throw UsageError("'--add' requires one or two arguments"); { auto url = args[0]; std::string name; @@ -213,12 +220,14 @@ static int _main(int argc, char ** argv) break; case cRemove: if (args.size() != 1) - throw UsageError("'--remove' requires one argument"); + throw Error(""); + // throw UsageError("'--remove' requires one argument"); removeChannel(args[0]); break; case cList: if (!args.empty()) - throw UsageError("'--list' expects no arguments"); + throw Error(""); + // throw UsageError("'--list' expects no arguments"); readChannels(); for (const auto & channel : channels) std::cout << channel.first << ' ' << channel.second << '\n'; @@ -228,7 +237,8 @@ static int _main(int argc, char ** argv) break; case cRollback: if (args.size() > 1) - throw UsageError("'--rollback' has at most one argument"); + throw Error(""); + // throw UsageError("'--rollback' has at most one argument"); Strings envArgs{"--profile", profile}; if (args.size() == 1) { envArgs.push_back("--switch-generation"); diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index e68d1b1be..5f78ab464 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -36,7 +36,7 @@ using namespace nix::daemon; #define SPLICE_F_MOVE 0 static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags) { - /* We ignore most parameters, we just have them for conformance with the linux syscall */ + // We ignore most parameters, we just have them for conformance with the linux syscall std::vector buf(8192); auto read_count = read(fd_in, buf.data(), buf.size()); if (read_count == -1) @@ -57,7 +57,7 @@ static void sigChldHandler(int sigNo) { // Ensure we don't modify errno of whatever we've interrupted auto saved_errno = errno; - /* Reap all dead children. */ + // Reap all dead children. while (waitpid(-1, 0, WNOHANG) > 0) ; errno = saved_errno; } @@ -106,7 +106,7 @@ struct PeerInfo }; -/* Get the identity of the caller, if possible. */ +// Get the identity of the caller, if possible. static PeerInfo getPeerInfo(int remote) { PeerInfo peer = { false, 0, false, 0, false, 0 }; @@ -154,13 +154,12 @@ static void daemonLoop(char * * argv) if (chdir("/") == -1) throw SysError("cannot change current directory"); - /* Get rid of children automatically; don't let them become - zombies. */ + // Get rid of children automatically; don't let them become zombies. setSigChldAction(true); AutoCloseFD fdSocket; - /* Handle socket-based activation by systemd. */ + // Handle socket-based activation by systemd. auto listenFds = getEnv("LISTEN_FDS"); if (listenFds) { if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1") @@ -169,17 +168,17 @@ static void daemonLoop(char * * argv) closeOnExec(fdSocket.get()); } - /* Otherwise, create and bind to a Unix domain socket. */ + // Otherwise, create and bind to a Unix domain socket. else { createDirs(dirOf(settings.nixDaemonSocketFile)); fdSocket = createUnixDomainSocket(settings.nixDaemonSocketFile, 0666); } - /* Loop accepting connections. */ + // Loop accepting connections. while (1) { try { - /* Accept a connection. */ + // Accept a connection. struct sockaddr_un remoteAddr; socklen_t remoteAddrLen = sizeof(remoteAddr); @@ -209,13 +208,13 @@ static void daemonLoop(char * * argv) trusted = Trusted; if ((!trusted && !matchUser(user, group, allowedUsers)) || group == settings.buildUsersGroup) - throw Error(format("user '%1%' is not allowed to connect to the Nix daemon") % user); + throw Error("user '%1%' is not allowed to connect to the Nix daemon", user); printInfo(format((string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : "")) % (peer.pidKnown ? std::to_string(peer.pid) : "") % (peer.uidKnown ? user : "")); - /* Fork a child to handle the connection. */ + // Fork a child to handle the connection. ProcessOptions options; options.errorPrefix = "unexpected Nix daemon error: "; options.dieWithParent = false; @@ -224,20 +223,20 @@ static void daemonLoop(char * * argv) startProcess([&]() { fdSocket = -1; - /* Background the daemon. */ + // Background the daemon. if (setsid() == -1) - throw SysError(format("creating a new session")); + throw SysError("creating a new session"); - /* Restore normal handling of SIGCHLD. */ + // Restore normal handling of SIGCHLD. setSigChldAction(false); - /* For debugging, stuff the pid into argv[1]. */ + // For debugging, stuff the pid into argv[1]. if (peer.pidKnown && argv[1]) { string processName = std::to_string(peer.pid); strncpy(argv[1], processName.c_str(), strlen(argv[1])); } - /* Handle the connection. */ + // Handle the connection. FdSource from(remote.get()); FdSink to(remote.get()); processConnection(openUncachedStore(), from, to, trusted, NotRecursive, user, peer.uid); @@ -248,7 +247,7 @@ static void daemonLoop(char * * argv) } catch (Interrupted & e) { return; } catch (Error & e) { - printError(format("error processing connection: %1%") % e.msg()); + printError("error processing connection: %1%", e.msg()); } } } @@ -261,7 +260,7 @@ static int _main(int argc, char * * argv) parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { if (*arg == "--daemon") - ; /* ignored for backwards compatibility */ + ; // ignored for backwards compatibility else if (*arg == "--help") showManPage("nix-daemon"); else if (*arg == "--version") @@ -276,7 +275,7 @@ static int _main(int argc, char * * argv) if (stdio) { if (getStoreType() == tDaemon) { - /* Forward on this connection to the real daemon */ + // Forward on this connection to the real daemon auto socketPath = settings.nixDaemonSocketFile; auto s = socket(PF_UNIX, SOCK_STREAM, 0); if (s == -1) @@ -284,17 +283,17 @@ static int _main(int argc, char * * argv) auto socketDir = dirOf(socketPath); if (chdir(socketDir.c_str()) == -1) - throw SysError(format("changing to socket directory '%1%'") % socketDir); + throw SysError("changing to socket directory '%1%'", socketDir); auto socketName = std::string(baseNameOf(socketPath)); auto addr = sockaddr_un{}; addr.sun_family = AF_UNIX; if (socketName.size() + 1 >= sizeof(addr.sun_path)) - throw Error(format("socket name %1% is too long") % socketName); + throw Error("socket name %1% is too long", socketName); strcpy(addr.sun_path, socketName.c_str()); if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1) - throw SysError(format("cannot connect to daemon at %1%") % socketPath); + throw SysError("cannot connect to daemon at %1%", socketPath); auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1; while (true) { diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 1a2bb42a3..dde8875f1 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -25,7 +25,6 @@ #include #include - using namespace nix; using std::cout; @@ -70,8 +69,7 @@ typedef void (* Operation) (Globals & globals, static string needArg(Strings::iterator & i, Strings & args, const string & arg) { - if (i == args.end()) throw UsageError( - format("'%1%' requires an argument") % arg); + if (i == args.end()) throw UsageError( "'%1%' requires an argument", arg); return *i++; } @@ -133,7 +131,7 @@ static void getAllExprs(EvalState & state, Value & vArg(*state.allocValue()); mkString(vArg, path2); if (v.attrs->size() == v.attrs->capacity()) - throw Error(format("too many Nix expressions in directory '%1%'") % path); + throw Error("too many Nix expressions in directory '%1%'", path); mkApp(*state.allocAttr(v, state.symbols.create(attrName)), vFun, vArg); } else if (S_ISDIR(st.st_mode)) @@ -144,11 +142,12 @@ static void getAllExprs(EvalState & state, } + static void loadSourceExpr(EvalState & state, const Path & path, Value & v) { struct stat st; if (stat(path.c_str(), &st) == -1) - throw SysError(format("getting information about '%1%'") % path); + throw SysError("getting inon about '%1%'", path); if (isNixExpr(path, st)) state.evalFile(path, v); @@ -221,7 +220,7 @@ static void checkSelectorUse(DrvNames & selectors) /* Check that all selectors have been used. */ for (auto & i : selectors) if (i.hits == 0 && i.fullName != "*") - throw Error(format("selector '%1%' matches no derivations") % i.fullName); + throw Error("selector '%1%' matches no derivations", i.fullName); } @@ -507,7 +506,7 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs) globals.preserveInstalled = true; else if (arg == "--remove-all" || arg == "-r") globals.removeAll = true; - else throw UsageError(format("unknown flag '%1%'") % arg); + else throw UsageError("unknown flag '%1%'", arg); } installDerivations(globals, opArgs, globals.profile); @@ -618,7 +617,7 @@ static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs) else if (arg == "--leq") upgradeType = utLeq; else if (arg == "--eq") upgradeType = utEq; else if (arg == "--always") upgradeType = utAlways; - else throw UsageError(format("unknown flag '%1%'") % arg); + else throw UsageError("unknown flag '%1%'", arg); } upgradeDerivations(globals, opArgs, upgradeType); @@ -637,7 +636,7 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv, static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() < 2) throw UsageError("not enough arguments to '--set-flag'"); @@ -680,7 +679,7 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs) for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { string arg = *i++; if (parseInstallSourceOptions(globals, i, opFlags, arg)) ; - else throw UsageError(format("unknown flag '%1%'") % arg); + else throw UsageError("unknown flag '%1%'", arg); } DrvInfos elems; @@ -748,7 +747,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors, static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); uninstallDerivations(globals, opArgs, globals.profile); } @@ -911,7 +910,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) else if (arg == "--attr" || arg == "-A") attrPath = needArg(i, opFlags, arg); else - throw UsageError(format("unknown flag '%1%'") % arg); + throw UsageError("unknown flag '%1%'", arg); } if (printAttrPath && source != sAvailable) @@ -1177,9 +1176,9 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() != 1) - throw UsageError(format("exactly one argument expected")); + throw UsageError("exactly one argument expected"); Path profile = absPath(opArgs.front()); Path profileLink = getHome() + "/.nix-profile"; @@ -1207,10 +1206,10 @@ static void switchGeneration(Globals & globals, int dstGen) if (!dst) { if (dstGen == prevGen) - throw Error(format("no generation older than the current (%1%) exists") - % curGen); + throw Error("no generation older than the current (%1%) exists", + curGen); else - throw Error(format("generation %1% does not exist") % dstGen); + throw Error("generation %1% does not exist", dstGen); } printInfo(format("switching from generation %1% to %2%") @@ -1225,13 +1224,13 @@ static void switchGeneration(Globals & globals, int dstGen) static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() != 1) - throw UsageError(format("exactly one argument expected")); + throw UsageError("exactly one argument expected"); int dstGen; if (!string2Int(opArgs.front(), dstGen)) - throw UsageError(format("expected a generation number")); + throw UsageError("expected a generation number"); switchGeneration(globals, dstGen); } @@ -1240,9 +1239,9 @@ static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArg static void opRollback(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() != 0) - throw UsageError(format("no arguments expected")); + throw UsageError("no arguments expected"); switchGeneration(globals, prevGen); } @@ -1251,9 +1250,9 @@ static void opRollback(Globals & globals, Strings opFlags, Strings opArgs) static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() != 0) - throw UsageError(format("no arguments expected")); + throw UsageError("no arguments expected"); PathLocks lock; lockProfile(lock, globals.profile); @@ -1278,7 +1277,7 @@ static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) - throw UsageError(format("unknown flag '%1%'") % opFlags.front()); + throw UsageError("unknown flag '%1%'", opFlags.front()); if (opArgs.size() == 1 && opArgs.front() == "old") { deleteOldGenerations(globals.profile, globals.dryRun); @@ -1286,18 +1285,18 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr deleteGenerationsOlderThan(globals.profile, opArgs.front(), globals.dryRun); } else if (opArgs.size() == 1 && opArgs.front().find('+') != string::npos) { if(opArgs.front().size() < 2) - throw Error(format("invalid number of generations ‘%1%’") % opArgs.front()); + throw Error("invalid number of generations ‘%1%’", opArgs.front()); string str_max = string(opArgs.front(), 1, opArgs.front().size()); int max; if (!string2Int(str_max, max) || max == 0) - throw Error(format("invalid number of generations to keep ‘%1%’") % opArgs.front()); + throw Error("invalid number of generations to keep ‘%1%’", opArgs.front()); deleteGenerationsGreaterThan(globals.profile, max, globals.dryRun); } else { std::set gens; for (auto & i : opArgs) { unsigned int n; if (!string2Int(i, n)) - throw UsageError(format("invalid generation number '%1%'") % i); + throw UsageError("invalid generation number '%1%'", i); gens.insert(n); } deleteGenerations(globals.profile, gens, globals.dryRun); diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 6c99d1181..bf353677a 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -66,7 +66,7 @@ void processExpr(EvalState & state, const Strings & attrPaths, /* What output do we want? */ string outputName = i.queryOutputName(); if (outputName == "") - throw Error(format("derivation '%1%' lacks an 'outputName' attribute ") % drvPath); + throw Error("derivation '%1%' lacks an 'outputName' attribute ", drvPath); if (gcRoot == "") printGCWarning(); @@ -166,7 +166,7 @@ static int _main(int argc, char * * argv) if (findFile) { for (auto & i : files) { Path p = state->findFile(i); - if (p == "") throw Error(format("unable to find '%1%'") % i); + if (p == "") throw Error("unable to find '%1%'", i); std::cout << p << std::endl; } return 0; diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc index 2b9254659..d3d05cc50 100644 --- a/src/nix-prefetch-url/nix-prefetch-url.cc +++ b/src/nix-prefetch-url/nix-prefetch-url.cc @@ -37,11 +37,11 @@ string resolveMirrorUri(EvalState & state, string uri) auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName)); if (mirrorList == vMirrors.attrs->end()) - throw Error(format("unknown mirror name '%1%'") % mirrorName); + throw Error("unknown mirror name '%1%'", mirrorName); state.forceList(*mirrorList->value); if (mirrorList->value->listSize() < 1) - throw Error(format("mirror URI '%1%' did not expand to anything") % uri); + throw Error("mirror URI '%1%' did not expand to anything", uri); string mirror = state.forceString(*mirrorList->value->listElems()[0]); return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1); @@ -73,7 +73,7 @@ static int _main(int argc, char * * argv) string s = getArg(*arg, arg, end); ht = parseHashType(s); if (ht == htUnknown) - throw UsageError(format("unknown hash type '%1%'") % s); + throw UsageError("unknown hash type '%1%'", s); } else if (*arg == "--print-path") printPath = true; @@ -151,7 +151,7 @@ static int _main(int argc, char * * argv) if (name.empty()) name = baseNameOf(uri); if (name.empty()) - throw Error(format("cannot figure out file name for '%1%'") % uri); + throw Error("cannot figure out file name for '%1%'", uri); /* If an expected hash is given, the file may already exist in the store. */ @@ -206,7 +206,7 @@ static int _main(int argc, char * * argv) hash = unpack ? hashPath(ht, tmpFile).first : hashFile(ht, tmpFile); if (expectedHash != Hash(ht) && expectedHash != hash) - throw Error(format("hash mismatch for '%1%'") % uri); + throw Error("hash mismatch for '%1%'", uri); /* Copy the file to the Nix store. FIXME: if RemoteStore implemented addToStoreFromDump() and downloadFile() diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index fcc00175a..e4dd9bc96 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs) else if (i == "--repair") buildMode = bmRepair; else if (i == "--check") buildMode = bmCheck; else if (i == "--ignore-unknown") ignoreUnknown = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); std::vector paths; for (auto & i : opArgs) @@ -178,7 +178,7 @@ static void opAddFixed(Strings opFlags, Strings opArgs) for (auto & i : opFlags) if (i == "--recursive") recursive = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (opArgs.empty()) throw UsageError("first argument must be hash algorithm"); @@ -198,10 +198,10 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs) for (auto i : opFlags) if (i == "--recursive") recursive = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (opArgs.size() != 3) - throw UsageError(format("'--print-fixed-path' requires three arguments")); + throw UsageError("'--print-fixed-path' requires three arguments"); Strings::iterator i = opArgs.begin(); HashType hashAlgo = parseHashType(*i++); @@ -296,9 +296,9 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (i == "--use-output" || i == "-u") useOutput = true; else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true; else if (i == "--include-outputs") includeOutputs = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (prev != qDefault && prev != query) - throw UsageError(format("query type '%1%' conflicts with earlier flag") % i); + throw UsageError("query type '%1%' conflicts with earlier flag", i); } if (query == qDefault) query = qOutputs; @@ -444,7 +444,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs) Derivation drv = store->derivationFromPath(store->parseStorePath(drvPath)); /* Print each environment variable in the derivation in a format - that can be sourced by the shell. */ + * that can be sourced by the shell. */ for (auto & i : drv.env) cout << format("export %1%; %1%=%2%\n") % i.first % shellEscape(i.second); @@ -531,7 +531,7 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs) for (auto & i : opFlags) if (i == "--reregister") reregister = true; else if (i == "--hash-given") hashGiven = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -545,7 +545,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs) for (auto & i : opFlags) if (i == "--print-invalid") printInvalid = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); for (auto & i : opArgs) { auto path = store->followLinksToStorePath(i); @@ -576,7 +576,7 @@ static void opGC(Strings opFlags, Strings opArgs) long long maxFreed = getIntArg(*i, i, opFlags.end(), true); options.maxFreed = maxFreed >= 0 ? maxFreed : 0; } - else throw UsageError(format("bad sub-operation '%1%' in GC") % *i); + else throw UsageError("bad sub-operation '%1%' in GC", *i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -612,7 +612,7 @@ static void opDelete(Strings opFlags, Strings opArgs) for (auto & i : opFlags) if (i == "--ignore-liveness") options.ignoreLiveness = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); for (auto & i : opArgs) options.pathsToDelete.insert(store->followLinksToStorePath(i)); @@ -650,7 +650,7 @@ static void opRestore(Strings opFlags, Strings opArgs) static void opExport(Strings opFlags, Strings opArgs) { for (auto & i : opFlags) - throw UsageError(format("unknown flag '%1%'") % i); + throw UsageError("unknown flag '%1%'", i); StorePathSet paths; @@ -666,7 +666,7 @@ static void opExport(Strings opFlags, Strings opArgs) static void opImport(Strings opFlags, Strings opArgs) { for (auto & i : opFlags) - throw UsageError(format("unknown flag '%1%'") % i); + throw UsageError("unknown flag '%1%'", i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -701,7 +701,7 @@ static void opVerify(Strings opFlags, Strings opArgs) for (auto & i : opFlags) if (i == "--check-contents") checkContents = true; else if (i == "--repair") repair = Repair; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (store->verifyStore(checkContents, repair)) { printError("warning: not all errors were fixed"); @@ -764,7 +764,7 @@ static void opServe(Strings opFlags, Strings opArgs) bool writeAllowed = false; for (auto & i : opFlags) if (i == "--write") writeAllowed = true; - else throw UsageError(format("unknown flag '%1%'") % i); + else throw UsageError("unknown flag '%1%'", i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -835,7 +835,7 @@ static void opServe(Strings opFlags, Strings opArgs) for (auto & p : willSubstitute) subs.emplace_back(p.clone()); store->buildPaths(subs); } catch (Error & e) { - printError(format("warning: %1%") % e.msg()); + printError("warning: %1%", e.msg()); } } @@ -906,7 +906,7 @@ static void opServe(Strings opFlags, Strings opArgs) if (!writeAllowed) throw Error("building paths is not allowed"); - auto drvPath = store->parseStorePath(readString(in)); // informational only + auto drvPath = store->parseStorePath(readString(in)); // inonal ony BasicDerivation drv; readDerivation(in, *store, drv); @@ -962,7 +962,7 @@ static void opServe(Strings opFlags, Strings opArgs) } default: - throw Error(format("unknown serve command %1%") % cmd); + throw Error("unknown serve command %1%", cmd); } out.flush(); @@ -973,7 +973,7 @@ static void opServe(Strings opFlags, Strings opArgs) static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs) { for (auto & i : opFlags) - throw UsageError(format("unknown flag '%1%'") % i); + throw UsageError("unknown flag '%1%'", i); if (opArgs.size() != 3) throw UsageError("three arguments expected"); auto i = opArgs.begin(); diff --git a/src/nix/cat.cc b/src/nix/cat.cc index 851f90abd..4e14f50ed 100644 --- a/src/nix/cat.cc +++ b/src/nix/cat.cc @@ -13,9 +13,9 @@ struct MixCat : virtual Args { auto st = accessor->stat(path); if (st.type == FSAccessor::Type::tMissing) - throw Error(format("path '%1%' does not exist") % path); + throw Error("path '%1%' does not exist", path); if (st.type != FSAccessor::Type::tRegular) - throw Error(format("path '%1%' is not a regular file") % path); + throw Error("path '%1%' is not a regular file", path); std::cout << accessor->readFile(path); } diff --git a/src/nix/hash.cc b/src/nix/hash.cc index 0cc523f50..128708339 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -126,7 +126,7 @@ static int compatNixHash(int argc, char * * argv) string s = getArg(*arg, arg, end); ht = parseHashType(s); if (ht == htUnknown) - throw UsageError(format("unknown hash type '%1%'") % s); + throw UsageError("unknown hash type '%1%'", s); } else if (*arg == "--to-base16") op = opTo16; else if (*arg == "--to-base32") op = opTo32; diff --git a/src/nix/ls.cc b/src/nix/ls.cc index 3ef1f2750..5d55bd4d5 100644 --- a/src/nix/ls.cc +++ b/src/nix/ls.cc @@ -65,7 +65,7 @@ struct MixLs : virtual Args, MixJSON auto st = accessor->stat(path); if (st.type == FSAccessor::Type::tMissing) - throw Error(format("path '%1%' does not exist") % path); + throw Error("path '%1%' does not exist", path); doPath(st, path, st.type == FSAccessor::Type::tDirectory ? "." : std::string(baseNameOf(path)), showDirectory); diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 27727bd25..c770fd4a4 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -252,12 +252,12 @@ void NixRepl::mainLoop(const std::vector & files) // input without clearing the input so far. continue; } else { - printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); + printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); } } catch (Error & e) { - printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); + printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); } catch (Interrupted & e) { - printMsg(lvlError, format(error + "%1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); + printMsg(lvlError, error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); } // We handled the current input fully, so we should clear it @@ -546,7 +546,7 @@ bool NixRepl::processLine(string line) return false; else if (command != "") - throw Error(format("unknown command '%1%'") % command); + throw Error("unknown command '%1%'", command); else { size_t p = line.find('='); diff --git a/src/nix/run.cc b/src/nix/run.cc index 8e30264c0..d790979a4 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -197,10 +197,10 @@ void chrootHelper(int argc, char * * argv) Finally freeCwd([&]() { free(cwd); }); if (chroot(tmpDir.c_str()) == -1) - throw SysError(format("chrooting into '%s'") % tmpDir); + throw SysError("chrooting into '%s'", tmpDir); if (chdir(cwd) == -1) - throw SysError(format("chdir to '%s' in chroot") % cwd); + throw SysError("chdir to '%s' in chroot", cwd); } else if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1) throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir); -- cgit v1.2.3 From 3bc9155dfc14434f5e9566fd15c79141899f6d07 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Apr 2020 15:00:11 -0600 Subject: a few more 'format's rremoved --- src/libexpr/lexer.l | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index c34e5c383..85376a08f 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -127,14 +127,14 @@ or { return OR_KW; } try { yylval->n = boost::lexical_cast(yytext); } catch (const boost::bad_lexical_cast &) { - throw ParseError(format("invalid integer '%1%'") % yytext); + throw ParseError("invalid integer '%1%'", yytext); } return INT; } {FLOAT} { errno = 0; yylval->nf = strtod(yytext, 0); if (errno != 0) - throw ParseError(format("invalid float '%1%'") % yytext); + throw ParseError("invalid float '%1%'", yytext); return FLOAT; } -- cgit v1.2.3 From 833501f6f11095ae226c13948eb3dc1de2a246ea Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Apr 2020 15:55:34 -0600 Subject: 'what' string --- src/libutil/types.hh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 2261adb82..141bc6b3c 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -88,6 +88,13 @@ class BaseError : public std::exception protected: string prefix_; // used for location traces etc. ErrorInfo err; + string what_; + void initWhat() + { + std::ostringstream oss; + oss << err; + what_ = oss.str(); + } public: unsigned int status = 1; // exit status @@ -97,30 +104,27 @@ public: .hint = hintfmt(args...) } , status(status) - { - } + { initWhat(); } template BaseError(const Args & ... args) : err { .level = lvlError, .hint = hintfmt(args...) } - { - } + { initWhat(); } BaseError(ErrorInfo e) : err(e) - { - } + { initWhat(); } #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() const throw () { return err.description.c_str(); } + const char * what() const throw () { return what_.c_str(); } #else - const char * what() const noexcept { return err.description.c_str(); } + const char * what() const noexcept { return what_.c_str(); } #endif - const string & msg() const { return err.description; } + const string & msg() const { return what_; } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); -- cgit v1.2.3 From d9632765a81604d270bf4693bddd53c22ee189d4 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 24 Apr 2020 12:44:23 -0600 Subject: add has_value check; remove obslete friend class --- src/libutil/error.cc | 2 +- src/libutil/fmt.hh | 5 ++--- src/libutil/logging.hh | 9 +++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 41595b0df..c6bca7135 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -162,7 +162,7 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) out << prefix << std::endl; // lines of code. - if (einfo.nixCode->errLineOfCode != "") { + if (einfo.nixCode.has_value() && einfo.nixCode->errLineOfCode != "") { printCodeLines(prefix, *einfo.nixCode); out << prefix << std::endl; } diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh index d65215063..d182adc3a 100644 --- a/src/libutil/fmt.hh +++ b/src/libutil/fmt.hh @@ -92,9 +92,11 @@ public: { fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); } + hintformat(const hintformat &hf) : fmt(hf.fmt) {} + template hintformat& operator%(const T &value) { @@ -102,14 +104,11 @@ public: return *this; } - std::string str() const { return fmt.str(); } - template - friend class AddHint; private: format fmt; }; diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 8269e2e1a..89fd98419 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -62,11 +62,12 @@ public: virtual void logEI(const ErrorInfo &ei) = 0; - void logEI(Verbosity lvl, ErrorInfo ei) { - ei.level = lvl; - logEI(ei); + void logEI(Verbosity lvl, ErrorInfo ei) + { + ei.level = lvl; + logEI(ei); } - + virtual void warn(const std::string & msg); virtual void startActivity(ActivityId act, Verbosity lvl, ActivityType type, -- cgit v1.2.3 From d8d4844b883dcea67cccb9bd75eecb14e60ae496 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 24 Apr 2020 14:57:51 -0600 Subject: all things error to error.hh --- src/libmain/shared.cc | 9 ++- src/libutil/error.cc | 18 ++++++ src/libutil/types.hh | 151 ++------------------------------------------------ src/libutil/util.cc | 18 ------ src/libutil/util.hh | 1 + 5 files changed, 30 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index f7ab56271..8551eb048 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -281,6 +281,8 @@ int handleExceptions(const string & programName, std::function fun) { ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this + ErrorInfo::programName = programName; + string error = ANSI_RED "error:" ANSI_NORMAL " "; try { try { @@ -296,12 +298,15 @@ int handleExceptions(const string & programName, std::function fun) } catch (Exit & e) { return e.status; } catch (UsageError & e) { + // TODO: switch to logError + // logError(e.info()); printError( - format(error + "%1%\nTry '%2% --help' for more information.") + format("%1%\nTry '%2% --help' for more information.") % e.what() % programName); return 1; } catch (BaseError & e) { - printError(error + "%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); + // logError(e.info()); + printError("%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); if (e.prefix() != "" && !settings.showTrace) printError("(use '--show-trace' to show detailed location information)"); return e.status; diff --git a/src/libutil/error.cc b/src/libutil/error.cc index c6bca7135..20b97ea3d 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -7,6 +7,24 @@ namespace nix { + +const std::string nativeSystem = SYSTEM; + + +BaseError & BaseError::addPrefix(const FormatOrString & fs) +{ + prefix_ = fs.s + prefix_; + return *this; +} + + +std::string SysError::addErrno(const std::string & s) +{ + errNo = errno; + return s + ": " + strerror(errNo); +} + + std::optional ErrorInfo::programName = std::nullopt; std::ostream& operator<<(std::ostream &os, const hintformat &hf) diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 141bc6b3c..f11256f61 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -5,20 +5,8 @@ #include #include -#include #include -#include -#include "fmt.hh" - -/* Before 4.7, gcc's std::exception uses empty throw() specifiers for - * its (virtual) destructor and what() in c++11 mode, in violation of spec - */ -#ifdef __GNUC__ -#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -#define EXCEPTION_NEEDS_THROW_SPEC -#endif -#endif namespace nix { @@ -26,144 +14,13 @@ using std::list; using std::set; using std::vector; -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - -struct ErrPos -{ - int line; - int column; - string file; - - template - ErrPos& operator=(const P &pos) - { - line = pos.line; - column = pos.column; - file = pos.file; - return *this; - } - - template - ErrPos(const P &p) - { - *this = p; - } -}; - -struct NixCode -{ - ErrPos errPos; - std::optional prevLineOfCode; - string errLineOfCode; - std::optional nextLineOfCode; -}; - -// ------------------------------------------------- -// ErrorInfo. -struct ErrorInfo -{ - Verbosity level; - string name; - string description; - std::optional hint; - std::optional nixCode; - - static std::optional programName; -}; - -std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); - -/* BaseError should generally not be caught, as it has Interrupted as - a subclass. Catch Error instead. */ -class BaseError : public std::exception -{ -protected: - string prefix_; // used for location traces etc. - ErrorInfo err; - string what_; - void initWhat() - { - std::ostringstream oss; - oss << err; - what_ = oss.str(); - } -public: - unsigned int status = 1; // exit status - - template - BaseError(unsigned int status, const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(args...) - } - , status(status) - { initWhat(); } - - template - BaseError(const Args & ... args) - : err { .level = lvlError, - .hint = hintfmt(args...) - } - { initWhat(); } - - BaseError(ErrorInfo e) - : err(e) - { initWhat(); } - -#ifdef EXCEPTION_NEEDS_THROW_SPEC - ~BaseError() throw () { }; - const char * what() const throw () { return what_.c_str(); } -#else - const char * what() const noexcept { return what_.c_str(); } -#endif - - const string & msg() const { return what_; } - const string & prefix() const { return prefix_; } - BaseError & addPrefix(const FormatOrString & fs); - - const ErrorInfo & info() const { return err; } -}; - -#define MakeError(newClass, superClass) \ - class newClass : public superClass \ - { \ - public: \ - using superClass::superClass; \ - } - -MakeError(Error, BaseError); - -class SysError : public Error -{ -public: - int errNo; - - template - SysError(const Args & ... args) - : Error(args...) // TODO addErrNo for hintfmt - // : Error(addErrno(hintfmt(args...))) - { } - -private: - - std::string addErrno(const std::string & s); -}; - - -typedef list Strings; -typedef set StringSet; +typedef list Strings; +typedef set StringSet; typedef std::map StringMap; - /* Paths are just strings. */ -typedef string Path; + +typedef std::string Path; typedef list Paths; typedef set PathSet; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index bffcbcccf..747a9e991 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -40,24 +40,6 @@ extern char * * environ; namespace nix { - -const std::string nativeSystem = SYSTEM; - - -BaseError & BaseError::addPrefix(const FormatOrString & fs) -{ - prefix_ = fs.s + prefix_; - return *this; -} - - -std::string SysError::addErrno(const std::string & s) -{ - errNo = errno; - return s + ": " + strerror(errNo); -} - - std::optional getEnv(const std::string & key) { char * value = getenv(key.c_str()); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 636f3ba6c..978e14a30 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -1,6 +1,7 @@ #pragma once #include "types.hh" +#include "error.hh" #include "logging.hh" #include "ansicolor.hh" -- cgit v1.2.3 From cdac083dc54b65f66f88caf193c617c1dbf3bbd6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 24 Apr 2020 21:40:13 -0600 Subject: don't print blank lines for blank description --- src/libutil/error.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 20b97ea3d..c800fe9a8 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -88,7 +88,7 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) { int errwidth = 80; - string prefix = " "; + string prefix = ""; string levelString; switch (einfo.level) { @@ -176,8 +176,10 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) } // description - out << prefix << einfo.description << std::endl; - out << prefix << std::endl; + if (einfo.description != "") { + out << prefix << einfo.description << std::endl; + out << prefix << std::endl; + } // lines of code. if (einfo.nixCode.has_value() && einfo.nixCode->errLineOfCode != "") { -- cgit v1.2.3 From d4fd7b543ee8dcea2a06c2f857b7e4dd72d34ccc Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 25 Apr 2020 12:05:26 -0600 Subject: print dashes instead of empty name string --- src/libutil/error.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index c800fe9a8..2c34325ac 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -148,14 +148,21 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) dashes.append("-"); // divider. - out << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, - prefix, - levelString, - "---", - einfo.name, - dashes, - einfo.programName.value_or("")) - << std::endl; + if (einfo.name != "") + out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, + prefix, + levelString, + einfo.name, + dashes, + einfo.programName.value_or("")) + << std::endl; + else + out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, + prefix, + levelString, + dashes, + einfo.programName.value_or("")) + << std::endl; // filename. if (einfo.nixCode.has_value()) { -- cgit v1.2.3 From 1ff42722ce44f485c7dfabc6bb370494080f2755 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 26 Apr 2020 14:47:41 -0600 Subject: error.hh --- src/libutil/error.hh | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/libutil/error.hh (limited to 'src') diff --git a/src/libutil/error.hh b/src/libutil/error.hh new file mode 100644 index 000000000..e33b1d3d6 --- /dev/null +++ b/src/libutil/error.hh @@ -0,0 +1,157 @@ +#pragma once + + +#include "ref.hh" + +#include +#include +#include +#include + +#include "fmt.hh" + +/* Before 4.7, gcc's std::exception uses empty throw() specifiers for + * its (virtual) destructor and what() in c++11 mode, in violation of spec + */ +#ifdef __GNUC__ +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#define EXCEPTION_NEEDS_THROW_SPEC +#endif +#endif + +namespace nix { + +using std::list; +using std::vector; + +typedef enum { + lvlError = 0, + lvlWarn, + lvlInfo, + lvlTalkative, + lvlChatty, + lvlDebug, + lvlVomit +} Verbosity; + +struct ErrPos +{ + int line; + int column; + string file; + + template + ErrPos& operator=(const P &pos) + { + line = pos.line; + column = pos.column; + file = pos.file; + return *this; + } + + template + ErrPos(const P &p) + { + *this = p; + } +}; + +struct NixCode +{ + ErrPos errPos; + std::optional prevLineOfCode; + string errLineOfCode; + std::optional nextLineOfCode; +}; + +// ------------------------------------------------- +// ErrorInfo. +struct ErrorInfo +{ + Verbosity level; + string name; + string description; + std::optional hint; + std::optional nixCode; + + static std::optional programName; +}; + +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); + +/* BaseError should generally not be caught, as it has Interrupted as + a subclass. Catch Error instead. */ +class BaseError : public std::exception +{ +protected: + string prefix_; // used for location traces etc. + ErrorInfo err; + string what_; + void initWhat() + { + std::ostringstream oss; + oss << err; + what_ = oss.str(); + } +public: + unsigned int status = 1; // exit status + + template + BaseError(unsigned int status, const Args & ... args) + : err { .level = lvlError, + .hint = hintfmt(args...) + } + , status(status) + { initWhat(); } + + template + BaseError(const Args & ... args) + : err { .level = lvlError, + .hint = hintfmt(args...) + } + { initWhat(); } + + BaseError(ErrorInfo e) + : err(e) + { initWhat(); } + +#ifdef EXCEPTION_NEEDS_THROW_SPEC + ~BaseError() throw () { }; + const char * what() const throw () { return what_.c_str(); } +#else + const char * what() const noexcept { return what_.c_str(); } +#endif + + const string & msg() const { return what_; } + const string & prefix() const { return prefix_; } + BaseError & addPrefix(const FormatOrString & fs); + + const ErrorInfo & info() const { return err; } +}; + +#define MakeError(newClass, superClass) \ + class newClass : public superClass \ + { \ + public: \ + using superClass::superClass; \ + } + +MakeError(Error, BaseError); + +class SysError : public Error +{ +public: + int errNo; + + template + SysError(const Args & ... args) + : Error(args...) // TODO addErrNo for hintfmt + // : Error(addErrno(hintfmt(args...))) + { } + +private: + + std::string addErrno(const std::string & s); +}; + +} -- cgit v1.2.3 From e51a757720ade58e48128730134400cf12f54851 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Apr 2020 15:15:08 -0600 Subject: astyle format --- src/libutil/error.hh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libutil/error.hh b/src/libutil/error.hh index e33b1d3d6..b715c3e45 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -24,7 +24,8 @@ namespace nix { using std::list; using std::vector; -typedef enum { +typedef enum +{ lvlError = 0, lvlWarn, lvlInfo, @@ -52,7 +53,7 @@ struct ErrPos template ErrPos(const P &p) { - *this = p; + *this = p; } }; @@ -87,7 +88,7 @@ protected: string prefix_; // used for location traces etc. ErrorInfo err; string what_; - void initWhat() + void initWhat() { std::ostringstream oss; oss << err; @@ -106,7 +107,7 @@ public: template BaseError(const Args & ... args) - : err { .level = lvlError, + : err { .level = lvlError, .hint = hintfmt(args...) } { initWhat(); } @@ -146,7 +147,7 @@ public: template SysError(const Args & ... args) : Error(args...) // TODO addErrNo for hintfmt - // : Error(addErrno(hintfmt(args...))) + // : Error(addErrno(hintfmt(args...))) { } private: -- cgit v1.2.3 From 22e6490311015e076a09d5608834bd0dec1d7020 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 28 Apr 2020 21:06:08 -0600 Subject: Error classname as name --- src/error-demo/error-demo.cc | 16 +++++++++++---- src/libstore/sqlite.cc | 2 +- src/libstore/sqlite.hh | 2 +- src/libutil/error.cc | 29 +++++++++++++-------------- src/libutil/error.hh | 47 +++++++++++++++++++++++++------------------- 5 files changed, 55 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 14027278d..98018ca0e 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -4,10 +4,12 @@ #include #include +using namespace nix; + +MakeError(DemoError, Error); + int main() { - using namespace nix; - makeDefaultLogger(); verbosity = lvlVomit; @@ -15,6 +17,12 @@ int main() // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); + try { + throw DemoError("demo error was thrown"); + } catch (Error &e) { + logger->logEI(e.info()); + } + // For completeness sake, info through vomit levels. // But this is maybe a heavy format for those. logger->logEI( @@ -79,7 +87,7 @@ int main() .prevLineOfCode = std::nullopt, .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::nullopt - }}); + }}); // Error with previous and next lines of code. logError( @@ -93,7 +101,7 @@ int main() .prevLineOfCode = std::optional("previous line of code"), .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::optional("next line of code"), - }}); + }}); return 0; diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 3407e5826..a72cd5d88 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -196,7 +196,7 @@ SQLiteTxn::~SQLiteTxn() } } -void handleSQLiteBusy(const SQLiteBusy & e) +void handleSQLiteBusy(SQLiteBusy & e) { static std::atomic lastWarned{0}; diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index fd04c9b07..ce27033c9 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -99,7 +99,7 @@ MakeError(SQLiteBusy, SQLiteError); [[noreturn]] void throwSQLiteError(sqlite3 * db, const FormatOrString & fs); -void handleSQLiteBusy(const SQLiteBusy & e); +void handleSQLiteBusy(SQLiteBusy & e); /* Convenience function for retrying a SQLite transaction when the database is busy. */ diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 2c34325ac..8f0e0aa1a 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -4,8 +4,7 @@ #include #include "serialise.hh" -namespace nix -{ +namespace nix { const std::string nativeSystem = SYSTEM; @@ -149,20 +148,20 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) // divider. if (einfo.name != "") - out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, - prefix, - levelString, - einfo.name, - dashes, - einfo.programName.value_or("")) - << std::endl; + out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, + prefix, + levelString, + einfo.name, + dashes, + einfo.programName.value_or("")) + << std::endl; else - out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, - prefix, - levelString, - dashes, - einfo.programName.value_or("")) - << std::endl; + out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, + prefix, + levelString, + dashes, + einfo.programName.value_or("")) + << std::endl; // filename. if (einfo.nixCode.has_value()) { diff --git a/src/libutil/error.hh b/src/libutil/error.hh index b715c3e45..03e43241f 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -24,8 +24,7 @@ namespace nix { using std::list; using std::vector; -typedef enum -{ +typedef enum { lvlError = 0, lvlWarn, lvlInfo, @@ -35,8 +34,7 @@ typedef enum lvlVomit } Verbosity; -struct ErrPos -{ +struct ErrPos { int line; int column; string file; @@ -57,8 +55,7 @@ struct ErrPos } }; -struct NixCode -{ +struct NixCode { ErrPos errPos; std::optional prevLineOfCode; string errLineOfCode; @@ -67,8 +64,7 @@ struct NixCode // ------------------------------------------------- // ErrorInfo. -struct ErrorInfo -{ +struct ErrorInfo { Verbosity level; string name; string description; @@ -87,12 +83,20 @@ class BaseError : public std::exception protected: string prefix_; // used for location traces etc. ErrorInfo err; - string what_; - void initWhat() + std::optional what_; + const string& calcWhat() { - std::ostringstream oss; - oss << err; - what_ = oss.str(); + if (what_.has_value()) + return *what_; + else { + err.name = sname(); + + std::ostringstream oss; + oss << err; + what_ = oss.str(); + + return *what_; + } } public: unsigned int status = 1; // exit status @@ -103,31 +107,33 @@ public: .hint = hintfmt(args...) } , status(status) - { initWhat(); } + { } template BaseError(const Args & ... args) : err { .level = lvlError, .hint = hintfmt(args...) } - { initWhat(); } + { } BaseError(ErrorInfo e) : err(e) - { initWhat(); } + { } + + virtual const char* sname() const { return "BaseError"; } #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() const throw () { return what_.c_str(); } + const char * what() throw () { return calcWhat().c_str(); } #else - const char * what() const noexcept { return what_.c_str(); } + const char * what() noexcept { return calcWhat().c_str(); } #endif - const string & msg() const { return what_; } + const string & msg() { return calcWhat(); } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); - const ErrorInfo & info() const { return err; } + const ErrorInfo & info() { calcWhat(); return err; } }; #define MakeError(newClass, superClass) \ @@ -135,6 +141,7 @@ public: { \ public: \ using superClass::superClass; \ + virtual const char* sname() const override { return #newClass; } \ } MakeError(Error, BaseError); -- cgit v1.2.3 From e2f61263ebf41958f4f3d6f6135377024e33457c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 29 Apr 2020 10:14:32 -0600 Subject: uncrustify formatting --- src/error-demo/error-demo.cc | 26 ++++++++++++------------ src/libexpr/nixexpr.hh | 3 ++- src/libutil/error.cc | 48 ++++++++++++++++++++++---------------------- src/libutil/logging.cc | 42 ++++++++++++++++++-------------------- src/libutil/logging.hh | 4 ++-- 5 files changed, 61 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 98018ca0e..437a761c4 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -29,38 +29,38 @@ int main() ErrorInfo { .level = lvlInfo, .name = "Info name", .description = "Info description", - }); + }); logger->logEI( ErrorInfo { .level = lvlTalkative, .name = "Talkative name", .description = "Talkative description", - }); + }); logger->logEI( ErrorInfo { .level = lvlChatty, .name = "Chatty name", .description = "Chatty description", - }); + }); logger->logEI( ErrorInfo { .level = lvlDebug, .name = "Debug name", .description = "Debug description", - }); + }); logger->logEI( ErrorInfo { .level = lvlVomit, .name = "Vomit name", .description = "Vomit description", - }); + }); // Error in a program; no hint and no nix code. logError( ErrorInfo { .name = "name", .description = "error description", - }); + }); // Warning with name, description, and hint. // The hintfmt function makes all the substituted text yellow. @@ -68,7 +68,7 @@ int main() ErrorInfo { .name = "name", .description = "error description", .hint = hintfmt("there was a %1%", "warning"), - }); + }); // Warning with nix file, line number, column, and the lines of @@ -80,28 +80,28 @@ int main() ErrorInfo { .name = "warning name", .description = "warning description", .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), + "yellow", + "values"), .nixCode = NixCode { .errPos = Pos(problem_file, 40, 13), .prevLineOfCode = std::nullopt, .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::nullopt - }}); + }}); // Error with previous and next lines of code. logError( ErrorInfo { .name = "error name", .description = "error description", .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), + "yellow", + "values"), .nixCode = NixCode { .errPos = Pos(problem_file, 40, 13), .prevLineOfCode = std::optional("previous line of code"), .errLineOfCode = "this is the problem line of code", .nextLineOfCode = std::optional("next line of code"), - }}); + }}); return 0; diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 79e3f90e5..a8bae0a61 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -234,7 +234,8 @@ struct ExprLambda : Expr : pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body) { if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end()) - throw ParseError("duplicate formal function argument '%1%' at %2%", arg, pos); }; + throw ParseError("duplicate formal function argument '%1%' at %2%", arg, pos); + }; void setName(Symbol & name); string showNamePos() const; COMMON_METHODS diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 8f0e0aa1a..91fa1ccd8 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -45,17 +45,17 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) // previous line of code. if (nixCode.prevLineOfCode.has_value()) { std::cout << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line - 1), - *nixCode.prevLineOfCode) + prefix, + (nixCode.errPos.line - 1), + *nixCode.prevLineOfCode) << std::endl; } // line of code containing the error.%2$+5d% std::cout << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line), - nixCode.errLineOfCode) + prefix, + (nixCode.errPos.line), + nixCode.errLineOfCode) << std::endl; // error arrows for the column range. @@ -69,17 +69,17 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) std::string arrows("^"); std::cout << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, - prefix, - spaces, - arrows) << std::endl; + prefix, + spaces, + arrows) << std::endl; } // next line of code. if (nixCode.nextLineOfCode.has_value()) { std::cout << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line + 1), - *nixCode.nextLineOfCode) + prefix, + (nixCode.errPos.line + 1), + *nixCode.nextLineOfCode) << std::endl; } } @@ -149,18 +149,18 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) // divider. if (einfo.name != "") out << fmt("%1%%2%" ANSI_BLUE " --- %3% %4% %5%" ANSI_NORMAL, - prefix, - levelString, - einfo.name, - dashes, - einfo.programName.value_or("")) + prefix, + levelString, + einfo.name, + dashes, + einfo.programName.value_or("")) << std::endl; else out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, - prefix, - levelString, - dashes, - einfo.programName.value_or("")) + prefix, + levelString, + dashes, + einfo.programName.value_or("")) << std::endl; // filename. @@ -171,9 +171,9 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) : ""; out << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, - prefix, - einfo.nixCode->errPos.file, - eline) << std::endl; + prefix, + einfo.nixCode->errPos.file, + eline) << std::endl; out << prefix << std::endl; } else { out << fmt("%1%from command line argument", prefix) << std::endl; diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 4a8b98640..e1750eb2a 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -60,7 +60,7 @@ public: void logEI(const ErrorInfo & ei) override { - std::stringstream oss; + std::stringstream oss; oss << ei; log(ei.level, oss.str()); @@ -68,7 +68,7 @@ public: void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) - override + override { if (lvl <= verbosity && !s.empty()) log(lvl, s + "..."); @@ -111,8 +111,7 @@ Activity::Activity(Logger & logger, Verbosity lvl, ActivityType type, logger.startActivity(id, lvl, type, s, fields, parent); } -struct JSONLogger : Logger -{ +struct JSONLogger : Logger { Logger & prevLogger; JSONLogger(Logger & prevLogger) : prevLogger(prevLogger) { } @@ -155,28 +154,26 @@ struct JSONLogger : Logger json["level"] = ei.level; json["msg"] = oss.str(); - // Extra things that COULD go into json. Useful? + // Extra things that COULD go into json. Useful? // TODO: decide if useful. // TODO: make a json obj that goes into json["msg"]? json["name"] = ei.name; json["description"] = ei.description; - if (ei.hint.has_value()) - { - json["hint"] = ei.hint->str(); + if (ei.hint.has_value()) { + json["hint"] = ei.hint->str(); } - if (ei.nixCode.has_value()) - { - if (ei.nixCode->errPos.line != 0) - json["line"] = ei.nixCode->errPos.line; - if (ei.nixCode->errPos.column != 0) - json["column"] = ei.nixCode->errPos.column; - if (ei.nixCode->errPos.file != "") - json["file"] = ei.nixCode->errPos.file; - if (ei.nixCode->prevLineOfCode.has_value()) - json["prevLineOfCode"] = *ei.nixCode->prevLineOfCode; - json["errLineOfCode"] = ei.nixCode->errLineOfCode; - if (ei.nixCode->nextLineOfCode.has_value()) - json["nextLineOfCode"] = *ei.nixCode->nextLineOfCode; + if (ei.nixCode.has_value()) { + if (ei.nixCode->errPos.line != 0) + json["line"] = ei.nixCode->errPos.line; + if (ei.nixCode->errPos.column != 0) + json["column"] = ei.nixCode->errPos.column; + if (ei.nixCode->errPos.file != "") + json["file"] = ei.nixCode->errPos.file; + if (ei.nixCode->prevLineOfCode.has_value()) + json["prevLineOfCode"] = *ei.nixCode->prevLineOfCode; + json["errLineOfCode"] = ei.nixCode->errLineOfCode; + if (ei.nixCode->nextLineOfCode.has_value()) + json["nextLineOfCode"] = *ei.nixCode->nextLineOfCode; } write(json); @@ -278,7 +275,8 @@ bool handleJSONLogMessage(const std::string & msg, return true; } -Activity::~Activity() { +Activity::~Activity() +{ try { logger.stopActivity(id); } catch (...) { diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 89fd98419..0c4980b83 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -62,12 +62,12 @@ public: virtual void logEI(const ErrorInfo &ei) = 0; - void logEI(Verbosity lvl, ErrorInfo ei) + void logEI(Verbosity lvl, ErrorInfo ei) { ei.level = lvl; logEI(ei); } - + virtual void warn(const std::string & msg); virtual void startActivity(ActivityId act, Verbosity lvl, ActivityType type, -- cgit v1.2.3 From 39ff80d031c5c9c1831ba5ea597c0de0181bfe34 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 29 Apr 2020 18:57:05 -0600 Subject: errorinfo constructor test --- src/error-demo/error-demo.cc | 10 ++++++++++ src/libstore/binary-cache-store.cc | 2 +- src/libstore/remote-store.cc | 2 +- src/libutil/error.hh | 7 ++++--- 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 437a761c4..2c4f2da6e 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -23,6 +23,16 @@ int main() logger->logEI(e.info()); } + + // ErrorInfo constructor + try { + auto e = Error("generic error"); + throw DemoError(e.info()); + } catch (Error &e) { + logger->logEI(e.info()); + } + + // For completeness sake, info through vomit levels. // But this is maybe a heavy format for those. logger->logEI( diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 4b7385c6b..97e34a75d 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -284,7 +284,7 @@ void BinaryCacheStore::narFromPath(const StorePath & storePath, Sink & sink) try { getFile(info->url, *decompressor); } catch (NoSuchBinaryCacheFile & e) { - throw SubstituteGone(e.what()); + throw SubstituteGone(e.info()); } decompressor->finish(); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 0f8126aee..cc336e460 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -365,7 +365,7 @@ void RemoteStore::queryPathInfoUncached(const StorePath & path, } catch (Error & e) { // Ugly backwards compatibility hack. if (e.msg().find("is not valid") != std::string::npos) - throw InvalidPath(e.what()); + throw InvalidPath(e.info()); throw; } if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) { diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 03e43241f..48e6311bd 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -83,6 +83,7 @@ class BaseError : public std::exception protected: string prefix_; // used for location traces etc. ErrorInfo err; + std::optional what_; const string& calcWhat() { @@ -107,18 +108,18 @@ public: .hint = hintfmt(args...) } , status(status) - { } + { } template BaseError(const Args & ... args) : err { .level = lvlError, .hint = hintfmt(args...) } - { } + { } BaseError(ErrorInfo e) : err(e) - { } + { } virtual const char* sname() const { return "BaseError"; } -- cgit v1.2.3 From 171b4ce85c491563004ad6b74377a8cb70a7d06c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 30 Apr 2020 09:57:01 -0600 Subject: typo --- src/nix/shell.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nix/shell.cc b/src/nix/shell.cc index 71e640667..e0546ef78 100644 --- a/src/nix/shell.cc +++ b/src/nix/shell.cc @@ -219,7 +219,7 @@ struct CmdDevShell : Common, MixEnvironment mkFlag() .longName("command") .shortName('c') - .description("command and arguments to be executed insted of an interactive shell") + .description("command and arguments to be executed instead of an interactive shell") .labels({"command", "args"}) .arity(ArityAny) .handler([&](std::vector ss) { -- cgit v1.2.3 From f5d3215c8740feec8053a697eca04c12eb71191b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 30 Apr 2020 16:31:47 -0600 Subject: logError --- src/error-demo/error-demo.cc | 2 -- src/nix/verify.cc | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 2c4f2da6e..514258416 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -65,7 +65,6 @@ int main() .description = "Vomit description", }); - // Error in a program; no hint and no nix code. logError( ErrorInfo { .name = "name", @@ -80,7 +79,6 @@ int main() .hint = hintfmt("there was a %1%", "warning"), }); - // Warning with nix file, line number, column, and the lines of // code where a warning occurred. SymbolTable testTable; diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 9b0658803..6e043dc2d 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -137,7 +137,7 @@ struct CmdVerify : StorePathsCommand doSigs(info2->sigs); } catch (InvalidPath &) { } catch (Error & e) { - printError(format(ANSI_RED "error:" ANSI_NORMAL " %s") % e.what()); + logError(e.info()); } } @@ -156,7 +156,7 @@ struct CmdVerify : StorePathsCommand done++; } catch (Error & e) { - printError(format(ANSI_RED "error:" ANSI_NORMAL " %s") % e.what()); + logError(e.info()); failed++; } -- cgit v1.2.3 From a3030e3c3186f980716c475155c387bf18041a3f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 30 Apr 2020 17:56:26 -0600 Subject: fix error calls --- src/nix-channel/nix-channel.cc | 30 ++++++++++-------------------- src/nix-store/nix-store.cc | 2 +- 2 files changed, 11 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index c403e3780..589a061c7 100755 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -37,8 +37,7 @@ static void writeChannels() { auto channelsFD = AutoCloseFD{open(channelsList.c_str(), O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC, 0644)}; if (!channelsFD) - throw Error(""); - // throw SysError("opening '%1%' for writing", channelsList); + throw SysError("opening '%1%' for writing", channelsList); for (const auto & channel : channels) writeFull(channelsFD.get(), channel.second + " " + channel.first + "\n"); } @@ -47,11 +46,9 @@ static void writeChannels() static void addChannel(const string & url, const string & name) { if (!regex_search(url, std::regex("^(file|http|https)://"))) - throw Error(""); - // throw Error("invalid channel URL '%1%'", url); + throw Error("invalid channel URL '%1%'", url); if (!regex_search(name, std::regex("^[a-zA-Z0-9_][a-zA-Z0-9_\\.-]*$"))) - throw Error(""); - // throw Error("invalid channel identifier '%1%'", name); + throw Error("invalid channel identifier '%1%'", name); readChannels(); channels[name] = url; writeChannels(); @@ -143,11 +140,9 @@ static void update(const StringSet & channelNames) if (S_ISLNK(st.st_mode)) // old-skool ~/.nix-defexpr if (unlink(nixDefExpr.c_str()) == -1) - throw Error(""); - // throw SysError("unlinking %1%", nixDefExpr); + throw SysError("unlinking %1%", nixDefExpr); } else if (errno != ENOENT) { - throw Error(""); - // throw SysError("getting status of %1%", nixDefExpr); + throw SysError("getting status of %1%", nixDefExpr); } createDirs(nixDefExpr); auto channelLink = nixDefExpr + "/channels"; @@ -199,12 +194,10 @@ static int _main(int argc, char ** argv) switch (cmd) { case cNone: - throw Error(""); - // throw UsageError("no command specified"); + throw UsageError("no command specified"); case cAdd: if (args.size() < 1 || args.size() > 2) - throw Error(""); - // throw UsageError("'--add' requires one or two arguments"); + throw UsageError("'--add' requires one or two arguments"); { auto url = args[0]; std::string name; @@ -220,14 +213,12 @@ static int _main(int argc, char ** argv) break; case cRemove: if (args.size() != 1) - throw Error(""); - // throw UsageError("'--remove' requires one argument"); + throw UsageError("'--remove' requires one argument"); removeChannel(args[0]); break; case cList: if (!args.empty()) - throw Error(""); - // throw UsageError("'--list' expects no arguments"); + throw UsageError("'--list' expects no arguments"); readChannels(); for (const auto & channel : channels) std::cout << channel.first << ' ' << channel.second << '\n'; @@ -237,8 +228,7 @@ static int _main(int argc, char ** argv) break; case cRollback: if (args.size() > 1) - throw Error(""); - // throw UsageError("'--rollback' has at most one argument"); + throw UsageError("'--rollback' has at most one argument"); Strings envArgs{"--profile", profile}; if (args.size() == 1) { envArgs.push_back("--switch-generation"); diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index e4dd9bc96..1e8a88a7b 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -906,7 +906,7 @@ static void opServe(Strings opFlags, Strings opArgs) if (!writeAllowed) throw Error("building paths is not allowed"); - auto drvPath = store->parseStorePath(readString(in)); // inonal ony + auto drvPath = store->parseStorePath(readString(in)); // informational only BasicDerivation drv; readDerivation(in, *store, drv); -- cgit v1.2.3 From 4b99c09f5ccd385d2bf0c82a8c9a4ae1658abbe8 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 1 May 2020 14:32:06 -0600 Subject: convert some errors --- src/libstore/builtins/buildenv.cc | 12 +++++++++-- src/libstore/download.cc | 7 ++++++- src/libstore/gc.cc | 13 ++++++++---- src/libstore/local-store.cc | 44 +++++++++++++++++++++++++++++---------- src/libstore/optimise-store.cc | 18 +++++++++++++--- src/libstore/remote-store.cc | 9 ++++++++ src/libstore/sqlite.cc | 5 ++++- 7 files changed, 86 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index 000769094..64085fcc9 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -22,7 +22,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, srcFiles = readDirectory(srcDir); } catch (SysError & e) { if (e.errNo == ENOTDIR) { - printError("warning: not including '%s' in the user environment because it's not a directory", srcDir); + logWarning( + ErrorInfo { + .name = "Create Links - Directory", + .hint = hintfmt("not including '%s' in the user environment because it's not a directory", srcDir) + }); return; } throw; @@ -41,7 +45,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, throw SysError("getting status of '%1%'", srcFile); } catch (SysError & e) { if (e.errNo == ENOENT || e.errNo == ENOTDIR) { - printError("warning: skipping dangling symlink '%s'", dstFile); + logWarning( + ErrorInfo { + .name = "Create Links - Skipping Symlink", + .hint = hintfmt("skipping dangling symlink '%s'", dstFile) + }); continue; } throw; diff --git a/src/libstore/download.cc b/src/libstore/download.cc index 7d0cb449b..60c6a80f3 100644 --- a/src/libstore/download.cc +++ b/src/libstore/download.cc @@ -600,7 +600,12 @@ struct CurlDownloader : public Downloader workerThreadMain(); } catch (nix::Interrupted & e) { } catch (std::exception & e) { - printError("unexpected error in download thread: %s", e.what()); + logError( + ErrorInfo { + .name = "download", + .hint = hintfmt("unexpected error in download thread: %s", + e.what()) + }); } { diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 27bd3f3e9..4f6f78a99 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -41,7 +41,8 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) throw SysError("opening global GC lock '%1%'", fnGCLock); if (!lockFile(fdGCLock.get(), lockType, false)) { - printError(format("waiting for the big garbage collector lock...")); + // TODO: info? + printError("waiting for the big garbage collector lock..."); lockFile(fdGCLock.get(), lockType, true); } @@ -129,10 +130,14 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, if (settings.checkRootReachability) { auto roots = findRoots(false); if (roots[storePath.clone()].count(gcRoot) == 0) - printError( - "warning: '%1%' is not in a directory where the garbage collector looks for roots; " + + logWarning( + ErrorInfo { + .name = "GC Root", + .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " "therefore, '%2%' might be removed by the garbage collector", - gcRoot, printStorePath(storePath)); + gcRoot, printStorePath(storePath)) + }); } /* Grab the global GC root, causing us to block while a GC is in diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index db5a3b53c..1f16a22b1 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -87,8 +87,13 @@ LocalStore::LocalStore(const Params & params) struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); if (!gr) - printError(format("warning: the group '%1%' specified in 'build-users-group' does not exist") - % settings.buildUsersGroup); + logError( + ErrorInfo { + .name = "'build-users-group' not found", + .hint = hintfmt( + "warning: the group '%1%' specified in 'build-users-group' does not exist", + settings.buildUsersGroup) + }); else { struct stat st; if (stat(realStoreDir.c_str(), &st)) @@ -876,7 +881,7 @@ void LocalStore::querySubstitutablePathInfos(const StorePathSet & paths, } catch (SubstituterDisabled &) { } catch (Error & e) { if (settings.tryFallback) - printError(e.what()); + logError(e.info()); else throw; } @@ -1237,9 +1242,13 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) Path linkPath = linksDir + "/" + link.name; string hash = hashPath(htSHA256, linkPath).first.to_string(Base32, false); if (hash != link.name) { - printError( + logError( + ErrorInfo { + .name = "Invalid Hash", + .hint = hintfmt( "link '%s' was modified! expected hash '%s', got '%s'", - linkPath, link.name, hash); + linkPath, link.name, hash) + }); if (repair) { if (unlink(linkPath.c_str()) == 0) printError("removed link '%s'", linkPath); @@ -1272,8 +1281,12 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) auto current = hashSink->finish(); if (info->narHash != nullHash && info->narHash != current.first) { - printError("path '%s' was modified! expected hash '%s', got '%s'", - printStorePath(i), info->narHash.to_string(), current.first.to_string()); + logError( + ErrorInfo { + .name = "Invalid Hash - Path Modified", + .hint = hintfmt("path '%s' was modified! expected hash '%s', got '%s'", + printStorePath(i), info->narHash.to_string(), current.first.to_string()) + }); if (repair) repairPath(i); else errors = true; } else { @@ -1304,7 +1317,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) /* It's possible that the path got GC'ed, so ignore errors on invalid paths. */ if (isValidPath(i)) - printError("error: %s", e.msg()); + logError(e.info()); else warn(e.msg()); errors = true; @@ -1324,7 +1337,11 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, if (!done.insert(pathS).second) return; if (!isStorePath(pathS)) { - printError("path '%s' is not in the Nix store", pathS); + logError( + ErrorInfo { + .name = "Nix path not found", + .hint = hintfmt("path '%s' is not in the Nix store", pathS) + }); return; } @@ -1347,12 +1364,17 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, auto state(_state.lock()); invalidatePath(*state, path); } else { - printError("path '%s' disappeared, but it still has valid referrers!", pathS); + // TODO log as warning if repair successful?? + logError( + ErrorInfo { + .name = "Missing path with referrers", + .hint = hintfmt("path '%s' disappeared, but it still has valid referrers!", pathS) + }); if (repair) try { repairPath(path); } catch (Error & e) { - warn(e.msg()); + logWarning(e.info()); errors = true; } else errors = true; diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index f9cf2bb6b..9f6112183 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -130,7 +130,11 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, NixOS (example: $fontconfig/var/cache being modified). Skip those files. FIXME: check the modification time. */ if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { - printError("skipping suspicious writable file '%1%'", path); + logWarning( + ErrorInfo { + .name = "Suspicious File", + .hint = hintfmt("skipping suspicious writable file '%1%'", path) + }); return; } @@ -194,7 +198,11 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, } if (st.st_size != stLink.st_size) { - printError("removing corrupted link '%1%'", linkPath); + logWarning( + ErrorInfo { + .name = "Corrupted Link", + .hint = hintfmt("removing corrupted link '%1%'", linkPath) + }); unlink(linkPath.c_str()); goto retry; } @@ -229,7 +237,11 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, /* Atomically replace the old file with the new hard link. */ if (rename(tempLink.c_str(), path.c_str()) == -1) { if (unlink(tempLink.c_str()) == -1) - printError("unable to unlink '%1%'", tempLink); + logError( + ErrorInfo { + .name = "Unlink error", + .hint = hintfmt("unable to unlink '%1%'", tempLink) + }); if (errno == EMLINK) { /* Some filesystems generate too many links on the rename, rather than on the original link. (Probably it diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index cc336e460..7c50c1065 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -780,6 +780,15 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source * } else if (msg == STDERR_NEXT) + // TODO: is this really an ErrorInfo error? Seems like we're forwarding the + // stderr output of the remote to current stderr/log + // ErrorInfo gets lost in this scenario. + // An alternative might be a logger on the remote that forwards ErrorInfo and etc. + // logError( + // ErrorInfo { + // // .name = "Remote Store" TODO reasonable name. + // .hint = hintfmt(chomp(readString(from))) + // }); printError(chomp(readString(from))); else if (msg == STDERR_START_ACTIVITY) { diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index a72cd5d88..082c54005 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -204,7 +204,10 @@ void handleSQLiteBusy(SQLiteBusy & e) if (now > lastWarned + 10) { lastWarned = now; - printError("warning: %s", e.what()); + logWarning( + ErrorInfo { .name = "sqlite busy", + .hint = hintfmt(e.what()) + }); } /* Sleep for a while since retrying the transaction right away -- cgit v1.2.3 From ab6f0b9641ad6e9cef72f73d23e31138a97a225b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 3 May 2020 08:01:25 -0600 Subject: convert some printError calls to logError --- src/build-remote/build-remote.cc | 8 +- src/libexpr/parser.y | 15 +++- src/libmain/shared.cc | 10 +-- src/libstore/build.cc | 97 ++++++++++++++++------ src/libstore/pathlocks.cc | 3 +- src/libstore/s3-binary-cache-store.cc | 4 +- src/libstore/store-api.cc | 2 +- src/libutil/affinity.cc | 4 +- src/libutil/error.hh | 6 ++ src/libutil/logging.hh | 1 + src/libutil/util.cc | 18 ++-- src/nix-build/nix-build.cc | 2 + src/nix-daemon/nix-daemon.cc | 3 +- src/nix-env/nix-env.cc | 23 ++++- src/nix-env/user-env.cc | 2 +- src/nix-store/nix-store.cc | 15 +++- src/nix/upgrade-nix.cc | 8 +- src/nix/verify.cc | 20 ++++- .../resolve-system-dependencies.cc | 24 +++++- 19 files changed, 195 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 00340b787..0d6859596 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -200,9 +200,13 @@ static int _main(int argc, char * * argv) } catch (std::exception & e) { auto msg = chomp(drainFD(5, false)); - printError("cannot build on '%s': %s%s", + logError( + ErrorInfo { + .name = "remote build", + .hint = hintfmt("cannot build on '%s': %s%s", bestMachine->storeUri, e.what(), - (msg.empty() ? "" : ": " + msg)); + (msg.empty() ? "" : ": " + msg)) + }); bestMachine->enabled = false; continue; } diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 3767532d5..3ed9a7a4f 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -689,8 +689,12 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl request.unpack = true; res = { true, getDownloader()->downloadCached(store, request).path }; } catch (DownloadError & e) { - // TODO: change to warn()? - printError("warning: Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second); + logWarning( + ErrorInfo { + .name = "Download Error", + .hint = hintfmt("warning: Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second) + }); + res = { false, "" }; } } else { @@ -698,8 +702,11 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl if (pathExists(path)) res = { true, path }; else { - // TODO: change to warn()? - printError("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second); + logWarning( + ErrorInfo { + .name = "Search path not found", + .hint = hintfmt("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second) + }); res = { false, "" }; } } diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 8551eb048..5773d90cc 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -300,21 +300,21 @@ int handleExceptions(const string & programName, std::function fun) } catch (UsageError & e) { // TODO: switch to logError // logError(e.info()); - printError( + _printError( format("%1%\nTry '%2% --help' for more information.") % e.what() % programName); return 1; } catch (BaseError & e) { // logError(e.info()); - printError("%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); + _printError("%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); if (e.prefix() != "" && !settings.showTrace) - printError("(use '--show-trace' to show detailed location information)"); + _printError("(use '--show-trace' to show detailed location information)"); return e.status; } catch (std::bad_alloc & e) { - printError(error + "out of memory"); + _printError(error + "out of memory"); return 1; } catch (std::exception & e) { - printError(error + e.what()); + _printError(error + e.what()); return 1; } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 2301adb16..bacbd5808 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -493,7 +493,9 @@ void handleDiffHook( if (diffRes.second != "") printError(chomp(diffRes.second)); } catch (Error & error) { - printError("diff hook execution failed: %s", error.what()); + // logError(error.info()) + // TODO append message onto errorinfo... + _printError("diff hook execution failed: %s", error.what()); } } } @@ -1144,7 +1146,11 @@ void DerivationGoal::loadDerivation() trace("loading derivation"); if (nrFailed != 0) { - printError("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)); + logError( + ErrorInfo { + .name = "missing derivation during build", + .hint = hintfmt("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)) + }); done(BuildResult::MiscFailure); return; } @@ -1295,8 +1301,14 @@ void DerivationGoal::repairClosure() /* Check each path (slow!). */ for (auto & i : outputClosure) { if (worker.pathContentsGood(i)) continue; - printError("found corrupted or missing path '%s' in the output closure of '%s'", - worker.store.printStorePath(i), worker.store.printStorePath(drvPath)); + logError( + ErrorInfo { + .name = "Corrupt path in closure", + .hint = hintfmt( + "found corrupted or missing path '%s' in the output closure of '%s'", + worker.store.printStorePath(i), worker.store.printStorePath(drvPath)) + }); + auto drvPath2 = outputsToDrv.find(i); if (drvPath2 == outputsToDrv.end()) addWaitee(worker.makeSubstitutionGoal(i, Repair)); @@ -1330,8 +1342,13 @@ void DerivationGoal::inputsRealised() if (nrFailed != 0) { if (!useDerivation) throw Error("some dependencies of '%s' are missing", worker.store.printStorePath(drvPath)); - printError("cannot build derivation '%s': %s dependencies couldn't be built", - worker.store.printStorePath(drvPath), nrFailed); + logError( + ErrorInfo { + .name = "Dependencies could not be built", + .hint = hintfmt( + "cannot build derivation '%s': %s dependencies couldn't be built", + worker.store.printStorePath(drvPath), nrFailed) + }); done(BuildResult::DependencyFailed); return; } @@ -1489,7 +1506,7 @@ void DerivationGoal::tryToBuild() startBuilder(); } catch (BuildError & e) { - printError(e.msg()); + logError(e.info()); outputLocks.unlock(); buildUser.reset(); worker.permanentFailure = true; @@ -1709,7 +1726,7 @@ void DerivationGoal::buildDone() outputLocks.unlock(); } catch (BuildError & e) { - printError(e.msg()); + logError(e.info()); outputLocks.unlock(); @@ -1788,8 +1805,13 @@ HookReply DerivationGoal::tryBuildHook() } catch (SysError & e) { if (e.errNo == EPIPE) { - printError("build hook died unexpectedly: %s", - chomp(drainFD(worker.hook->fromHook.readSide.get()))); + logError( + ErrorInfo { + .name = "Build hook died", + .hint = hintfmt( + "build hook died unexpectedly: %s", + chomp(drainFD(worker.hook->fromHook.readSide.get()))) + }); worker.hook = 0; return rpDecline; } else @@ -3783,10 +3805,10 @@ void DerivationGoal::registerOutputs() result.isNonDeterministic = true; Path prev = worker.store.printStorePath(i->second.path) + checkSuffix; bool prevExists = keepPreviousRound && pathExists(prev); - auto msg = prevExists - ? fmt("output '%s' of '%s' differs from '%s' from previous round", + hintformat hint = prevExists + ? hintfmt("output '%s' of '%s' differs from '%s' from previous round", worker.store.printStorePath(i->second.path), worker.store.printStorePath(drvPath), prev) - : fmt("output '%s' of '%s' differs from previous round", + : hintfmt("output '%s' of '%s' differs from previous round", worker.store.printStorePath(i->second.path), worker.store.printStorePath(drvPath)); handleDiffHook( @@ -3796,9 +3818,15 @@ void DerivationGoal::registerOutputs() worker.store.printStorePath(drvPath), tmpDir); if (settings.enforceDeterminism) - throw NotDeterministic(msg); + throw NotDeterministic(hint); + + logError( + ErrorInfo { + .name = "Output determinism error", + .hint = hint + }); + - printError(msg); curRound = nrRounds; // we know enough, bail out early } } @@ -4060,9 +4088,13 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) { logSize += data.size(); if (settings.maxLogSize && logSize > settings.maxLogSize) { - printError( - format("%1% killed after writing more than %2% bytes of log output") - % getName() % settings.maxLogSize); + logError( + ErrorInfo { + .name = "Max log size exceeded", + .hint = hintfmt( + "%1% killed after writing more than %2% bytes of log output", + getName(), settings.maxLogSize) + }); killChild(); done(BuildResult::LogLimitExceeded); return; @@ -4352,7 +4384,7 @@ void SubstitutionGoal::tryNext() throw; } catch (Error & e) { if (settings.tryFallback) { - printError(e.what()); + logError(e.info()); tryNext(); return; } @@ -4864,9 +4896,13 @@ void Worker::waitForInput() j->respectTimeouts && after - j->lastOutput >= std::chrono::seconds(settings.maxSilentTime)) { - printError( - format("%1% timed out after %2% seconds of silence") - % goal->getName() % settings.maxSilentTime); + logError( + ErrorInfo { + .name = "Silent build timeout", + .hint = hintfmt( + "%1% timed out after %2% seconds of silence", + goal->getName(), settings.maxSilentTime) + }); goal->timedOut(); } @@ -4875,9 +4911,13 @@ void Worker::waitForInput() j->respectTimeouts && after - j->timeStarted >= std::chrono::seconds(settings.buildTimeout)) { - printError( - format("%1% timed out after %2% seconds") - % goal->getName() % settings.buildTimeout); + logError( + ErrorInfo { + .name = "Build timeout", + .hint = hintfmt( + "%1% timed out after %2% seconds", + goal->getName(), settings.buildTimeout) + }); goal->timedOut(); } } @@ -4939,7 +4979,12 @@ bool Worker::pathContentsGood(const StorePath & path) res = info->narHash == nullHash || info->narHash == current.first; } pathContentsGoodCache.insert_or_assign(path.clone(), res); - if (!res) printError("path '%s' is corrupted or missing!", store.printStorePath(path)); + if (!res) + logError( + ErrorInfo { + .name = "Corrupted path", + .hint = hintfmt("path '%s' is corrupted or missing!", store.printStorePath(path)) + }); return res; } diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index 52d430ffd..926f4ea1e 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -160,7 +160,8 @@ void PathLocks::unlock() if (close(i.first) == -1) printError( - format("error (ignored): cannot close lock file on '%1%'") % i.second); + "error (ignored): cannot close lock file on '%1%'", + i.second); debug(format("lock released on '%1%'") % i.second); } diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 0326821f6..3175eb69b 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -111,7 +111,9 @@ class RetryStrategy : public Aws::Client::DefaultRetryStrategy auto retry = Aws::Client::DefaultRetryStrategy::ShouldRetry(error, attemptedRetries); if (retry) printError("AWS error '%s' (%s), will retry in %d ms", - error.GetExceptionName(), error.GetMessage(), CalculateDelayBeforeNextRetry(error, attemptedRetries)); + error.GetExceptionName(), + error.GetMessage(), + CalculateDelayBeforeNextRetry(error, attemptedRetries)); return retry; } }; diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index a04d5013e..542e5c552 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -961,7 +961,7 @@ std::list> getDefaultSubstituters() try { stores.push_back(openStore(uri)); } catch (Error & e) { - printError("warning: %s", e.what()); + logWarning(e.info()); } }; diff --git a/src/libutil/affinity.cc b/src/libutil/affinity.cc index 98f8287ad..e3cf33b58 100644 --- a/src/libutil/affinity.cc +++ b/src/libutil/affinity.cc @@ -25,7 +25,7 @@ void setAffinityTo(int cpu) CPU_ZERO(&newAffinity); CPU_SET(cpu, &newAffinity); if (sched_setaffinity(0, sizeof(cpu_set_t), &newAffinity) == -1) - printError(format("failed to lock thread to CPU %1%") % cpu); + printError("failed to lock thread to CPU %1%", cpu); #endif } @@ -47,7 +47,7 @@ void restoreAffinity() #if __linux__ if (!didSaveAffinity) return; if (sched_setaffinity(0, sizeof(cpu_set_t), &savedAffinity) == -1) - printError("failed to restore affinity %1%"); + _printError("failed to restore affinity"); #endif } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 48e6311bd..86cff5609 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -117,6 +117,12 @@ public: } { } + BaseError(hintformat hint) + : err { .level = lvlError, + .hint = hint + } + { } + BaseError(ErrorInfo e) : err(e) { } diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 0c4980b83..5f03cdf41 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -149,6 +149,7 @@ extern Verbosity verbosity; /* suppress msgs > this */ } \ } while (0) +#define _printError(args...) printMsg(lvlError, args) #define printError(args...) printMsg(lvlError, args) #define printInfo(args...) printMsg(lvlInfo, args) #define printTalkative(args...) printMsg(lvlTalkative, args) diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 747a9e991..68dc1b738 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1417,15 +1417,15 @@ string base64Decode(const string & s) } -void callFailure(const std::function & failure, std::exception_ptr exc) -{ - try { - failure(exc); - } catch (std::exception & e) { - printError("uncaught exception: %s", e.what()); - abort(); - } -} +// void callFailure(const std::function & failure, std::exception_ptr exc) +// { +// try { +// failure(exc); +// } catch (std::exception & e) { +// printError("uncaught exception: %s", e.what()); +// abort(); +// } +// } static Sync> windowSize{{0, 0}}; diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 0a058a31b..401c8d340 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -368,6 +368,8 @@ static void _main(int argc, char * * argv) shell = drv->queryOutPath() + "/bin/bash"; } catch (Error & e) { + // TODO: append error msg + logError(e.info()); printError("warning: %s; will use bash from your environment", e.what()); shell = "bash"; } diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 5f78ab464..3cd2c3a6b 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -247,7 +247,8 @@ static void daemonLoop(char * * argv) } catch (Interrupted & e) { return; } catch (Error & e) { - printError("error processing connection: %1%", e.msg()); + // TODO append error message + _printError("error processing connection: %1%", e.msg()); } } } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index dde8875f1..76008d00c 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -123,7 +123,11 @@ static void getAllExprs(EvalState & state, if (hasSuffix(attrName, ".nix")) attrName = string(attrName, 0, attrName.size() - 4); if (!attrs.insert(attrName).second) { - printError(format("warning: name collision in input Nix expressions, skipping '%1%'") % path2); + logError( + ErrorInfo { + .name = "Name collision", + .hint = hintfmt("warning: name collision in input Nix expressions, skipping '%1%'", path2) + }); continue; } /* Load the expression on demand. */ @@ -860,7 +864,12 @@ static void queryJSON(Globals & globals, vector & elems) auto placeholder = metaObj.placeholder(j); Value * v = i.queryMeta(j); if (!v) { - printError("derivation '%s' has invalid meta attribute '%s'", i.queryName(), j); + logError( + ErrorInfo { + .name = "Invalid meta attribute", + .hint = hintfmt("derivation '%s' has invalid meta attribute '%s'", + i.queryName(), j) + }); placeholder.write(nullptr); } else { PathSet context; @@ -1110,8 +1119,14 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) XMLAttrs attrs2; attrs2["name"] = j; Value * v = i.queryMeta(j); - if (!v) - printError("derivation '%s' has invalid meta attribute '%s'", i.queryName(), j); + if (!v) + logError( + ErrorInfo { + .name = "Invalid meta attribute", + .hint = hintfmt( + "derivation '%s' has invalid meta attribute '%s'", + i.queryName(), j) + }); else { if (v->type == tString) { attrs2["type"] = "string"; diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc index f852916d8..2484b9759 100644 --- a/src/nix-env/user-env.cc +++ b/src/nix-env/user-env.cc @@ -146,7 +146,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, Path lockTokenCur = optimisticLockProfile(profile); if (lockToken != lockTokenCur) { - printError(format("profile '%1%' changed while we were busy; restarting") % profile); + printError("profile '%1%' changed while we were busy; restarting", profile); return false; } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 1e8a88a7b..2e2276b4a 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -726,9 +726,15 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) store->narFromPath(path, sink); auto current = sink.finish(); if (current.first != info->narHash) { - printError( - "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(path), info->narHash.to_string(), current.first.to_string()); + logError( + ErrorInfo { + .name = "Hash match error", + .hint = hintfmt( + "path '%s' was modified! expected hash '%s', got '%s'", + store->printStorePath(path), + info->narHash.to_string(), + current.first.to_string()) + }); status = 1; } } @@ -835,7 +841,8 @@ static void opServe(Strings opFlags, Strings opArgs) for (auto & p : willSubstitute) subs.emplace_back(p.clone()); store->buildPaths(subs); } catch (Error & e) { - printError("warning: %1%", e.msg()); + // logWarning(e.info()) TODO: + _printError("warning: %1%", e.msg()); } } diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index c05c29517..8f4e529bc 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -64,7 +64,13 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand if (dryRun) { stopProgressBar(); - printError("would upgrade to version %s", version); + // TODO change to info? + logWarning( + ErrorInfo { + .name = "Version update", + .hint = hintfmt("would upgrade to version %s", version) + }); + // printError("would upgrade to version %s", version); return; } diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 6e043dc2d..f53217239 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -97,9 +97,15 @@ struct CmdVerify : StorePathsCommand if (hash.first != info->narHash) { corrupted++; act2.result(resCorruptedPath, store->printStorePath(info->path)); - printError( - "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(info->path), info->narHash.to_string(), hash.first.to_string()); + logError( + ErrorInfo { + .name = "Hash error - path modified", + .hint = hintfmt( + "path '%s' was modified! expected hash '%s', got '%s'", + store->printStorePath(info->path), + info->narHash.to_string(), + hash.first.to_string()) + }); } } @@ -148,7 +154,13 @@ struct CmdVerify : StorePathsCommand if (!good) { untrusted++; act2.result(resUntrustedPath, store->printStorePath(info->path)); - printError("path '%s' is untrusted", store->printStorePath(info->path)); + logError( + ErrorInfo { + .name = "Untrusted path", + .hint = hintfmt("path '%s' is untrusted", + store->printStorePath(info->path)) + }); + } } diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc index 8f0c99c84..dcea72529 100644 --- a/src/resolve-system-dependencies/resolve-system-dependencies.cc +++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc @@ -39,12 +39,20 @@ std::set runResolver(const Path & filename) throw SysError("statting '%s'", filename); if (!S_ISREG(st.st_mode)) { - printError("file '%s' is not a regular file", filename); + logError( + ErrorInfo { + .name = "Regular MACH file", + .hint = hintfmt("file '%s' is not a regular file", filename) + }); return {}; } if (st.st_size < sizeof(mach_header_64)) { - printError("file '%s' is too short for a MACH binary", filename); + logError( + ErrorInfo { + .name = "File too short", + .hint = hintfmt("file '%s' is too short for a MACH binary", filename) + }); return {}; } @@ -66,13 +74,21 @@ std::set runResolver(const Path & filename) } } if (mach64_offset == 0) { - printError(format("Could not find any mach64 blobs in file '%1%', continuing...") % filename); + logError( + ErrorInfo { + .name = "No mach64 blobs", + .hint = hintfmt("Could not find any mach64 blobs in file '%1%', continuing...", filename) + }); return {}; } } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) { mach64_offset = 0; } else { - printError(format("Object file has unknown magic number '%1%', skipping it...") % magic); + logError( + ErrorInfo { + .name = "Magic number", + .hint = hintfmt("Object file has unknown magic number '%1%', skipping it...", magic) + }); return {}; } -- cgit v1.2.3 From 9c5ece44a7f32784dd5e2ea0faf110054f9233a8 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 4 May 2020 13:46:15 -0600 Subject: separate msgs instead of appending to what() --- src/libmain/shared.cc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 5773d90cc..db1e0ba1d 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -298,23 +298,21 @@ int handleExceptions(const string & programName, std::function fun) } catch (Exit & e) { return e.status; } catch (UsageError & e) { - // TODO: switch to logError - // logError(e.info()); - _printError( - format("%1%\nTry '%2% --help' for more information.") - % e.what() % programName); + logError(e.info()); + printError("Try '%1% --help' for more information.", programName); return 1; } catch (BaseError & e) { - // logError(e.info()); - _printError("%1%%2%", (settings.showTrace ? e.prefix() : ""), e.msg()); + if (settings.showTrace && e.prefix() != "") + printError(e.prefix()); + logError(e.info()); if (e.prefix() != "" && !settings.showTrace) - _printError("(use '--show-trace' to show detailed location information)"); + printError("(use '--show-trace' to show detailed location information)"); return e.status; } catch (std::bad_alloc & e) { - _printError(error + "out of memory"); + printError(error + "out of memory"); return 1; } catch (std::exception & e) { - _printError(error + e.what()); + printError(error + e.what()); return 1; } -- cgit v1.2.3 From afaa541013549c254f9c54e0865dc254973eea96 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 4 May 2020 14:44:00 -0600 Subject: affinity operator<< --- src/libutil/affinity.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libutil/affinity.cc b/src/libutil/affinity.cc index e3cf33b58..ac2295e4a 100644 --- a/src/libutil/affinity.cc +++ b/src/libutil/affinity.cc @@ -12,6 +12,17 @@ namespace nix { #if __linux__ static bool didSaveAffinity = false; static cpu_set_t savedAffinity; + +std::ostream& operator<<(std::ostream &os, const cpu_set_t &cset) +{ + auto count = CPU_COUNT(&cset); + for (int i=0; i < count; ++i) + { + os << (CPU_ISSET(i,&cset) ? "1" : "0"); + } + + return os; +} #endif @@ -47,7 +58,11 @@ void restoreAffinity() #if __linux__ if (!didSaveAffinity) return; if (sched_setaffinity(0, sizeof(cpu_set_t), &savedAffinity) == -1) - _printError("failed to restore affinity"); + { + std::ostringstream oss; + oss << savedAffinity; + printError("failed to restore CPU affinity %1%", oss.str()); + } #endif } -- cgit v1.2.3 From 8c8f2b74ec3fe37f8661c8411749965b6e8d44d2 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 4 May 2020 14:44:42 -0600 Subject: log as warning --- src/nix-store/nix-store.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 2e2276b4a..57063d42f 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -841,8 +841,7 @@ static void opServe(Strings opFlags, Strings opArgs) for (auto & p : willSubstitute) subs.emplace_back(p.clone()); store->buildPaths(subs); } catch (Error & e) { - // logWarning(e.info()) TODO: - _printError("warning: %1%", e.msg()); + logWarning(e.info()); } } -- cgit v1.2.3 From f30de61578edd9c19744256985185045e7baab84 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 4 May 2020 16:19:20 -0600 Subject: add normaltxt, yellowify->yellowtxt --- src/libutil/fmt.hh | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh index d182adc3a..bfacfeb4d 100644 --- a/src/libutil/fmt.hh +++ b/src/libutil/fmt.hh @@ -73,18 +73,31 @@ inline std::string fmt(const std::string & fs, const Args & ... args) // are always in yellow. template -struct yellowify +struct yellowtxt { - yellowify(T &s) : value(s) {} + yellowtxt(T &s) : value(s) {} T &value; }; template -std::ostream& operator<<(std::ostream &out, const yellowify &y) +std::ostream& operator<<(std::ostream &out, const yellowtxt &y) { return out << ANSI_YELLOW << y.value << ANSI_NORMAL; } +template +struct normaltxt +{ + normaltxt(T &s) : value(s) {} + T &value; +}; + +template +std::ostream& operator<<(std::ostream &out, const normaltxt &y) +{ + return out << ANSI_NORMAL << y.value; +} + class hintformat { public: @@ -100,7 +113,7 @@ public: template hintformat& operator%(const T &value) { - fmt % yellowify(value); + fmt % yellowtxt(value); return *this; } -- cgit v1.2.3 From 7ffb5efdbc943851d2ee9d0573dca3e96b9bd742 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 4 May 2020 16:19:57 -0600 Subject: appending to hints; remove _printError --- src/error-demo/error-demo.cc | 7 +++++-- src/libstore/build.cc | 12 ++++++++---- src/libutil/logging.hh | 1 - src/nix-daemon/nix-daemon.cc | 7 +++++-- 4 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 514258416..82b03d71b 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -26,10 +26,13 @@ int main() // ErrorInfo constructor try { - auto e = Error("generic error"); + auto e = Error("some error"); throw DemoError(e.info()); } catch (Error &e) { - logger->logEI(e.info()); + ErrorInfo ei = e.info(); + string prevhint = (e.info().hint.has_value() ? e.info().hint->str() : ""); + ei.hint = std::optional(hintfmt("previous hint was: %s", normaltxt(prevhint))); + logger->logEI(ei); } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index bacbd5808..f8cc1ce36 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -488,14 +488,18 @@ void handleDiffHook( auto diffRes = runProgram(diffHookOptions); if (!statusOk(diffRes.first)) - throw ExecError(diffRes.first, "diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first)); + throw ExecError(diffRes.first, + "diff-hook program '%1%' %2%", + diffHook, + statusToString(diffRes.first)); if (diffRes.second != "") printError(chomp(diffRes.second)); } catch (Error & error) { - // logError(error.info()) - // TODO append message onto errorinfo... - _printError("diff hook execution failed: %s", error.what()); + ErrorInfo ei = error.info(); + string prevhint = (error.info().hint.has_value() ? error.info().hint->str() : ""); + ei.hint = std::optional(hintfmt("diff hook execution failed: %s", prevhint)); + logError(ei); } } } diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 5f03cdf41..0c4980b83 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -149,7 +149,6 @@ extern Verbosity verbosity; /* suppress msgs > this */ } \ } while (0) -#define _printError(args...) printMsg(lvlError, args) #define printError(args...) printMsg(lvlError, args) #define printInfo(args...) printMsg(lvlInfo, args) #define printTalkative(args...) printMsg(lvlTalkative, args) diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 3cd2c3a6b..5336db136 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -246,9 +246,12 @@ static void daemonLoop(char * * argv) } catch (Interrupted & e) { return; - } catch (Error & e) { + } catch (Error & error) { // TODO append error message - _printError("error processing connection: %1%", e.msg()); + ErrorInfo ei = error.info(); + string prevhint = (error.info().hint.has_value() ? error.info().hint->str() : ""); + ei.hint = std::optional(hintfmt("error processing connection: %1%", prevhint)); + logError(ei); } } } -- cgit v1.2.3 From e76ad2e48a71aa9804311f4dfb34374a5295b3b6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 6 May 2020 14:07:20 -0600 Subject: implement SysError errno handling --- src/error-demo/error-demo.cc | 8 ++++++++ src/libutil/error.cc | 8 -------- src/libutil/error.hh | 13 +++++++------ src/libutil/fmt.hh | 8 ++++---- src/libutil/util.cc | 3 ++- 5 files changed, 21 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 82b03d71b..b1b313e32 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -35,6 +35,14 @@ int main() logger->logEI(ei); } + // SysError; picks up errno + try { + auto x = readFile(-1); + } + catch (Error &e) { + std::cout << "error: " << e.sname() << std::endl; + logError(e.info()); + } // For completeness sake, info through vomit levels. // But this is maybe a heavy format for those. diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 91fa1ccd8..d4305ddd8 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -16,14 +16,6 @@ BaseError & BaseError::addPrefix(const FormatOrString & fs) return *this; } - -std::string SysError::addErrno(const std::string & s) -{ - errNo = errno; - return s + ": " + strerror(errNo); -} - - std::optional ErrorInfo::programName = std::nullopt; std::ostream& operator<<(std::ostream &os, const hintformat &hf) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 86cff5609..2155ad344 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -160,13 +160,14 @@ public: template SysError(const Args & ... args) - : Error(args...) // TODO addErrNo for hintfmt - // : Error(addErrno(hintfmt(args...))) - { } - -private: + :Error("") + { + errNo = errno; + auto hf = hintfmt(args...); + err.hint = hintfmt("%1% : %2%", normaltxt(hf.str()), strerror(errNo)); + } - std::string addErrno(const std::string & s); + virtual const char* sname() const override { return "SysError"; } }; } diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh index bfacfeb4d..12ab9c407 100644 --- a/src/libutil/fmt.hh +++ b/src/libutil/fmt.hh @@ -75,8 +75,8 @@ inline std::string fmt(const std::string & fs, const Args & ... args) template struct yellowtxt { - yellowtxt(T &s) : value(s) {} - T &value; + yellowtxt(const T &s) : value(s) {} + const T &value; }; template @@ -88,8 +88,8 @@ std::ostream& operator<<(std::ostream &out, const yellowtxt &y) template struct normaltxt { - normaltxt(T &s) : value(s) {} - T &value; + normaltxt(const T &s) : value(s) {} + const T &value; }; template diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 68dc1b738..e8f22ab71 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -312,7 +312,8 @@ string readFile(const Path & path, bool drain) void readFile(const Path & path, Sink & sink) { AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (!fd) throw SysError("opening file '%s'", path); + if (!fd) + throw SysError("opening file '%s'", path); drainFD(fd.get(), sink); } -- cgit v1.2.3 From e3901638b50d91ddc9c356adc35ded00a00fe94b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 6 May 2020 15:01:13 -0600 Subject: todo removal --- src/error-demo/error-demo.cc | 1 - src/libstore/gc.cc | 1 - src/nix-daemon/nix-daemon.cc | 1 - src/nix/upgrade-nix.cc | 2 -- 4 files changed, 5 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index b1b313e32..0d3dcf616 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -23,7 +23,6 @@ int main() logger->logEI(e.info()); } - // ErrorInfo constructor try { auto e = Error("some error"); diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 4f6f78a99..629c4360c 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -41,7 +41,6 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) throw SysError("opening global GC lock '%1%'", fnGCLock); if (!lockFile(fdGCLock.get(), lockType, false)) { - // TODO: info? printError("waiting for the big garbage collector lock..."); lockFile(fdGCLock.get(), lockType, true); } diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 5336db136..731ab22e5 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -247,7 +247,6 @@ static void daemonLoop(char * * argv) } catch (Interrupted & e) { return; } catch (Error & error) { - // TODO append error message ErrorInfo ei = error.info(); string prevhint = (error.info().hint.has_value() ? error.info().hint->str() : ""); ei.hint = std::optional(hintfmt("error processing connection: %1%", prevhint)); diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index 8f4e529bc..831a83fd1 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -64,13 +64,11 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand if (dryRun) { stopProgressBar(); - // TODO change to info? logWarning( ErrorInfo { .name = "Version update", .hint = hintfmt("would upgrade to version %s", version) }); - // printError("would upgrade to version %s", version); return; } -- cgit v1.2.3 From 1b801cec407454b904466153dfc56cec6b433f4b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 7 May 2020 16:43:36 -0600 Subject: pretending to be const --- src/error-demo/error-demo.cc | 16 ++++++++++++++++ src/libutil/error.hh | 12 ++++++------ src/nix-build/nix-build.cc | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 0d3dcf616..89ba5a78d 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -43,6 +43,22 @@ int main() logError(e.info()); } + // current exception + try { + throw DemoError("DemoError handled as a %1%", "std::exception"); + } + catch (...) { + const std::exception_ptr &eptr = std::current_exception(); + try + { + std::rethrow_exception(eptr); + } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + // For completeness sake, info through vomit levels. // But this is maybe a heavy format for those. logger->logEI( diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 2155ad344..19a806cc1 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -82,10 +82,10 @@ class BaseError : public std::exception { protected: string prefix_; // used for location traces etc. - ErrorInfo err; + mutable ErrorInfo err; - std::optional what_; - const string& calcWhat() + mutable std::optional what_; + const string& calcWhat() const { if (what_.has_value()) return *what_; @@ -131,12 +131,12 @@ public: #ifdef EXCEPTION_NEEDS_THROW_SPEC ~BaseError() throw () { }; - const char * what() throw () { return calcWhat().c_str(); } + const char * what() const throw () { return calcWhat().c_str(); } #else - const char * what() noexcept { return calcWhat().c_str(); } + const char * what() const noexcept override { return calcWhat().c_str(); } #endif - const string & msg() { return calcWhat(); } + const string & msg() const { return calcWhat(); } const string & prefix() const { return prefix_; } BaseError & addPrefix(const FormatOrString & fs); diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 401c8d340..3c2f4f00c 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -368,7 +368,7 @@ static void _main(int argc, char * * argv) shell = drv->queryOutPath() + "/bin/bash"; } catch (Error & e) { - // TODO: append error msg + // TODO: append error msg; warn()? logError(e.info()); printError("warning: %s; will use bash from your environment", e.what()); shell = "bash"; -- cgit v1.2.3 From 55eb71714854b262b5e1079ff250a13cc0bbf644 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 May 2020 18:18:28 -0600 Subject: add pos to errorinfo, remove from hints --- src/error-demo/error-demo.cc | 17 +- src/libexpr/attr-set.hh | 7 +- src/libexpr/eval-inline.hh | 18 +- src/libexpr/eval.cc | 76 +++++--- src/libexpr/parser.y | 17 +- src/libexpr/primops.cc | 331 ++++++++++++++++++++++++++++------ src/libexpr/primops/context.cc | 20 +- src/libexpr/primops/fetchGit.cc | 12 +- src/libexpr/primops/fetchMercurial.cc | 13 +- src/libutil/error.cc | 170 ++++++++--------- src/libutil/error.hh | 11 +- src/libutil/logging.cc | 3 +- 12 files changed, 503 insertions(+), 192 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 89ba5a78d..41293427c 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -126,17 +126,28 @@ int main() // Error with previous and next lines of code. logError( ErrorInfo { .name = "error name", - .description = "error description", + .description = "error with code lines", .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), .nixCode = NixCode { .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::optional("previous line of code"), + .prevLineOfCode = "previous line of code", .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::optional("next line of code"), + .nextLineOfCode = "next line of code", }}); + // Error without lines of code. + logError( + ErrorInfo { .name = "error name", + .description = "error without any code lines.", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); + return 0; } diff --git a/src/libexpr/attr-set.hh b/src/libexpr/attr-set.hh index 118c7bd5d..f5651891f 100644 --- a/src/libexpr/attr-set.hh +++ b/src/libexpr/attr-set.hh @@ -76,7 +76,12 @@ public: { auto a = get(name); if (!a) - throw Error("attribute '%s' missing, at %s", name, pos); + throw Error( + ErrorInfo { + .hint = hintfmt("attribute '%s' missing", name), + .nixCode = NixCode { .errPos = pos } + }); + return *a; } diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index 4d82ccf09..d03633cc7 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -9,7 +9,11 @@ namespace nix { LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos)) { - throw EvalError(s, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt(s), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) @@ -20,7 +24,11 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos)) { - throw TypeError(s, showType(v), pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt(s, showType(v)), + .nixCode = NixCode { .errPos = pos } + }); } @@ -43,7 +51,7 @@ void EvalState::forceValue(Value & v, const Pos & pos) else if (v.type == tApp) callFunction(*v.app.left, *v.app.right, v, noPos); else if (v.type == tBlackhole) - throwEvalError("infinite recursion encountered, at %1%", pos); + throwEvalError("infinite recursion encountered", pos); } @@ -59,7 +67,7 @@ inline void EvalState::forceAttrs(Value & v, const Pos & pos) { forceValue(v); if (v.type != tAttrs) - throwTypeError("value is %1% while a set was expected, at %2%", v, pos); + throwTypeError("value is %1% while a set was expected", v, pos); } @@ -75,7 +83,7 @@ inline void EvalState::forceList(Value & v, const Pos & pos) { forceValue(v); if (!v.isList()) - throwTypeError("value is %1% while a list was expected, at %2%", v, pos); + throwTypeError("value is %1% while a list was expected", v, pos); } /* Note: Various places expect the allocated memory to be zeroed. */ diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 516c25b02..a19b85be4 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -498,7 +498,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2)) LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos)) { - throw EvalError(s, s2, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt(s, s2), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3)) @@ -508,7 +512,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos)) { - throw EvalError(s, s2, s3, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt(s, s2, s3), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) @@ -518,7 +526,11 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, co LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos)) { - throw TypeError(s, pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt(s), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) @@ -528,17 +540,29 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos)) { - throw TypeError(s, fun.showNamePos(), s2, pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt(s, fun.showNamePos(), s2), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos)) { - throw AssertionError(s, s1, pos); + throw AssertionError( + ErrorInfo { + .hint = hintfmt(s, s1), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos)) { - throw UndefinedVarError(s, s1, pos); + throw UndefinedVarError( + ErrorInfo { + .hint = hintfmt(s, s1), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2)) @@ -804,7 +828,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos) Value v; e->eval(*this, env, v); if (v.type != tBool) - throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos); + throwTypeError("value is %1% while a Boolean was expected", v, pos); return v.boolean; } @@ -1006,7 +1030,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError("attribute '%1%' missing, at %2%", name, pos); + throwEvalError("attribute '%1%' missing", name, pos); } vAttrs = j->value; pos2 = j->pos; @@ -1132,7 +1156,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po } if (fun.type != tLambda) - throwTypeError("attempt to call something which is not a function but %1%, at %2%", fun, pos); + throwTypeError("attempt to call something which is not a function but %1%", fun, pos); ExprLambda & lambda(*fun.lambda.fun); @@ -1160,7 +1184,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { - if (!i.def) throwTypeError("%1% called without required argument '%2%', at %3%", + if (!i.def) throwTypeError("%1% called without required argument '%2%'", lambda, i.name, pos); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { @@ -1176,7 +1200,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po user. */ for (auto & i : *arg.attrs) if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end()) - throwTypeError("%1% called with unexpected argument '%2%', at %3%", lambda, i.name, pos); + throwTypeError("%1% called with unexpected argument '%2%'", lambda, i.name, pos); abort(); // can't happen } } @@ -1417,14 +1441,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } else - throwEvalError("cannot add %1% to an integer, at %2%", showType(vTmp), pos); + throwEvalError("cannot add %1% to an integer", showType(vTmp), pos); } else if (firstType == tFloat) { if (vTmp.type == tInt) { nf += vTmp.integer; } else if (vTmp.type == tFloat) { nf += vTmp.fpoint; } else - throwEvalError("cannot add %1% to a float, at %2%", showType(vTmp), pos); + throwEvalError("cannot add %1% to a float", showType(vTmp), pos); } else s << state.coerceToString(pos, vTmp, context, false, firstType == tString); } @@ -1435,7 +1459,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) mkFloat(v, nf); else if (firstType == tPath) { if (!context.empty()) - throwEvalError("a string that refers to a store path cannot be appended to a path, at %1%", pos); + throwEvalError("a string that refers to a store path cannot be appended to a path", pos); auto path = canonPath(s.str()); mkPath(v, path.c_str()); } else @@ -1484,7 +1508,7 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type != tInt) - throwTypeError("value is %1% while an integer was expected, at %2%", v, pos); + throwTypeError("value is %1% while an integer was expected", v, pos); return v.integer; } @@ -1495,7 +1519,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) if (v.type == tInt) return v.integer; else if (v.type != tFloat) - throwTypeError("value is %1% while a float was expected, at %2%", v, pos); + throwTypeError("value is %1% while a float was expected", v, pos); return v.fpoint; } @@ -1504,7 +1528,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v); if (v.type != tBool) - throwTypeError("value is %1% while a Boolean was expected, at %2%", v, pos); + throwTypeError("value is %1% while a Boolean was expected", v, pos); return v.boolean; } @@ -1519,7 +1543,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) { forceValue(v); if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v)) - throwTypeError("value is %1% while a function was expected, at %2%", v, pos); + throwTypeError("value is %1% while a function was expected", v, pos); } @@ -1528,7 +1552,7 @@ string EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type != tString) { if (pos) - throwTypeError("value is %1% while a string was expected, at %2%", v, pos); + throwTypeError("value is %1% while a string was expected", v, pos); else throwTypeError("value is %1% while a string was expected", v); } @@ -1557,7 +1581,7 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) string s = forceString(v, pos); if (v.string.context) { if (pos) - throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%'), at %3%", + throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], pos); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", @@ -1614,7 +1638,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, return *maybeString; } auto i = v.attrs->find(sOutPath); - if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos); + if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string", pos); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -1645,7 +1669,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError("cannot coerce %1% to a string, at %2%", v, pos); + throwTypeError("cannot coerce %1% to a string", v, pos); } @@ -1676,7 +1700,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) { string path = coerceToString(pos, v, context, false, false); if (path == "" || path[0] != '/') - throwEvalError("string '%1%' doesn't represent an absolute path, at %2%", path, pos); + throwEvalError("string '%1%' doesn't represent an absolute path", path, pos); return path; } @@ -1883,7 +1907,11 @@ void EvalState::printStats() string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const { - throw TypeError("cannot coerce %1% to a string, at %2%", showType(), pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt("cannot coerce %1% to a string", showType()), + .nixCode = NixCode { .errPos = pos } + }); } diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 3ed9a7a4f..a3ad54a3d 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -404,7 +404,12 @@ expr_simple | URI { static bool noURLLiterals = settings.isExperimentalFeatureEnabled("no-url-literals"); if (noURLLiterals) - throw ParseError("URL literals are disabled, at %s", CUR_POS); + throw ParseError( + ErrorInfo { + .hint = hintfmt("URL literals are disabled"), + .nixCode = NixCode { .errPos = CUR_POS } + }); + $$ = new ExprString(data->symbols.create($1)); } | '(' expr ')' { $$ = $2; } @@ -669,10 +674,12 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos Path res = r.second + suffix; if (pathExists(res)) return canonPath(res); } - string f = - "file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)" - + string(pos ? ", at %2%" : ""); - throw ThrownError(f, path, pos); + + throw ThrownError( + ErrorInfo { + .hint = hintfmt("file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)", path), + .nixCode = NixCode { .errPos = pos } + }); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 13eb1ba58..771136af9 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -94,8 +94,13 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%", - path, e.path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot import '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); + } Path realPath = state.checkSourcePath(state.toRealPath(path, context)); @@ -171,8 +176,13 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError("cannot import '%1%', since path '%2%' is not valid, at %3%" - , path, e.path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt( + "cannot import '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } path = state.checkSourcePath(path); @@ -207,7 +217,11 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) auto elems = args[0]->listElems(); auto count = args[0]->listSize(); if (count == 0) { - throw EvalError("at least one argument to 'exec' required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("at least one argument to 'exec' required"), + .nixCode = NixCode { .errPos = pos } + }); } PathSet context; auto program = state.coerceToString(pos, *elems[0], context, false, false); @@ -218,9 +232,12 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError("cannot execute '%1%', since path '%2%' is not valid, at %3%" - , program, e.path, pos); - } + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot execute '%1%', since path '%2%' is not valid" + , program, e.path), + .nixCode = NixCode { .errPos = pos } + });} auto output = runProgram(program, true, commandArgs); Expr * parsed; @@ -371,7 +388,11 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator startSet = args[0]->attrs->find(state.symbols.create("startSet")); if (startSet == args[0]->attrs->end()) - throw EvalError("attribute 'startSet' required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("attribute 'startSet' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceList(*startSet->value, pos); ValueList workSet; @@ -382,7 +403,11 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator op = args[0]->attrs->find(state.symbols.create("operator")); if (op == args[0]->attrs->end()) - throw EvalError("attribute 'operator' required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("attribute 'operator' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*op->value); /* Construct the closure by applying the operator to element of @@ -401,7 +426,11 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator key = e->attrs->find(state.symbols.create("key")); if (key == e->attrs->end()) - throw EvalError("attribute 'key' required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("attribute 'key' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*key->value); if (!doneKeys.insert(key->value).second) continue; @@ -533,7 +562,11 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Figure out the name first (for stack backtraces). */ Bindings::iterator attr = args[0]->attrs->find(state.sName); if (attr == args[0]->attrs->end()) - throw EvalError("required attribute 'name' missing, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("required attribute 'name' missing"), + .nixCode = NixCode { .errPos = pos } + }); string drvName; Pos & posDrvName(*attr->pos); try { @@ -576,25 +609,45 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * auto handleHashMode = [&](const std::string & s) { if (s == "recursive") outputHashRecursive = true; else if (s == "flat") outputHashRecursive = false; - else throw EvalError("invalid value '%s' for 'outputHashMode' attribute, at %s", s, posDrvName); + else + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid value '%s' for 'outputHashMode' attribute", s), + .nixCode = NixCode { .errPos = posDrvName } + }); }; auto handleOutputs = [&](const Strings & ss) { outputs.clear(); for (auto & j : ss) { if (outputs.find(j) != outputs.end()) - throw EvalError("duplicate derivation output '%1%', at %2%", j, posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("duplicate derivation output '%1%'", j), + .nixCode = NixCode { .errPos = posDrvName } + }); + + /* !!! Check whether j is a valid attribute name. */ /* Derivations cannot be named ‘drv’, because then we'd have an attribute ‘drvPath’ in the resulting set. */ if (j == "drv") - throw EvalError("invalid derivation output name 'drv', at %1%", posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid derivation output name 'drv'" ), + .nixCode = NixCode { .errPos = posDrvName } + }); + outputs.insert(j); } if (outputs.empty()) - throw EvalError("derivation cannot have an empty set of outputs, at %1%", posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("derivation cannot have an empty set of outputs"), + .nixCode = NixCode { .errPos = posDrvName } + }); }; try { @@ -706,18 +759,37 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Do we have all required attributes? */ if (drv.builder == "") - throw EvalError("required attribute 'builder' missing, at %1%", posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("required attribute 'builder' missing"), + .nixCode = NixCode { .errPos = posDrvName } + }); + if (drv.platform == "") - throw EvalError("required attribute 'system' missing, at %1%", posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("required attribute 'system' missing"), + .nixCode = NixCode { .errPos = posDrvName } + }); + /* Check whether the derivation name is valid. */ if (isDerivation(drvName)) - throw EvalError("derivation names are not allowed to end in '%s', at %s", drvExtension, posDrvName); + throw EvalError( + ErrorInfo { + .hint = hintfmt("derivation names are not allowed to end in '%s'", drvExtension), + .nixCode = NixCode { .errPos = posDrvName } + }); + if (outputHash) { /* Handle fixed-output derivations. */ if (outputs.size() != 1 || *(outputs.begin()) != "out") - throw Error("multiple outputs are not supported in fixed-output derivations, at %1%", posDrvName); + throw Error( + ErrorInfo { + .hint = hintfmt("multiple outputs are not supported in fixed-output derivations"), + .nixCode = NixCode { .errPos = posDrvName } + }); HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); Hash h(*outputHash, ht); @@ -818,7 +890,11 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V e.g. nix-push does the right thing. */ if (!state.store->isStorePath(path)) path = canonPath(path, true); if (!state.store->isInStore(path)) - throw EvalError("path '%1%' is not in the Nix store, at %2%", path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("path '%1%' is not in the Nix store", path), + .nixCode = NixCode { .errPos = pos } + }); Path path2 = state.store->toStorePath(path); if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(path2)); @@ -835,8 +911,12 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, state.realiseContext(context); } catch (InvalidPathError & e) { throw EvalError( - "cannot check the existence of '%1%', since path '%2%' is not valid, at %3%", - path, e.path, pos); + ErrorInfo { + .hint = hintfmt( + "cannot check the existence of '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } try { @@ -879,9 +959,13 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%" - , path, e.path, pos); - } + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid" + , path, e.path), + .nixCode = NixCode { .errPos = pos } + }); + } string s = readFile(state.checkSourcePath(state.toRealPath(path, context))); if (s.find((char) 0) != string::npos) throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path); @@ -908,7 +992,11 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va i = v2.attrs->find(state.symbols.create("path")); if (i == v2.attrs->end()) - throw EvalError("attribute 'path' missing, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("attribute 'path' missing"), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; string path = state.coerceToString(pos, *i->value, context, false, false); @@ -916,8 +1004,12 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError("cannot find '%1%', since path '%2%' is not valid, at %3%", - path, e.path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot find '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } searchPath.emplace_back(prefix, path); @@ -934,7 +1026,11 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error("unknown hash type '%1%', at %2%", type, pos); + throw Error( + ErrorInfo { + .hint = hintfmt("unknown hash type '%1%'", type), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; // discarded Path p = state.coerceToPath(pos, *args[1], context); @@ -950,8 +1046,12 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val try { state.realiseContext(ctx); } catch (InvalidPathError & e) { - throw EvalError("cannot read '%1%', since path '%2%' is not valid, at %3%", - path, e.path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } DirEntries entries = readDirectory(state.checkSourcePath(path)); @@ -1021,7 +1121,13 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu for (auto path : context) { if (path.at(0) != '/') - throw EvalError("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%", name, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt( + "in 'toFile': the file '%1%' cannot refer to derivation outputs", \ + name), + .nixCode = NixCode { .errPos = pos } + }); refs.insert(state.store->parseStorePath(path)); } @@ -1089,11 +1195,21 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args PathSet context; Path path = state.coerceToPath(pos, *args[1], context); if (!context.empty()) - throw EvalError("string '%1%' cannot refer to other paths, at %2%", path, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("string '%1%' cannot refer to other paths", path), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*args[0]); if (args[0]->type != tLambda) - throw TypeError("first argument in call to 'filterSource' is not a function but %1%, at %2%", showType(*args[0]), pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt( + "first argument in call to 'filterSource' is not a function but %1%", + showType(*args[0])), + .nixCode = NixCode { .errPos = pos } + }); addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v); } @@ -1113,7 +1229,13 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value PathSet context; path = state.coerceToPath(*attr.pos, *attr.value, context); if (!context.empty()) - throw EvalError("string '%1%' cannot refer to other paths, at %2%", path, *attr.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("string '%1%' cannot refer to other paths", + path), + .nixCode = NixCode { .errPos = *attr.pos } + }); + } else if (attr.name == state.sName) name = state.forceStringNoCtx(*attr.value, *attr.pos); else if (n == "filter") { @@ -1124,10 +1246,19 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value else if (n == "sha256") expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); else - throw EvalError("unsupported argument '%1%' to 'addPath', at %2%", attr.name, *attr.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("unsupported argument '%1%' to 'addPath'", + attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (path.empty()) - throw EvalError("'path' required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("'path' required"), + .nixCode = NixCode { .errPos = pos } + }); if (name.empty()) name = baseNameOf(path); @@ -1185,7 +1316,12 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) // !!! Should we create a symbol here or just do a lookup? Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); if (i == args[1]->attrs->end()) - throw EvalError("attribute '%1%' missing, at %2%", attr, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("attribute '%1%' missing", attr), + .nixCode = NixCode { .errPos = pos } + }); + // !!! add to stack trace? if (state.countCalls && i->pos) state.attrSelects[*i->pos]++; state.forceValue(*i->value); @@ -1265,14 +1401,23 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, Bindings::iterator j = v2.attrs->find(state.sName); if (j == v2.attrs->end()) - throw TypeError("'name' attribute missing in a call to 'listToAttrs', at %1%", pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt("'name' attribute missing in a call to 'listToAttrs'"), + .nixCode = NixCode { .errPos = pos } + }); + string name = state.forceStringNoCtx(*j->value, pos); Symbol sym = state.symbols.create(name); if (seen.insert(sym).second) { Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue)); if (j2 == v2.attrs->end()) - throw TypeError("'value' attribute missing in a call to 'listToAttrs', at %1%", pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt("'value' attribute missing in a call to 'listToAttrs'"), + .nixCode = NixCode { .errPos = pos } + }); v.attrs->push_back(Attr(sym, j2->value, j2->pos)); } @@ -1346,7 +1491,12 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args { state.forceValue(*args[0]); if (args[0]->type != tLambda) - throw TypeError("'functionArgs' requires a function, at %1%", pos); + throw TypeError( + ErrorInfo { + .hint = hintfmt("'functionArgs' requires a function"), + .nixCode = NixCode { .errPos = pos } + }); + if (!args[0]->lambda.fun->matchAttrs) { state.mkAttrs(v, 0); @@ -1396,7 +1546,12 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu { state.forceList(list, pos); if (n < 0 || (unsigned int) n >= list.listSize()) - throw Error("list index %1% is out of bounds, at %2%", n, pos); + throw Error( + ErrorInfo { + .hint = hintfmt("list index %1% is out of bounds", n), + .nixCode = NixCode { .errPos = pos } + }); + state.forceValue(*list.listElems()[n]); v = *list.listElems()[n]; } @@ -1423,7 +1578,12 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value { state.forceList(*args[0], pos); if (args[0]->listSize() == 0) - throw Error("'tail' called on an empty list, at %1%", pos); + throw Error( + ErrorInfo { + .hint = hintfmt("'tail' called on an empty list"), + .nixCode = NixCode { .errPos = pos } + }); + state.mkList(v, args[0]->listSize() - 1); for (unsigned int n = 0; n < v.listSize(); ++n) v.listElems()[n] = args[0]->listElems()[n + 1]; @@ -1564,7 +1724,12 @@ static void prim_genList(EvalState & state, const Pos & pos, Value * * args, Val auto len = state.forceInt(*args[1], pos); if (len < 0) - throw EvalError("cannot create list of size %1%, at %2%", len, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("cannot create list of size %1%", len), + .nixCode = NixCode { .errPos = pos } + }); + state.mkList(v, len); @@ -1722,7 +1887,12 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & state.forceValue(*args[1], pos); NixFloat f2 = state.forceFloat(*args[1], pos); - if (f2 == 0) throw EvalError("division by zero, at %1%", pos); + if (f2 == 0) + throw EvalError( + ErrorInfo { + .hint = hintfmt("division by zero"), + .nixCode = NixCode { .errPos = pos } + }); if (args[0]->type == tFloat || args[1]->type == tFloat) { mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos)); @@ -1731,7 +1901,12 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & NixInt i2 = state.forceInt(*args[1], pos); /* Avoid division overflow as it might raise SIGFPE. */ if (i1 == std::numeric_limits::min() && i2 == -1) - throw EvalError("overflow in integer division, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("overflow in integer division"), + .nixCode = NixCode { .errPos = pos } + }); + mkInt(v, i1 / i2); } } @@ -1787,7 +1962,12 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V PathSet context; string s = state.coerceToString(pos, *args[2], context); - if (start < 0) throw EvalError("negative start position in 'substring', at %1%", pos); + if (start < 0) + throw EvalError( + ErrorInfo { + .hint = hintfmt("negative start position in 'substring'"), + .nixCode = NixCode { .errPos = pos } + }); mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context); } @@ -1807,7 +1987,11 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error("unknown hash type '%1%', at %2%", type, pos); + throw Error( + ErrorInfo { + .hint = hintfmt("unknown hash type '%1%'", type), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; // discarded string s = state.forceString(*args[1], context, pos); @@ -1849,10 +2033,18 @@ void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v) } catch (std::regex_error &e) { if (e.code() == std::regex_constants::error_space) { - // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ - throw EvalError("memory limit exceeded by regular expression '%s', at %s", re, pos); + // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ + throw EvalError( + ErrorInfo { + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } else { - throw EvalError("invalid regular expression '%s', at %s", re, pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } } } @@ -1917,10 +2109,18 @@ static void prim_split(EvalState & state, const Pos & pos, Value * * args, Value } catch (std::regex_error &e) { if (e.code() == std::regex_constants::error_space) { // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ - throw EvalError("memory limit exceeded by regular expression '%s', at %s", re, pos); - } else { - throw EvalError("invalid regular expression '%s', at %s", re, pos); - } + throw EvalError( + ErrorInfo { + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); + } else { + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); + } } } @@ -1950,7 +2150,11 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar state.forceList(*args[0], pos); state.forceList(*args[1], pos); if (args[0]->listSize() != args[1]->listSize()) - throw EvalError("'from' and 'to' arguments to 'replaceStrings' have different lengths, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("'from' and 'to' arguments to 'replaceStrings' have different lengths"), + .nixCode = NixCode { .errPos = pos } + }); vector from; from.reserve(args[0]->listSize()); @@ -2072,11 +2276,20 @@ void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, else if (n == "name") request.name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError("unsupported argument '%1%' to '%2%', at %3%", attr.name, who, attr.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("unsupported argument '%1%' to '%2%'", attr.name, who), + .nixCode = NixCode { .errPos = pos } + }); + } if (request.uri.empty()) - throw EvalError("'url' argument required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else request.uri = state.forceStringNoCtx(*args[0], pos); diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 94fa0158c..768936453 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -146,7 +146,12 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg auto sAllOutputs = state.symbols.create("allOutputs"); for (auto & i : *args[1]->attrs) { if (!state.store->isStorePath(i.name)) - throw EvalError("Context key '%s' is not a store path, at %s", i.name, i.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("Context key '%s' is not a store path", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); + if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(i.name)); state.forceAttrs(*i.value, *i.pos); @@ -160,7 +165,12 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg if (iter != i.value->attrs->end()) { if (state.forceBool(*iter->value, *iter->pos)) { if (!isDerivation(i.name)) { - throw EvalError("Tried to add all-outputs context of %s, which is not a derivation, to a string, at %s", i.name, i.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); + } context.insert("=" + string(i.name)); } @@ -170,7 +180,11 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg if (iter != i.value->attrs->end()) { state.forceList(*iter->value, *iter->pos); if (iter->value->listSize() && !isDerivation(i.name)) { - throw EvalError("Tried to add derivation output context of %s, which is not a derivation, to a string, at %s", i.name, i.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); } for (unsigned int n = 0; n < iter->value->listSize(); ++n) { auto name = state.forceStringNoCtx(*iter->value->listElems()[n], *iter->pos); diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 480cc1adc..68ffed513 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -217,11 +217,19 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError("unsupported argument '%s' to 'fetchGit', at %s", attr.name, *attr.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("unsupported argument '%s' to 'fetchGit'", attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (url.empty()) - throw EvalError("'url' argument required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 76029f548..ce99928e2 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -187,11 +187,20 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError("unsupported argument '%s' to 'fetchMercurial', at %s", attr.name, *attr.pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("unsupported argument '%s' to 'fetchMercurial'", attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); + } if (url.empty()) - throw EvalError("'url' argument required, at %1%", pos); + throw EvalError( + ErrorInfo { + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libutil/error.cc b/src/libutil/error.cc index d4305ddd8..ce5dde6c3 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -1,4 +1,4 @@ -#include "types.hh" +#include "error.hh" #include #include @@ -25,54 +25,60 @@ std::ostream& operator<<(std::ostream &os, const hintformat &hf) string showErrPos(const ErrPos &errPos) { - if (errPos.column > 0) { - return fmt("(%1%:%2%)", errPos.line, errPos.column); - } else { - return fmt("(%1%)", errPos.line); - }; + if (errPos.line > 0) { + if (errPos.column > 0) { + return fmt("(%1%:%2%)", errPos.line, errPos.column); + } else { + return fmt("(%1%)", errPos.line); + } + } + else { + return ""; + } } -void printCodeLines(const string &prefix, const NixCode &nixCode) +void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixCode) { // previous line of code. if (nixCode.prevLineOfCode.has_value()) { - std::cout << fmt("%1% %|2$5d|| %3%", + out << fmt("%1% %|2$5d|| %3%", prefix, (nixCode.errPos.line - 1), *nixCode.prevLineOfCode) - << std::endl; + << std::endl; } - // line of code containing the error.%2$+5d% - std::cout << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line), - nixCode.errLineOfCode) - << std::endl; - - // error arrows for the column range. - if (nixCode.errPos.column > 0) { - int start = nixCode.errPos.column; - std::string spaces; - for (int i = 0; i < start; ++i) { - spaces.append(" "); - } + if (nixCode.errLineOfCode.has_value()) { + // line of code containing the error. + out << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.line), + *nixCode.errLineOfCode) + << std::endl; + // error arrows for the column range. + if (nixCode.errPos.column > 0) { + int start = nixCode.errPos.column; + std::string spaces; + for (int i = 0; i < start; ++i) { + spaces.append(" "); + } - std::string arrows("^"); + std::string arrows("^"); - std::cout << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, - prefix, - spaces, - arrows) << std::endl; + out << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, + prefix, + spaces, + arrows) << std::endl; + } } // next line of code. if (nixCode.nextLineOfCode.has_value()) { - std::cout << fmt("%1% %|2$5d|| %3%", + out << fmt("%1% %|2$5d|| %3%", prefix, (nixCode.errPos.line + 1), *nixCode.nextLineOfCode) - << std::endl; + << std::endl; } } @@ -83,52 +89,52 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) string levelString; switch (einfo.level) { - case Verbosity::lvlError: { - levelString = ANSI_RED; - levelString += "error:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlWarn: { - levelString = ANSI_YELLOW; - levelString += "warning:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlInfo: { - levelString = ANSI_GREEN; - levelString += "info:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlTalkative: { - levelString = ANSI_GREEN; - levelString += "talk:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlChatty: { - levelString = ANSI_GREEN; - levelString += "chat:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlVomit: { - levelString = ANSI_GREEN; - levelString += "vomit:"; - levelString += ANSI_NORMAL; - break; - } - case Verbosity::lvlDebug: { - levelString = ANSI_YELLOW; - levelString += "debug:"; - levelString += ANSI_NORMAL; - break; - } - default: { - levelString = fmt("invalid error level: %1%", einfo.level); - break; - } + case Verbosity::lvlError: { + levelString = ANSI_RED; + levelString += "error:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlWarn: { + levelString = ANSI_YELLOW; + levelString += "warning:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlInfo: { + levelString = ANSI_GREEN; + levelString += "info:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlTalkative: { + levelString = ANSI_GREEN; + levelString += "talk:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlChatty: { + levelString = ANSI_GREEN; + levelString += "chat:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlVomit: { + levelString = ANSI_GREEN; + levelString += "vomit:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlDebug: { + levelString = ANSI_YELLOW; + levelString += "debug:"; + levelString += ANSI_NORMAL; + break; + } + default: { + levelString = fmt("invalid error level: %1%", einfo.level); + break; + } } int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); @@ -158,14 +164,10 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) // filename. if (einfo.nixCode.has_value()) { if (einfo.nixCode->errPos.file != "") { - string eline = einfo.nixCode->errLineOfCode != "" - ? string(" ") + showErrPos(einfo.nixCode->errPos) - : ""; - - out << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, + out << fmt("%1%in file: " ANSI_BLUE "%2% %3%" ANSI_NORMAL, prefix, einfo.nixCode->errPos.file, - eline) << std::endl; + showErrPos(einfo.nixCode->errPos)) << std::endl; out << prefix << std::endl; } else { out << fmt("%1%from command line argument", prefix) << std::endl; @@ -180,8 +182,8 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) } // lines of code. - if (einfo.nixCode.has_value() && einfo.nixCode->errLineOfCode != "") { - printCodeLines(prefix, *einfo.nixCode); + if (einfo.nixCode.has_value()) { + printCodeLines(out, prefix, *einfo.nixCode); out << prefix << std::endl; } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 19a806cc1..7e2cca2f9 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -35,10 +35,15 @@ typedef enum { } Verbosity; struct ErrPos { - int line; - int column; + int line = 0; + int column = 0; string file; + operator bool() const + { + return line != 0; + } + template ErrPos& operator=(const P &pos) { @@ -58,7 +63,7 @@ struct ErrPos { struct NixCode { ErrPos errPos; std::optional prevLineOfCode; - string errLineOfCode; + std::optional errLineOfCode; std::optional nextLineOfCode; }; diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index e1750eb2a..4244d1221 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -171,7 +171,8 @@ struct JSONLogger : Logger { json["file"] = ei.nixCode->errPos.file; if (ei.nixCode->prevLineOfCode.has_value()) json["prevLineOfCode"] = *ei.nixCode->prevLineOfCode; - json["errLineOfCode"] = ei.nixCode->errLineOfCode; + if (ei.nixCode->errLineOfCode.has_value()) + json["errLineOfCode"] = *ei.nixCode->errLineOfCode; if (ei.nixCode->nextLineOfCode.has_value()) json["nextLineOfCode"] = *ei.nixCode->nextLineOfCode; } -- cgit v1.2.3 From 958e81987b5b86fba06090078a556f51037aa23c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 May 2020 13:02:16 -0600 Subject: switch from printError warnings to logWarnings --- src/libstore/build.cc | 14 +++++++++++--- src/libstore/store-api.cc | 6 +++++- src/libutil/error.cc | 2 +- src/libutil/serialise.cc | 5 ++++- src/nix-build/nix-build.cc | 9 ++++++--- src/nix-store/nix-store.cc | 5 ++++- 6 files changed, 31 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f8cc1ce36..a7d6e53b0 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -3647,7 +3647,11 @@ void DerivationGoal::registerOutputs() /* Apply hash rewriting if necessary. */ bool rewritten = false; if (!outputRewrites.empty()) { - printError("warning: rewriting hashes in '%1%'; cross fingers", path); + logWarning( + ErrorInfo { + .name = "Rewriting hashes", + .hint = hintfmt("rewriting hashes in '%1%'; cross fingers", path) + }); /* Canonicalise first. This ensures that the path we're rewriting doesn't contain a hard link to /etc/shadow or @@ -4414,8 +4418,12 @@ void SubstitutionGoal::tryNext() && !sub->isTrusted && !info->checkSignatures(worker.store, worker.store.getPublicKeys())) { - printError("warning: substituter '%s' does not have a valid signature for path '%s'", - sub->getUri(), worker.store.printStorePath(storePath)); + logWarning( + ErrorInfo { + .name = "Invalid path signature", + .hint = hintfmt("substituter '%s' does not have a valid signature for path '%s'", + sub->getUri(), worker.store.printStorePath(storePath)) + }); tryNext(); return; } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 542e5c552..d1281d130 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -769,7 +769,11 @@ void ValidPathInfo::sign(const Store & store, const SecretKey & secretKey) bool ValidPathInfo::isContentAddressed(const Store & store) const { auto warn = [&]() { - printError("warning: path '%s' claims to be content-addressed but isn't", store.printStorePath(path)); + logWarning( + ErrorInfo{ + .name = "Path not content-addressed", + .hint = hintfmt("path '%s' claims to be content-addressed but isn't", store.printStorePath(path)) + }); }; if (hasPrefix(ca, "text:")) { diff --git a/src/libutil/error.cc b/src/libutil/error.cc index ce5dde6c3..e4f45a2d3 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -161,7 +161,7 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) einfo.programName.value_or("")) << std::endl; - // filename. + // filename, line, column. if (einfo.nixCode.has_value()) { if (einfo.nixCode->errPos.file != "") { out << fmt("%1%in file: " ANSI_BLUE "%2% %3%" ANSI_NORMAL, diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 8201549fd..35f7ee917 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -52,7 +52,10 @@ size_t threshold = 256 * 1024 * 1024; static void warnLargeDump() { - printError("warning: dumping very large path (> 256 MiB); this may run out of memory"); + logWarning(ErrorInfo { + .name = "Large path", + .description = "dumping very large path (> 256 MiB); this may run out of memory" + }); } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 3c2f4f00c..03200d050 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -368,9 +368,12 @@ static void _main(int argc, char * * argv) shell = drv->queryOutPath() + "/bin/bash"; } catch (Error & e) { - // TODO: append error msg; warn()? - logError(e.info()); - printError("warning: %s; will use bash from your environment", e.what()); + logWarning( + ErrorInfo { + .name = "bashInteractive", + .hint = hintfmt("%s; will use bash from your environment", + (e.info().hint ? e.info().hint->str() : "")) + }); shell = "bash"; } } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 57063d42f..9b5cceccf 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -704,7 +704,10 @@ static void opVerify(Strings opFlags, Strings opArgs) else throw UsageError("unknown flag '%1%'", i); if (store->verifyStore(checkContents, repair)) { - printError("warning: not all errors were fixed"); + logWarning(ErrorInfo { + .name = "Store consistency", + .description = "not all errors were fixed" + }); throw Exit(1); } } -- cgit v1.2.3 From 536bbf53e12c80f52c2679aec734d895b0058f5b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 May 2020 13:58:38 -0600 Subject: comments and cleanup --- src/error-demo/error-demo.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 41293427c..8f484431c 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -10,27 +10,27 @@ MakeError(DemoError, Error); int main() { - makeDefaultLogger(); - verbosity = lvlVomit; // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); + // 'DemoError' appears as error name. try { throw DemoError("demo error was thrown"); } catch (Error &e) { logger->logEI(e.info()); } - // ErrorInfo constructor + // appending to the hint from the previous error try { - auto e = Error("some error"); + auto e = Error("initial error"); throw DemoError(e.info()); } catch (Error &e) { ErrorInfo ei = e.info(); - string prevhint = (e.info().hint.has_value() ? e.info().hint->str() : ""); - ei.hint = std::optional(hintfmt("previous hint was: %s", normaltxt(prevhint))); + // using normaltxt to avoid the default yellow highlighting. + ei.hint = hintfmt("%s; subsequent error message.", + normaltxt(e.info().hint ? e.info().hint->str() : "")); logger->logEI(ei); } @@ -38,8 +38,8 @@ int main() try { auto x = readFile(-1); } - catch (Error &e) { - std::cout << "error: " << e.sname() << std::endl; + catch (SysError &e) { + std::cout << "errno was: " << e.errNo << std::endl; logError(e.info()); } @@ -59,7 +59,7 @@ int main() } } - // For completeness sake, info through vomit levels. + // For completeness sake, show 'info' through 'vomit' levels. // But this is maybe a heavy format for those. logger->logEI( ErrorInfo { .level = lvlInfo, -- cgit v1.2.3 From b93c1bf3d67716231d2ff7ee4154b8c80a251b10 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 May 2020 15:52:15 -0600 Subject: fixes to merged code --- src/libexpr/nixexpr.hh | 1 + src/libexpr/primops.cc | 2 +- src/libmain/stack.cc | 2 +- src/libstore/build.cc | 20 ++++++++++---------- src/libstore/filetransfer.hh | 3 ++- src/libstore/local-store.cc | 1 + src/libstore/sqlite.hh | 2 +- src/libutil/args.cc | 7 ------- src/libutil/error.hh | 4 +--- src/libutil/logging.hh | 1 + src/libutil/types.hh | 1 + src/libutil/url.hh | 2 +- src/libutil/util.cc | 16 ++++++++-------- 13 files changed, 29 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 137fe7198..a185d5785 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -2,6 +2,7 @@ #include "value.hh" #include "symbol-table.hh" +#include "error.hh" #include diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 10e8c6b42..657ce3001 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1124,7 +1124,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu ErrorInfo { .hint = hintfmt( "in 'toFile': the file named '%1%' must not contain a reference " - "to a derivation but contains (%2%)" + "to a derivation but contains (%2%)", name, path), .nixCode = NixCode { .errPos = pos } diff --git a/src/libmain/stack.cc b/src/libmain/stack.cc index e6224de7d..b0a4a4c5d 100644 --- a/src/libmain/stack.cc +++ b/src/libmain/stack.cc @@ -1,4 +1,4 @@ -#include "types.hh" +#include "error.hh" #include #include diff --git a/src/libstore/build.cc b/src/libstore/build.cc index d6f3553d9..0359b10ac 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -547,7 +547,7 @@ UserLock::UserLock() /* Copy the result of getgrnam. */ Strings users; for (char * * p = gr->gr_mem; *p; ++p) { - debug(format("found build user '%1%'") % *p); + debug("found build user '%1%'", *p); users.push_back(*p); } @@ -558,7 +558,7 @@ UserLock::UserLock() /* Find a user account that isn't currently in use for another build. */ for (auto & i : users) { - debug(format("trying user '%1%'") % i); + debug("trying user '%1%'", i); struct passwd * pw = getpwnam(i.c_str()); if (!pw) @@ -1794,7 +1794,7 @@ HookReply DerivationGoal::tryBuildHook() } } - debug(format("hook reply is '%1%'") % reply); + debug("hook reply is '%1%'", reply); if (reply == "decline") return rpDecline; @@ -2255,7 +2255,7 @@ void DerivationGoal::startBuilder() startDaemon(); /* Run the builder. */ - printMsg(lvlChatty, format("executing builder '%1%'") % drv->builder); + printMsg(lvlChatty, "executing builder '%1%'", drv->builder); /* Create the log file. */ Path logFile = openLogFile(); @@ -3195,7 +3195,7 @@ void DerivationGoal::runChild() filesystem that we want in the chroot environment. */ auto doBind = [&](const Path & source, const Path & target, bool optional = false) { - debug(format("bind mounting '%1%' to '%2%'") % source % target); + debug("bind mounting '%1%' to '%2%'", source, target); struct stat st; if (stat(source.c_str(), &st) == -1) { if (optional && errno == ENOENT) @@ -3572,7 +3572,7 @@ static void moveCheckToStore(const Path & src, const Path & dst) directory's parent link ".."). */ struct stat st; if (lstat(src.c_str(), &st) == -1) { - throw SysError(format("getting attributes of path '%1%'") % src); + throw SysError("getting attributes of path '%1%'", src); } bool changePerm = (geteuid() && S_ISDIR(st.st_mode) && !(st.st_mode & S_IWUSR)); @@ -3581,7 +3581,7 @@ static void moveCheckToStore(const Path & src, const Path & dst) chmod_(src, st.st_mode | S_IWUSR); if (rename(src.c_str(), dst.c_str())) - throw SysError(format("renaming '%1%' to '%2%'") % src % dst); + throw SysError("renaming '%1%' to '%2%'", src, dst); if (changePerm) chmod_(dst, st.st_mode); @@ -4911,15 +4911,15 @@ void Worker::waitForInput() // FIXME: is there a cleaner way to handle pt close // than EIO? Is this even standard? if (rd == 0 || (rd == -1 && errno == EIO)) { - debug(format("%1%: got EOF") % goal->getName()); + debug("%1%: got EOF", goal->getName()); goal->handleEOF(k); j->fds.erase(k); } else if (rd == -1) { if (errno != EINTR) throw SysError("%s: read failed", goal->getName()); } else { - printMsg(lvlVomit, format("%1%: read %2% bytes") - % goal->getName() % rd); + printMsg(lvlVomit, "%1%: read %2% bytes", + goal->getName(), rd); string data((char *) buffer.data(), rd); j->lastOutput = after; goal->handleChildOutput(k, data); diff --git a/src/libstore/filetransfer.hh b/src/libstore/filetransfer.hh index 517b1a7d3..11dca2fe0 100644 --- a/src/libstore/filetransfer.hh +++ b/src/libstore/filetransfer.hh @@ -103,8 +103,9 @@ class FileTransferError : public Error { public: FileTransfer::Error error; + template FileTransferError(FileTransfer::Error error, const Args & ... args) - : Error(fs), error(error) + : Error(args...), error(error) { } }; diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 1f16a22b1..eb7548543 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -6,6 +6,7 @@ #include "derivations.hh" #include "nar-info.hh" #include "references.hh" +#include "error.hh" #include #include diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index ce27033c9..ccfac48d8 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -3,7 +3,7 @@ #include #include -#include "types.hh" +#include "error.hh" struct sqlite3; struct sqlite3_stmt; diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 423b99c96..10d6e89bb 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -101,15 +101,8 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end) std::vector args; for (size_t n = 0 ; n < flag.handler.arity; ++n) { if (pos == end) { -<<<<<<< HEAD - if (flag.arity == ArityAny) break; - throw UsageError("flag '%1%' requires %2% argument(s)", - name, - flag.arity); -======= if (flag.handler.arity == ArityAny) break; throw UsageError("flag '%s' requires %d argument(s)", name, flag.handler.arity); ->>>>>>> master } args.push_back(*pos++); } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 7e2cca2f9..19c6e35a1 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -2,6 +2,7 @@ #include "ref.hh" +#include "types.hh" #include #include @@ -21,9 +22,6 @@ namespace nix { -using std::list; -using std::vector; - typedef enum { lvlError = 0, lvlWarn, diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index bb7d356c8..39692a291 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -1,6 +1,7 @@ #pragma once #include "types.hh" +#include "error.hh" namespace nix { diff --git a/src/libutil/types.hh b/src/libutil/types.hh index a831b9924..4d783b564 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -13,6 +13,7 @@ namespace nix { using std::list; using std::set; using std::vector; +using std::string; typedef list Strings; typedef set StringSet; diff --git a/src/libutil/url.hh b/src/libutil/url.hh index 1503023a2..a184eadce 100644 --- a/src/libutil/url.hh +++ b/src/libutil/url.hh @@ -1,6 +1,6 @@ #pragma once -#include "types.hh" +#include "error.hh" #include diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 8207ff701..ac7c2967b 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -276,7 +276,7 @@ DirEntries readDirectory(DIR *dir, const Path & path) DirEntries readDirectory(const Path & path) { AutoCloseDir dir(opendir(path.c_str())); - if (!dir) throw SysError(format("opening directory '%1%'") % path); + if (!dir) throw SysError("opening directory '%1%'", path); return readDirectory(dir.get(), path); } @@ -306,7 +306,7 @@ string readFile(const Path & path) { AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); if (!fd) - throw SysError(format("opening file '%1%'") % path); + throw SysError("opening file '%1%'", path); return readFile(fd.get()); } @@ -394,15 +394,15 @@ static void _deletePath(int parentfd, const Path & path, unsigned long long & by const auto PERM_MASK = S_IRUSR | S_IWUSR | S_IXUSR; if ((st.st_mode & PERM_MASK) != PERM_MASK) { if (fchmodat(parentfd, name.c_str(), st.st_mode | PERM_MASK, 0) == -1) - throw SysError(format("chmod '%1%'") % path); + throw SysError("chmod '%1%'", path); } int fd = openat(parentfd, path.c_str(), O_RDONLY); if (!fd) - throw SysError(format("opening directory '%1%'") % path); + throw SysError("opening directory '%1%'", path); AutoCloseDir dir(fdopendir(fd)); if (!dir) - throw SysError(format("opening directory '%1%'") % path); + throw SysError("opening directory '%1%'", path); for (auto & i : readDirectory(dir.get(), path)) _deletePath(dirfd(dir.get()), path + "/" + i.name, bytesFreed); } @@ -426,7 +426,7 @@ static void _deletePath(const Path & path, unsigned long long & bytesFreed) // for backwards compatibility. if (errno == ENOENT) return; - throw SysError(format("opening directory '%1%'") % path); + throw SysError("opening directory '%1%'", path); } _deletePath(dirfd.get(), path, bytesFreed); @@ -845,7 +845,7 @@ int Pid::kill() { assert(pid != -1); - debug(format("killing process %1%") % pid); + debug("killing process %1%", pid); /* Send the requested signal to the child. If it has its own process group, send the signal to every process in the child @@ -903,7 +903,7 @@ pid_t Pid::release() void killUser(uid_t uid) { - debug(format("killing all processes running under uid '%1%'") % uid); + debug("killing all processes running under uid '%1%'", uid); assert(uid != 0); /* just to be safe... */ -- cgit v1.2.3 From 631642c5b40032a087b8e2e131b2ebcac00913d3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 May 2020 16:58:08 -0600 Subject: new format for pos --- src/libexpr/parser.y | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 82d5753ab..6d50d74ba 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -64,15 +64,23 @@ namespace nix { static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos) { - throw ParseError("attribute '%1%' at %2% already defined at %3%", - showAttrPath(attrPath), pos, prevPos); + throw ParseError( + ErrorInfo { + .hint = hintfmt("attribute '%1%' already defined at %2%", + showAttrPath(attrPath), prevPos), + .nixCode = NixCode { .errPos = pos }, + }); } static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos) { - throw ParseError("attribute '%1%' at %2% already defined at %3%", - attr, pos, prevPos); + throw ParseError( + ErrorInfo { + .hint = hintfmt("attribute '%1%' already defined at %2%", + attr, prevPos), + .nixCode = NixCode { .errPos = pos }, + }); } @@ -140,8 +148,12 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, static void addFormal(const Pos & pos, Formals * formals, const Formal & formal) { if (!formals->argNames.insert(formal.name).second) - throw ParseError("duplicate formal function argument '%1%' at %2%", - formal.name, pos); + throw ParseError( + ErrorInfo { + .hint = hintfmt("duplicate formal function argument '%1%'", + formal.name), + .nixCode = NixCode { .errPos = pos }, + }); formals->formals.push_front(formal); } @@ -327,7 +339,11 @@ expr_function { $$ = new ExprWith(CUR_POS, $2, $4); } | LET binds IN expr_function { if (!$2->dynamicAttrs.empty()) - throw ParseError("dynamic attributes not allowed in let at %1%", CUR_POS); + throw ParseError( + ErrorInfo { + .hint = hintfmt("dynamic attributes not allowed in let"), + .nixCode = NixCode { .errPos = CUR_POS }, + }); $$ = new ExprLet($2, $4); } | expr_if @@ -479,8 +495,11 @@ attrs $$->push_back(AttrName(str->s)); delete str; } else - throw ParseError("dynamic attributes not allowed in inherit at %1%", - makeCurPos(@2, data)); + throw ParseError( + ErrorInfo { + .hint = hintfmt("dynamic attributes not allowed in inherit"), + .nixCode = NixCode { .errPos = makeCurPos(@2, data) }, + }); } | { $$ = new AttrPath; } ; -- cgit v1.2.3 From 7c3138844ca9ab92e2f231a7d17d7aee420ae76e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 May 2020 17:34:57 -0600 Subject: more pos reporting --- src/libexpr/nixexpr.cc | 8 ++++++-- src/libexpr/parser.y | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index a9955f6df..91a508305 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -267,8 +267,12 @@ void ExprVar::bindVars(const StaticEnv & env) /* Otherwise, the variable must be obtained from the nearest enclosing `with'. If there is no `with', then we can issue an "undefined variable" error now. */ - if (withLevel == -1) throw UndefinedVarError("undefined variable '%1%' at %2%", name, pos); - + if (withLevel == -1) + throw UndefinedVarError( + ErrorInfo { + .hint = hintfmt("undefined variable '%1%'", name), + .nixCode = NixCode { .errPos = pos } + }); fromWith = true; this->level = withLevel; } diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 6d50d74ba..3ae7bbafd 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -31,7 +31,7 @@ namespace nix { Expr * result; Path basePath; Symbol path; - string error; + ErrorInfo error; Symbol sLetBody; ParseData(EvalState & state) : state(state) @@ -261,8 +261,10 @@ static inline Pos makeCurPos(const YYLTYPE & loc, ParseData * data) void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * error) { - data->error = (format("%1%, at %2%") - % error % makeCurPos(*loc, data)).str(); + data->error = ErrorInfo { + .hint = hintfmt(error), + .nixCode = NixCode { .errPos = makeCurPos(*loc, data) } + }; } -- cgit v1.2.3 From ec870b9c853ad86fb1ccb482ca87802f1b155a2c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 10:52:26 -0600 Subject: new pos format for more errors --- src/libexpr/eval.cc | 11 ++++++++--- src/libexpr/nixexpr.hh | 6 +++++- src/libexpr/primops/fetchTree.cc | 23 +++++++++++++++++------ src/libexpr/primops/fromTOML.cc | 6 +++++- src/libstore/local-store.cc | 1 - 5 files changed, 35 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 65071206f..7af665118 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -529,7 +529,12 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) { - throw EvalError(s, sym, p1, p2); + // p1 is where the error occurred; p2 is a position mentioned in the message. + throw EvalError( + ErrorInfo { + .hint = hintfmt(s, sym, p2), + .nixCode = NixCode { .errPos = p1 } + }); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos)) @@ -638,7 +643,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError("undefined variable '%1%' at %2%", var.name, var.pos); + throwUndefinedVarError("undefined variable '%1%'", var.name, var.pos); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -950,7 +955,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError("dynamic attribute '%1%' at %2% already defined at %3%", nameSym, i.pos, *j->pos); + throwEvalError("dynamic attribute '%1%' already defined at %2%", nameSym, i.pos, *j->pos); i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index a185d5785..47d0e85ec 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -236,7 +236,11 @@ struct ExprLambda : Expr : pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body) { if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end()) - throw ParseError("duplicate formal function argument '%1%' at %2%", arg, pos); + throw ParseError( + ErrorInfo { + .hint = hintfmt("duplicate formal function argument '%1%'", arg), + .nixCode = NixCode { .errPos = pos } + }); }; void setName(Symbol & name); string showNamePos() const; diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index c5a0d9886..af3b61d6a 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -66,7 +66,11 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V } if (!attrs.count("type")) - throw Error("attribute 'type' is missing in call to 'fetchTree', at %s", pos); + throw Error( + ErrorInfo { + .hint = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), + .nixCode = NixCode { .errPos = pos } + }); input = fetchers::inputFromAttrs(attrs); } else @@ -107,13 +111,20 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError("unsupported argument '%s' to '%s', at %s", - attr.name, who, *attr.pos); - } + throw EvalError( + ErrorInfo { + .hint = hintfmt("unsupported argument '%s' to '%s'", + attr.name, who), + .nixCode = NixCode { .errPos = *attr.pos } + }); + } if (!url) - throw EvalError("'url' argument required, at %s", pos); - + throw EvalError( + ErrorInfo { + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.forceStringNoCtx(*args[0], pos); diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index c43324dbb..948069401 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -81,7 +81,11 @@ static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Va try { visit(v, parser(tomlStream).parse()); } catch (std::runtime_error & e) { - throw EvalError("while parsing a TOML string at %s: %s", pos, e.what()); + throw EvalError( + ErrorInfo { + .hint = hintfmt("while parsing a TOML string: %s", e.what()), + .nixCode = NixCode { .errPos = pos } + }); } } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index eb7548543..1f16a22b1 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -6,7 +6,6 @@ #include "derivations.hh" #include "nar-info.hh" #include "references.hh" -#include "error.hh" #include #include -- cgit v1.2.3 From 2a19bf86197083e17d9b35596c21e3c1b3f4a170 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 11:27:37 -0600 Subject: move pos to the first arg, to indicate its not used in a fmt template --- src/libexpr/eval-inline.hh | 10 ++++---- src/libexpr/eval.cc | 58 +++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index e6b838665..eee49e02e 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -7,7 +7,7 @@ namespace nix { -LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s)) { throw EvalError( ErrorInfo { @@ -22,7 +22,7 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) } -LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v)) { throw TypeError( ErrorInfo { @@ -51,7 +51,7 @@ void EvalState::forceValue(Value & v, const Pos & pos) else if (v.type == tApp) callFunction(*v.app.left, *v.app.right, v, noPos); else if (v.type == tBlackhole) - throwEvalError("infinite recursion encountered", pos); + throwEvalError(pos, "infinite recursion encountered"); } @@ -67,7 +67,7 @@ inline void EvalState::forceAttrs(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type != tAttrs) - throwTypeError("value is %1% while a set was expected", v, pos); + throwTypeError(pos, "value is %1% while a set was expected", v); } @@ -83,7 +83,7 @@ inline void EvalState::forceList(Value & v, const Pos & pos) { forceValue(v, pos); if (!v.isList()) - throwTypeError("value is %1% while a list was expected", v, pos); + throwTypeError(pos, "value is %1% while a list was expected", v); } /* Note: Various places expect the allocated memory to be zeroed. */ diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7af665118..e4bc6dc83 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -504,7 +504,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2)) throw EvalError(s, s2); } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const Pos & pos)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2)) { throw EvalError( ErrorInfo { @@ -518,7 +518,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con throw EvalError(s, s2, s3); } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, const Pos & pos)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3)) { throw EvalError( ErrorInfo { @@ -527,7 +527,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con }); } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, const Pos & p1, const Pos & p2)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2)) { // p1 is where the error occurred; p2 is a position mentioned in the message. throw EvalError( @@ -537,7 +537,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const Symbol & sym, co }); } -LocalNoInlineNoReturn(void throwTypeError(const char * s, const Pos & pos)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s)) { throw TypeError( ErrorInfo { @@ -551,7 +551,7 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) throw TypeError(s, s1); } -LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun, const Symbol & s2, const Pos & pos)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2)) { throw TypeError( ErrorInfo { @@ -560,7 +560,7 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const ExprLambda & fun }); } -LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1, const Pos & pos)) +LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1)) { throw AssertionError( ErrorInfo { @@ -569,7 +569,7 @@ LocalNoInlineNoReturn(void throwAssertionError(const char * s, const string & s1 }); } -LocalNoInlineNoReturn(void throwUndefinedVarError(const char * s, const string & s1, const Pos & pos)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1)) { throw UndefinedVarError( ErrorInfo { @@ -643,7 +643,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError("undefined variable '%1%'", var.name, var.pos); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -841,7 +841,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos) Value v; e->eval(*this, env, v); if (v.type != tBool) - throwTypeError("value is %1% while a Boolean was expected", v, pos); + throwTypeError(pos, "value is %1% while a Boolean was expected", v); return v.boolean; } @@ -955,7 +955,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError("dynamic attribute '%1%' already defined at %2%", nameSym, i.pos, *j->pos); + throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos); i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ @@ -1043,7 +1043,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError("attribute '%1%' missing", name, pos); + throwEvalError(pos, "attribute '%1%' missing", name); } vAttrs = j->value; pos2 = j->pos; @@ -1169,7 +1169,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po } if (fun.type != tLambda) - throwTypeError("attempt to call something which is not a function but %1%", fun, pos); + throwTypeError(pos, "attempt to call something which is not a function but %1%", fun); ExprLambda & lambda(*fun.lambda.fun); @@ -1197,8 +1197,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { - if (!i.def) throwTypeError("%1% called without required argument '%2%'", - lambda, i.name, pos); + if (!i.def) throwTypeError(pos, "%1% called without required argument '%2%'", + lambda, i.name); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1213,7 +1213,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po user. */ for (auto & i : *arg.attrs) if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end()) - throwTypeError("%1% called with unexpected argument '%2%'", lambda, i.name, pos); + throwTypeError(pos, "%1% called with unexpected argument '%2%'", lambda, i.name); abort(); // can't happen } } @@ -1302,7 +1302,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v) if (!state.evalBool(env, cond, pos)) { std::ostringstream out; cond->show(out); - throwAssertionError("assertion '%1%' failed at %2%", out.str(), pos); + throwAssertionError(pos, "assertion '%1%' failed at %2%", out.str()); } body->eval(state, env, v); } @@ -1454,14 +1454,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } else - throwEvalError("cannot add %1% to an integer", showType(vTmp), pos); + throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp)); } else if (firstType == tFloat) { if (vTmp.type == tInt) { nf += vTmp.integer; } else if (vTmp.type == tFloat) { nf += vTmp.fpoint; } else - throwEvalError("cannot add %1% to a float", showType(vTmp), pos); + throwEvalError(pos, "cannot add %1% to a float", showType(vTmp)); } else s << state.coerceToString(pos, vTmp, context, false, firstType == tString); } @@ -1472,7 +1472,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) mkFloat(v, nf); else if (firstType == tPath) { if (!context.empty()) - throwEvalError("a string that refers to a store path cannot be appended to a path", pos); + throwEvalError(pos, "a string that refers to a store path cannot be appended to a path"); auto path = canonPath(s.str()); mkPath(v, path.c_str()); } else @@ -1521,7 +1521,7 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type != tInt) - throwTypeError("value is %1% while an integer was expected", v, pos); + throwTypeError(pos, "value is %1% while an integer was expected", v); return v.integer; } @@ -1532,7 +1532,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) if (v.type == tInt) return v.integer; else if (v.type != tFloat) - throwTypeError("value is %1% while a float was expected", v, pos); + throwTypeError(pos, "value is %1% while a float was expected", v); return v.fpoint; } @@ -1541,7 +1541,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type != tBool) - throwTypeError("value is %1% while a Boolean was expected", v, pos); + throwTypeError(pos, "value is %1% while a Boolean was expected", v); return v.boolean; } @@ -1556,7 +1556,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type != tLambda && v.type != tPrimOp && v.type != tPrimOpApp && !isFunctor(v)) - throwTypeError("value is %1% while a function was expected", v, pos); + throwTypeError(pos, "value is %1% while a function was expected", v); } @@ -1565,7 +1565,7 @@ string EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type != tString) { if (pos) - throwTypeError("value is %1% while a string was expected", v, pos); + throwTypeError(pos, "value is %1% while a string was expected", v); else throwTypeError("value is %1% while a string was expected", v); } @@ -1594,8 +1594,8 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) string s = forceString(v, pos); if (v.string.context) { if (pos) - throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], pos); + throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", + v.string.s, v.string.context[0]); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]); @@ -1651,7 +1651,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, return *maybeString; } auto i = v.attrs->find(sOutPath); - if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string", pos); + if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string"); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -1682,7 +1682,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError("cannot coerce %1% to a string", v, pos); + throwTypeError(pos, "cannot coerce %1% to a string", v); } @@ -1713,7 +1713,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) { string path = coerceToString(pos, v, context, false, false); if (path == "" || path[0] != '/') - throwEvalError("string '%1%' doesn't represent an absolute path", path, pos); + throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path); return path; } -- cgit v1.2.3 From 19cffc29c995af8fb155f2764664f0b079879b4f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 12:09:12 -0600 Subject: remove unused extra json fields --- src/libstore/local-store.cc | 1 - src/libstore/remote-store.cc | 9 --------- src/libutil/logging.cc | 24 ------------------------ 3 files changed, 34 deletions(-) (limited to 'src') diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 1f16a22b1..63a825af0 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1364,7 +1364,6 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, auto state(_state.lock()); invalidatePath(*state, path); } else { - // TODO log as warning if repair successful?? logError( ErrorInfo { .name = "Missing path with referrers", diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 7c50c1065..cc336e460 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -780,15 +780,6 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source * } else if (msg == STDERR_NEXT) - // TODO: is this really an ErrorInfo error? Seems like we're forwarding the - // stderr output of the remote to current stderr/log - // ErrorInfo gets lost in this scenario. - // An alternative might be a logger on the remote that forwards ErrorInfo and etc. - // logError( - // ErrorInfo { - // // .name = "Remote Store" TODO reasonable name. - // .hint = hintfmt(chomp(readString(from))) - // }); printError(chomp(readString(from))); else if (msg == STDERR_START_ACTIVITY) { diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 7c75456ee..736ce604e 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -150,7 +150,6 @@ struct JSONLogger : Logger { void logEI(const ErrorInfo & ei) override { - // add fields like Pos info and etc? std::ostringstream oss; oss << ei; @@ -159,29 +158,6 @@ struct JSONLogger : Logger { json["level"] = ei.level; json["msg"] = oss.str(); - // Extra things that COULD go into json. Useful? - // TODO: decide if useful. - // TODO: make a json obj that goes into json["msg"]? - json["name"] = ei.name; - json["description"] = ei.description; - if (ei.hint.has_value()) { - json["hint"] = ei.hint->str(); - } - if (ei.nixCode.has_value()) { - if (ei.nixCode->errPos.line != 0) - json["line"] = ei.nixCode->errPos.line; - if (ei.nixCode->errPos.column != 0) - json["column"] = ei.nixCode->errPos.column; - if (ei.nixCode->errPos.file != "") - json["file"] = ei.nixCode->errPos.file; - if (ei.nixCode->prevLineOfCode.has_value()) - json["prevLineOfCode"] = *ei.nixCode->prevLineOfCode; - if (ei.nixCode->errLineOfCode.has_value()) - json["errLineOfCode"] = *ei.nixCode->errLineOfCode; - if (ei.nixCode->nextLineOfCode.has_value()) - json["nextLineOfCode"] = *ei.nixCode->nextLineOfCode; - } - write(json); } -- cgit v1.2.3 From 72ecccee5781ec0b57b2860f677b8a64db43cda7 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 12:19:34 -0600 Subject: convert to logWarning format --- src/libexpr/parser.y | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 3ae7bbafd..49fb8ad37 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -717,7 +717,11 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl res = { true, store->toRealPath(fetchers::downloadTarball( store, resolveUri(elem.second), "source", false).storePath) }; } catch (FileTransferError & e) { - printError("warning: Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second); + logWarning( + ErrorInfo { + .name = "Entry download", + .hint = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second) + }); res = { false, "" }; } } else { @@ -727,7 +731,7 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl else { logWarning( ErrorInfo { - .name = "Search path not found", + .name = "Entry not found", .hint = hintfmt("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second) }); res = { false, "" }; -- cgit v1.2.3 From 960d4362ed2215f87a596e0a994e39aa28680db1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 13:54:18 -0600 Subject: hint only --- src/error-demo/error-demo.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 8f484431c..82e9f0580 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -149,5 +149,13 @@ int main() .errPos = Pos(problem_file, 40, 13) }}); + // Error with only hint and name.. + logError( + ErrorInfo { .name = "error name", + .hint = hintfmt("hint %1%", "only"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); + return 0; } -- cgit v1.2.3 From ecbb8e9c0a4374b26defde2cd10932d633affed3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 12 May 2020 14:41:30 -0600 Subject: no blank line if no LOC --- src/error-demo/error-demo.cc | 1 + src/libutil/error.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 82e9f0580..0216092e3 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -1,5 +1,6 @@ #include "logging.hh" #include "nixexpr.hh" +#include "util.hh" #include #include diff --git a/src/libutil/error.cc b/src/libutil/error.cc index e4f45a2d3..0765a2945 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -182,7 +182,7 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) } // lines of code. - if (einfo.nixCode.has_value()) { + if (einfo.nixCode.has_value() && einfo.nixCode->errLineOfCode.has_value()) { printCodeLines(out, prefix, *einfo.nixCode); out << prefix << std::endl; } -- cgit v1.2.3 From bfca5fc395bdaf5823413e1a1679f1b0b6db29dd Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 13 May 2020 09:52:36 -0600 Subject: change status messages to info level --- src/libstore/build.cc | 2 +- src/libstore/gc.cc | 12 ++++++------ src/libstore/local-store.cc | 18 +++++++++--------- src/libutil/logging.cc | 6 +++++- src/libutil/util.cc | 13 +------------ src/nix-env/user-env.cc | 2 +- src/nix/make-content-addressable.cc | 2 +- src/nix/upgrade-nix.cc | 2 +- 8 files changed, 25 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 0359b10ac..961110d58 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -4862,7 +4862,7 @@ void Worker::waitForInput() if (!waitingForAWhile.empty()) { useTimeout = true; if (lastWokenUp == steady_time_point::min()) - printError("waiting for locks or build slots..."); + printInfo("waiting for locks or build slots..."); if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before; timeout = std::max(1L, (long) std::chrono::duration_cast( diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index e99423257..e529416b7 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -41,7 +41,7 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) throw SysError("opening global GC lock '%1%'", fnGCLock); if (!lockFile(fdGCLock.get(), lockType, false)) { - printError("waiting for the big garbage collector lock..."); + printInfo("waiting for the big garbage collector lock..."); lockFile(fdGCLock.get(), lockType, true); } @@ -231,7 +231,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor) only succeed if the owning process has died. In that case we don't care about its temporary roots. */ if (lockFile(fd->get(), ltWrite, false)) { - printError("removing stale temporary roots file '%1%'", path); + printInfo("removing stale temporary roots file '%1%'", path); unlink(path.c_str()); writeFull(fd->get(), "d"); continue; @@ -751,7 +751,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) /* Find the roots. Since we've grabbed the GC lock, the set of permanent roots cannot increase now. */ - printError("finding garbage collector roots..."); + printInfo("finding garbage collector roots..."); Roots rootMap; if (!options.ignoreLiveness) findRootsNoTemp(rootMap, true); @@ -803,9 +803,9 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) } else if (options.maxFreed > 0) { if (state.shouldDelete) - printError("deleting garbage..."); + printInfo("deleting garbage..."); else - printError("determining live/dead paths..."); + printInfo("determining live/dead paths..."); try { @@ -872,7 +872,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) /* Clean up the links directory. */ if (options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific) { - printError("deleting unused links..."); + printInfo("deleting unused links..."); removeUnusedLinks(state); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 63a825af0..59d551032 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -152,7 +152,7 @@ LocalStore::LocalStore(const Params & params) globalLock = openLockFile(globalLockPath.c_str(), true); if (!lockFile(globalLock.get(), ltRead, false)) { - printError("waiting for the big Nix store lock..."); + printInfo("waiting for the big Nix store lock..."); lockFile(globalLock.get(), ltRead, true); } @@ -183,7 +183,7 @@ LocalStore::LocalStore(const Params & params) "please upgrade Nix to version 1.11 first."); if (!lockFile(globalLock.get(), ltWrite, false)) { - printError("waiting for exclusive access to the Nix store..."); + printInfo("waiting for exclusive access to the Nix store..."); lockFile(globalLock.get(), ltWrite, true); } @@ -261,7 +261,7 @@ LocalStore::~LocalStore() } if (future.valid()) { - printError("waiting for auto-GC to finish on exit..."); + printInfo("waiting for auto-GC to finish on exit..."); future.get(); } @@ -1210,7 +1210,7 @@ void LocalStore::invalidatePathChecked(const StorePath & path) bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) { - printError(format("reading the Nix store...")); + printInfo(format("reading the Nix store...")); bool errors = false; @@ -1251,7 +1251,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) }); if (repair) { if (unlink(linkPath.c_str()) == 0) - printError("removed link '%s'", linkPath); + printInfo("removed link '%s'", linkPath); else throw SysError("removing corrupt link '%s'", linkPath); } else { @@ -1294,14 +1294,14 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) /* Fill in missing hashes. */ if (info->narHash == nullHash) { - printError("fixing missing hash on '%s'", printStorePath(i)); + printInfo("fixing missing hash on '%s'", printStorePath(i)); info->narHash = current.first; update = true; } /* Fill in missing narSize fields (from old stores). */ if (info->narSize == 0) { - printError("updating size field on '%s' to %s", printStorePath(i), current.second); + printInfo("updating size field on '%s' to %s", printStorePath(i), current.second); info->narSize = current.second; update = true; } @@ -1360,7 +1360,7 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, } if (canInvalidate) { - printError("path '%s' disappeared, removing from database...", pathS); + printInfo("path '%s' disappeared, removing from database...", pathS); auto state(_state.lock()); invalidatePath(*state, path); } else { @@ -1431,7 +1431,7 @@ static void makeMutable(const Path & path) void LocalStore::upgradeStore7() { if (getuid() != 0) return; - printError("removing immutable bits from the Nix store (this may take a while)..."); + printInfo("removing immutable bits from the Nix store (this may take a while)..."); makeMutable(realStoreDir); } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 736ce604e..071a7ec7e 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -251,7 +251,11 @@ bool handleJSONLogMessage(const std::string & msg, } } catch (std::exception & e) { - printError("bad log message from builder: %s", e.what()); + logError( + ErrorInfo { + .name = "Json log message", + .hint = hintfmt("bad log message from builder: %s", e.what()) + }); } return true; diff --git a/src/libutil/util.cc b/src/libutil/util.cc index ac7c2967b..dcf89ff69 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -857,7 +857,7 @@ int Pid::kill() #if __FreeBSD__ || __APPLE__ if (errno != EPERM || ::kill(pid, 0) != 0) #endif - printError((SysError("killing process %d", pid).msg())); + logError(SysError("killing process %d", pid).info()); } return wait(); @@ -1447,17 +1447,6 @@ string base64Decode(const string & s) } -// void callFailure(const std::function & failure, std::exception_ptr exc) -// { -// try { -// failure(exc); -// } catch (std::exception & e) { -// printError("uncaught exception: %s", e.what()); -// abort(); -// } -// } - - static Sync> windowSize{{0, 0}}; diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc index 2484b9759..f804b77a0 100644 --- a/src/nix-env/user-env.cc +++ b/src/nix-env/user-env.cc @@ -146,7 +146,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, Path lockTokenCur = optimisticLockProfile(profile); if (lockToken != lockTokenCur) { - printError("profile '%1%' changed while we were busy; restarting", profile); + printInfo("profile '%1%' changed while we were busy; restarting", profile); return false; } diff --git a/src/nix/make-content-addressable.cc b/src/nix/make-content-addressable.cc index 8803461f4..0da4fa4b4 100644 --- a/src/nix/make-content-addressable.cc +++ b/src/nix/make-content-addressable.cc @@ -85,7 +85,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON info.ca = makeFixedOutputCA(true, info.narHash); if (!json) - printError("rewrote '%s' to '%s'", pathS, store->printStorePath(info.path)); + printInfo("rewrote '%s' to '%s'", pathS, store->printStorePath(info.path)); auto source = sinkToSource([&](Sink & nextSink) { RewritingSink rsink2(oldHashPart, storePathToHash(store->printStorePath(info.path)), nextSink); diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index 9e7ebcd9c..fdf94e5a3 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -98,7 +98,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand {"--profile", profileDir, "-i", store->printStorePath(storePath), "--no-sandbox"}); } - printError(ANSI_GREEN "upgrade to version %s done" ANSI_NORMAL, version); + printInfo(ANSI_GREEN "upgrade to version %s done" ANSI_NORMAL, version); } /* Return the profile in which Nix is installed. */ -- cgit v1.2.3 From c79d4addab7ea476f551bc8727e4d1f27adcef31 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 13 May 2020 10:02:18 -0600 Subject: consistent capitalization --- src/build-remote/build-remote.cc | 2 +- src/libstore/builtins/buildenv.cc | 4 ++-- src/libstore/filetransfer.cc | 2 +- src/libstore/gc.cc | 2 +- src/libstore/local-store.cc | 4 ++-- src/libstore/optimise-store.cc | 4 ++-- src/libstore/sqlite.cc | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 0d6859596..0caa97fa4 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -202,7 +202,7 @@ static int _main(int argc, char * * argv) auto msg = chomp(drainFD(5, false)); logError( ErrorInfo { - .name = "remote build", + .name = "Remote build", .hint = hintfmt("cannot build on '%s': %s%s", bestMachine->storeUri, e.what(), (msg.empty() ? "" : ": " + msg)) diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index 64085fcc9..6c493ed77 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -24,7 +24,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, if (e.errNo == ENOTDIR) { logWarning( ErrorInfo { - .name = "Create Links - Directory", + .name = "Create links - directory", .hint = hintfmt("not including '%s' in the user environment because it's not a directory", srcDir) }); return; @@ -47,7 +47,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, if (e.errNo == ENOENT || e.errNo == ENOTDIR) { logWarning( ErrorInfo { - .name = "Create Links - Skipping Symlink", + .name = "Create links - skipping symlink", .hint = hintfmt("skipping dangling symlink '%s'", dstFile) }); continue; diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 3285edded..89588d662 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -601,7 +601,7 @@ struct curlFileTransfer : public FileTransfer } catch (std::exception & e) { logError( ErrorInfo { - .name = "download", + .name = "File transfer", .hint = hintfmt("unexpected error in download thread: %s", e.what()) }); diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index e529416b7..d53d458e9 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -132,7 +132,7 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, logWarning( ErrorInfo { - .name = "GC Root", + .name = "GC root", .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " "therefore, '%2%' might be removed by the garbage collector", gcRoot, printStorePath(storePath)) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 59d551032..194eefc78 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1244,7 +1244,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) if (hash != link.name) { logError( ErrorInfo { - .name = "Invalid Hash", + .name = "Invalid hash", .hint = hintfmt( "link '%s' was modified! expected hash '%s', got '%s'", linkPath, link.name, hash) @@ -1283,7 +1283,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) if (info->narHash != nullHash && info->narHash != current.first) { logError( ErrorInfo { - .name = "Invalid Hash - Path Modified", + .name = "Invalid hash - path modified", .hint = hintfmt("path '%s' was modified! expected hash '%s', got '%s'", printStorePath(i), info->narHash.to_string(), current.first.to_string()) }); diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index 9f6112183..c9ecca5a8 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -132,7 +132,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { logWarning( ErrorInfo { - .name = "Suspicious File", + .name = "Suspicious file", .hint = hintfmt("skipping suspicious writable file '%1%'", path) }); return; @@ -200,7 +200,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, if (st.st_size != stLink.st_size) { logWarning( ErrorInfo { - .name = "Corrupted Link", + .name = "Corrupted link", .hint = hintfmt("removing corrupted link '%1%'", linkPath) }); unlink(linkPath.c_str()); diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 082c54005..34ef5e57b 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -205,7 +205,7 @@ void handleSQLiteBusy(SQLiteBusy & e) if (now > lastWarned + 10) { lastWarned = now; logWarning( - ErrorInfo { .name = "sqlite busy", + ErrorInfo { .name = "Sqlite busy", .hint = hintfmt(e.what()) }); } -- cgit v1.2.3 From ef9dd9f9bc18abc9761812e30a26008c99a26166 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 13 May 2020 15:56:39 -0600 Subject: formatting and a few minor changes --- src/libexpr/parser.y | 2 -- src/libexpr/primops.cc | 59 +++++++++++++++-------------------- src/libexpr/primops/context.cc | 2 -- src/libexpr/primops/fetchMercurial.cc | 1 - src/libstore/build.cc | 40 ++++++++++-------------- src/libstore/gc.cc | 1 - src/libstore/local-store.cc | 2 +- src/libstore/sqlite.cc | 2 +- src/libstore/sqlite.hh | 2 +- src/libutil/types.hh | 8 ++--- src/nix-daemon/nix-daemon.cc | 4 +-- src/nix-env/nix-env.cc | 6 ++-- src/nix-store/nix-store.cc | 2 +- 13 files changed, 54 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 49fb8ad37..0417a3c21 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -427,7 +427,6 @@ expr_simple .hint = hintfmt("URL literals are disabled"), .nixCode = NixCode { .errPos = CUR_POS } }); - $$ = new ExprString(data->symbols.create($1)); } | '(' expr ')' { $$ = $2; } @@ -696,7 +695,6 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos Path res = r.second + suffix; if (pathExists(res)) return canonPath(res); } - throw ThrownError( ErrorInfo { .hint = hintfmt("file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)", path), diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 657ce3001..d21c49813 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -99,7 +99,6 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args path, e.path), .nixCode = NixCode { .errPos = pos } }); - } Path realPath = state.checkSourcePath(state.toRealPath(path, context)); @@ -179,7 +178,7 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value ErrorInfo { .hint = hintfmt( "cannot import '%1%', since path '%2%' is not valid", - path, e.path), + path, e.path), .nixCode = NixCode { .errPos = pos } }); } @@ -199,8 +198,8 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value if (message) throw EvalError("could not load symbol '%1%' from '%2%': %3%", sym, path, message); else - throw EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected" - , sym, path); + throw EvalError("symbol '%1%' from '%2%' resolved to NULL when a function pointer was expected", + sym, path); } (func)(state, v); @@ -233,8 +232,8 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) } catch (InvalidPathError & e) { throw EvalError( ErrorInfo { - .hint = hintfmt("cannot execute '%1%', since path '%2%' is not valid" - , program, e.path), + .hint = hintfmt("cannot execute '%1%', since path '%2%' is not valid", + program, e.path), .nixCode = NixCode { .errPos = pos } });} @@ -625,8 +624,6 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * .hint = hintfmt("duplicate derivation output '%1%'", j), .nixCode = NixCode { .errPos = posDrvName } }); - - /* !!! Check whether j is a valid attribute name. */ /* Derivations cannot be named ‘drv’, because @@ -638,7 +635,6 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * .hint = hintfmt("invalid derivation output name 'drv'" ), .nixCode = NixCode { .errPos = posDrvName } }); - outputs.insert(j); } if (outputs.empty()) @@ -1236,7 +1232,6 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value path), .nixCode = NixCode { .errPos = *attr.pos } }); - } else if (attr.name == state.sName) name = state.forceStringNoCtx(*attr.value, *attr.pos); else if (n == "filter") { @@ -1322,7 +1317,6 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) .hint = hintfmt("attribute '%1%' missing", attr), .nixCode = NixCode { .errPos = pos } }); - // !!! add to stack trace? if (state.countCalls && i->pos) state.attrSelects[*i->pos]++; state.forceValue(*i->value, pos); @@ -1407,7 +1401,6 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, .hint = hintfmt("'name' attribute missing in a call to 'listToAttrs'"), .nixCode = NixCode { .errPos = pos } }); - string name = state.forceStringNoCtx(*j->value, pos); Symbol sym = state.symbols.create(name); @@ -1419,7 +1412,6 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, .hint = hintfmt("'value' attribute missing in a call to 'listToAttrs'"), .nixCode = NixCode { .errPos = pos } }); - v.attrs->push_back(Attr(sym, j2->value, j2->pos)); } } @@ -1498,7 +1490,6 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args .nixCode = NixCode { .errPos = pos } }); - if (!args[0]->lambda.fun->matchAttrs) { state.mkAttrs(v, 0); return; @@ -2038,16 +2029,16 @@ void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v) if (e.code() == std::regex_constants::error_space) { // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ throw EvalError( - ErrorInfo { - .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + ErrorInfo { + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), .nixCode = NixCode { .errPos = pos } }); } else { - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } } } @@ -2111,19 +2102,19 @@ static void prim_split(EvalState & state, const Pos & pos, Value * * args, Value } catch (std::regex_error &e) { if (e.code() == std::regex_constants::error_space) { - // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ - throw EvalError( - ErrorInfo { - .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); - } else { - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); - } + // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ + throw EvalError( + ErrorInfo { + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); + } else { + throw EvalError( + ErrorInfo { + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); + } } } diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 768936453..7f895fc01 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -151,7 +151,6 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg .hint = hintfmt("Context key '%s' is not a store path", i.name), .nixCode = NixCode { .errPos = *i.pos } }); - if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(i.name)); state.forceAttrs(*i.value, *i.pos); @@ -170,7 +169,6 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg .hint = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", i.name), .nixCode = NixCode { .errPos = *i.pos } }); - } context.insert("=" + string(i.name)); } diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 1e8b9d4a0..bb008ba6b 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -43,7 +43,6 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar .hint = hintfmt("unsupported argument '%s' to 'fetchMercurial'", attr.name), .nixCode = NixCode { .errPos = *attr.pos } }); - } if (url.empty()) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 961110d58..64bc9c4b8 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -497,8 +497,8 @@ void handleDiffHook( printError(chomp(diffRes.second)); } catch (Error & error) { ErrorInfo ei = error.info(); - string prevhint = (error.info().hint.has_value() ? error.info().hint->str() : ""); - ei.hint = std::optional(hintfmt("diff hook execution failed: %s", prevhint)); + ei.hint = hintfmt("diff hook execution failed: %s", + (error.info().hint.has_value() ? error.info().hint->str() : "")); logError(ei); } } @@ -1151,7 +1151,7 @@ void DerivationGoal::loadDerivation() if (nrFailed != 0) { logError( - ErrorInfo { + ErrorInfo { .name = "missing derivation during build", .hint = hintfmt("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)) }); @@ -1306,13 +1306,12 @@ void DerivationGoal::repairClosure() for (auto & i : outputClosure) { if (worker.pathContentsGood(i)) continue; logError( - ErrorInfo { + ErrorInfo { .name = "Corrupt path in closure", .hint = hintfmt( "found corrupted or missing path '%s' in the output closure of '%s'", worker.store.printStorePath(i), worker.store.printStorePath(drvPath)) }); - auto drvPath2 = outputsToDrv.find(i); if (drvPath2 == outputsToDrv.end()) addWaitee(worker.makeSubstitutionGoal(i, Repair)); @@ -1347,7 +1346,7 @@ void DerivationGoal::inputsRealised() if (!useDerivation) throw Error("some dependencies of '%s' are missing", worker.store.printStorePath(drvPath)); logError( - ErrorInfo { + ErrorInfo { .name = "Dependencies could not be built", .hint = hintfmt( "cannot build derivation '%s': %s dependencies couldn't be built", @@ -1811,7 +1810,7 @@ HookReply DerivationGoal::tryBuildHook() } catch (SysError & e) { if (e.errNo == EPIPE) { logError( - ErrorInfo { + ErrorInfo { .name = "Build hook died", .hint = hintfmt( "build hook died unexpectedly: %s", @@ -3676,7 +3675,7 @@ void DerivationGoal::registerOutputs() if (!outputRewrites.empty()) { logWarning( ErrorInfo { - .name = "Rewriting hashes", + .name = "Rewriting hashes", .hint = hintfmt("rewriting hashes in '%1%'; cross fingers", path) }); @@ -3856,7 +3855,7 @@ void DerivationGoal::registerOutputs() throw NotDeterministic(hint); logError( - ErrorInfo { + ErrorInfo { .name = "Output determinism error", .hint = hint }); @@ -4124,7 +4123,7 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) logSize += data.size(); if (settings.maxLogSize && logSize > settings.maxLogSize) { logError( - ErrorInfo { + ErrorInfo { .name = "Max log size exceeded", .hint = hintfmt( "%1% killed after writing more than %2% bytes of log output", @@ -4447,9 +4446,9 @@ void SubstitutionGoal::tryNext() { logWarning( ErrorInfo { - .name = "Invalid path signature", + .name = "Invalid path signature", .hint = hintfmt("substituter '%s' does not have a valid signature for path '%s'", - sub->getUri(), worker.store.printStorePath(storePath)) + sub->getUri(), worker.store.printStorePath(storePath)) }); tryNext(); return; @@ -4809,7 +4808,7 @@ void Worker::run(const Goals & _topGoals) if (!children.empty() || !waitingForAWhile.empty()) waitForInput(); else { - if (awake.empty() && 0 == settings.maxBuildJobs) + if (awake.empty() && 0 == settings.maxBuildJobs) throw Error("unable to start any build; either increase '--max-jobs' " "or enable remote builds"); assert(!awake.empty()); @@ -4933,7 +4932,7 @@ void Worker::waitForInput() after - j->lastOutput >= std::chrono::seconds(settings.maxSilentTime)) { logError( - ErrorInfo { + ErrorInfo { .name = "Silent build timeout", .hint = hintfmt( "%1% timed out after %2% seconds of silence", @@ -4948,7 +4947,7 @@ void Worker::waitForInput() after - j->timeStarted >= std::chrono::seconds(settings.buildTimeout)) { logError( - ErrorInfo { + ErrorInfo { .name = "Build timeout", .hint = hintfmt( "%1% timed out after %2% seconds", @@ -4969,9 +4968,6 @@ void Worker::waitForInput() } - - - unsigned int Worker::exitStatus() { /* @@ -5015,9 +5011,9 @@ bool Worker::pathContentsGood(const StorePath & path) res = info->narHash == nullHash || info->narHash == current.first; } pathContentsGoodCache.insert_or_assign(path.clone(), res); - if (!res) + if (!res) logError( - ErrorInfo { + ErrorInfo { .name = "Corrupted path", .hint = hintfmt("path '%s' is corrupted or missing!", store.printStorePath(path)) }); @@ -5136,8 +5132,4 @@ void LocalStore::repairPath(const StorePath & path) } - } - - - diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index d53d458e9..92f9328c3 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -129,7 +129,6 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, if (settings.checkRootReachability) { auto roots = findRoots(false); if (roots[storePath.clone()].count(gcRoot) == 0) - logWarning( ErrorInfo { .name = "GC root", diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 194eefc78..6f88a3e32 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -504,7 +504,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe chown(path.c_str(), geteuid(), getegid()) == -1) #endif throw SysError("changing owner of '%1%' to %2%", - path, geteuid()); + path, geteuid()); } if (S_ISDIR(st.st_mode)) { diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 34ef5e57b..16cdb6619 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -196,7 +196,7 @@ SQLiteTxn::~SQLiteTxn() } } -void handleSQLiteBusy(SQLiteBusy & e) +void handleSQLiteBusy(const SQLiteBusy & e) { static std::atomic lastWarned{0}; diff --git a/src/libstore/sqlite.hh b/src/libstore/sqlite.hh index ccfac48d8..dd81ab051 100644 --- a/src/libstore/sqlite.hh +++ b/src/libstore/sqlite.hh @@ -99,7 +99,7 @@ MakeError(SQLiteBusy, SQLiteError); [[noreturn]] void throwSQLiteError(sqlite3 * db, const FormatOrString & fs); -void handleSQLiteBusy(SQLiteBusy & e); +void handleSQLiteBusy(const SQLiteBusy & e); /* Convenience function for retrying a SQLite transaction when the database is busy. */ diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 4d783b564..66072e8f7 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -15,13 +15,13 @@ using std::set; using std::vector; using std::string; -typedef list Strings; -typedef set StringSet; -typedef std::map StringMap; +typedef list Strings; +typedef set StringSet; +typedef std::map StringMap; /* Paths are just strings. */ -typedef std::string Path; +typedef string Path; typedef list Paths; typedef set PathSet; diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 731ab22e5..582c78d14 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -248,8 +248,8 @@ static void daemonLoop(char * * argv) return; } catch (Error & error) { ErrorInfo ei = error.info(); - string prevhint = (error.info().hint.has_value() ? error.info().hint->str() : ""); - ei.hint = std::optional(hintfmt("error processing connection: %1%", prevhint)); + ei.hint = std::optional(hintfmt("error processing connection: %1%", + (error.info().hint.has_value() ? error.info().hint->str() : ""))); logError(ei); } } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 0f99f5fe1..bbce5dcda 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -69,7 +69,7 @@ typedef void (* Operation) (Globals & globals, static string needArg(Strings::iterator & i, Strings & args, const string & arg) { - if (i == args.end()) throw UsageError( "'%1%' requires an argument", arg); + if (i == args.end()) throw UsageError("'%1%' requires an argument", arg); return *i++; } @@ -151,7 +151,7 @@ static void loadSourceExpr(EvalState & state, const Path & path, Value & v) { struct stat st; if (stat(path.c_str(), &st) == -1) - throw SysError("getting inon about '%1%'", path); + throw SysError("getting information about '%1%'", path); if (isNixExpr(path, st)) state.evalFile(path, v); @@ -1233,7 +1233,7 @@ static void switchGeneration(Globals & globals, int dstGen) if (!dst) { if (dstGen == prevGen) throw Error("no generation older than the current (%1%) exists", - curGen); + curGen); else throw Error("generation %1% does not exist", dstGen); } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 9b5cceccf..77deea5a7 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -731,7 +731,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) if (current.first != info->narHash) { logError( ErrorInfo { - .name = "Hash match error", + .name = "Hash mismatch", .hint = hintfmt( "path '%s' was modified! expected hash '%s', got '%s'", store->printStorePath(path), -- cgit v1.2.3 From 4daccb279c547b90b0c17c8a64825f04abdf0f7e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 14 May 2020 10:28:17 -0600 Subject: formatting --- src/libexpr/primops.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index d21c49813..9b9cbfc2e 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -767,7 +767,6 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * .nixCode = NixCode { .errPos = posDrvName } }); - /* Check whether the derivation name is valid. */ if (isDerivation(drvName)) throw EvalError( @@ -776,7 +775,6 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * .nixCode = NixCode { .errPos = posDrvName } }); - if (outputHash) { /* Handle fixed-output derivations. */ if (outputs.size() != 1 || *(outputs.begin()) != "out") -- cgit v1.2.3 From 19694aa213961daa5cbe2263bfaca53dc068a40c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 14 May 2020 12:28:18 -0600 Subject: fix compile errors --- src/libutil/error.cc | 16 ++++++++++++++++ src/libutil/error.hh | 16 ++-------------- src/libutil/types.hh | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 0765a2945..59628d875 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -3,6 +3,7 @@ #include #include #include "serialise.hh" +#include namespace nix { @@ -16,6 +17,21 @@ BaseError & BaseError::addPrefix(const FormatOrString & fs) return *this; } +const string& BaseError::calcWhat() const +{ + if (what_.has_value()) + return *what_; + else { + err.name = sname(); + + std::ostringstream oss; + oss << err; + what_ = oss.str(); + + return *what_; + } +} + std::optional ErrorInfo::programName = std::nullopt; std::ostream& operator<<(std::ostream &os, const hintformat &hf) diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 19c6e35a1..b374c2780 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -88,20 +88,8 @@ protected: mutable ErrorInfo err; mutable std::optional what_; - const string& calcWhat() const - { - if (what_.has_value()) - return *what_; - else { - err.name = sname(); - - std::ostringstream oss; - oss << err; - what_ = oss.str(); - - return *what_; - } - } + const string& calcWhat() const; + public: unsigned int status = 1; // exit status diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 66072e8f7..89ae108f9 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -6,7 +6,7 @@ #include #include #include - +#include namespace nix { -- cgit v1.2.3 From d82d230b4015c50e698e3be1ec7a3e12277a3251 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 2 Jun 2020 08:22:24 -0600 Subject: elide the 'ErrorInfo' in logError and logWarning calls --- src/build-remote/build-remote.cc | 11 +- src/error-demo/error-demo.cc | 111 ++++++++++----------- src/libstore/build.cc | 107 +++++++++----------- src/libstore/filetransfer.cc | 11 +- src/libstore/local-store.cc | 45 ++++----- src/libstore/optimise-store.cc | 21 ++-- src/libutil/logging.cc | 7 +- src/nix-env/nix-env.cc | 27 +++-- src/nix-store/nix-store.cc | 17 ++-- src/nix/verify.cc | 26 +++-- .../resolve-system-dependencies.cc | 28 +++--- 11 files changed, 187 insertions(+), 224 deletions(-) (limited to 'src') diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 0caa97fa4..2f0b8c825 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -200,12 +200,11 @@ static int _main(int argc, char * * argv) } catch (std::exception & e) { auto msg = chomp(drainFD(5, false)); - logError( - ErrorInfo { - .name = "Remote build", - .hint = hintfmt("cannot build on '%s': %s%s", - bestMachine->storeUri, e.what(), - (msg.empty() ? "" : ": " + msg)) + logError({ + .name = "Remote build", + .hint = hintfmt("cannot build on '%s': %s%s", + bestMachine->storeUri, e.what(), + (msg.empty() ? "" : ": " + msg)) }); bestMachine->enabled = false; continue; diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index 0216092e3..f1e17b3de 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -62,101 +62,96 @@ int main() // For completeness sake, show 'info' through 'vomit' levels. // But this is maybe a heavy format for those. - logger->logEI( - ErrorInfo { .level = lvlInfo, + logger->logEI({ .level = lvlInfo, .name = "Info name", .description = "Info description", }); - logger->logEI( - ErrorInfo { .level = lvlTalkative, + logger->logEI({ .level = lvlTalkative, .name = "Talkative name", .description = "Talkative description", }); - logger->logEI( - ErrorInfo { .level = lvlChatty, + logger->logEI({ .level = lvlChatty, .name = "Chatty name", .description = "Chatty description", }); - logger->logEI( - ErrorInfo { .level = lvlDebug, + logger->logEI({ .level = lvlDebug, .name = "Debug name", .description = "Debug description", }); - logger->logEI( - ErrorInfo { .level = lvlVomit, + logger->logEI({ .level = lvlVomit, .name = "Vomit name", .description = "Vomit description", }); // Error in a program; no hint and no nix code. - logError( - ErrorInfo { .name = "name", - .description = "error description", - }); + logError({ + .name = "name", + .description = "error description", + }); // Warning with name, description, and hint. // The hintfmt function makes all the substituted text yellow. - logWarning( - ErrorInfo { .name = "name", - .description = "error description", - .hint = hintfmt("there was a %1%", "warning"), - }); + logWarning({ + .name = "name", + .description = "error description", + .hint = hintfmt("there was a %1%", "warning"), + }); // Warning with nix file, line number, column, and the lines of // code where a warning occurred. SymbolTable testTable; auto problem_file = testTable.create("myfile.nix"); - logWarning( - ErrorInfo { .name = "warning name", - .description = "warning description", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::nullopt, - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::nullopt - }}); + logWarning({ + .name = "warning name", + .description = "warning description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::nullopt, + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::nullopt + }}); // Error with previous and next lines of code. - logError( - ErrorInfo { .name = "error name", - .description = "error with code lines", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = "previous line of code", - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = "next line of code", - }}); + logError({ + .name = "error name", + .description = "error with code lines", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = "previous line of code", + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = "next line of code", + }}); // Error without lines of code. - logError( - ErrorInfo { .name = "error name", - .description = "error without any code lines.", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13) - }}); + logError({ + .name = "error name", + .description = "error without any code lines.", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); // Error with only hint and name.. - logError( - ErrorInfo { .name = "error name", - .hint = hintfmt("hint %1%", "only"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13) - }}); + logError({ + .name = "error name", + .hint = hintfmt("hint %1%", "only"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); return 0; } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 4630432c9..04e8d2ebe 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1158,10 +1158,9 @@ void DerivationGoal::loadDerivation() trace("loading derivation"); if (nrFailed != 0) { - logError( - ErrorInfo { - .name = "missing derivation during build", - .hint = hintfmt("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)) + logError({ + .name = "missing derivation during build", + .hint = hintfmt("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)) }); done(BuildResult::MiscFailure); return; @@ -1313,12 +1312,11 @@ void DerivationGoal::repairClosure() /* Check each path (slow!). */ for (auto & i : outputClosure) { if (worker.pathContentsGood(i)) continue; - logError( - ErrorInfo { - .name = "Corrupt path in closure", - .hint = hintfmt( - "found corrupted or missing path '%s' in the output closure of '%s'", - worker.store.printStorePath(i), worker.store.printStorePath(drvPath)) + logError({ + .name = "Corrupt path in closure", + .hint = hintfmt( + "found corrupted or missing path '%s' in the output closure of '%s'", + worker.store.printStorePath(i), worker.store.printStorePath(drvPath)) }); auto drvPath2 = outputsToDrv.find(i); if (drvPath2 == outputsToDrv.end()) @@ -1353,12 +1351,11 @@ void DerivationGoal::inputsRealised() if (nrFailed != 0) { if (!useDerivation) throw Error("some dependencies of '%s' are missing", worker.store.printStorePath(drvPath)); - logError( - ErrorInfo { - .name = "Dependencies could not be built", - .hint = hintfmt( - "cannot build derivation '%s': %s dependencies couldn't be built", - worker.store.printStorePath(drvPath), nrFailed) + logError({ + .name = "Dependencies could not be built", + .hint = hintfmt( + "cannot build derivation '%s': %s dependencies couldn't be built", + worker.store.printStorePath(drvPath), nrFailed) }); done(BuildResult::DependencyFailed); return; @@ -1844,12 +1841,11 @@ HookReply DerivationGoal::tryBuildHook() } catch (SysError & e) { if (e.errNo == EPIPE) { - logError( - ErrorInfo { - .name = "Build hook died", - .hint = hintfmt( - "build hook died unexpectedly: %s", - chomp(drainFD(worker.hook->fromHook.readSide.get()))) + logError({ + .name = "Build hook died", + .hint = hintfmt( + "build hook died unexpectedly: %s", + chomp(drainFD(worker.hook->fromHook.readSide.get()))) }); worker.hook = 0; return rpDecline; @@ -3692,11 +3688,10 @@ void DerivationGoal::registerOutputs() /* Apply hash rewriting if necessary. */ bool rewritten = false; if (!outputRewrites.empty()) { - logWarning( - ErrorInfo { - .name = "Rewriting hashes", - .hint = hintfmt("rewriting hashes in '%1%'; cross fingers", path) - }); + logWarning({ + .name = "Rewriting hashes", + .hint = hintfmt("rewriting hashes in '%1%'; cross fingers", path) + }); /* Canonicalise first. This ensures that the path we're rewriting doesn't contain a hard link to /etc/shadow or @@ -3875,10 +3870,9 @@ void DerivationGoal::registerOutputs() if (settings.enforceDeterminism) throw NotDeterministic(hint); - logError( - ErrorInfo { - .name = "Output determinism error", - .hint = hint + logError({ + .name = "Output determinism error", + .hint = hint }); @@ -4145,12 +4139,11 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) { logSize += data.size(); if (settings.maxLogSize && logSize > settings.maxLogSize) { - logError( - ErrorInfo { - .name = "Max log size exceeded", - .hint = hintfmt( - "%1% killed after writing more than %2% bytes of log output", - getName(), settings.maxLogSize) + logError({ + .name = "Max log size exceeded", + .hint = hintfmt( + "%1% killed after writing more than %2% bytes of log output", + getName(), settings.maxLogSize) }); killChild(); done(BuildResult::LogLimitExceeded); @@ -4467,12 +4460,11 @@ void SubstitutionGoal::tryNext() && !sub->isTrusted && !info->checkSignatures(worker.store, worker.store.getPublicKeys())) { - logWarning( - ErrorInfo { - .name = "Invalid path signature", - .hint = hintfmt("substituter '%s' does not have a valid signature for path '%s'", - sub->getUri(), worker.store.printStorePath(storePath)) - }); + logWarning({ + .name = "Invalid path signature", + .hint = hintfmt("substituter '%s' does not have a valid signature for path '%s'", + sub->getUri(), worker.store.printStorePath(storePath)) + }); tryNext(); return; } @@ -4954,12 +4946,11 @@ void Worker::waitForInput() j->respectTimeouts && after - j->lastOutput >= std::chrono::seconds(settings.maxSilentTime)) { - logError( - ErrorInfo { - .name = "Silent build timeout", - .hint = hintfmt( - "%1% timed out after %2% seconds of silence", - goal->getName(), settings.maxSilentTime) + logError({ + .name = "Silent build timeout", + .hint = hintfmt( + "%1% timed out after %2% seconds of silence", + goal->getName(), settings.maxSilentTime) }); goal->timedOut(); } @@ -4969,12 +4960,11 @@ void Worker::waitForInput() j->respectTimeouts && after - j->timeStarted >= std::chrono::seconds(settings.buildTimeout)) { - logError( - ErrorInfo { - .name = "Build timeout", - .hint = hintfmt( - "%1% timed out after %2% seconds", - goal->getName(), settings.buildTimeout) + logError({ + .name = "Build timeout", + .hint = hintfmt( + "%1% timed out after %2% seconds", + goal->getName(), settings.buildTimeout) }); goal->timedOut(); } @@ -5035,10 +5025,9 @@ bool Worker::pathContentsGood(const StorePath & path) } pathContentsGoodCache.insert_or_assign(path.clone(), res); if (!res) - logError( - ErrorInfo { - .name = "Corrupted path", - .hint = hintfmt("path '%s' is corrupted or missing!", store.printStorePath(path)) + logError({ + .name = "Corrupted path", + .hint = hintfmt("path '%s' is corrupted or missing!", store.printStorePath(path)) }); return res; } diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 89588d662..6ca3393ab 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -599,12 +599,11 @@ struct curlFileTransfer : public FileTransfer workerThreadMain(); } catch (nix::Interrupted & e) { } catch (std::exception & e) { - logError( - ErrorInfo { - .name = "File transfer", - .hint = hintfmt("unexpected error in download thread: %s", - e.what()) - }); + logError({ + .name = "File transfer", + .hint = hintfmt("unexpected error in download thread: %s", + e.what()) + }); } { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index abcfe5271..53fb4ce68 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -87,12 +87,11 @@ LocalStore::LocalStore(const Params & params) struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); if (!gr) - logError( - ErrorInfo { - .name = "'build-users-group' not found", - .hint = hintfmt( - "warning: the group '%1%' specified in 'build-users-group' does not exist", - settings.buildUsersGroup) + logError({ + .name = "'build-users-group' not found", + .hint = hintfmt( + "warning: the group '%1%' specified in 'build-users-group' does not exist", + settings.buildUsersGroup) }); else { struct stat st; @@ -1242,12 +1241,11 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) Path linkPath = linksDir + "/" + link.name; string hash = hashPath(htSHA256, linkPath).first.to_string(Base32, false); if (hash != link.name) { - logError( - ErrorInfo { - .name = "Invalid hash", - .hint = hintfmt( - "link '%s' was modified! expected hash '%s', got '%s'", - linkPath, link.name, hash) + logError({ + .name = "Invalid hash", + .hint = hintfmt( + "link '%s' was modified! expected hash '%s', got '%s'", + linkPath, link.name, hash) }); if (repair) { if (unlink(linkPath.c_str()) == 0) @@ -1281,11 +1279,10 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) auto current = hashSink->finish(); if (info->narHash != nullHash && info->narHash != current.first) { - logError( - ErrorInfo { - .name = "Invalid hash - path modified", - .hint = hintfmt("path '%s' was modified! expected hash '%s', got '%s'", - printStorePath(i), info->narHash.to_string(), current.first.to_string()) + logError({ + .name = "Invalid hash - path modified", + .hint = hintfmt("path '%s' was modified! expected hash '%s', got '%s'", + printStorePath(i), info->narHash.to_string(), current.first.to_string()) }); if (repair) repairPath(i); else errors = true; } else { @@ -1337,10 +1334,9 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, if (!done.insert(pathS).second) return; if (!isStorePath(pathS)) { - logError( - ErrorInfo { - .name = "Nix path not found", - .hint = hintfmt("path '%s' is not in the Nix store", pathS) + logError({ + .name = "Nix path not found", + .hint = hintfmt("path '%s' is not in the Nix store", pathS) }); return; } @@ -1364,10 +1360,9 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, auto state(_state.lock()); invalidatePath(*state, path); } else { - logError( - ErrorInfo { - .name = "Missing path with referrers", - .hint = hintfmt("path '%s' disappeared, but it still has valid referrers!", pathS) + logError({ + .name = "Missing path with referrers", + .hint = hintfmt("path '%s' disappeared, but it still has valid referrers!", pathS) }); if (repair) try { diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index c9ecca5a8..cc0507be2 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -130,10 +130,9 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, NixOS (example: $fontconfig/var/cache being modified). Skip those files. FIXME: check the modification time. */ if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { - logWarning( - ErrorInfo { - .name = "Suspicious file", - .hint = hintfmt("skipping suspicious writable file '%1%'", path) + logWarning({ + .name = "Suspicious file", + .hint = hintfmt("skipping suspicious writable file '%1%'", path) }); return; } @@ -198,10 +197,9 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, } if (st.st_size != stLink.st_size) { - logWarning( - ErrorInfo { - .name = "Corrupted link", - .hint = hintfmt("removing corrupted link '%1%'", linkPath) + logWarning({ + .name = "Corrupted link", + .hint = hintfmt("removing corrupted link '%1%'", linkPath) }); unlink(linkPath.c_str()); goto retry; @@ -237,10 +235,9 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, /* Atomically replace the old file with the new hard link. */ if (rename(tempLink.c_str(), path.c_str()) == -1) { if (unlink(tempLink.c_str()) == -1) - logError( - ErrorInfo { - .name = "Unlink error", - .hint = hintfmt("unable to unlink '%1%'", tempLink) + logError({ + .name = "Unlink error", + .hint = hintfmt("unable to unlink '%1%'", tempLink) }); if (errno == EMLINK) { /* Some filesystems generate too many links on the rename, diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 071a7ec7e..41378b0db 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -251,10 +251,9 @@ bool handleJSONLogMessage(const std::string & msg, } } catch (std::exception & e) { - logError( - ErrorInfo { - .name = "Json log message", - .hint = hintfmt("bad log message from builder: %s", e.what()) + logError({ + .name = "Json log message", + .hint = hintfmt("bad log message from builder: %s", e.what()) }); } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index bbce5dcda..8231a07a4 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -123,10 +123,9 @@ static void getAllExprs(EvalState & state, if (hasSuffix(attrName, ".nix")) attrName = string(attrName, 0, attrName.size() - 4); if (!attrs.insert(attrName).second) { - logError( - ErrorInfo { - .name = "Name collision", - .hint = hintfmt("warning: name collision in input Nix expressions, skipping '%1%'", path2) + logError({ + .name = "Name collision", + .hint = hintfmt("warning: name collision in input Nix expressions, skipping '%1%'", path2) }); continue; } @@ -875,11 +874,10 @@ static void queryJSON(Globals & globals, vector & elems) auto placeholder = metaObj.placeholder(j); Value * v = i.queryMeta(j); if (!v) { - logError( - ErrorInfo { - .name = "Invalid meta attribute", - .hint = hintfmt("derivation '%s' has invalid meta attribute '%s'", - i.queryName(), j) + logError({ + .name = "Invalid meta attribute", + .hint = hintfmt("derivation '%s' has invalid meta attribute '%s'", + i.queryName(), j) }); placeholder.write(nullptr); } else { @@ -1131,12 +1129,11 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) attrs2["name"] = j; Value * v = i.queryMeta(j); if (!v) - logError( - ErrorInfo { - .name = "Invalid meta attribute", - .hint = hintfmt( - "derivation '%s' has invalid meta attribute '%s'", - i.queryName(), j) + logError({ + .name = "Invalid meta attribute", + .hint = hintfmt( + "derivation '%s' has invalid meta attribute '%s'", + i.queryName(), j) }); else { if (v->type == tString) { diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 6b83093b1..5e42736fc 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -704,7 +704,7 @@ static void opVerify(Strings opFlags, Strings opArgs) else throw UsageError("unknown flag '%1%'", i); if (store->verifyStore(checkContents, repair)) { - logWarning(ErrorInfo { + logWarning({ .name = "Store consistency", .description = "not all errors were fixed" }); @@ -729,14 +729,13 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) store->narFromPath(path, sink); auto current = sink.finish(); if (current.first != info->narHash) { - logError( - ErrorInfo { - .name = "Hash mismatch", - .hint = hintfmt( - "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(path), - info->narHash.to_string(), - current.first.to_string()) + logError({ + .name = "Hash mismatch", + .hint = hintfmt( + "path '%s' was modified! expected hash '%s', got '%s'", + store->printStorePath(path), + info->narHash.to_string(), + current.first.to_string()) }); status = 1; } diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 8c845bfc2..8ecd9a8f3 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -99,15 +99,14 @@ struct CmdVerify : StorePathsCommand if (hash.first != info->narHash) { corrupted++; act2.result(resCorruptedPath, store->printStorePath(info->path)); - logError( - ErrorInfo { - .name = "Hash error - path modified", - .hint = hintfmt( - "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(info->path), - info->narHash.to_string(), - hash.first.to_string()) - }); + logError({ + .name = "Hash error - path modified", + .hint = hintfmt( + "path '%s' was modified! expected hash '%s', got '%s'", + store->printStorePath(info->path), + info->narHash.to_string(), + hash.first.to_string()) + }); } } @@ -156,11 +155,10 @@ struct CmdVerify : StorePathsCommand if (!good) { untrusted++; act2.result(resUntrustedPath, store->printStorePath(info->path)); - logError( - ErrorInfo { - .name = "Untrusted path", - .hint = hintfmt("path '%s' is untrusted", - store->printStorePath(info->path)) + logError({ + .name = "Untrusted path", + .hint = hintfmt("path '%s' is untrusted", + store->printStorePath(info->path)) }); } diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc index dcea72529..82feacb3d 100644 --- a/src/resolve-system-dependencies/resolve-system-dependencies.cc +++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc @@ -39,19 +39,17 @@ std::set runResolver(const Path & filename) throw SysError("statting '%s'", filename); if (!S_ISREG(st.st_mode)) { - logError( - ErrorInfo { - .name = "Regular MACH file", - .hint = hintfmt("file '%s' is not a regular file", filename) + logError({ + .name = "Regular MACH file", + .hint = hintfmt("file '%s' is not a regular file", filename) }); return {}; } if (st.st_size < sizeof(mach_header_64)) { - logError( - ErrorInfo { - .name = "File too short", - .hint = hintfmt("file '%s' is too short for a MACH binary", filename) + logError({ + .name = "File too short", + .hint = hintfmt("file '%s' is too short for a MACH binary", filename) }); return {}; } @@ -74,20 +72,18 @@ std::set runResolver(const Path & filename) } } if (mach64_offset == 0) { - logError( - ErrorInfo { - .name = "No mach64 blobs", - .hint = hintfmt("Could not find any mach64 blobs in file '%1%', continuing...", filename) + logError({ + .name = "No mach64 blobs", + .hint = hintfmt("Could not find any mach64 blobs in file '%1%', continuing...", filename) }); return {}; } } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) { mach64_offset = 0; } else { - logError( - ErrorInfo { - .name = "Magic number", - .hint = hintfmt("Object file has unknown magic number '%1%', skipping it...", magic) + logError({ + .name = "Magic number", + .hint = hintfmt("Object file has unknown magic number '%1%', skipping it...", magic) }); return {}; } -- cgit v1.2.3 From 156d4f8bc892baa4e25814d5f79a332994c750d1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 2 Jun 2020 08:45:37 -0600 Subject: remove extra space in SysErrors --- src/libutil/error.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libutil/error.hh b/src/libutil/error.hh index b374c2780..0ca0c8b15 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -155,7 +155,7 @@ public: { errNo = errno; auto hf = hintfmt(args...); - err.hint = hintfmt("%1% : %2%", normaltxt(hf.str()), strerror(errNo)); + err.hint = hintfmt("%1%: %2%", normaltxt(hf.str()), strerror(errNo)); } virtual const char* sname() const override { return "SysError"; } -- cgit v1.2.3 From 6ee03b8444e1838b9985a9fd4f0f46947e958b3b Mon Sep 17 00:00:00 2001 From: zimbatm Date: Wed, 3 Jun 2020 12:38:23 +0200 Subject: libutils/hash: remove default encoding This will make it easier to reason about the hash encoding and switch to SRI everywhere where possible. --- src/libexpr/primops/fetchTree.cc | 4 ++-- src/libfetchers/fetchers.cc | 4 ++-- src/libfetchers/tarball.cc | 6 +++--- src/libstore/build.cc | 2 +- src/libstore/export-import.cc | 2 +- src/libstore/local-store.cc | 10 +++++----- src/libstore/nar-info-disk-cache.cc | 4 ++-- src/libstore/nar-info.cc | 4 ++-- src/libstore/optimise-store.cc | 2 +- src/libstore/store-api.cc | 12 ++++++------ src/libutil/hash.hh | 2 +- src/libutil/tests/hash.cc | 16 ++++++++-------- src/nix-store/nix-store.cc | 6 +++--- src/nix/verify.cc | 2 +- 14 files changed, 38 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index c5a0d9886..b90408798 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -23,7 +23,7 @@ void emitTreeAttrs( assert(tree.info.narHash); mkString(*state.allocAttr(v, state.symbols.create("narHash")), - tree.info.narHash.to_string(SRI)); + tree.info.narHash.to_string(SRI, true)); if (input->getRev()) { mkString(*state.allocAttr(v, state.symbols.create("rev")), input->getRev()->gitRev()); @@ -140,7 +140,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, : hashFile(htSHA256, path); if (hash != *expectedHash) throw Error((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s", - *url, expectedHash->to_string(), hash.to_string()); + *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); } if (state.allowedPaths) diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 94ac30e38..ca555114d 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -47,7 +47,7 @@ Attrs Input::toAttrs() const { auto attrs = toAttrsInternal(); if (narHash) - attrs.emplace("narHash", narHash->to_string(SRI)); + attrs.emplace("narHash", narHash->to_string(SRI, true)); attrs.emplace("type", type()); return attrs; } @@ -67,7 +67,7 @@ std::pair> Input::fetchTree(ref store) if (narHash && narHash != input->narHash) throw Error("NAR hash mismatch in input '%s' (%s), expected '%s', got '%s'", - to_string(), tree.actualPath, narHash->to_string(SRI), input->narHash->to_string(SRI)); + to_string(), tree.actualPath, narHash->to_string(SRI, true), input->narHash->to_string(SRI, true)); return {std::move(tree), input}; } diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index b6e57379b..1b0eba18a 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -196,9 +196,9 @@ struct TarballInput : Input // NAR hashes are preferred over file hashes since tar/zip files // don't have a canonical representation. if (narHash) - url2.query.insert_or_assign("narHash", narHash->to_string(SRI)); + url2.query.insert_or_assign("narHash", narHash->to_string(SRI, true)); else if (hash) - url2.query.insert_or_assign("hash", hash->to_string(SRI)); + url2.query.insert_or_assign("hash", hash->to_string(SRI, true)); return url2; } @@ -207,7 +207,7 @@ struct TarballInput : Input Attrs attrs; attrs.emplace("url", url.to_string()); if (hash) - attrs.emplace("hash", hash->to_string(SRI)); + attrs.emplace("hash", hash->to_string(SRI, true)); return attrs; } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f5c132a83..9582a9007 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -3718,7 +3718,7 @@ void DerivationGoal::registerOutputs() worker.hashMismatch = true; delayedException = std::make_exception_ptr( BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s", - worker.store.printStorePath(dest), h.to_string(SRI), h2.to_string(SRI))); + worker.store.printStorePath(dest), h.to_string(SRI, true), h2.to_string(SRI, true))); Path actualDest = worker.store.Store::toRealPath(dest); diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc index f0d01a240..54471d4a3 100644 --- a/src/libstore/export-import.cc +++ b/src/libstore/export-import.cc @@ -57,7 +57,7 @@ void Store::exportPath(const StorePath & path, Sink & sink) Hash hash = hashAndWriteSink.currentHash(); if (hash != info->narHash && info->narHash != Hash(info->narHash.type)) throw Error("hash of path '%s' has changed from '%s' to '%s'!", - printStorePath(path), info->narHash.to_string(), hash.to_string()); + printStorePath(path), info->narHash.to_string(Base32, true), hash.to_string(Base32, true)); hashAndWriteSink << exportMagic diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 80851b591..1c3795eb1 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -580,7 +580,7 @@ uint64_t LocalStore::addValidPath(State & state, state.stmtRegisterValidPath.use() (printStorePath(info.path)) - (info.narHash.to_string(Base16)) + (info.narHash.to_string(Base16, true)) (info.registrationTime == 0 ? time(0) : info.registrationTime) (info.deriver ? printStorePath(*info.deriver) : "", (bool) info.deriver) (info.narSize, info.narSize != 0) @@ -680,7 +680,7 @@ void LocalStore::updatePathInfo(State & state, const ValidPathInfo & info) { state.stmtUpdatePathInfo.use() (info.narSize, info.narSize != 0) - (info.narHash.to_string(Base16)) + (info.narHash.to_string(Base16, true)) (info.ultimate ? 1 : 0, info.ultimate) (concatStringsSep(" ", info.sigs), !info.sigs.empty()) (info.ca, !info.ca.empty()) @@ -1022,7 +1022,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, if (hashResult.first != info.narHash) throw Error("hash mismatch importing path '%s';\n wanted: %s\n got: %s", - printStorePath(info.path), info.narHash.to_string(), hashResult.first.to_string()); + printStorePath(info.path), info.narHash.to_string(Base32, true), hashResult.first.to_string(Base32, true)); if (hashResult.second != info.narSize) throw Error("size mismatch importing path '%s';\n wanted: %s\n got: %s", @@ -1155,7 +1155,7 @@ StorePath LocalStore::addTextToStore(const string & name, const string & s, info.narHash = narHash; info.narSize = sink.s->size(); info.references = cloneStorePathSet(references); - info.ca = "text:" + hash.to_string(); + info.ca = "text:" + hash.to_string(Base32, true); registerValidPath(info); } @@ -1273,7 +1273,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) if (info->narHash != nullHash && info->narHash != current.first) { printError("path '%s' was modified! expected hash '%s', got '%s'", - printStorePath(i), info->narHash.to_string(), current.first.to_string()); + printStorePath(i), info->narHash.to_string(Base32, true), current.first.to_string(Base32, true)); if (repair) repairPath(i); else errors = true; } else { diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index 442541330..e8cf1d177 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -230,9 +230,9 @@ public: (std::string(info->path.name())) (narInfo ? narInfo->url : "", narInfo != 0) (narInfo ? narInfo->compression : "", narInfo != 0) - (narInfo && narInfo->fileHash ? narInfo->fileHash.to_string() : "", narInfo && narInfo->fileHash) + (narInfo && narInfo->fileHash ? narInfo->fileHash.to_string(Base32, true) : "", narInfo && narInfo->fileHash) (narInfo ? narInfo->fileSize : 0, narInfo != 0 && narInfo->fileSize) - (info->narHash.to_string()) + (info->narHash.to_string(Base32, true)) (info->narSize) (concatStringsSep(" ", info->shortRefs())) (info->deriver ? std::string(info->deriver->to_string()) : "", (bool) info->deriver) diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 1375094b5..6b16be08a 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -87,10 +87,10 @@ std::string NarInfo::to_string(const Store & store) const assert(compression != ""); res += "Compression: " + compression + "\n"; assert(fileHash.type == htSHA256); - res += "FileHash: " + fileHash.to_string(Base32) + "\n"; + res += "FileHash: " + fileHash.to_string(Base32, true) + "\n"; res += "FileSize: " + std::to_string(fileSize) + "\n"; assert(narHash.type == htSHA256); - res += "NarHash: " + narHash.to_string(Base32) + "\n"; + res += "NarHash: " + narHash.to_string(Base32, true) + "\n"; res += "NarSize: " + std::to_string(narSize) + "\n"; res += "References: " + concatStringsSep(" ", shortRefs()) + "\n"; diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index 8ac382e9d..3f4b72b9c 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -150,7 +150,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, contents of the symlink (i.e. the result of readlink()), not the contents of the target (which may not even exist). */ Hash hash = hashPath(htSHA256, path).first; - debug(format("'%1%' has hash '%2%'") % path % hash.to_string()); + debug(format("'%1%' has hash '%2%'") % path % hash.to_string(Base32, true)); /* Check if this is a known hash. */ Path linkPath = linksDir + "/" + hash.to_string(Base32, false); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 095363d0c..0645fca84 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -142,7 +142,7 @@ StorePath Store::makeStorePath(const string & type, const Hash & hash, std::string_view name) const { /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */ - string s = type + ":" + hash.to_string(Base16) + ":" + storeDir + ":" + std::string(name); + string s = type + ":" + hash.to_string(Base16, true) + ":" + storeDir + ":" + std::string(name); auto h = compressHash(hashString(htSHA256, s), 20); return StorePath::make(h.hash, name); } @@ -186,7 +186,7 @@ StorePath Store::makeFixedOutputPath( hashString(htSHA256, "fixed:out:" + (recursive == FileIngestionMethod::Recursive ? (string) "r:" : "") - + hash.to_string(Base16) + ":"), + + hash.to_string(Base16, true) + ":"), name); } } @@ -461,7 +461,7 @@ void Store::pathInfoToJSON(JSONPlaceholder & jsonOut, const StorePathSet & store auto info = queryPathInfo(storePath); jsonPath - .attr("narHash", info->narHash.to_string(hashBase)) + .attr("narHash", info->narHash.to_string(hashBase, true)) .attr("narSize", info->narSize); { @@ -504,7 +504,7 @@ void Store::pathInfoToJSON(JSONPlaceholder & jsonOut, const StorePathSet & store if (!narInfo->url.empty()) jsonPath.attr("url", narInfo->url); if (narInfo->fileHash) - jsonPath.attr("downloadHash", narInfo->fileHash.to_string()); + jsonPath.attr("downloadHash", narInfo->fileHash.to_string(Base32, true)); if (narInfo->fileSize) jsonPath.attr("downloadSize", narInfo->fileSize); if (showClosureSize) @@ -760,7 +760,7 @@ std::string ValidPathInfo::fingerprint(const Store & store) const store.printStorePath(path)); return "1;" + store.printStorePath(path) + ";" - + narHash.to_string(Base32) + ";" + + narHash.to_string(Base32, true) + ";" + std::to_string(narSize) + ";" + concatStringsSep(",", store.printStorePathSet(references)); } @@ -836,7 +836,7 @@ std::string makeFixedOutputCA(FileIngestionMethod recursive, const Hash & hash) { return "fixed:" + (recursive == FileIngestionMethod::Recursive ? (std::string) "r:" : "") - + hash.to_string(); + + hash.to_string(Base32, true); } diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index ea9fca3e7..4ff13f6b2 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -79,7 +79,7 @@ struct Hash /* Return a string representation of the hash, in base-16, base-32 or base-64. By default, this is prefixed by the hash type (e.g. "sha256:"). */ - std::string to_string(Base base = Base32, bool includeType = true) const; + std::string to_string(Base base, bool includeType) const; std::string gitRev() const { diff --git a/src/libutil/tests/hash.cc b/src/libutil/tests/hash.cc index 7cb439817..5334b046e 100644 --- a/src/libutil/tests/hash.cc +++ b/src/libutil/tests/hash.cc @@ -11,28 +11,28 @@ namespace nix { // values taken from: https://tools.ietf.org/html/rfc1321 auto s1 = ""; auto hash = hashString(HashType::htMD5, s1); - ASSERT_EQ(hash.to_string(Base::Base16), "md5:d41d8cd98f00b204e9800998ecf8427e"); + ASSERT_EQ(hash.to_string(Base::Base16, true), "md5:d41d8cd98f00b204e9800998ecf8427e"); } TEST(hashString, testKnownMD5Hashes2) { // values taken from: https://tools.ietf.org/html/rfc1321 auto s2 = "abc"; auto hash = hashString(HashType::htMD5, s2); - ASSERT_EQ(hash.to_string(Base::Base16), "md5:900150983cd24fb0d6963f7d28e17f72"); + ASSERT_EQ(hash.to_string(Base::Base16, true), "md5:900150983cd24fb0d6963f7d28e17f72"); } TEST(hashString, testKnownSHA1Hashes1) { // values taken from: https://tools.ietf.org/html/rfc3174 auto s = "abc"; auto hash = hashString(HashType::htSHA1, s); - ASSERT_EQ(hash.to_string(Base::Base16),"sha1:a9993e364706816aba3e25717850c26c9cd0d89d"); + ASSERT_EQ(hash.to_string(Base::Base16, true),"sha1:a9993e364706816aba3e25717850c26c9cd0d89d"); } TEST(hashString, testKnownSHA1Hashes2) { // values taken from: https://tools.ietf.org/html/rfc3174 auto s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; auto hash = hashString(HashType::htSHA1, s); - ASSERT_EQ(hash.to_string(Base::Base16),"sha1:84983e441c3bd26ebaae4aa1f95129e5e54670f1"); + ASSERT_EQ(hash.to_string(Base::Base16, true),"sha1:84983e441c3bd26ebaae4aa1f95129e5e54670f1"); } TEST(hashString, testKnownSHA256Hashes1) { @@ -40,7 +40,7 @@ namespace nix { auto s = "abc"; auto hash = hashString(HashType::htSHA256, s); - ASSERT_EQ(hash.to_string(Base::Base16), + ASSERT_EQ(hash.to_string(Base::Base16, true), "sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); } @@ -48,7 +48,7 @@ namespace nix { // values taken from: https://tools.ietf.org/html/rfc4634 auto s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; auto hash = hashString(HashType::htSHA256, s); - ASSERT_EQ(hash.to_string(Base::Base16), + ASSERT_EQ(hash.to_string(Base::Base16, true), "sha256:248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); } @@ -56,7 +56,7 @@ namespace nix { // values taken from: https://tools.ietf.org/html/rfc4634 auto s = "abc"; auto hash = hashString(HashType::htSHA512, s); - ASSERT_EQ(hash.to_string(Base::Base16), + ASSERT_EQ(hash.to_string(Base::Base16, true), "sha512:ddaf35a193617abacc417349ae20413112e6fa4e89a9" "7ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd" "454d4423643ce80e2a9ac94fa54ca49f"); @@ -67,7 +67,7 @@ namespace nix { auto s = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; auto hash = hashString(HashType::htSHA512, s); - ASSERT_EQ(hash.to_string(Base::Base16), + ASSERT_EQ(hash.to_string(Base::Base16, true), "sha512:8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa1" "7299aeadb6889018501d289e4900f7e4331b99dec4b5433a" "c7d329eeb6dd26545e96e55b874be909"); diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 3a3060ad8..9491a0c26 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -373,7 +373,7 @@ static void opQuery(Strings opFlags, Strings opArgs) auto info = store->queryPathInfo(j); if (query == qHash) { assert(info->narHash.type == htSHA256); - cout << fmt("%s\n", info->narHash.to_string(Base32)); + cout << fmt("%s\n", info->narHash.to_string(Base32, true)); } else if (query == qSize) cout << fmt("%d\n", info->narSize); } @@ -728,7 +728,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) if (current.first != info->narHash) { printError( "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(path), info->narHash.to_string(), current.first.to_string()); + store->printStorePath(path), info->narHash.to_string(Base32, true), current.first.to_string(Base32, true)); status = 1; } } @@ -856,7 +856,7 @@ static void opServe(Strings opFlags, Strings opArgs) out << info->narSize // downloadSize << info->narSize; if (GET_PROTOCOL_MINOR(clientVersion) >= 4) - out << (info->narHash ? info->narHash.to_string() : "") << info->ca << info->sigs; + out << (info->narHash ? info->narHash.to_string(Base32, true) : "") << info->ca << info->sigs; } catch (InvalidPath &) { } } diff --git a/src/nix/verify.cc b/src/nix/verify.cc index cf1fa6a99..287dad101 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -101,7 +101,7 @@ struct CmdVerify : StorePathsCommand act2.result(resCorruptedPath, store->printStorePath(info->path)); printError( "path '%s' was modified! expected hash '%s', got '%s'", - store->printStorePath(info->path), info->narHash.to_string(), hash.first.to_string()); + store->printStorePath(info->path), info->narHash.to_string(Base32, true), hash.first.to_string(Base32, true)); } } -- cgit v1.2.3 From 132d6f2c2419891b92870c61c599a5e6aa97c865 Mon Sep 17 00:00:00 2001 From: Carlo Nucera Date: Wed, 3 Jun 2020 16:08:32 -0400 Subject: Clarify the description of StorePath construction --- src/libstore/store-api.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 095363d0c..e5492ce34 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -69,7 +69,7 @@ string storePathToHash(const Path & path) /* Store paths have the following form: - /- + = /- where @@ -93,11 +93,14 @@ string storePathToHash(const Path & path) = one of: "text:::..." for plain text files written to the store using - addTextToStore(); ... are the references of the - path. - "source" + addTextToStore(); ... are the store paths referenced + by this path, in the form described by + "source:::...::self" for paths copied to the store using addToStore() when recursive - = true and hashAlgo = "sha256" + = true and hashAlgo = "sha256". Just like in the text case, we + can have the store paths referenced by the path. + Additionally, we can have an optional :self label to denote self + reference. "output:" for either the outputs created by derivations, OR paths copied to the store using addToStore() with recursive != true or @@ -125,6 +128,12 @@ string storePathToHash(const Path & path) the contents of the path (or expected contents of the path for fixed-output derivations) + Note that since an output derivation has always type output, while + something added by addToStore can have type output or source depending + on the hash, this means that the same input can be hashed differently + if added to the store via addToStore or via a derivation, in the sha256 + recursive case. + It would have been nicer to handle fixed-output derivations under "source", e.g. have something like "source:", but we're stuck with this for now... -- cgit v1.2.3 From f97576c5d91d5278155a67e2b8982d2233d4335a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 3 Jun 2020 14:47:00 -0600 Subject: newline-as-prefix; no final newline in output. --- src/libutil/error.cc | 73 ++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 59628d875..539a7543f 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -57,20 +57,20 @@ void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixC { // previous line of code. if (nixCode.prevLineOfCode.has_value()) { - out << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line - 1), - *nixCode.prevLineOfCode) - << std::endl; + out << std::endl + << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.line - 1), + *nixCode.prevLineOfCode); } if (nixCode.errLineOfCode.has_value()) { // line of code containing the error. - out << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line), - *nixCode.errLineOfCode) - << std::endl; + out << std::endl + << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.line), + *nixCode.errLineOfCode); // error arrows for the column range. if (nixCode.errPos.column > 0) { int start = nixCode.errPos.column; @@ -81,20 +81,21 @@ void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixC std::string arrows("^"); - out << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, - prefix, - spaces, - arrows) << std::endl; + out << std::endl + << fmt("%1% |%2%" ANSI_RED "%3%" ANSI_NORMAL, + prefix, + spaces, + arrows); } } // next line of code. if (nixCode.nextLineOfCode.has_value()) { - out << fmt("%1% %|2$5d|| %3%", - prefix, - (nixCode.errPos.line + 1), - *nixCode.nextLineOfCode) - << std::endl; + out << std::endl + << fmt("%1% %|2$5d|| %3%", + prefix, + (nixCode.errPos.line + 1), + *nixCode.nextLineOfCode); } } @@ -167,46 +168,50 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) levelString, einfo.name, dashes, - einfo.programName.value_or("")) - << std::endl; + einfo.programName.value_or("")); else out << fmt("%1%%2%" ANSI_BLUE " -----%3% %4%" ANSI_NORMAL, prefix, levelString, dashes, - einfo.programName.value_or("")) - << std::endl; + einfo.programName.value_or("")); - // filename, line, column. + bool nl = false; // intersperse newline between sections. if (einfo.nixCode.has_value()) { if (einfo.nixCode->errPos.file != "") { - out << fmt("%1%in file: " ANSI_BLUE "%2% %3%" ANSI_NORMAL, + // filename, line, column. + out << std::endl << fmt("%1%in file: " ANSI_BLUE "%2% %3%" ANSI_NORMAL, prefix, einfo.nixCode->errPos.file, - showErrPos(einfo.nixCode->errPos)) << std::endl; - out << prefix << std::endl; + showErrPos(einfo.nixCode->errPos)); } else { - out << fmt("%1%from command line argument", prefix) << std::endl; - out << prefix << std::endl; + out << std::endl << fmt("%1%from command line argument", prefix); } + nl = true; } // description if (einfo.description != "") { - out << prefix << einfo.description << std::endl; - out << prefix << std::endl; + if (nl) + out << std::endl << prefix; + out << std::endl << prefix << einfo.description; + nl = true; } // lines of code. if (einfo.nixCode.has_value() && einfo.nixCode->errLineOfCode.has_value()) { + if (nl) + out << std::endl << prefix; printCodeLines(out, prefix, *einfo.nixCode); - out << prefix << std::endl; + nl = true; } // hint if (einfo.hint.has_value()) { - out << prefix << *einfo.hint << std::endl; - out << prefix << std::endl; + if (nl) + out << std::endl << prefix; + out << std::endl << prefix << *einfo.hint; + nl = true; } return out; -- cgit v1.2.3 From 94427ffee3493077206f960e3cda9bbb659583be Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 4 Jun 2020 11:53:19 -0600 Subject: add some comments --- src/libutil/error.cc | 6 +++++- src/libutil/error.hh | 21 +++++++++++++++++++-- src/libutil/logging.hh | 33 ++++++++++++++++++--------------- 3 files changed, 42 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 539a7543f..1fcb8111c 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -10,13 +10,16 @@ namespace nix { const std::string nativeSystem = SYSTEM; - +// addPrefix is used for show-trace. Strings added with addPrefix +// will print ahead of the error itself. BaseError & BaseError::addPrefix(const FormatOrString & fs) { prefix_ = fs.s + prefix_; return *this; } +// c++ std::exception descendants must have a 'const char* what()' function. +// This stringifies the error and caches it for use by what(), or similarly by msg(). const string& BaseError::calcWhat() const { if (what_.has_value()) @@ -53,6 +56,7 @@ string showErrPos(const ErrPos &errPos) } } +// if nixCode contains lines of code, print them to the ostream, indicating the error column. void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixCode) { // previous line of code. diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 0ca0c8b15..8a48fa105 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -22,6 +22,23 @@ namespace nix { +/* + +This file defines two main structs/classes used in nix error handling. + +ErrorInfo provides a standard payload of error information, with conversion to string +happening in the logger rather than at the call site. + +BaseError is the ancestor of nix specific exceptions (and Interrupted), and contains +an ErrorInfo. + +ErrorInfo structs are sent to the logger as part of an exception, or directly with the +logError or logWarning macros. + +See the error-demo.cc program for usage examples. + +*/ + typedef enum { lvlError = 0, lvlWarn, @@ -32,6 +49,7 @@ typedef enum { lvlVomit } Verbosity; +// ErrPos indicates the location of an error in a nix file. struct ErrPos { int line = 0; int column = 0; @@ -42,6 +60,7 @@ struct ErrPos { return line != 0; } + // convert from the Pos struct, found in libexpr. template ErrPos& operator=(const P &pos) { @@ -65,8 +84,6 @@ struct NixCode { std::optional nextLineOfCode; }; -// ------------------------------------------------- -// ErrorInfo. struct ErrorInfo { Verbosity level; string name; diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 39692a291..eeb7233e9 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -150,9 +150,23 @@ bool handleJSONLogMessage(const std::string & msg, extern Verbosity verbosity; /* suppress msgs > this */ -/* Print a message if the current log level is at least the specified - level. Note that this has to be implemented as a macro to ensure - that the arguments are evaluated lazily. */ +/* Print a message with the standard ErrorInfo format. + In general, use these 'log' macros for reporting problems that may require user + intervention or that need more explanation. Use the 'print' macros for more + lightweight status messages. */ +#define logErrorInfo(level, errorInfo...) \ + do { \ + if (level <= nix::verbosity) { \ + logger->logEI(level, errorInfo); \ + } \ + } while (0) + +#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo) +#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo) + +/* Print a string message if the current log level is at least the specified + level. Note that this has to be implemented as a macro to ensure that the + arguments are evaluated lazily. */ #define printMsg(level, args...) \ do { \ if (level <= nix::verbosity) { \ @@ -166,18 +180,7 @@ extern Verbosity verbosity; /* suppress msgs > this */ #define debug(args...) printMsg(lvlDebug, args) #define vomit(args...) printMsg(lvlVomit, args) -#define logErrorInfo(level, errorInfo...) \ - do { \ - if (level <= nix::verbosity) { \ - logger->logEI(level, errorInfo); \ - } \ - } while (0) - -#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo) -#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo) - - - +/* if verbosity >= lvlWarn, print a message with a yellow 'warning:' prefix. */ template inline void warn(const std::string & fs, const Args & ... args) { -- cgit v1.2.3 From 952e72c804ce79ffeee8f58261d4cbdeb9d56ac6 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Sat, 6 Jun 2020 10:22:32 +0200 Subject: Add tests for logging.hh --- src/libutil/tests/local.mk | 2 +- src/libutil/tests/logging.cc | 251 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 src/libutil/tests/logging.cc (limited to 'src') diff --git a/src/libutil/tests/local.mk b/src/libutil/tests/local.mk index a297edb64..815e18560 100644 --- a/src/libutil/tests/local.mk +++ b/src/libutil/tests/local.mk @@ -8,7 +8,7 @@ libutil-tests_INSTALL_DIR := libutil-tests_SOURCES := $(wildcard $(d)/*.cc) -libutil-tests_CXXFLAGS += -I src/libutil +libutil-tests_CXXFLAGS += -I src/libutil -I src/libexpr libutil-tests_LIBS = libutil diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc new file mode 100644 index 000000000..ac015a16d --- /dev/null +++ b/src/libutil/tests/logging.cc @@ -0,0 +1,251 @@ +#include "logging.hh" +#include "nixexpr.hh" +#include "util.hh" + +#include + +namespace nix { + + /* ---------------------------------------------------------------------------- + * logEI + * --------------------------------------------------------------------------*/ + + TEST(logEI, catpuresBasicProperties) { + + MakeError(TestError, Error); + ErrorInfo::programName = std::optional("error-unit-test"); + + try { + throw TestError("an error for testing purposes"); + } catch (Error &e) { + testing::internal::CaptureStderr(); + logger->logEI(e.info()); + auto str = testing::internal::GetCapturedStderr(); + + ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\nan error for testing purposes\n"); + } + } + + TEST(logEI, appendingHintsToPreviousError) { + + MakeError(TestError, Error); + ErrorInfo::programName = std::optional("error-unit-test"); + + try { + auto e = Error("initial error"); + throw TestError(e.info()); + } catch (Error &e) { + ErrorInfo ei = e.info(); + ei.hint = hintfmt("%s; subsequent error message.", normaltxt(e.info().hint ? e.info().hint->str() : "")); + + testing::internal::CaptureStderr(); + logger->logEI(ei); + auto str = testing::internal::GetCapturedStderr(); + + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0minitial error\x1B[0m; subsequent error message.\n"); + } + + } + + TEST(logEI, picksUpSysErrorExitCode) { + + MakeError(TestError, Error); + ErrorInfo::programName = std::optional("error-unit-test"); + + try { + auto x = readFile(-1); + } + catch (SysError &e) { + testing::internal::CaptureStderr(); + logError(e.info()); + auto str = testing::internal::GetCapturedStderr(); + + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError ------------------------------------- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0mstatting file\x1B[0m: \x1B[33;1mBad file descriptor\x1B[0m\n"); + + } + } + + TEST(logEI, loggingErrorOnInfoLevel) { + testing::internal::CaptureStderr(); + + logger->logEI({ .level = lvlInfo, + .name = "Info name", + .description = "Info description", + }); + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name ------------------------------------- error-unit-test\x1B[0m\nInfo description\n"); + } + + TEST(logEI, loggingErrorOnTalkativeLevel) { + testing::internal::CaptureStderr(); + + logger->logEI({ .level = lvlTalkative, + .name = "Talkative name", + .description = "Talkative description", + }); + + auto str = testing::internal::GetCapturedStderr(); + // XXX: why is this the empty string? + ASSERT_STREQ(str.c_str(), ""); + } + + TEST(logEI, loggingErrorOnChattyLevel) { + testing::internal::CaptureStderr(); + + logger->logEI({ .level = lvlChatty, + .name = "Chatty name", + .description = "Talkative description", + }); + + auto str = testing::internal::GetCapturedStderr(); + // XXX: why is this the empty string? + ASSERT_STREQ(str.c_str(), ""); + } + + TEST(logEI, loggingErrorOnDebugLevel) { + testing::internal::CaptureStderr(); + + logger->logEI({ .level = lvlDebug, + .name = "Debug name", + .description = "Debug description", + }); + + auto str = testing::internal::GetCapturedStderr(); + // XXX: why is this the empty string? + ASSERT_STREQ(str.c_str(), ""); + } + + TEST(logEI, loggingErrorOnVomitLevel) { + testing::internal::CaptureStderr(); + + logger->logEI({ .level = lvlVomit, + .name = "Vomit name", + .description = "Vomit description", + }); + + auto str = testing::internal::GetCapturedStderr(); + // XXX: why is this the empty string? + ASSERT_STREQ(str.c_str(), ""); + } + + /* ---------------------------------------------------------------------------- + * logError + * --------------------------------------------------------------------------*/ + + + TEST(logError, logErrorWithoutHintOrCode) { + testing::internal::CaptureStderr(); + + logError({ + .name = "name", + .description = "error description", + }); + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name ----------------------------------------- error-unit-test\x1B[0m\nerror description\n"); + } + + TEST(logError, logErrorWithPreviousAndNextLinesOfCode) { + SymbolTable testTable; + auto problem_file = testTable.create("myfile.nix"); + + testing::internal::CaptureStderr(); + + logError({ + .name = "error name", + .description = "error with code lines", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = "previous line of code", + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = "next line of code", + }}); + + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror with code lines\n\n 39| previous line of code\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 41| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + } + + TEST(logError, logErrorWithoutLinesOfCode) { + SymbolTable testTable; + auto problem_file = testTable.create("myfile.nix"); + testing::internal::CaptureStderr(); + + logError({ + .name = "error name", + .description = "error without any code lines.", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + } + + TEST(logError, logErrorWithOnlyHintAndName) { + SymbolTable testTable; + auto problem_file = testTable.create("myfile.nix"); + testing::internal::CaptureStderr(); + + logError({ + .name = "error name", + .hint = hintfmt("hint %1%", "only"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13) + }}); + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nhint \x1B[33;1monly\x1B[0m\n"); + + } + + /* ---------------------------------------------------------------------------- + * logWarning + * --------------------------------------------------------------------------*/ + + TEST(logWarning, logWarningWithNameDescriptionAndHint) { + testing::internal::CaptureStderr(); + + logWarning({ + .name = "name", + .description = "error description", + .hint = hintfmt("there was a %1%", "warning"), + }); + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --------------------------------------- error-unit-test\x1B[0m\nerror description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n"); + } + + TEST(logWarning, logWarningWithFileLineNumAndCode) { + + SymbolTable testTable; + auto problem_file = testTable.create("myfile.nix"); + + testing::internal::CaptureStderr(); + + logWarning({ + .name = "warning name", + .description = "warning description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::nullopt, + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::nullopt + }}); + + + auto str = testing::internal::GetCapturedStderr(); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name ------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nwarning description\n\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + } + +} -- cgit v1.2.3 From e60747b5fbe8b9c646ffe07ef8d28d949302efa6 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Sat, 6 Jun 2020 10:23:12 +0200 Subject: Remove error-demo/error-demo.cc The logging.hh superseeds the demo --- src/error-demo/error-demo.cc | 157 ------------------------------------------- src/error-demo/local.mk | 12 ---- 2 files changed, 169 deletions(-) delete mode 100644 src/error-demo/error-demo.cc delete mode 100644 src/error-demo/local.mk (limited to 'src') diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc deleted file mode 100644 index f1e17b3de..000000000 --- a/src/error-demo/error-demo.cc +++ /dev/null @@ -1,157 +0,0 @@ -#include "logging.hh" -#include "nixexpr.hh" -#include "util.hh" - -#include -#include - -using namespace nix; - -MakeError(DemoError, Error); - -int main() -{ - verbosity = lvlVomit; - - // In each program where errors occur, this has to be set. - ErrorInfo::programName = std::optional("error-demo"); - - // 'DemoError' appears as error name. - try { - throw DemoError("demo error was thrown"); - } catch (Error &e) { - logger->logEI(e.info()); - } - - // appending to the hint from the previous error - try { - auto e = Error("initial error"); - throw DemoError(e.info()); - } catch (Error &e) { - ErrorInfo ei = e.info(); - // using normaltxt to avoid the default yellow highlighting. - ei.hint = hintfmt("%s; subsequent error message.", - normaltxt(e.info().hint ? e.info().hint->str() : "")); - logger->logEI(ei); - } - - // SysError; picks up errno - try { - auto x = readFile(-1); - } - catch (SysError &e) { - std::cout << "errno was: " << e.errNo << std::endl; - logError(e.info()); - } - - // current exception - try { - throw DemoError("DemoError handled as a %1%", "std::exception"); - } - catch (...) { - const std::exception_ptr &eptr = std::current_exception(); - try - { - std::rethrow_exception(eptr); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - } - } - - // For completeness sake, show 'info' through 'vomit' levels. - // But this is maybe a heavy format for those. - logger->logEI({ .level = lvlInfo, - .name = "Info name", - .description = "Info description", - }); - - logger->logEI({ .level = lvlTalkative, - .name = "Talkative name", - .description = "Talkative description", - }); - - logger->logEI({ .level = lvlChatty, - .name = "Chatty name", - .description = "Chatty description", - }); - - logger->logEI({ .level = lvlDebug, - .name = "Debug name", - .description = "Debug description", - }); - - logger->logEI({ .level = lvlVomit, - .name = "Vomit name", - .description = "Vomit description", - }); - - // Error in a program; no hint and no nix code. - logError({ - .name = "name", - .description = "error description", - }); - - // Warning with name, description, and hint. - // The hintfmt function makes all the substituted text yellow. - logWarning({ - .name = "name", - .description = "error description", - .hint = hintfmt("there was a %1%", "warning"), - }); - - // Warning with nix file, line number, column, and the lines of - // code where a warning occurred. - SymbolTable testTable; - auto problem_file = testTable.create("myfile.nix"); - - logWarning({ - .name = "warning name", - .description = "warning description", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::nullopt, - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::nullopt - }}); - - // Error with previous and next lines of code. - logError({ - .name = "error name", - .description = "error with code lines", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = "previous line of code", - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = "next line of code", - }}); - - - // Error without lines of code. - logError({ - .name = "error name", - .description = "error without any code lines.", - .hint = hintfmt("this hint has %1% templated %2%!!", - "yellow", - "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13) - }}); - - // Error with only hint and name.. - logError({ - .name = "error name", - .hint = hintfmt("hint %1%", "only"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13) - }}); - - return 0; -} diff --git a/src/error-demo/local.mk b/src/error-demo/local.mk deleted file mode 100644 index 2c528490a..000000000 --- a/src/error-demo/local.mk +++ /dev/null @@ -1,12 +0,0 @@ -programs += error-demo - -error-demo_DIR := $(d) - -error-demo_SOURCES := \ - $(wildcard $(d)/*.cc) \ - -error-demo_CXXFLAGS += -I src/libutil -I src/libexpr - -error-demo_LIBS = libutil libexpr - -error-demo_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system -- cgit v1.2.3 From 94c347577ecea5dcd10a31ebfadf94db6ca5ab0d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 7 Jun 2020 07:24:49 -0600 Subject: set verbosity levels --- src/libutil/tests/logging.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc index ac015a16d..fbdc91253 100644 --- a/src/libutil/tests/logging.cc +++ b/src/libutil/tests/logging.cc @@ -78,6 +78,8 @@ namespace nix { } TEST(logEI, loggingErrorOnTalkativeLevel) { + verbosity = lvlTalkative; + testing::internal::CaptureStderr(); logger->logEI({ .level = lvlTalkative, @@ -86,11 +88,12 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - // XXX: why is this the empty string? - ASSERT_STREQ(str.c_str(), ""); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mtalk:\x1B[0m\x1B[34;1m --- Talkative name -------------------------------- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnChattyLevel) { + verbosity = lvlChatty; + testing::internal::CaptureStderr(); logger->logEI({ .level = lvlChatty, @@ -99,11 +102,12 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - // XXX: why is this the empty string? - ASSERT_STREQ(str.c_str(), ""); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mchat:\x1B[0m\x1B[34;1m --- Chatty name ----------------------------------- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnDebugLevel) { + verbosity = lvlDebug; + testing::internal::CaptureStderr(); logger->logEI({ .level = lvlDebug, @@ -112,11 +116,12 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - // XXX: why is this the empty string? - ASSERT_STREQ(str.c_str(), ""); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mdebug:\x1B[0m\x1B[34;1m --- Debug name ----------------------------------- error-unit-test\x1B[0m\nDebug description\n"); } TEST(logEI, loggingErrorOnVomitLevel) { + verbosity = lvlVomit; + testing::internal::CaptureStderr(); logger->logEI({ .level = lvlVomit, @@ -125,8 +130,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - // XXX: why is this the empty string? - ASSERT_STREQ(str.c_str(), ""); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mvomit:\x1B[0m\x1B[34;1m --- Vomit name ----------------------------------- error-unit-test\x1B[0m\nVomit description\n"); } /* ---------------------------------------------------------------------------- -- cgit v1.2.3 From 170e86dff5724264e0d3d25b9af1bd42df6aec74 Mon Sep 17 00:00:00 2001 From: regnat Date: Fri, 5 Jun 2020 17:01:02 +0200 Subject: Make the logger customisable Add a new `--log-format` cli argument to change the format of the logs. The possible values are - raw (the default one for old-style commands) - bar (the default one for new-style commands) - bar-with-logs (equivalent to `--print-build-logs`) - internal-json (the internal machine-readable json format) --- src/libmain/common-args.cc | 9 +++++++++ src/libmain/loggers.cc | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/libmain/loggers.hh | 19 +++++++++++++++++++ src/libutil/logging.cc | 4 ++-- src/libutil/logging.hh | 4 +++- src/libutil/util.cc | 2 +- src/nix-build/nix-build.cc | 4 ++++ src/nix-env/nix-env.cc | 2 ++ src/nix-store/nix-store.cc | 2 ++ src/nix/main.cc | 11 ++++++----- src/nix/progress-bar.cc | 14 ++++++++++---- src/nix/progress-bar.hh | 2 ++ 12 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 src/libmain/loggers.cc create mode 100644 src/libmain/loggers.hh (limited to 'src') diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc index 51e199ea5..a0cccceb4 100644 --- a/src/libmain/common-args.cc +++ b/src/libmain/common-args.cc @@ -1,5 +1,6 @@ #include "common-args.hh" #include "globals.hh" +#include "loggers.hh" namespace nix { @@ -38,6 +39,14 @@ MixCommonArgs::MixCommonArgs(const string & programName) }}, }); + addFlag({ + .longName = "log-format", + .description = "Format of the logs. One of \"raw\", \"internal-json\", \"bar\" " + "or \"bar-with-logs\".", + .labels = {"format"}, + .handler = {[](std::string format) { setLogFormat(format); }}, + }); + addFlag({ .longName = "max-jobs", .shortName = 'j', diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc new file mode 100644 index 000000000..d3d5b104b --- /dev/null +++ b/src/libmain/loggers.cc @@ -0,0 +1,47 @@ +#include "loggers.hh" +#include "../nix/progress-bar.hh" + +namespace nix { + +LogFormat defaultLogFormat = LogFormat::raw; + +LogFormat parseLogFormat(const string &logFormatStr) { + if (logFormatStr == "raw") + return LogFormat::raw; + else if (logFormatStr == "internal-json") + return LogFormat::internalJson; + else if (logFormatStr == "bar") + return LogFormat::bar; + else if (logFormatStr == "bar-with-logs") + return LogFormat::barWithLogs; + throw Error(format("option 'log-format' has an invalid value '%s'") % + logFormatStr); +} + +Logger *makeDefaultLogger() { + switch (defaultLogFormat) { + case LogFormat::raw: + return makeSimpleLogger(); + case LogFormat::internalJson: + return makeJSONLogger(*makeSimpleLogger()); + case LogFormat::bar: + return makeProgressBar(); + case LogFormat::barWithLogs: + return makeProgressBar(true); + } +} + +void setLogFormat(const string &logFormatStr) { + setLogFormat(parseLogFormat(logFormatStr)); +} + +void setLogFormat(const LogFormat &logFormat) { + defaultLogFormat = logFormat; + createDefaultLogger(); +} + +void createDefaultLogger() { + logger = makeDefaultLogger(); +} + +} diff --git a/src/libmain/loggers.hh b/src/libmain/loggers.hh new file mode 100644 index 000000000..f50cbb682 --- /dev/null +++ b/src/libmain/loggers.hh @@ -0,0 +1,19 @@ +#pragma once + +#include "types.hh" + +namespace nix { + +enum class LogFormat { + raw, + internalJson, + bar, + barWithLogs, +}; + +void setLogFormat(const string &logFormatStr); +void setLogFormat(const LogFormat &logFormat); + +void createDefaultLogger(); + +} diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 3cc4ef8f1..6aec16e58 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -18,7 +18,7 @@ void setCurActivity(const ActivityId activityId) curActivity = activityId; } -Logger * logger = makeDefaultLogger(); +Logger * logger = makeSimpleLogger(); void Logger::warn(const std::string & msg) { @@ -94,7 +94,7 @@ void writeToStderr(const string & s) } } -Logger * makeDefaultLogger() +Logger * makeSimpleLogger() { return new SimpleLogger(); } diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 18c24d508..e319790fc 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -63,6 +63,8 @@ public: virtual ~Logger() { } + virtual void stop() { }; + virtual void log(Verbosity lvl, const FormatOrString & fs) = 0; void log(const FormatOrString & fs) @@ -141,7 +143,7 @@ struct PushActivity extern Logger * logger; -Logger * makeDefaultLogger(); +Logger * makeSimpleLogger(); Logger * makeJSONLogger(Logger & prevLogger); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 71db92d77..e0a99152b 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -989,7 +989,7 @@ pid_t startProcess(std::function fun, const ProcessOptions & options) { auto wrapper = [&]() { if (!options.allowVfork) - logger = makeDefaultLogger(); + logger = makeSimpleLogger(); try { #if __linux__ if (options.dieWithParent && prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 0a058a31b..8649de5e9 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -472,6 +472,8 @@ static void _main(int argc, char * * argv) restoreSignals(); + logger->stop(); + execvp(shell->c_str(), argPtrs.data()); throw SysError("executing shell '%s'", *shell); @@ -521,6 +523,8 @@ static void _main(int argc, char * * argv) if (auto store2 = store.dynamic_pointer_cast()) store2->addPermRoot(store->parseStorePath(symlink.second), absPath(symlink.first), true); + logger->stop(); + for (auto & path : outPaths) std::cout << path << '\n'; } diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index d62febaff..f7b04eb2b 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1446,6 +1446,8 @@ static int _main(int argc, char * * argv) globals.state->printStats(); + logger->stop(); + return 0; } } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 3a3060ad8..708591b14 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -1098,6 +1098,8 @@ static int _main(int argc, char * * argv) op(opFlags, opArgs); + logger->stop(); + return 0; } } diff --git a/src/nix/main.cc b/src/nix/main.cc index 1120ba5ef..203901168 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -10,6 +10,7 @@ #include "progress-bar.hh" #include "filetransfer.hh" #include "finally.hh" +#include "loggers.hh" #include #include @@ -90,7 +91,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs .longName = "print-build-logs", .shortName = 'L', .description = "print full build logs on stderr", - .handler = {&printBuildLogs, true}, + .handler = {[&]() {setLogFormat(LogFormat::barWithLogs); }}, }); addFlag({ @@ -165,6 +166,10 @@ void mainWrapped(int argc, char * * argv) verbosity = lvlWarn; settings.verboseBuild = false; + setLogFormat("bar"); + + Finally f([] { logger->stop(); }); + NixArgs args; args.parseCmdline(argvToStrings(argc, argv)); @@ -178,10 +183,6 @@ void mainWrapped(int argc, char * * argv) && args.command->first != "upgrade-nix") settings.requireExperimentalFeature("nix-command"); - Finally f([]() { stopProgressBar(); }); - - startProgressBar(args.printBuildLogs); - if (args.useNet && !haveInternet()) { warn("you don't have Internet access; disabling some network-dependent features"); args.useNet = false; diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc index c67701098..828541bfe 100644 --- a/src/nix/progress-bar.cc +++ b/src/nix/progress-bar.cc @@ -106,7 +106,7 @@ public: updateThread.join(); } - void stop() + void stop() override { auto state(state_.lock()); if (!state->active) return; @@ -457,11 +457,17 @@ public: } }; -void startProgressBar(bool printBuildLogs) +Logger *makeProgressBar(bool printBuildLogs) { - logger = new ProgressBar( + return new ProgressBar( printBuildLogs, - isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb"); + isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb" + ); +} + +void startProgressBar(bool printBuildLogs) +{ + logger = makeProgressBar(printBuildLogs); } void stopProgressBar() diff --git a/src/nix/progress-bar.hh b/src/nix/progress-bar.hh index 4d61175c2..60d0a2076 100644 --- a/src/nix/progress-bar.hh +++ b/src/nix/progress-bar.hh @@ -4,6 +4,8 @@ namespace nix { +Logger* makeProgressBar(bool printBuildLogs = false); + void startProgressBar(bool printBuildLogs = false); void stopProgressBar(); -- cgit v1.2.3 From 4983401440e1c46d6c576bc36ac86169bd296f9f Mon Sep 17 00:00:00 2001 From: regnat Date: Fri, 5 Jun 2020 18:20:11 +0200 Subject: Unify the printing of the logs between bar-with-logs and raw Make the printing of the build logs systematically go through the logger, and replicate the behavior of `no-build-output` by having two different loggers (one that prints the build logs and one that doesn't) --- src/libmain/loggers.cc | 6 +++++- src/libmain/loggers.hh | 1 + src/libmain/shared.cc | 3 ++- src/libstore/build.cc | 17 ++++------------- src/libutil/logging.cc | 30 ++++++++++++++++++++++++++---- src/libutil/logging.hh | 5 ++++- src/nix/progress-bar.cc | 4 ++++ 7 files changed, 46 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index d3d5b104b..b81096931 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -8,6 +8,8 @@ LogFormat defaultLogFormat = LogFormat::raw; LogFormat parseLogFormat(const string &logFormatStr) { if (logFormatStr == "raw") return LogFormat::raw; + else if (logFormatStr == "raw-with-logs") + return LogFormat::rawWithLogs; else if (logFormatStr == "internal-json") return LogFormat::internalJson; else if (logFormatStr == "bar") @@ -21,7 +23,9 @@ LogFormat parseLogFormat(const string &logFormatStr) { Logger *makeDefaultLogger() { switch (defaultLogFormat) { case LogFormat::raw: - return makeSimpleLogger(); + return makeSimpleLogger(false); + case LogFormat::rawWithLogs: + return makeSimpleLogger(true); case LogFormat::internalJson: return makeJSONLogger(*makeSimpleLogger()); case LogFormat::bar: diff --git a/src/libmain/loggers.hh b/src/libmain/loggers.hh index f50cbb682..f9ba5ee5e 100644 --- a/src/libmain/loggers.hh +++ b/src/libmain/loggers.hh @@ -6,6 +6,7 @@ namespace nix { enum class LogFormat { raw, + rawWithLogs, internalJson, bar, barWithLogs, diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 70d1f0186..3bbb5cf93 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -2,6 +2,7 @@ #include "shared.hh" #include "store-api.hh" #include "util.hh" +#include "loggers.hh" #include #include @@ -169,7 +170,7 @@ LegacyArgs::LegacyArgs(const std::string & programName, .longName = "no-build-output", .shortName = 'Q', .description = "do not show build output", - .handler = {&settings.verboseBuild, false}, + .handler = {[&]() {setLogFormat(LogFormat::raw); }}, }); addFlag({ diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f5c132a83..2d022093c 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1642,7 +1642,7 @@ void DerivationGoal::buildDone() worker.store.printStorePath(drvPath), statusToString(status)); - if (!settings.verboseBuild && !logTail.empty()) { + if (!logger->isVerbose() && !logTail.empty()) { msg += (format("; last %d log lines:") % logTail.size()).str(); for (auto & line : logTail) msg += "\n " + line; @@ -1691,11 +1691,7 @@ void DerivationGoal::buildDone() } void flushLine() { - if (settings.verboseBuild) { - printError("post-build-hook: " + currentLine); - } else { - act.result(resPostBuildLogLine, currentLine); - } + act.result(resPostBuildLogLine, currentLine); currentLine.clear(); } @@ -4155,13 +4151,8 @@ void DerivationGoal::flushLine() ; else { - if (settings.verboseBuild && - (settings.printRepeatedBuilds || curRound == 1)) - printError(currentLogLine); - else { - logTail.push_back(currentLogLine); - if (logTail.size() > settings.logLines) logTail.pop_front(); - } + logTail.push_back(currentLogLine); + if (logTail.size() > settings.logLines) logTail.pop_front(); act->result(resBuildLogLine, currentLogLine); } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 6aec16e58..15cbc1589 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -18,7 +18,7 @@ void setCurActivity(const ActivityId activityId) curActivity = activityId; } -Logger * logger = makeSimpleLogger(); +Logger * logger = makeSimpleLogger(true); void Logger::warn(const std::string & msg) { @@ -35,13 +35,19 @@ class SimpleLogger : public Logger public: bool systemd, tty; + bool printBuildLogs; - SimpleLogger() + SimpleLogger(bool printBuildLogs) + : printBuildLogs(printBuildLogs) { systemd = getEnv("IN_SYSTEMD") == "1"; tty = isatty(STDERR_FILENO); } + bool isVerbose() override { + return printBuildLogs; + } + void log(Verbosity lvl, const FormatOrString & fs) override { if (lvl > verbosity) return; @@ -70,6 +76,18 @@ public: if (lvl <= verbosity && !s.empty()) log(lvl, s + "..."); } + + void result(ActivityId act, ResultType type, const Fields & fields) override + { + if (type == resBuildLogLine && printBuildLogs) { + auto lastLine = fields[0].s; + printError(lastLine); + } + else if (type == resPostBuildLogLine && printBuildLogs) { + auto lastLine = fields[0].s; + printError("post-build-hook: " + lastLine); + } + } }; Verbosity verbosity = lvlInfo; @@ -94,9 +112,9 @@ void writeToStderr(const string & s) } } -Logger * makeSimpleLogger() +Logger * makeSimpleLogger(bool printBuildLogs) { - return new SimpleLogger(); + return new SimpleLogger(printBuildLogs); } std::atomic nextId{(uint64_t) getpid() << 32}; @@ -114,6 +132,10 @@ struct JSONLogger : Logger JSONLogger(Logger & prevLogger) : prevLogger(prevLogger) { } + bool isVerbose() override { + return true; + } + void addFields(nlohmann::json & json, const Fields & fields) { if (fields.empty()) return; diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index e319790fc..e3d91e01f 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -65,6 +65,9 @@ public: virtual void stop() { }; + // Whether the logger prints the whole build log + virtual bool isVerbose() { return false; } + virtual void log(Verbosity lvl, const FormatOrString & fs) = 0; void log(const FormatOrString & fs) @@ -143,7 +146,7 @@ struct PushActivity extern Logger * logger; -Logger * makeSimpleLogger(); +Logger * makeSimpleLogger(bool printBuildLogs = true); Logger * makeJSONLogger(Logger & prevLogger); diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc index 828541bfe..c9ba89714 100644 --- a/src/nix/progress-bar.cc +++ b/src/nix/progress-bar.cc @@ -119,6 +119,10 @@ public: quitCV.notify_one(); } + bool isVerbose() override { + return printBuildLogs; + } + void log(Verbosity lvl, const FormatOrString & fs) override { auto state(state_.lock()); -- cgit v1.2.3 From c27f92698bbbb99df3c4403db6590276318940a0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 8 Jun 2020 13:24:01 +0200 Subject: Style fixes --- src/libmain/common-args.cc | 4 ++-- src/libmain/loggers.cc | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc index a0cccceb4..051668e53 100644 --- a/src/libmain/common-args.cc +++ b/src/libmain/common-args.cc @@ -41,8 +41,8 @@ MixCommonArgs::MixCommonArgs(const string & programName) addFlag({ .longName = "log-format", - .description = "Format of the logs. One of \"raw\", \"internal-json\", \"bar\" " - "or \"bar-with-logs\".", + .description = "format of log output; \"raw\", \"internal-json\", \"bar\" " + "or \"bar-with-logs\"", .labels = {"format"}, .handler = {[](std::string format) { setLogFormat(format); }}, }); diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index b81096931..ee3836382 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -16,8 +16,7 @@ LogFormat parseLogFormat(const string &logFormatStr) { return LogFormat::bar; else if (logFormatStr == "bar-with-logs") return LogFormat::barWithLogs; - throw Error(format("option 'log-format' has an invalid value '%s'") % - logFormatStr); + throw Error("option 'log-format' has an invalid value '%s'", logFormatStr); } Logger *makeDefaultLogger() { -- cgit v1.2.3 From 801112de1af8e519e29e1e1c678f97de45a8c49d Mon Sep 17 00:00:00 2001 From: regnat Date: Mon, 8 Jun 2020 17:16:52 +0200 Subject: Move progress-bar.cc to libmain Needed so that we can include it as a logger in loggers.cc without adding a dependency on nix This also requires moving names.hh to libutil to prevent a circular dependency between libmain and libexpr --- src/libexpr/names.cc | 107 ------- src/libexpr/names.hh | 32 -- src/libmain/loggers.cc | 2 +- src/libmain/progress-bar.cc | 484 +++++++++++++++++++++++++++++++ src/libmain/progress-bar.hh | 13 + src/libutil/names.cc | 107 +++++++ src/libutil/names.hh | 32 ++ src/nix-prefetch-url/nix-prefetch-url.cc | 2 +- src/nix/progress-bar.cc | 484 ------------------------------- src/nix/progress-bar.hh | 13 - 10 files changed, 638 insertions(+), 638 deletions(-) delete mode 100644 src/libexpr/names.cc delete mode 100644 src/libexpr/names.hh create mode 100644 src/libmain/progress-bar.cc create mode 100644 src/libmain/progress-bar.hh create mode 100644 src/libutil/names.cc create mode 100644 src/libutil/names.hh delete mode 100644 src/nix/progress-bar.cc delete mode 100644 src/nix/progress-bar.hh (limited to 'src') diff --git a/src/libexpr/names.cc b/src/libexpr/names.cc deleted file mode 100644 index d1c8a6101..000000000 --- a/src/libexpr/names.cc +++ /dev/null @@ -1,107 +0,0 @@ -#include "names.hh" -#include "util.hh" - - -namespace nix { - - -DrvName::DrvName() -{ - name = ""; -} - - -/* Parse a derivation name. The `name' part of a derivation name is - everything up to but not including the first dash *not* followed by - a letter. The `version' part is the rest (excluding the separating - dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd', - '2.0.48'). */ -DrvName::DrvName(std::string_view s) : hits(0) -{ - name = fullName = std::string(s); - for (unsigned int i = 0; i < s.size(); ++i) { - /* !!! isalpha/isdigit are affected by the locale. */ - if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) { - name = s.substr(0, i); - version = s.substr(i + 1); - break; - } - } -} - - -bool DrvName::matches(DrvName & n) -{ - if (name != "*") { - if (!regex) regex = std::unique_ptr(new std::regex(name, std::regex::extended)); - if (!std::regex_match(n.name, *regex)) return false; - } - if (version != "" && version != n.version) return false; - return true; -} - - -string nextComponent(string::const_iterator & p, - const string::const_iterator end) -{ - /* Skip any dots and dashes (component separators). */ - while (p != end && (*p == '.' || *p == '-')) ++p; - - if (p == end) return ""; - - /* If the first character is a digit, consume the longest sequence - of digits. Otherwise, consume the longest sequence of - non-digit, non-separator characters. */ - string s; - if (isdigit(*p)) - while (p != end && isdigit(*p)) s += *p++; - else - while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) - s += *p++; - - return s; -} - - -static bool componentsLT(const string & c1, const string & c2) -{ - int n1, n2; - bool c1Num = string2Int(c1, n1), c2Num = string2Int(c2, n2); - - if (c1Num && c2Num) return n1 < n2; - else if (c1 == "" && c2Num) return true; - else if (c1 == "pre" && c2 != "pre") return true; - else if (c2 == "pre") return false; - /* Assume that `2.3a' < `2.3.1'. */ - else if (c2Num) return true; - else if (c1Num) return false; - else return c1 < c2; -} - - -int compareVersions(const string & v1, const string & v2) -{ - string::const_iterator p1 = v1.begin(); - string::const_iterator p2 = v2.begin(); - - while (p1 != v1.end() || p2 != v2.end()) { - string c1 = nextComponent(p1, v1.end()); - string c2 = nextComponent(p2, v2.end()); - if (componentsLT(c1, c2)) return -1; - else if (componentsLT(c2, c1)) return 1; - } - - return 0; -} - - -DrvNames drvNamesFromArgs(const Strings & opArgs) -{ - DrvNames result; - for (auto & i : opArgs) - result.push_back(DrvName(i)); - return result; -} - - -} diff --git a/src/libexpr/names.hh b/src/libexpr/names.hh deleted file mode 100644 index 00e14b8c7..000000000 --- a/src/libexpr/names.hh +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include - -#include "types.hh" -#include - -namespace nix { - -struct DrvName -{ - string fullName; - string name; - string version; - unsigned int hits; - - DrvName(); - DrvName(std::string_view s); - bool matches(DrvName & n); - -private: - std::unique_ptr regex; -}; - -typedef list DrvNames; - -string nextComponent(string::const_iterator & p, - const string::const_iterator end); -int compareVersions(const string & v1, const string & v2); -DrvNames drvNamesFromArgs(const Strings & opArgs); - -} diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index ee3836382..41f0b35fb 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -1,5 +1,5 @@ #include "loggers.hh" -#include "../nix/progress-bar.hh" +#include "progress-bar.hh" namespace nix { diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc new file mode 100644 index 000000000..c9ba89714 --- /dev/null +++ b/src/libmain/progress-bar.cc @@ -0,0 +1,484 @@ +#include "progress-bar.hh" +#include "util.hh" +#include "sync.hh" +#include "store-api.hh" +#include "names.hh" + +#include +#include +#include +#include + +namespace nix { + +static std::string getS(const std::vector & fields, size_t n) +{ + assert(n < fields.size()); + assert(fields[n].type == Logger::Field::tString); + return fields[n].s; +} + +static uint64_t getI(const std::vector & fields, size_t n) +{ + assert(n < fields.size()); + assert(fields[n].type == Logger::Field::tInt); + return fields[n].i; +} + +static std::string_view storePathToName(std::string_view path) +{ + auto base = baseNameOf(path); + auto i = base.find('-'); + return i == std::string::npos ? base.substr(0, 0) : base.substr(i + 1); +} + +class ProgressBar : public Logger +{ +private: + + struct ActInfo + { + std::string s, lastLine, phase; + ActivityType type = actUnknown; + uint64_t done = 0; + uint64_t expected = 0; + uint64_t running = 0; + uint64_t failed = 0; + std::map expectedByType; + bool visible = true; + ActivityId parent; + std::optional name; + }; + + struct ActivitiesByType + { + std::map::iterator> its; + uint64_t done = 0; + uint64_t expected = 0; + uint64_t failed = 0; + }; + + struct State + { + std::list activities; + std::map::iterator> its; + + std::map activitiesByType; + + uint64_t filesLinked = 0, bytesLinked = 0; + + uint64_t corruptedPaths = 0, untrustedPaths = 0; + + bool active = true; + bool haveUpdate = true; + }; + + Sync state_; + + std::thread updateThread; + + std::condition_variable quitCV, updateCV; + + bool printBuildLogs; + bool isTTY; + +public: + + ProgressBar(bool printBuildLogs, bool isTTY) + : printBuildLogs(printBuildLogs) + , isTTY(isTTY) + { + state_.lock()->active = isTTY; + updateThread = std::thread([&]() { + auto state(state_.lock()); + while (state->active) { + if (!state->haveUpdate) + state.wait(updateCV); + draw(*state); + state.wait_for(quitCV, std::chrono::milliseconds(50)); + } + }); + } + + ~ProgressBar() + { + stop(); + updateThread.join(); + } + + void stop() override + { + auto state(state_.lock()); + if (!state->active) return; + state->active = false; + std::string status = getStatus(*state); + writeToStderr("\r\e[K"); + if (status != "") + writeToStderr("[" + status + "]\n"); + updateCV.notify_one(); + quitCV.notify_one(); + } + + bool isVerbose() override { + return printBuildLogs; + } + + void log(Verbosity lvl, const FormatOrString & fs) override + { + auto state(state_.lock()); + log(*state, lvl, fs.s); + } + + void log(State & state, Verbosity lvl, const std::string & s) + { + if (state.active) { + writeToStderr("\r\e[K" + filterANSIEscapes(s, !isTTY) + ANSI_NORMAL "\n"); + draw(state); + } else { + auto s2 = s + ANSI_NORMAL "\n"; + if (!isTTY) s2 = filterANSIEscapes(s2, true); + writeToStderr(s2); + } + } + + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, + const std::string & s, const Fields & fields, ActivityId parent) override + { + auto state(state_.lock()); + + if (lvl <= verbosity && !s.empty()) + log(*state, lvl, s + "..."); + + state->activities.emplace_back(ActInfo()); + auto i = std::prev(state->activities.end()); + i->s = s; + i->type = type; + i->parent = parent; + state->its.emplace(act, i); + state->activitiesByType[type].its.emplace(act, i); + + if (type == actBuild) { + std::string name(storePathToName(getS(fields, 0))); + if (hasSuffix(name, ".drv")) + name = name.substr(0, name.size() - 4); + i->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name); + auto machineName = getS(fields, 1); + if (machineName != "") + i->s += fmt(" on " ANSI_BOLD "%s" ANSI_NORMAL, machineName); + auto curRound = getI(fields, 2); + auto nrRounds = getI(fields, 3); + if (nrRounds != 1) + i->s += fmt(" (round %d/%d)", curRound, nrRounds); + i->name = DrvName(name).name; + } + + if (type == actSubstitute) { + auto name = storePathToName(getS(fields, 0)); + auto sub = getS(fields, 1); + i->s = fmt( + hasPrefix(sub, "local") + ? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s" + : "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s", + name, sub); + } + + if (type == actPostBuildHook) { + auto name = storePathToName(getS(fields, 0)); + if (hasSuffix(name, ".drv")) + name = name.substr(0, name.size() - 4); + i->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name); + i->name = DrvName(name).name; + } + + if (type == actQueryPathInfo) { + auto name = storePathToName(getS(fields, 0)); + i->s = fmt("querying " ANSI_BOLD "%s" ANSI_NORMAL " on %s", name, getS(fields, 1)); + } + + if ((type == actFileTransfer && hasAncestor(*state, actCopyPath, parent)) + || (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, parent)) + || (type == actCopyPath && hasAncestor(*state, actSubstitute, parent))) + i->visible = false; + + update(*state); + } + + /* Check whether an activity has an ancestore with the specified + type. */ + bool hasAncestor(State & state, ActivityType type, ActivityId act) + { + while (act != 0) { + auto i = state.its.find(act); + if (i == state.its.end()) break; + if (i->second->type == type) return true; + act = i->second->parent; + } + return false; + } + + void stopActivity(ActivityId act) override + { + auto state(state_.lock()); + + auto i = state->its.find(act); + if (i != state->its.end()) { + + auto & actByType = state->activitiesByType[i->second->type]; + actByType.done += i->second->done; + actByType.failed += i->second->failed; + + for (auto & j : i->second->expectedByType) + state->activitiesByType[j.first].expected -= j.second; + + actByType.its.erase(act); + state->activities.erase(i->second); + state->its.erase(i); + } + + update(*state); + } + + void result(ActivityId act, ResultType type, const std::vector & fields) override + { + auto state(state_.lock()); + + if (type == resFileLinked) { + state->filesLinked++; + state->bytesLinked += getI(fields, 0); + update(*state); + } + + else if (type == resBuildLogLine || type == resPostBuildLogLine) { + auto lastLine = trim(getS(fields, 0)); + if (!lastLine.empty()) { + auto i = state->its.find(act); + assert(i != state->its.end()); + ActInfo info = *i->second; + if (printBuildLogs) { + auto suffix = "> "; + if (type == resPostBuildLogLine) { + suffix = " (post)> "; + } + log(*state, lvlInfo, ANSI_FAINT + info.name.value_or("unnamed") + suffix + ANSI_NORMAL + lastLine); + } else { + state->activities.erase(i->second); + info.lastLine = lastLine; + state->activities.emplace_back(info); + i->second = std::prev(state->activities.end()); + update(*state); + } + } + } + + else if (type == resUntrustedPath) { + state->untrustedPaths++; + update(*state); + } + + else if (type == resCorruptedPath) { + state->corruptedPaths++; + update(*state); + } + + else if (type == resSetPhase) { + auto i = state->its.find(act); + assert(i != state->its.end()); + i->second->phase = getS(fields, 0); + update(*state); + } + + else if (type == resProgress) { + auto i = state->its.find(act); + assert(i != state->its.end()); + ActInfo & actInfo = *i->second; + actInfo.done = getI(fields, 0); + actInfo.expected = getI(fields, 1); + actInfo.running = getI(fields, 2); + actInfo.failed = getI(fields, 3); + update(*state); + } + + else if (type == resSetExpected) { + auto i = state->its.find(act); + assert(i != state->its.end()); + ActInfo & actInfo = *i->second; + auto type = (ActivityType) getI(fields, 0); + auto & j = actInfo.expectedByType[type]; + state->activitiesByType[type].expected -= j; + j = getI(fields, 1); + state->activitiesByType[type].expected += j; + update(*state); + } + } + + void update(State & state) + { + state.haveUpdate = true; + updateCV.notify_one(); + } + + void draw(State & state) + { + state.haveUpdate = false; + if (!state.active) return; + + std::string line; + + std::string status = getStatus(state); + if (!status.empty()) { + line += '['; + line += status; + line += "]"; + } + + if (!state.activities.empty()) { + if (!status.empty()) line += " "; + auto i = state.activities.rbegin(); + + while (i != state.activities.rend() && (!i->visible || (i->s.empty() && i->lastLine.empty()))) + ++i; + + if (i != state.activities.rend()) { + line += i->s; + if (!i->phase.empty()) { + line += " ("; + line += i->phase; + line += ")"; + } + if (!i->lastLine.empty()) { + if (!i->s.empty()) line += ": "; + line += i->lastLine; + } + } + } + + auto width = getWindowSize().second; + if (width <= 0) width = std::numeric_limits::max(); + + writeToStderr("\r" + filterANSIEscapes(line, false, width) + "\e[K"); + } + + std::string getStatus(State & state) + { + auto MiB = 1024.0 * 1024.0; + + std::string res; + + auto renderActivity = [&](ActivityType type, const std::string & itemFmt, const std::string & numberFmt = "%d", double unit = 1) { + auto & act = state.activitiesByType[type]; + uint64_t done = act.done, expected = act.done, running = 0, failed = act.failed; + for (auto & j : act.its) { + done += j.second->done; + expected += j.second->expected; + running += j.second->running; + failed += j.second->failed; + } + + expected = std::max(expected, act.expected); + + std::string s; + + if (running || done || expected || failed) { + if (running) + if (expected != 0) + s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt, + running / unit, done / unit, expected / unit); + else + s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL, + running / unit, done / unit); + else if (expected != done) + if (expected != 0) + s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt, + done / unit, expected / unit); + else + s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL, done / unit); + else + s = fmt(done ? ANSI_GREEN + numberFmt + ANSI_NORMAL : numberFmt, done / unit); + s = fmt(itemFmt, s); + + if (failed) + s += fmt(" (" ANSI_RED "%d failed" ANSI_NORMAL ")", failed / unit); + } + + return s; + }; + + auto showActivity = [&](ActivityType type, const std::string & itemFmt, const std::string & numberFmt = "%d", double unit = 1) { + auto s = renderActivity(type, itemFmt, numberFmt, unit); + if (s.empty()) return; + if (!res.empty()) res += ", "; + res += s; + }; + + showActivity(actBuilds, "%s built"); + + auto s1 = renderActivity(actCopyPaths, "%s copied"); + auto s2 = renderActivity(actCopyPath, "%s MiB", "%.1f", MiB); + + if (!s1.empty() || !s2.empty()) { + if (!res.empty()) res += ", "; + if (s1.empty()) res += "0 copied"; else res += s1; + if (!s2.empty()) { res += " ("; res += s2; res += ')'; } + } + + showActivity(actFileTransfer, "%s MiB DL", "%.1f", MiB); + + { + auto s = renderActivity(actOptimiseStore, "%s paths optimised"); + if (s != "") { + s += fmt(", %.1f MiB / %d inodes freed", state.bytesLinked / MiB, state.filesLinked); + if (!res.empty()) res += ", "; + res += s; + } + } + + // FIXME: don't show "done" paths in green. + showActivity(actVerifyPaths, "%s paths verified"); + + if (state.corruptedPaths) { + if (!res.empty()) res += ", "; + res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths); + } + + if (state.untrustedPaths) { + if (!res.empty()) res += ", "; + res += fmt(ANSI_RED "%d untrusted" ANSI_NORMAL, state.untrustedPaths); + } + + return res; + } + + void writeToStdout(std::string_view s) override + { + auto state(state_.lock()); + if (state->active) { + std::cerr << "\r\e[K"; + Logger::writeToStdout(s); + draw(*state); + } else { + Logger::writeToStdout(s); + } + } +}; + +Logger *makeProgressBar(bool printBuildLogs) +{ + return new ProgressBar( + printBuildLogs, + isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb" + ); +} + +void startProgressBar(bool printBuildLogs) +{ + logger = makeProgressBar(printBuildLogs); +} + +void stopProgressBar() +{ + auto progressBar = dynamic_cast(logger); + if (progressBar) progressBar->stop(); + +} + +} diff --git a/src/libmain/progress-bar.hh b/src/libmain/progress-bar.hh new file mode 100644 index 000000000..60d0a2076 --- /dev/null +++ b/src/libmain/progress-bar.hh @@ -0,0 +1,13 @@ +#pragma once + +#include "logging.hh" + +namespace nix { + +Logger* makeProgressBar(bool printBuildLogs = false); + +void startProgressBar(bool printBuildLogs = false); + +void stopProgressBar(); + +} diff --git a/src/libutil/names.cc b/src/libutil/names.cc new file mode 100644 index 000000000..d1c8a6101 --- /dev/null +++ b/src/libutil/names.cc @@ -0,0 +1,107 @@ +#include "names.hh" +#include "util.hh" + + +namespace nix { + + +DrvName::DrvName() +{ + name = ""; +} + + +/* Parse a derivation name. The `name' part of a derivation name is + everything up to but not including the first dash *not* followed by + a letter. The `version' part is the rest (excluding the separating + dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd', + '2.0.48'). */ +DrvName::DrvName(std::string_view s) : hits(0) +{ + name = fullName = std::string(s); + for (unsigned int i = 0; i < s.size(); ++i) { + /* !!! isalpha/isdigit are affected by the locale. */ + if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) { + name = s.substr(0, i); + version = s.substr(i + 1); + break; + } + } +} + + +bool DrvName::matches(DrvName & n) +{ + if (name != "*") { + if (!regex) regex = std::unique_ptr(new std::regex(name, std::regex::extended)); + if (!std::regex_match(n.name, *regex)) return false; + } + if (version != "" && version != n.version) return false; + return true; +} + + +string nextComponent(string::const_iterator & p, + const string::const_iterator end) +{ + /* Skip any dots and dashes (component separators). */ + while (p != end && (*p == '.' || *p == '-')) ++p; + + if (p == end) return ""; + + /* If the first character is a digit, consume the longest sequence + of digits. Otherwise, consume the longest sequence of + non-digit, non-separator characters. */ + string s; + if (isdigit(*p)) + while (p != end && isdigit(*p)) s += *p++; + else + while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) + s += *p++; + + return s; +} + + +static bool componentsLT(const string & c1, const string & c2) +{ + int n1, n2; + bool c1Num = string2Int(c1, n1), c2Num = string2Int(c2, n2); + + if (c1Num && c2Num) return n1 < n2; + else if (c1 == "" && c2Num) return true; + else if (c1 == "pre" && c2 != "pre") return true; + else if (c2 == "pre") return false; + /* Assume that `2.3a' < `2.3.1'. */ + else if (c2Num) return true; + else if (c1Num) return false; + else return c1 < c2; +} + + +int compareVersions(const string & v1, const string & v2) +{ + string::const_iterator p1 = v1.begin(); + string::const_iterator p2 = v2.begin(); + + while (p1 != v1.end() || p2 != v2.end()) { + string c1 = nextComponent(p1, v1.end()); + string c2 = nextComponent(p2, v2.end()); + if (componentsLT(c1, c2)) return -1; + else if (componentsLT(c2, c1)) return 1; + } + + return 0; +} + + +DrvNames drvNamesFromArgs(const Strings & opArgs) +{ + DrvNames result; + for (auto & i : opArgs) + result.push_back(DrvName(i)); + return result; +} + + +} diff --git a/src/libutil/names.hh b/src/libutil/names.hh new file mode 100644 index 000000000..00e14b8c7 --- /dev/null +++ b/src/libutil/names.hh @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include "types.hh" +#include + +namespace nix { + +struct DrvName +{ + string fullName; + string name; + string version; + unsigned int hits; + + DrvName(); + DrvName(std::string_view s); + bool matches(DrvName & n); + +private: + std::unique_ptr regex; +}; + +typedef list DrvNames; + +string nextComponent(string::const_iterator & p, + const string::const_iterator end); +int compareVersions(const string & v1, const string & v2); +DrvNames drvNamesFromArgs(const Strings & opArgs); + +} diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc index 5a686c8cd..b645bdc1b 100644 --- a/src/nix-prefetch-url/nix-prefetch-url.cc +++ b/src/nix-prefetch-url/nix-prefetch-url.cc @@ -8,7 +8,7 @@ #include "attr-path.hh" #include "finally.hh" #include "../nix/legacy.hh" -#include "../nix/progress-bar.hh" +#include "progress-bar.hh" #include "tarfile.hh" #include diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc deleted file mode 100644 index c9ba89714..000000000 --- a/src/nix/progress-bar.cc +++ /dev/null @@ -1,484 +0,0 @@ -#include "progress-bar.hh" -#include "util.hh" -#include "sync.hh" -#include "store-api.hh" -#include "names.hh" - -#include -#include -#include -#include - -namespace nix { - -static std::string getS(const std::vector & fields, size_t n) -{ - assert(n < fields.size()); - assert(fields[n].type == Logger::Field::tString); - return fields[n].s; -} - -static uint64_t getI(const std::vector & fields, size_t n) -{ - assert(n < fields.size()); - assert(fields[n].type == Logger::Field::tInt); - return fields[n].i; -} - -static std::string_view storePathToName(std::string_view path) -{ - auto base = baseNameOf(path); - auto i = base.find('-'); - return i == std::string::npos ? base.substr(0, 0) : base.substr(i + 1); -} - -class ProgressBar : public Logger -{ -private: - - struct ActInfo - { - std::string s, lastLine, phase; - ActivityType type = actUnknown; - uint64_t done = 0; - uint64_t expected = 0; - uint64_t running = 0; - uint64_t failed = 0; - std::map expectedByType; - bool visible = true; - ActivityId parent; - std::optional name; - }; - - struct ActivitiesByType - { - std::map::iterator> its; - uint64_t done = 0; - uint64_t expected = 0; - uint64_t failed = 0; - }; - - struct State - { - std::list activities; - std::map::iterator> its; - - std::map activitiesByType; - - uint64_t filesLinked = 0, bytesLinked = 0; - - uint64_t corruptedPaths = 0, untrustedPaths = 0; - - bool active = true; - bool haveUpdate = true; - }; - - Sync state_; - - std::thread updateThread; - - std::condition_variable quitCV, updateCV; - - bool printBuildLogs; - bool isTTY; - -public: - - ProgressBar(bool printBuildLogs, bool isTTY) - : printBuildLogs(printBuildLogs) - , isTTY(isTTY) - { - state_.lock()->active = isTTY; - updateThread = std::thread([&]() { - auto state(state_.lock()); - while (state->active) { - if (!state->haveUpdate) - state.wait(updateCV); - draw(*state); - state.wait_for(quitCV, std::chrono::milliseconds(50)); - } - }); - } - - ~ProgressBar() - { - stop(); - updateThread.join(); - } - - void stop() override - { - auto state(state_.lock()); - if (!state->active) return; - state->active = false; - std::string status = getStatus(*state); - writeToStderr("\r\e[K"); - if (status != "") - writeToStderr("[" + status + "]\n"); - updateCV.notify_one(); - quitCV.notify_one(); - } - - bool isVerbose() override { - return printBuildLogs; - } - - void log(Verbosity lvl, const FormatOrString & fs) override - { - auto state(state_.lock()); - log(*state, lvl, fs.s); - } - - void log(State & state, Verbosity lvl, const std::string & s) - { - if (state.active) { - writeToStderr("\r\e[K" + filterANSIEscapes(s, !isTTY) + ANSI_NORMAL "\n"); - draw(state); - } else { - auto s2 = s + ANSI_NORMAL "\n"; - if (!isTTY) s2 = filterANSIEscapes(s2, true); - writeToStderr(s2); - } - } - - void startActivity(ActivityId act, Verbosity lvl, ActivityType type, - const std::string & s, const Fields & fields, ActivityId parent) override - { - auto state(state_.lock()); - - if (lvl <= verbosity && !s.empty()) - log(*state, lvl, s + "..."); - - state->activities.emplace_back(ActInfo()); - auto i = std::prev(state->activities.end()); - i->s = s; - i->type = type; - i->parent = parent; - state->its.emplace(act, i); - state->activitiesByType[type].its.emplace(act, i); - - if (type == actBuild) { - std::string name(storePathToName(getS(fields, 0))); - if (hasSuffix(name, ".drv")) - name = name.substr(0, name.size() - 4); - i->s = fmt("building " ANSI_BOLD "%s" ANSI_NORMAL, name); - auto machineName = getS(fields, 1); - if (machineName != "") - i->s += fmt(" on " ANSI_BOLD "%s" ANSI_NORMAL, machineName); - auto curRound = getI(fields, 2); - auto nrRounds = getI(fields, 3); - if (nrRounds != 1) - i->s += fmt(" (round %d/%d)", curRound, nrRounds); - i->name = DrvName(name).name; - } - - if (type == actSubstitute) { - auto name = storePathToName(getS(fields, 0)); - auto sub = getS(fields, 1); - i->s = fmt( - hasPrefix(sub, "local") - ? "copying " ANSI_BOLD "%s" ANSI_NORMAL " from %s" - : "fetching " ANSI_BOLD "%s" ANSI_NORMAL " from %s", - name, sub); - } - - if (type == actPostBuildHook) { - auto name = storePathToName(getS(fields, 0)); - if (hasSuffix(name, ".drv")) - name = name.substr(0, name.size() - 4); - i->s = fmt("post-build " ANSI_BOLD "%s" ANSI_NORMAL, name); - i->name = DrvName(name).name; - } - - if (type == actQueryPathInfo) { - auto name = storePathToName(getS(fields, 0)); - i->s = fmt("querying " ANSI_BOLD "%s" ANSI_NORMAL " on %s", name, getS(fields, 1)); - } - - if ((type == actFileTransfer && hasAncestor(*state, actCopyPath, parent)) - || (type == actFileTransfer && hasAncestor(*state, actQueryPathInfo, parent)) - || (type == actCopyPath && hasAncestor(*state, actSubstitute, parent))) - i->visible = false; - - update(*state); - } - - /* Check whether an activity has an ancestore with the specified - type. */ - bool hasAncestor(State & state, ActivityType type, ActivityId act) - { - while (act != 0) { - auto i = state.its.find(act); - if (i == state.its.end()) break; - if (i->second->type == type) return true; - act = i->second->parent; - } - return false; - } - - void stopActivity(ActivityId act) override - { - auto state(state_.lock()); - - auto i = state->its.find(act); - if (i != state->its.end()) { - - auto & actByType = state->activitiesByType[i->second->type]; - actByType.done += i->second->done; - actByType.failed += i->second->failed; - - for (auto & j : i->second->expectedByType) - state->activitiesByType[j.first].expected -= j.second; - - actByType.its.erase(act); - state->activities.erase(i->second); - state->its.erase(i); - } - - update(*state); - } - - void result(ActivityId act, ResultType type, const std::vector & fields) override - { - auto state(state_.lock()); - - if (type == resFileLinked) { - state->filesLinked++; - state->bytesLinked += getI(fields, 0); - update(*state); - } - - else if (type == resBuildLogLine || type == resPostBuildLogLine) { - auto lastLine = trim(getS(fields, 0)); - if (!lastLine.empty()) { - auto i = state->its.find(act); - assert(i != state->its.end()); - ActInfo info = *i->second; - if (printBuildLogs) { - auto suffix = "> "; - if (type == resPostBuildLogLine) { - suffix = " (post)> "; - } - log(*state, lvlInfo, ANSI_FAINT + info.name.value_or("unnamed") + suffix + ANSI_NORMAL + lastLine); - } else { - state->activities.erase(i->second); - info.lastLine = lastLine; - state->activities.emplace_back(info); - i->second = std::prev(state->activities.end()); - update(*state); - } - } - } - - else if (type == resUntrustedPath) { - state->untrustedPaths++; - update(*state); - } - - else if (type == resCorruptedPath) { - state->corruptedPaths++; - update(*state); - } - - else if (type == resSetPhase) { - auto i = state->its.find(act); - assert(i != state->its.end()); - i->second->phase = getS(fields, 0); - update(*state); - } - - else if (type == resProgress) { - auto i = state->its.find(act); - assert(i != state->its.end()); - ActInfo & actInfo = *i->second; - actInfo.done = getI(fields, 0); - actInfo.expected = getI(fields, 1); - actInfo.running = getI(fields, 2); - actInfo.failed = getI(fields, 3); - update(*state); - } - - else if (type == resSetExpected) { - auto i = state->its.find(act); - assert(i != state->its.end()); - ActInfo & actInfo = *i->second; - auto type = (ActivityType) getI(fields, 0); - auto & j = actInfo.expectedByType[type]; - state->activitiesByType[type].expected -= j; - j = getI(fields, 1); - state->activitiesByType[type].expected += j; - update(*state); - } - } - - void update(State & state) - { - state.haveUpdate = true; - updateCV.notify_one(); - } - - void draw(State & state) - { - state.haveUpdate = false; - if (!state.active) return; - - std::string line; - - std::string status = getStatus(state); - if (!status.empty()) { - line += '['; - line += status; - line += "]"; - } - - if (!state.activities.empty()) { - if (!status.empty()) line += " "; - auto i = state.activities.rbegin(); - - while (i != state.activities.rend() && (!i->visible || (i->s.empty() && i->lastLine.empty()))) - ++i; - - if (i != state.activities.rend()) { - line += i->s; - if (!i->phase.empty()) { - line += " ("; - line += i->phase; - line += ")"; - } - if (!i->lastLine.empty()) { - if (!i->s.empty()) line += ": "; - line += i->lastLine; - } - } - } - - auto width = getWindowSize().second; - if (width <= 0) width = std::numeric_limits::max(); - - writeToStderr("\r" + filterANSIEscapes(line, false, width) + "\e[K"); - } - - std::string getStatus(State & state) - { - auto MiB = 1024.0 * 1024.0; - - std::string res; - - auto renderActivity = [&](ActivityType type, const std::string & itemFmt, const std::string & numberFmt = "%d", double unit = 1) { - auto & act = state.activitiesByType[type]; - uint64_t done = act.done, expected = act.done, running = 0, failed = act.failed; - for (auto & j : act.its) { - done += j.second->done; - expected += j.second->expected; - running += j.second->running; - failed += j.second->failed; - } - - expected = std::max(expected, act.expected); - - std::string s; - - if (running || done || expected || failed) { - if (running) - if (expected != 0) - s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt, - running / unit, done / unit, expected / unit); - else - s = fmt(ANSI_BLUE + numberFmt + ANSI_NORMAL "/" ANSI_GREEN + numberFmt + ANSI_NORMAL, - running / unit, done / unit); - else if (expected != done) - if (expected != 0) - s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL "/" + numberFmt, - done / unit, expected / unit); - else - s = fmt(ANSI_GREEN + numberFmt + ANSI_NORMAL, done / unit); - else - s = fmt(done ? ANSI_GREEN + numberFmt + ANSI_NORMAL : numberFmt, done / unit); - s = fmt(itemFmt, s); - - if (failed) - s += fmt(" (" ANSI_RED "%d failed" ANSI_NORMAL ")", failed / unit); - } - - return s; - }; - - auto showActivity = [&](ActivityType type, const std::string & itemFmt, const std::string & numberFmt = "%d", double unit = 1) { - auto s = renderActivity(type, itemFmt, numberFmt, unit); - if (s.empty()) return; - if (!res.empty()) res += ", "; - res += s; - }; - - showActivity(actBuilds, "%s built"); - - auto s1 = renderActivity(actCopyPaths, "%s copied"); - auto s2 = renderActivity(actCopyPath, "%s MiB", "%.1f", MiB); - - if (!s1.empty() || !s2.empty()) { - if (!res.empty()) res += ", "; - if (s1.empty()) res += "0 copied"; else res += s1; - if (!s2.empty()) { res += " ("; res += s2; res += ')'; } - } - - showActivity(actFileTransfer, "%s MiB DL", "%.1f", MiB); - - { - auto s = renderActivity(actOptimiseStore, "%s paths optimised"); - if (s != "") { - s += fmt(", %.1f MiB / %d inodes freed", state.bytesLinked / MiB, state.filesLinked); - if (!res.empty()) res += ", "; - res += s; - } - } - - // FIXME: don't show "done" paths in green. - showActivity(actVerifyPaths, "%s paths verified"); - - if (state.corruptedPaths) { - if (!res.empty()) res += ", "; - res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths); - } - - if (state.untrustedPaths) { - if (!res.empty()) res += ", "; - res += fmt(ANSI_RED "%d untrusted" ANSI_NORMAL, state.untrustedPaths); - } - - return res; - } - - void writeToStdout(std::string_view s) override - { - auto state(state_.lock()); - if (state->active) { - std::cerr << "\r\e[K"; - Logger::writeToStdout(s); - draw(*state); - } else { - Logger::writeToStdout(s); - } - } -}; - -Logger *makeProgressBar(bool printBuildLogs) -{ - return new ProgressBar( - printBuildLogs, - isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb" - ); -} - -void startProgressBar(bool printBuildLogs) -{ - logger = makeProgressBar(printBuildLogs); -} - -void stopProgressBar() -{ - auto progressBar = dynamic_cast(logger); - if (progressBar) progressBar->stop(); - -} - -} diff --git a/src/nix/progress-bar.hh b/src/nix/progress-bar.hh deleted file mode 100644 index 60d0a2076..000000000 --- a/src/nix/progress-bar.hh +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "logging.hh" - -namespace nix { - -Logger* makeProgressBar(bool printBuildLogs = false); - -void startProgressBar(bool printBuildLogs = false); - -void stopProgressBar(); - -} -- cgit v1.2.3 From 762273f1fd48b2b2f2bbedca65abfd4c07b5af05 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Tue, 9 Jun 2020 01:23:37 -0500 Subject: Allow empty hash in derivations follow up of https://github.com/NixOS/nix/pull/3544 This allows hash="" so that it can be used for debugging purposes. For instance, this gives you an error message like: warning: found empty hash, assuming you wanted 'sha256:0000000000000000000000000000000000000000000000000000' hash mismatch in fixed-output derivation '/nix/store/asx6qw1r1xk6iak6y6jph4n58h4hdmbm-nix': wanted: sha256:0000000000000000000000000000000000000000000000000000 got: sha256:0fpfhipl9v1mfzw2ffmxiyyzqwlkvww22bh9wcy4qrfslb4jm429 --- src/libexpr/primops.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index d458ab272..de04fd2be 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -719,7 +719,13 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * throw Error(format("multiple outputs are not supported in fixed-output derivations, at %1%") % posDrvName); HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); - Hash h(*outputHash, ht); + + Hash h; + if (outputHash->empty()) { + h = Hash(ht); + printError("warning: found empty hash, assuming you wanted '%s'", h.to_string()); + } else + h = Hash(*outputHash, ht); auto outPath = state.store->makeFixedOutputPath(ingestionMethod, h, drvName); if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath); -- cgit v1.2.3 From 19aa892f2064d437d32a3c12758d6a623b7ae8e5 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Tue, 9 Jun 2020 11:10:54 -0500 Subject: Support empty hash in fetchers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fetchTarball, fetchTree, and fetchGit all have *optional* hash attrs. This means that we need to be careful with what we allow to avoid accidentally making these defaults. When ‘hash = ""’ we assume the empty hash is wanted. --- src/libexpr/primops.cc | 11 ++++++++--- src/libexpr/primops/fetchTree.cc | 11 ++++++++--- src/libfetchers/fetchers.cc | 11 ++++++++--- src/libfetchers/tarball.cc | 11 ++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index de04fd2be..df3d4a459 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1131,9 +1131,14 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value filterFun = attr.value; } else if (n == "recursive") method = FileIngestionMethod { state.forceBool(*attr.value, *attr.pos) }; - else if (n == "sha256") - expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); - else + else if (n == "sha256") { + auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); + if (hashStr == "") { + expectedHash = Hash(htSHA256); + printError("warning: found empty hash, assuming you wanted '%s'", expectedHash.to_string()); + } else + expectedHash = Hash(hashStr, htSHA256); + } else throw EvalError(format("unsupported argument '%1%' to 'addPath', at %2%") % attr.name % *attr.pos); } if (path.empty()) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index c5a0d9886..745f65adf 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,9 +102,14 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, string n(attr.name); if (n == "url") url = state.forceStringNoCtx(*attr.value, *attr.pos); - else if (n == "sha256") - expectedHash = Hash(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); - else if (n == "name") + else if (n == "sha256") { + auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); + if (hashStr == "") { + expectedHash = Hash(htSHA256); + printError("warning: found empty hash, assuming you wanted '%s'", expectedHash->to_string()); + } else + expectedHash = Hash(hashStr, htSHA256); + } else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else throw EvalError("unsupported argument '%s' to '%s', at %s", diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 94ac30e38..988a8dc69 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -34,9 +34,14 @@ std::unique_ptr inputFromAttrs(const Attrs & attrs) for (auto & inputScheme : *inputSchemes) { auto res = inputScheme->inputFromAttrs(attrs2); if (res) { - if (auto narHash = maybeGetStrAttr(attrs, "narHash")) - // FIXME: require SRI hash. - res->narHash = Hash(*narHash); + if (auto narHash = maybeGetStrAttr(attrs, "narHash")) { + if (narHash->empty()) { + res->narHash = Hash(htUnknown); + printError("warning: found empty hash, assuming you wanted '%s'", res->narHash->to_string()); + } else + // FIXME: require SRI hash. + res->narHash = Hash(*narHash); + } return res; } } diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index b6e57379b..e4dafec0b 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -263,9 +263,14 @@ struct TarballInputScheme : InputScheme throw Error("unsupported tarball input attribute '%s'", name); auto input = std::make_unique(parseURL(getStrAttr(attrs, "url"))); - if (auto hash = maybeGetStrAttr(attrs, "hash")) - // FIXME: require SRI hash. - input->hash = Hash(*hash); + if (auto hash = maybeGetStrAttr(attrs, "hash")) { + if (hash->empty()) { + input->hash = Hash(htUnknown); + printError("warning: found empty hash, assuming you wanted '%s'", input->hash->to_string()); + } else + // FIXME: require SRI hash. + input->hash = Hash(*hash); + } return input; } -- cgit v1.2.3 From b2c8061b44b01a39d953d75db30e39bd8f300021 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Tue, 9 Jun 2020 16:53:53 -0500 Subject: Disable extra-platforms = i686-linux on wsl1 (#3676) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WSL1 doesn’t support i686-linux emulation, see https://github.com/microsoft/wsl/issues/2468 --- src/libstore/globals.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index da95fd3ae..2fbcafff8 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -271,7 +271,7 @@ public: "listed in 'trusted-public-keys'."}; Setting extraPlatforms{this, - std::string{SYSTEM} == "x86_64-linux" ? StringSet{"i686-linux"} : StringSet{}, + std::string{SYSTEM} == "x86_64-linux" && !isWSL1() ? StringSet{"i686-linux"} : StringSet{}, "extra-platforms", "Additional platforms that can be built on the local system. " "These may be supported natively (e.g. armv7 on some aarch64 CPUs " -- cgit v1.2.3 From 4750d98bbd7c233e993b1ed66dd5573e6bdf543c Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Mon, 8 Jun 2020 17:39:46 +0200 Subject: Add tests for pool.hh --- src/libutil/tests/pool.cc | 127 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/libutil/tests/pool.cc (limited to 'src') diff --git a/src/libutil/tests/pool.cc b/src/libutil/tests/pool.cc new file mode 100644 index 000000000..127e42dda --- /dev/null +++ b/src/libutil/tests/pool.cc @@ -0,0 +1,127 @@ +#include "pool.hh" +#include + +namespace nix { + + struct TestResource + { + + TestResource() { + static int counter = 0; + num = counter++; + } + + int dummyValue = 1; + bool good = true; + int num; + }; + + /* ---------------------------------------------------------------------------- + * Pool + * --------------------------------------------------------------------------*/ + + TEST(Pool, freshPoolHasZeroCountAndSpecifiedCapacity) { + auto isGood = [](const ref & r) { return r->good; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + + ASSERT_EQ(pool.count(), 0); + ASSERT_EQ(pool.capacity(), 1); + } + + TEST(Pool, freshPoolCanGetAResource) { + auto isGood = [](const ref & r) { return r->good; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + ASSERT_EQ(pool.count(), 0); + + TestResource r = *(pool.get()); + + ASSERT_EQ(pool.count(), 1); + ASSERT_EQ(pool.capacity(), 1); + ASSERT_EQ(r.dummyValue, 1); + ASSERT_EQ(r.good, true); + } + + TEST(Pool, capacityCanBeIncremented) { + auto isGood = [](const ref & r) { return r->good; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + ASSERT_EQ(pool.capacity(), 1); + pool.incCapacity(); + ASSERT_EQ(pool.capacity(), 2); + } + + TEST(Pool, capacityCanBeDecremented) { + auto isGood = [](const ref & r) { return r->good; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + ASSERT_EQ(pool.capacity(), 1); + pool.decCapacity(); + ASSERT_EQ(pool.capacity(), 0); + } + + TEST(Pool, flushBadDropsOutOfScopeResources) { + auto isGood = [](const ref & r) { return false; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + + { + auto _r = pool.get(); + ASSERT_EQ(pool.count(), 1); + } + + pool.flushBad(); + ASSERT_EQ(pool.count(), 0); + } + + // Test that the resources we allocate are being reused when they are still good. + TEST(Pool, reuseResource) { + auto isGood = [](const ref & r) { return true; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + + // Compare the instance counter between the two handles. We expect them to be equal + // as the pool should hand out the same (still) good one again. + int counter = -1; + { + Pool::Handle h = pool.get(); + counter = h->num; + } // the first handle goes out of scope + + { // the second handle should contain the same resource (with the same counter value) + Pool::Handle h = pool.get(); + ASSERT_EQ(h->num, counter); + } + } + + // Test that the resources we allocate are being thrown away when they are no longer good. + TEST(Pool, badResourceIsNotReused) { + auto isGood = [](const ref & r) { return false; }; + auto createResource = []() { return make_ref(); }; + + Pool pool = Pool((size_t)1, createResource, isGood); + + // Compare the instance counter between the two handles. We expect them + // to *not* be equal as the pool should hand out a new instance after + // the first one was returned. + int counter = -1; + { + Pool::Handle h = pool.get(); + counter = h->num; + } // the first handle goes out of scope + + { + // the second handle should contain a different resource (with a + //different counter value) + Pool::Handle h = pool.get(); + ASSERT_NE(h->num, counter); + } + } +} -- cgit v1.2.3 From 8bd892117a324c22803366b872bfe7ed783b34eb Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Jun 2020 15:39:08 +0200 Subject: Style fixes --- src/libmain/loggers.cc | 8 ++++---- src/libmain/loggers.hh | 4 ++-- src/libmain/progress-bar.cc | 2 +- src/libmain/progress-bar.hh | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index 41f0b35fb..350f90266 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -5,7 +5,7 @@ namespace nix { LogFormat defaultLogFormat = LogFormat::raw; -LogFormat parseLogFormat(const string &logFormatStr) { +LogFormat parseLogFormat(const std::string & logFormatStr) { if (logFormatStr == "raw") return LogFormat::raw; else if (logFormatStr == "raw-with-logs") @@ -19,7 +19,7 @@ LogFormat parseLogFormat(const string &logFormatStr) { throw Error("option 'log-format' has an invalid value '%s'", logFormatStr); } -Logger *makeDefaultLogger() { +Logger * makeDefaultLogger() { switch (defaultLogFormat) { case LogFormat::raw: return makeSimpleLogger(false); @@ -34,11 +34,11 @@ Logger *makeDefaultLogger() { } } -void setLogFormat(const string &logFormatStr) { +void setLogFormat(const std::string & logFormatStr) { setLogFormat(parseLogFormat(logFormatStr)); } -void setLogFormat(const LogFormat &logFormat) { +void setLogFormat(const LogFormat & logFormat) { defaultLogFormat = logFormat; createDefaultLogger(); } diff --git a/src/libmain/loggers.hh b/src/libmain/loggers.hh index f9ba5ee5e..cada03110 100644 --- a/src/libmain/loggers.hh +++ b/src/libmain/loggers.hh @@ -12,8 +12,8 @@ enum class LogFormat { barWithLogs, }; -void setLogFormat(const string &logFormatStr); -void setLogFormat(const LogFormat &logFormat); +void setLogFormat(const std::string & logFormatStr); +void setLogFormat(const LogFormat & logFormat); void createDefaultLogger(); diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index c9ba89714..b287de8a3 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -461,7 +461,7 @@ public: } }; -Logger *makeProgressBar(bool printBuildLogs) +Logger * makeProgressBar(bool printBuildLogs) { return new ProgressBar( printBuildLogs, diff --git a/src/libmain/progress-bar.hh b/src/libmain/progress-bar.hh index 60d0a2076..7f0dafecf 100644 --- a/src/libmain/progress-bar.hh +++ b/src/libmain/progress-bar.hh @@ -4,7 +4,7 @@ namespace nix { -Logger* makeProgressBar(bool printBuildLogs = false); +Logger * makeProgressBar(bool printBuildLogs = false); void startProgressBar(bool printBuildLogs = false); -- cgit v1.2.3 From 95eb0640620f0704b4ded6ed6c7509024c00273e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Jun 2020 15:39:30 +0200 Subject: Shut up warning --- src/libmain/loggers.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index 350f90266..c44bb6408 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -31,6 +31,8 @@ Logger * makeDefaultLogger() { return makeProgressBar(); case LogFormat::barWithLogs: return makeProgressBar(true); + default: + abort(); } } -- cgit v1.2.3 From dd9bb11d0d38139bb32411170403171c4c92f8cf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Jun 2020 15:42:18 +0200 Subject: Move names.{cc,hh} to libstore --- src/libstore/names.cc | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libstore/names.hh | 32 +++++++++++++++ src/libutil/names.cc | 107 -------------------------------------------------- src/libutil/names.hh | 32 --------------- 4 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 src/libstore/names.cc create mode 100644 src/libstore/names.hh delete mode 100644 src/libutil/names.cc delete mode 100644 src/libutil/names.hh (limited to 'src') diff --git a/src/libstore/names.cc b/src/libstore/names.cc new file mode 100644 index 000000000..d1c8a6101 --- /dev/null +++ b/src/libstore/names.cc @@ -0,0 +1,107 @@ +#include "names.hh" +#include "util.hh" + + +namespace nix { + + +DrvName::DrvName() +{ + name = ""; +} + + +/* Parse a derivation name. The `name' part of a derivation name is + everything up to but not including the first dash *not* followed by + a letter. The `version' part is the rest (excluding the separating + dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd', + '2.0.48'). */ +DrvName::DrvName(std::string_view s) : hits(0) +{ + name = fullName = std::string(s); + for (unsigned int i = 0; i < s.size(); ++i) { + /* !!! isalpha/isdigit are affected by the locale. */ + if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) { + name = s.substr(0, i); + version = s.substr(i + 1); + break; + } + } +} + + +bool DrvName::matches(DrvName & n) +{ + if (name != "*") { + if (!regex) regex = std::unique_ptr(new std::regex(name, std::regex::extended)); + if (!std::regex_match(n.name, *regex)) return false; + } + if (version != "" && version != n.version) return false; + return true; +} + + +string nextComponent(string::const_iterator & p, + const string::const_iterator end) +{ + /* Skip any dots and dashes (component separators). */ + while (p != end && (*p == '.' || *p == '-')) ++p; + + if (p == end) return ""; + + /* If the first character is a digit, consume the longest sequence + of digits. Otherwise, consume the longest sequence of + non-digit, non-separator characters. */ + string s; + if (isdigit(*p)) + while (p != end && isdigit(*p)) s += *p++; + else + while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) + s += *p++; + + return s; +} + + +static bool componentsLT(const string & c1, const string & c2) +{ + int n1, n2; + bool c1Num = string2Int(c1, n1), c2Num = string2Int(c2, n2); + + if (c1Num && c2Num) return n1 < n2; + else if (c1 == "" && c2Num) return true; + else if (c1 == "pre" && c2 != "pre") return true; + else if (c2 == "pre") return false; + /* Assume that `2.3a' < `2.3.1'. */ + else if (c2Num) return true; + else if (c1Num) return false; + else return c1 < c2; +} + + +int compareVersions(const string & v1, const string & v2) +{ + string::const_iterator p1 = v1.begin(); + string::const_iterator p2 = v2.begin(); + + while (p1 != v1.end() || p2 != v2.end()) { + string c1 = nextComponent(p1, v1.end()); + string c2 = nextComponent(p2, v2.end()); + if (componentsLT(c1, c2)) return -1; + else if (componentsLT(c2, c1)) return 1; + } + + return 0; +} + + +DrvNames drvNamesFromArgs(const Strings & opArgs) +{ + DrvNames result; + for (auto & i : opArgs) + result.push_back(DrvName(i)); + return result; +} + + +} diff --git a/src/libstore/names.hh b/src/libstore/names.hh new file mode 100644 index 000000000..00e14b8c7 --- /dev/null +++ b/src/libstore/names.hh @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include "types.hh" +#include + +namespace nix { + +struct DrvName +{ + string fullName; + string name; + string version; + unsigned int hits; + + DrvName(); + DrvName(std::string_view s); + bool matches(DrvName & n); + +private: + std::unique_ptr regex; +}; + +typedef list DrvNames; + +string nextComponent(string::const_iterator & p, + const string::const_iterator end); +int compareVersions(const string & v1, const string & v2); +DrvNames drvNamesFromArgs(const Strings & opArgs); + +} diff --git a/src/libutil/names.cc b/src/libutil/names.cc deleted file mode 100644 index d1c8a6101..000000000 --- a/src/libutil/names.cc +++ /dev/null @@ -1,107 +0,0 @@ -#include "names.hh" -#include "util.hh" - - -namespace nix { - - -DrvName::DrvName() -{ - name = ""; -} - - -/* Parse a derivation name. The `name' part of a derivation name is - everything up to but not including the first dash *not* followed by - a letter. The `version' part is the rest (excluding the separating - dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd', - '2.0.48'). */ -DrvName::DrvName(std::string_view s) : hits(0) -{ - name = fullName = std::string(s); - for (unsigned int i = 0; i < s.size(); ++i) { - /* !!! isalpha/isdigit are affected by the locale. */ - if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) { - name = s.substr(0, i); - version = s.substr(i + 1); - break; - } - } -} - - -bool DrvName::matches(DrvName & n) -{ - if (name != "*") { - if (!regex) regex = std::unique_ptr(new std::regex(name, std::regex::extended)); - if (!std::regex_match(n.name, *regex)) return false; - } - if (version != "" && version != n.version) return false; - return true; -} - - -string nextComponent(string::const_iterator & p, - const string::const_iterator end) -{ - /* Skip any dots and dashes (component separators). */ - while (p != end && (*p == '.' || *p == '-')) ++p; - - if (p == end) return ""; - - /* If the first character is a digit, consume the longest sequence - of digits. Otherwise, consume the longest sequence of - non-digit, non-separator characters. */ - string s; - if (isdigit(*p)) - while (p != end && isdigit(*p)) s += *p++; - else - while (p != end && (!isdigit(*p) && *p != '.' && *p != '-')) - s += *p++; - - return s; -} - - -static bool componentsLT(const string & c1, const string & c2) -{ - int n1, n2; - bool c1Num = string2Int(c1, n1), c2Num = string2Int(c2, n2); - - if (c1Num && c2Num) return n1 < n2; - else if (c1 == "" && c2Num) return true; - else if (c1 == "pre" && c2 != "pre") return true; - else if (c2 == "pre") return false; - /* Assume that `2.3a' < `2.3.1'. */ - else if (c2Num) return true; - else if (c1Num) return false; - else return c1 < c2; -} - - -int compareVersions(const string & v1, const string & v2) -{ - string::const_iterator p1 = v1.begin(); - string::const_iterator p2 = v2.begin(); - - while (p1 != v1.end() || p2 != v2.end()) { - string c1 = nextComponent(p1, v1.end()); - string c2 = nextComponent(p2, v2.end()); - if (componentsLT(c1, c2)) return -1; - else if (componentsLT(c2, c1)) return 1; - } - - return 0; -} - - -DrvNames drvNamesFromArgs(const Strings & opArgs) -{ - DrvNames result; - for (auto & i : opArgs) - result.push_back(DrvName(i)); - return result; -} - - -} diff --git a/src/libutil/names.hh b/src/libutil/names.hh deleted file mode 100644 index 00e14b8c7..000000000 --- a/src/libutil/names.hh +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include - -#include "types.hh" -#include - -namespace nix { - -struct DrvName -{ - string fullName; - string name; - string version; - unsigned int hits; - - DrvName(); - DrvName(std::string_view s); - bool matches(DrvName & n); - -private: - std::unique_ptr regex; -}; - -typedef list DrvNames; - -string nextComponent(string::const_iterator & p, - const string::const_iterator end); -int compareVersions(const string & v1, const string & v2); -DrvNames drvNamesFromArgs(const Strings & opArgs); - -} -- cgit v1.2.3 From 045b07200c77bf1fe19c0a986aafb531e7e1ba54 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Jun 2020 12:46:33 +0200 Subject: Remove Store::queryDerivationOutputNames() This function was used in only one place, where it could easily be replaced by readDerivation() since it's not performance-critical. (This function appears to have been modelled after queryDerivationOutputs(), which exists only to make the garbage collector faster.) --- src/libexpr/primops.cc | 2 +- src/libstore/build.cc | 3 --- src/libstore/daemon.cc | 3 +-- src/libstore/derivations.cc | 9 +++++++++ src/libstore/derivations.hh | 2 ++ src/libstore/local-store.cc | 17 ----------------- src/libstore/local-store.hh | 2 -- src/libstore/remote-store.cc | 9 --------- src/libstore/remote-store.hh | 2 -- src/libstore/store-api.hh | 4 ---- src/libstore/worker-protocol.hh | 2 +- 11 files changed, 14 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index d458ab272..9efb8eae5 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -688,7 +688,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * for (auto & j : refs) { drv.inputSrcs.insert(j.clone()); if (j.isDerivation()) - drv.inputDrvs[j.clone()] = state.store->queryDerivationOutputNames(j); + drv.inputDrvs[j.clone()] = readDerivation(*state.store, state.store->toRealPath(j)).outputNames(); } } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index bdf03ff94..3ab6220e3 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2723,9 +2723,6 @@ struct RestrictedStore : public LocalFSStore StorePathSet queryDerivationOutputs(const StorePath & path) override { throw Error("queryDerivationOutputs"); } - StringSet queryDerivationOutputNames(const StorePath & path) override - { throw Error("queryDerivationOutputNames"); } - std::optional queryPathFromHashPart(const std::string & hashPart) override { throw Error("queryPathFromHashPart"); } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 5cff170dd..dc2015579 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -329,8 +329,7 @@ static void performOp(TunnelLogger * logger, ref store, case wopQueryDerivationOutputNames: { auto path = store->parseStorePath(readString(from)); logger->startWork(); - StringSet names; - names = store->queryDerivationOutputNames(path); + auto names = readDerivation(*store, store->toRealPath(path)).outputNames(); logger->stopWork(); to << names; break; diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index c68e7b16b..6de91ec97 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -410,6 +410,15 @@ StorePathSet BasicDerivation::outputPaths() const } +StringSet BasicDerivation::outputNames() const +{ + StringSet names; + for (auto & i : outputs) + names.insert(i.first); + return names; +} + + Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv) { drv.outputs.clear(); diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index b1224b93b..88aed66bf 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -58,6 +58,8 @@ struct BasicDerivation /* Return the output paths of a derivation. */ StorePathSet outputPaths() const; + /* Return the output names of a derivation. */ + StringSet outputNames() const; }; struct Derivation : BasicDerivation diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 1c3795eb1..e379db426 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -785,23 +785,6 @@ StorePathSet LocalStore::queryDerivationOutputs(const StorePath & path) } -StringSet LocalStore::queryDerivationOutputNames(const StorePath & path) -{ - return retrySQLite([&]() { - auto state(_state.lock()); - - auto useQueryDerivationOutputs(state->stmtQueryDerivationOutputs.use() - (queryValidPathId(*state, path))); - - StringSet outputNames; - while (useQueryDerivationOutputs.next()) - outputNames.insert(useQueryDerivationOutputs.getStr(0)); - - return outputNames; - }); -} - - std::optional LocalStore::queryPathFromHashPart(const std::string & hashPart) { if (hashPart.size() != storePathHashLen) throw Error("invalid hash part"); diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index c1e75390c..e17cc45ae 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -135,8 +135,6 @@ public: StorePathSet queryDerivationOutputs(const StorePath & path) override; - StringSet queryDerivationOutputNames(const StorePath & path) override; - std::optional queryPathFromHashPart(const std::string & hashPart) override; StorePathSet querySubstitutablePaths(const StorePathSet & paths) override; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 5c36693e6..735f59a91 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -418,15 +418,6 @@ StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path) } -PathSet RemoteStore::queryDerivationOutputNames(const StorePath & path) -{ - auto conn(getConnection()); - conn->to << wopQueryDerivationOutputNames << printStorePath(path); - conn.processStderr(); - return readStrings(conn->from); -} - - std::optional RemoteStore::queryPathFromHashPart(const std::string & hashPart) { auto conn(getConnection()); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 3c86b4524..80c8e9f11 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -51,8 +51,6 @@ public: StorePathSet queryDerivationOutputs(const StorePath & path) override; - StringSet queryDerivationOutputNames(const StorePath & path) override; - std::optional queryPathFromHashPart(const std::string & hashPart) override; StorePathSet querySubstitutablePaths(const StorePathSet & paths) override; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index b1e25fc7d..5ba17e0bc 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -430,10 +430,6 @@ public: virtual StorePathSet queryDerivationOutputs(const StorePath & path) { unsupported("queryDerivationOutputs"); } - /* Query the output names of the derivation denoted by `path'. */ - virtual StringSet queryDerivationOutputNames(const StorePath & path) - { unsupported("queryDerivationOutputNames"); } - /* Query the full store path given the hash part of a valid store path, or empty if the path doesn't exist. */ virtual std::optional queryPathFromHashPart(const std::string & hashPart) = 0; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index 857d54d99..ac42457fc 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -36,7 +36,7 @@ typedef enum { wopClearFailedPaths = 25, wopQueryPathInfo = 26, wopImportPaths = 27, // obsolete - wopQueryDerivationOutputNames = 28, + wopQueryDerivationOutputNames = 28, // obsolete wopQueryPathFromHashPart = 29, wopQuerySubstitutablePathInfos = 30, wopQueryValidPaths = 31, -- cgit v1.2.3 From 9f736dd89d064718a378703a9557de56fdd1a734 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Jun 2020 13:04:52 +0200 Subject: Add Store::readDerivation() convenience function --- src/build-remote/build-remote.cc | 2 +- src/libexpr/primops.cc | 2 +- src/libstore/daemon.cc | 2 +- src/libstore/derivations.cc | 8 +++++++- src/libstore/local-store.cc | 5 ++--- src/libstore/store-api.hh | 3 +++ src/nix/show-derivation.cc | 6 ++---- 7 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 00340b787..d2ea6c956 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -241,7 +241,7 @@ connected: uploadLock = -1; - BasicDerivation drv(readDerivation(*store, store->realStoreDir + "/" + std::string(drvPath->to_string()))); + auto drv = store->readDerivation(*drvPath); drv.inputSrcs = store->parseStorePathSet(inputs); auto result = sshStore->buildDerivation(*drvPath, drv); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 9efb8eae5..3a27527a0 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -688,7 +688,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * for (auto & j : refs) { drv.inputSrcs.insert(j.clone()); if (j.isDerivation()) - drv.inputDrvs[j.clone()] = readDerivation(*state.store, state.store->toRealPath(j)).outputNames(); + drv.inputDrvs[j.clone()] = state.store->readDerivation(j).outputNames(); } } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index dc2015579..877c70a03 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -329,7 +329,7 @@ static void performOp(TunnelLogger * logger, ref store, case wopQueryDerivationOutputNames: { auto path = store->parseStorePath(readString(from)); logger->startWork(); - auto names = readDerivation(*store, store->toRealPath(path)).outputNames(); + auto names = store->readDerivation(path).outputNames(); logger->stopWork(); to << names; break; diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 6de91ec97..e268c65ff 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -204,6 +204,12 @@ Derivation readDerivation(const Store & store, const Path & drvPath) Derivation Store::derivationFromPath(const StorePath & drvPath) { ensurePath(drvPath); + return readDerivation(drvPath); +} + + +Derivation Store::readDerivation(const StorePath & drvPath) +{ auto accessor = getFSAccessor(); try { return parseDerivation(*this, accessor->readFile(printStorePath(drvPath))); @@ -378,7 +384,7 @@ Hash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutput if (h == drvHashes.end()) { assert(store.isValidPath(i.first)); h = drvHashes.insert_or_assign(i.first.clone(), hashDerivationModulo(store, - readDerivation(store, store.toRealPath(i.first)), false)).first; + store.readDerivation(i.first), false)).first; } inputs2.insert_or_assign(h->second.to_string(Base16, false), i.second); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index e379db426..c2c45b4c2 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -595,7 +595,7 @@ uint64_t LocalStore::addValidPath(State & state, efficiently query whether a path is an output of some derivation. */ if (info.path.isDerivation()) { - auto drv = readDerivation(*this, realStoreDir + "/" + std::string(info.path.to_string())); + auto drv = readDerivation(info.path); /* Verify that the output paths in the derivation are correct (i.e., follow the scheme for computing output paths from @@ -911,8 +911,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) for (auto & i : infos) if (i.path.isDerivation()) { // FIXME: inefficient; we already loaded the derivation in addValidPath(). - checkDerivationOutputs(i.path, - readDerivation(*this, realStoreDir + "/" + std::string(i.path.to_string()))); + checkDerivationOutputs(i.path, readDerivation(i.path)); } /* Do a topological sort of the paths. This will throw an diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 5ba17e0bc..5ef506326 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -583,6 +583,9 @@ public: ensurePath(). */ Derivation derivationFromPath(const StorePath & drvPath); + /* Read a derivation (which must already be valid). */ + Derivation readDerivation(const StorePath & drvPath); + /* Place in `out' the set of all store paths in the file system closure of `storePath'; that is, all paths than can be directly or indirectly reached from it. `out' is not cleared. If diff --git a/src/nix/show-derivation.cc b/src/nix/show-derivation.cc index 22c569f3c..2d31894c2 100644 --- a/src/nix/show-derivation.cc +++ b/src/nix/show-derivation.cc @@ -61,11 +61,9 @@ struct CmdShowDerivation : InstallablesCommand for (auto & drvPath : drvPaths) { if (!drvPath.isDerivation()) continue; - auto drvPathS = store->printStorePath(drvPath); + auto drvObj(jsonRoot.object(store->printStorePath(drvPath))); - auto drvObj(jsonRoot.object(drvPathS)); - - auto drv = readDerivation(*store, drvPathS); + auto drv = store->readDerivation(drvPath); { auto outputsObj(drvObj.object("outputs")); -- cgit v1.2.3 From b260c9ee0325d7a4c78d91e47bd6e2afbde16e28 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Fri, 12 Jun 2020 10:09:42 -0500 Subject: Add newHashAllowEmpty helper function This replaces the copy&paste with a helper function in hash.hh. --- src/libexpr/primops.cc | 18 ++++-------------- src/libexpr/primops/fetchTree.cc | 11 +++-------- src/libfetchers/fetchers.cc | 11 +++-------- src/libfetchers/tarball.cc | 10 ++-------- src/libutil/hash.cc | 10 ++++++++++ src/libutil/hash.hh | 2 ++ 6 files changed, 24 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index df3d4a459..083c7d398 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -720,12 +720,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); - Hash h; - if (outputHash->empty()) { - h = Hash(ht); - printError("warning: found empty hash, assuming you wanted '%s'", h.to_string()); - } else - h = Hash(*outputHash, ht); + Hash h = newHashAllowEmpty(*outputHash, ht); auto outPath = state.store->makeFixedOutputPath(ingestionMethod, h, drvName); if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath); @@ -1131,14 +1126,9 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value filterFun = attr.value; } else if (n == "recursive") method = FileIngestionMethod { state.forceBool(*attr.value, *attr.pos) }; - else if (n == "sha256") { - auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); - if (hashStr == "") { - expectedHash = Hash(htSHA256); - printError("warning: found empty hash, assuming you wanted '%s'", expectedHash.to_string()); - } else - expectedHash = Hash(hashStr, htSHA256); - } else + else if (n == "sha256") + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); + else throw EvalError(format("unsupported argument '%1%' to 'addPath', at %2%") % attr.name % *attr.pos); } if (path.empty()) diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 745f65adf..1464aa8b4 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -102,14 +102,9 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, string n(attr.name); if (n == "url") url = state.forceStringNoCtx(*attr.value, *attr.pos); - else if (n == "sha256") { - auto hashStr = state.forceStringNoCtx(*attr.value, *attr.pos); - if (hashStr == "") { - expectedHash = Hash(htSHA256); - printError("warning: found empty hash, assuming you wanted '%s'", expectedHash->to_string()); - } else - expectedHash = Hash(hashStr, htSHA256); - } else if (n == "name") + else if (n == "sha256") + expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); + else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else throw EvalError("unsupported argument '%s' to '%s', at %s", diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 988a8dc69..91b897e62 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -34,14 +34,9 @@ std::unique_ptr inputFromAttrs(const Attrs & attrs) for (auto & inputScheme : *inputSchemes) { auto res = inputScheme->inputFromAttrs(attrs2); if (res) { - if (auto narHash = maybeGetStrAttr(attrs, "narHash")) { - if (narHash->empty()) { - res->narHash = Hash(htUnknown); - printError("warning: found empty hash, assuming you wanted '%s'", res->narHash->to_string()); - } else - // FIXME: require SRI hash. - res->narHash = Hash(*narHash); - } + if (auto narHash = maybeGetStrAttr(attrs, "narHash")) + // FIXME: require SRI hash. + res->narHash = newHashAllowEmpty(*narHash, htUnknown); return res; } } diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index e4dafec0b..937f86bc6 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -263,14 +263,8 @@ struct TarballInputScheme : InputScheme throw Error("unsupported tarball input attribute '%s'", name); auto input = std::make_unique(parseURL(getStrAttr(attrs, "url"))); - if (auto hash = maybeGetStrAttr(attrs, "hash")) { - if (hash->empty()) { - input->hash = Hash(htUnknown); - printError("warning: found empty hash, assuming you wanted '%s'", input->hash->to_string()); - } else - // FIXME: require SRI hash. - input->hash = Hash(*hash); - } + if (auto hash = maybeGetStrAttr(attrs, "hash")) + input->hash = newHashAllowEmpty(*hash, htUnknown); return input; } diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 7caee1da7..2c8085e42 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -205,6 +205,16 @@ Hash::Hash(const std::string & s, HashType type) throw BadHash("hash '%s' has wrong length for hash type '%s'", s, printHashType(type)); } +Hash newHashAllowEmpty(std::string hashStr, HashType ht) +{ + if (hashStr.empty()) + { + Hash h(ht); + warn("found empty hash, assuming you wanted '%s'", h.to_string()); + } else + return Hash(hashStr, ht); +} + union Ctx { diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index ea9fca3e7..449cb1b86 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -94,6 +94,8 @@ struct Hash } }; +/* Helper that defaults empty hashes to the 0 hash. */ +Hash newHashAllowEmpty(std::string hashStr, HashType ht); /* Print a hash in base-16 if it's MD5, or base-32 otherwise. */ string printHash16or32(const Hash & hash); -- cgit v1.2.3 From ea0d29d99a400c328fa0ca05ba5e639351673ebc Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Fri, 12 Jun 2020 10:18:27 -0500 Subject: Provide base argument to to_string --- src/libutil/hash.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 2c8085e42..3f6d4c0c9 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -210,7 +210,7 @@ Hash newHashAllowEmpty(std::string hashStr, HashType ht) if (hashStr.empty()) { Hash h(ht); - warn("found empty hash, assuming you wanted '%s'", h.to_string()); + warn("found empty hash, assuming you wanted '%s'", h.to_string(SRI)); } else return Hash(hashStr, ht); } -- cgit v1.2.3 From 2853ba4ab26c254d564aee9e75fe8f9f664b94fc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 12 Jun 2020 19:00:48 +0200 Subject: Fix build --- src/libutil/hash.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 3f6d4c0c9..c935f05eb 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -207,10 +207,10 @@ Hash::Hash(const std::string & s, HashType type) Hash newHashAllowEmpty(std::string hashStr, HashType ht) { - if (hashStr.empty()) - { + if (hashStr.empty()) { Hash h(ht); - warn("found empty hash, assuming you wanted '%s'", h.to_string(SRI)); + warn("found empty hash, assuming '%s'", h.to_string(SRI, true)); + return h; } else return Hash(hashStr, ht); } -- cgit v1.2.3 From f6f01416b71f239c0d9594f5c6201dfd208fe8c4 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 12 Jun 2020 21:12:36 +0000 Subject: Use `std::string_view` in a few more places --- src/libfetchers/github.cc | 2 +- src/libstore/store-api.cc | 4 ++-- src/libutil/hash.cc | 4 ++-- src/libutil/hash.hh | 2 +- src/libutil/util.cc | 6 +++--- src/libutil/util.hh | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index 8675a5a66..0bee1d6b3 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -76,7 +76,7 @@ struct GitHubInput : Input readFile( store->toRealPath( downloadFile(store, url, "source", false).storePath))); - rev = Hash(json["sha"], htSHA1); + rev = Hash(std::string { json["sha"] }, htSHA1); debug("HEAD revision for '%s' is %s", url, rev->gitRev()); } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 0645fca84..f6901bf42 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -779,7 +779,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const }; if (hasPrefix(ca, "text:")) { - Hash hash(std::string(ca, 5)); + Hash hash(ca.substr(5)); if (store.makeTextPath(path.name(), hash, references) == path) return true; else @@ -788,7 +788,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const else if (hasPrefix(ca, "fixed:")) { FileIngestionMethod recursive { ca.compare(6, 2, "r:") == 0 }; - Hash hash(std::string(ca, recursive == FileIngestionMethod::Recursive ? 8 : 6)); + Hash hash(ca.substr(recursive == FileIngestionMethod::Recursive ? 8 : 6)); auto refs = cloneStorePathSet(references); bool hasSelfReference = false; if (refs.count(path)) { diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index c935f05eb..460d479a3 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -125,7 +125,7 @@ std::string Hash::to_string(Base base, bool includeType) const } -Hash::Hash(const std::string & s, HashType type) +Hash::Hash(std::string_view s, HashType type) : type(type) { size_t pos = 0; @@ -194,7 +194,7 @@ Hash::Hash(const std::string & s, HashType type) } else if (isSRI || size == base64Len()) { - auto d = base64Decode(std::string(s, pos)); + auto d = base64Decode(s.substr(pos)); if (d.size() != hashSize) throw BadHash("invalid %s hash '%s'", isSRI ? "SRI" : "base-64", s); assert(hashSize); diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index 5080539b2..180fb7633 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -42,7 +42,7 @@ struct Hash Subresource Integrity hash expression). If the 'type' argument is htUnknown, then the hash type must be specified in the string. */ - Hash(const std::string & s, HashType type = htUnknown); + Hash(std::string_view s, HashType type = htUnknown); void init(); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index e0a99152b..b66447e08 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1314,7 +1314,7 @@ bool statusOk(int status) } -bool hasPrefix(const string & s, const string & prefix) +bool hasPrefix(std::string_view s, std::string_view prefix) { return s.compare(0, prefix.size(), prefix) == 0; } @@ -1408,7 +1408,7 @@ std::string filterANSIEscapes(const std::string & s, bool filterAll, unsigned in static char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -string base64Encode(const string & s) +string base64Encode(std::string_view s) { string res; int data = 0, nbits = 0; @@ -1429,7 +1429,7 @@ string base64Encode(const string & s) } -string base64Decode(const string & s) +string base64Decode(std::string_view s) { bool init = false; char decode[256]; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 4b117f9bc..c95232317 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -416,7 +416,7 @@ template bool string2Float(const string & s, N & n) /* Return true iff `s' starts with `prefix'. */ -bool hasPrefix(const string & s, const string & prefix); +bool hasPrefix(std::string_view s, std::string_view prefix); /* Return true iff `s' ends in `suffix'. */ @@ -455,8 +455,8 @@ std::string filterANSIEscapes(const std::string & s, /* Base64 encoding/decoding. */ -string base64Encode(const string & s); -string base64Decode(const string & s); +string base64Encode(std::string_view s); +string base64Decode(std::string_view s); /* Get a value for the specified key from an associate container. */ -- cgit v1.2.3 From fd64e4fb96f814440dc337ce664cdbd22e0eabb2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 13:50:33 +0200 Subject: Disambiguate BaseError(Args) constructor This means that 'throw Error({ ... ErrorInfo ... })' now works. --- src/libexpr/eval.cc | 9 ++++----- src/libutil/types.hh | 3 --- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7bf25ea17..75e6a23a1 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -506,11 +506,10 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2)) LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2)) { - throw EvalError( - ErrorInfo { - .hint = hintfmt(s, s2), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt(s, s2), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3)) diff --git a/src/libutil/types.hh b/src/libutil/types.hh index 89ae108f9..3af485fa0 100644 --- a/src/libutil/types.hh +++ b/src/libutil/types.hh @@ -1,6 +1,5 @@ #pragma once - #include "ref.hh" #include @@ -25,7 +24,6 @@ typedef string Path; typedef list Paths; typedef set PathSet; - /* Helper class to run code at startup. */ template struct OnStartup @@ -33,5 +31,4 @@ struct OnStartup OnStartup(T && t) { t(); } }; - } -- cgit v1.2.3 From 1fb762d11fadc659ef41b79eaddddcce5fbbc192 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 14:06:58 +0200 Subject: Get rid of explicit ErrorInfo constructors --- src/libexpr/attr-set.hh | 9 +- src/libexpr/eval-inline.hh | 18 +- src/libexpr/eval.cc | 65 +++-- src/libexpr/nixexpr.cc | 9 +- src/libexpr/nixexpr.hh | 9 +- src/libexpr/parser.y | 86 +++---- src/libexpr/primops.cc | 442 +++++++++++++++------------------- src/libexpr/primops/context.cc | 27 +-- src/libexpr/primops/fetchGit.cc | 18 +- src/libexpr/primops/fetchMercurial.cc | 18 +- src/libexpr/primops/fetchTree.cc | 28 +-- src/libexpr/primops/fromTOML.cc | 9 +- src/libstore/builtins/buildenv.cc | 14 +- src/libstore/gc.cc | 11 +- src/libstore/sqlite.cc | 8 +- src/libutil/error.hh | 14 +- src/libutil/serialise.cc | 4 +- src/nix-build/nix-build.cc | 11 +- src/nix/upgrade-nix.cc | 7 +- 19 files changed, 360 insertions(+), 447 deletions(-) (limited to 'src') diff --git a/src/libexpr/attr-set.hh b/src/libexpr/attr-set.hh index f5651891f..c601d09c2 100644 --- a/src/libexpr/attr-set.hh +++ b/src/libexpr/attr-set.hh @@ -76,11 +76,10 @@ public: { auto a = get(name); if (!a) - throw Error( - ErrorInfo { - .hint = hintfmt("attribute '%s' missing", name), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("attribute '%s' missing", name), + .nixCode = NixCode { .errPos = pos } + }); return *a; } diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh index eee49e02e..3d544c903 100644 --- a/src/libexpr/eval-inline.hh +++ b/src/libexpr/eval-inline.hh @@ -9,11 +9,10 @@ namespace nix { LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s)) { - throw EvalError( - ErrorInfo { - .hint = hintfmt(s), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt(s), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) @@ -24,11 +23,10 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)) LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v)) { - throw TypeError( - ErrorInfo { - .hint = hintfmt(s, showType(v)), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt(s, showType(v)), + .nixCode = NixCode { .errPos = pos } + }); } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 75e6a23a1..8e71db2b8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -519,30 +519,27 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3)) { - throw EvalError( - ErrorInfo { - .hint = hintfmt(s, s2, s3), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt(s, s2, s3), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2)) { // p1 is where the error occurred; p2 is a position mentioned in the message. - throw EvalError( - ErrorInfo { - .hint = hintfmt(s, sym, p2), - .nixCode = NixCode { .errPos = p1 } - }); + throw EvalError({ + .hint = hintfmt(s, sym, p2), + .nixCode = NixCode { .errPos = p1 } + }); } LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s)) { - throw TypeError( - ErrorInfo { - .hint = hintfmt(s), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt(s), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) @@ -552,29 +549,26 @@ LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s1)) LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2)) { - throw TypeError( - ErrorInfo { - .hint = hintfmt(s, fun.showNamePos(), s2), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt(s, fun.showNamePos(), s2), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1)) { - throw AssertionError( - ErrorInfo { - .hint = hintfmt(s, s1), - .nixCode = NixCode { .errPos = pos } - }); + throw AssertionError({ + .hint = hintfmt(s, s1), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1)) { - throw UndefinedVarError( - ErrorInfo { - .hint = hintfmt(s, s1), - .nixCode = NixCode { .errPos = pos } - }); + throw UndefinedVarError({ + .hint = hintfmt(s, s1), + .nixCode = NixCode { .errPos = pos } + }); } LocalNoInline(void addErrorPrefix(Error & e, const char * s, const string & s2)) @@ -1593,7 +1587,7 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) string s = forceString(v, pos); if (v.string.context) { if (pos) - throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", + throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", @@ -1919,11 +1913,10 @@ void EvalState::printStats() string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const { - throw TypeError( - ErrorInfo { - .hint = hintfmt("cannot coerce %1% to a string", showType()), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt("cannot coerce %1% to a string", showType()), + .nixCode = NixCode { .errPos = pos } + }); } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 91a508305..5b2dd9751 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -268,11 +268,10 @@ void ExprVar::bindVars(const StaticEnv & env) enclosing `with'. If there is no `with', then we can issue an "undefined variable" error now. */ if (withLevel == -1) - throw UndefinedVarError( - ErrorInfo { - .hint = hintfmt("undefined variable '%1%'", name), - .nixCode = NixCode { .errPos = pos } - }); + throw UndefinedVarError({ + .hint = hintfmt("undefined variable '%1%'", name), + .nixCode = NixCode { .errPos = pos } + }); fromWith = true; this->level = withLevel; } diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 47d0e85ec..ec6fd3190 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -236,11 +236,10 @@ struct ExprLambda : Expr : pos(pos), arg(arg), matchAttrs(matchAttrs), formals(formals), body(body) { if (!arg.empty() && formals && formals->argNames.find(arg) != formals->argNames.end()) - throw ParseError( - ErrorInfo { - .hint = hintfmt("duplicate formal function argument '%1%'", arg), - .nixCode = NixCode { .errPos = pos } - }); + throw ParseError({ + .hint = hintfmt("duplicate formal function argument '%1%'", arg), + .nixCode = NixCode { .errPos = pos } + }); }; void setName(Symbol & name); string showNamePos() const; diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 0417a3c21..a1188dec0 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -64,23 +64,20 @@ namespace nix { static void dupAttr(const AttrPath & attrPath, const Pos & pos, const Pos & prevPos) { - throw ParseError( - ErrorInfo { - .hint = hintfmt("attribute '%1%' already defined at %2%", - showAttrPath(attrPath), prevPos), - .nixCode = NixCode { .errPos = pos }, - }); + throw ParseError({ + .hint = hintfmt("attribute '%1%' already defined at %2%", + showAttrPath(attrPath), prevPos), + .nixCode = NixCode { .errPos = pos }, + }); } static void dupAttr(Symbol attr, const Pos & pos, const Pos & prevPos) { - throw ParseError( - ErrorInfo { - .hint = hintfmt("attribute '%1%' already defined at %2%", - attr, prevPos), - .nixCode = NixCode { .errPos = pos }, - }); + throw ParseError({ + .hint = hintfmt("attribute '%1%' already defined at %2%", attr, prevPos), + .nixCode = NixCode { .errPos = pos }, + }); } @@ -148,12 +145,11 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, static void addFormal(const Pos & pos, Formals * formals, const Formal & formal) { if (!formals->argNames.insert(formal.name).second) - throw ParseError( - ErrorInfo { - .hint = hintfmt("duplicate formal function argument '%1%'", - formal.name), - .nixCode = NixCode { .errPos = pos }, - }); + throw ParseError({ + .hint = hintfmt("duplicate formal function argument '%1%'", + formal.name), + .nixCode = NixCode { .errPos = pos }, + }); formals->formals.push_front(formal); } @@ -261,10 +257,10 @@ static inline Pos makeCurPos(const YYLTYPE & loc, ParseData * data) void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * error) { - data->error = ErrorInfo { + data->error = { .hint = hintfmt(error), .nixCode = NixCode { .errPos = makeCurPos(*loc, data) } - }; + }; } @@ -341,11 +337,10 @@ expr_function { $$ = new ExprWith(CUR_POS, $2, $4); } | LET binds IN expr_function { if (!$2->dynamicAttrs.empty()) - throw ParseError( - ErrorInfo { - .hint = hintfmt("dynamic attributes not allowed in let"), - .nixCode = NixCode { .errPos = CUR_POS }, - }); + throw ParseError({ + .hint = hintfmt("dynamic attributes not allowed in let"), + .nixCode = NixCode { .errPos = CUR_POS }, + }); $$ = new ExprLet($2, $4); } | expr_if @@ -422,11 +417,10 @@ expr_simple | URI { static bool noURLLiterals = settings.isExperimentalFeatureEnabled("no-url-literals"); if (noURLLiterals) - throw ParseError( - ErrorInfo { - .hint = hintfmt("URL literals are disabled"), - .nixCode = NixCode { .errPos = CUR_POS } - }); + throw ParseError({ + .hint = hintfmt("URL literals are disabled"), + .nixCode = NixCode { .errPos = CUR_POS } + }); $$ = new ExprString(data->symbols.create($1)); } | '(' expr ')' { $$ = $2; } @@ -496,11 +490,10 @@ attrs $$->push_back(AttrName(str->s)); delete str; } else - throw ParseError( - ErrorInfo { - .hint = hintfmt("dynamic attributes not allowed in inherit"), - .nixCode = NixCode { .errPos = makeCurPos(@2, data) }, - }); + throw ParseError({ + .hint = hintfmt("dynamic attributes not allowed in inherit"), + .nixCode = NixCode { .errPos = makeCurPos(@2, data) }, + }); } | { $$ = new AttrPath; } ; @@ -695,11 +688,10 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos Path res = r.second + suffix; if (pathExists(res)) return canonPath(res); } - throw ThrownError( - ErrorInfo { - .hint = hintfmt("file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)", path), - .nixCode = NixCode { .errPos = pos } - }); + throw ThrownError({ + .hint = hintfmt("file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)", path), + .nixCode = NixCode { .errPos = pos } + }); } @@ -715,10 +707,9 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl res = { true, store->toRealPath(fetchers::downloadTarball( store, resolveUri(elem.second), "source", false).storePath) }; } catch (FileTransferError & e) { - logWarning( - ErrorInfo { - .name = "Entry download", - .hint = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second) + logWarning({ + .name = "Entry download", + .hint = hintfmt("Nix search path entry '%1%' cannot be downloaded, ignoring", elem.second) }); res = { false, "" }; } @@ -727,10 +718,9 @@ std::pair EvalState::resolveSearchPathElem(const SearchPathEl if (pathExists(path)) res = { true, path }; else { - logWarning( - ErrorInfo { - .name = "Entry not found", - .hint = hintfmt("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second) + logWarning({ + .name = "Entry not found", + .hint = hintfmt("warning: Nix search path entry '%1%' does not exist, ignoring", elem.second) }); res = { false, "" }; } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 23ab7dec6..62e5163c9 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -93,12 +93,10 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot import '%1%', since path '%2%' is not valid", - path, e.path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("cannot import '%1%', since path '%2%' is not valid", path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } Path realPath = state.checkSourcePath(state.toRealPath(path, context)); @@ -174,13 +172,12 @@ void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt( - "cannot import '%1%', since path '%2%' is not valid", - path, e.path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt( + "cannot import '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } path = state.checkSourcePath(path); @@ -215,11 +212,10 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) auto elems = args[0]->listElems(); auto count = args[0]->listSize(); if (count == 0) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("at least one argument to 'exec' required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("at least one argument to 'exec' required"), + .nixCode = NixCode { .errPos = pos } + }); } PathSet context; auto program = state.coerceToString(pos, *elems[0], context, false, false); @@ -230,12 +226,12 @@ void prim_exec(EvalState & state, const Pos & pos, Value * * args, Value & v) try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot execute '%1%', since path '%2%' is not valid", - program, e.path), - .nixCode = NixCode { .errPos = pos } - });} + throw EvalError({ + .hint = hintfmt("cannot execute '%1%', since path '%2%' is not valid", + program, e.path), + .nixCode = NixCode { .errPos = pos } + }); + } auto output = runProgram(program, true, commandArgs); Expr * parsed; @@ -386,11 +382,10 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator startSet = args[0]->attrs->find(state.symbols.create("startSet")); if (startSet == args[0]->attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("attribute 'startSet' required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("attribute 'startSet' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceList(*startSet->value, pos); ValueList workSet; @@ -401,11 +396,10 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator op = args[0]->attrs->find(state.symbols.create("operator")); if (op == args[0]->attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("attribute 'operator' required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("attribute 'operator' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*op->value, pos); /* Construct the closure by applying the operator to element of @@ -424,11 +418,10 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar Bindings::iterator key = e->attrs->find(state.symbols.create("key")); if (key == e->attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("attribute 'key' required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("attribute 'key' required"), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*key->value, pos); if (!doneKeys.insert(key->value).second) continue; @@ -560,11 +553,10 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Figure out the name first (for stack backtraces). */ Bindings::iterator attr = args[0]->attrs->find(state.sName); if (attr == args[0]->attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("required attribute 'name' missing"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("required attribute 'name' missing"), + .nixCode = NixCode { .errPos = pos } + }); string drvName; Pos & posDrvName(*attr->pos); try { @@ -607,42 +599,38 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * auto handleHashMode = [&](const std::string & s) { if (s == "recursive") ingestionMethod = FileIngestionMethod::Recursive; else if (s == "flat") ingestionMethod = FileIngestionMethod::Flat; - else - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid value '%s' for 'outputHashMode' attribute", s), - .nixCode = NixCode { .errPos = posDrvName } - }); + else + throw EvalError({ + .hint = hintfmt("invalid value '%s' for 'outputHashMode' attribute", s), + .nixCode = NixCode { .errPos = posDrvName } + }); }; auto handleOutputs = [&](const Strings & ss) { outputs.clear(); for (auto & j : ss) { if (outputs.find(j) != outputs.end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("duplicate derivation output '%1%'", j), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("duplicate derivation output '%1%'", j), + .nixCode = NixCode { .errPos = posDrvName } + }); /* !!! Check whether j is a valid attribute name. */ /* Derivations cannot be named ‘drv’, because then we'd have an attribute ‘drvPath’ in the resulting set. */ if (j == "drv") - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid derivation output name 'drv'" ), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("invalid derivation output name 'drv'" ), + .nixCode = NixCode { .errPos = posDrvName } + }); outputs.insert(j); } if (outputs.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("derivation cannot have an empty set of outputs"), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("derivation cannot have an empty set of outputs"), + .nixCode = NixCode { .errPos = posDrvName } + }); }; try { @@ -754,35 +742,31 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Do we have all required attributes? */ if (drv.builder == "") - throw EvalError( - ErrorInfo { - .hint = hintfmt("required attribute 'builder' missing"), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("required attribute 'builder' missing"), + .nixCode = NixCode { .errPos = posDrvName } + }); if (drv.platform == "") - throw EvalError( - ErrorInfo { - .hint = hintfmt("required attribute 'system' missing"), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("required attribute 'system' missing"), + .nixCode = NixCode { .errPos = posDrvName } + }); /* Check whether the derivation name is valid. */ if (isDerivation(drvName)) - throw EvalError( - ErrorInfo { - .hint = hintfmt("derivation names are not allowed to end in '%s'", drvExtension), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw EvalError({ + .hint = hintfmt("derivation names are not allowed to end in '%s'", drvExtension), + .nixCode = NixCode { .errPos = posDrvName } + }); if (outputHash) { /* Handle fixed-output derivations. */ if (outputs.size() != 1 || *(outputs.begin()) != "out") - throw Error( - ErrorInfo { - .hint = hintfmt("multiple outputs are not supported in fixed-output derivations"), - .nixCode = NixCode { .errPos = posDrvName } - }); + throw Error({ + .hint = hintfmt("multiple outputs are not supported in fixed-output derivations"), + .nixCode = NixCode { .errPos = posDrvName } + }); HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo); @@ -887,11 +871,10 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V e.g. nix-push does the right thing. */ if (!state.store->isStorePath(path)) path = canonPath(path, true); if (!state.store->isInStore(path)) - throw EvalError( - ErrorInfo { - .hint = hintfmt("path '%1%' is not in the Nix store", path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("path '%1%' is not in the Nix store", path), + .nixCode = NixCode { .errPos = pos } + }); Path path2 = state.store->toStorePath(path); if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(path2)); @@ -907,13 +890,12 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt( - "cannot check the existence of '%1%', since path '%2%' is not valid", - path, e.path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt( + "cannot check the existence of '%1%', since path '%2%' is not valid", + path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } try { @@ -956,13 +938,11 @@ static void prim_readFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid" - , path, e.path), - .nixCode = NixCode { .errPos = pos } - }); - } + throw EvalError({ + .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid", path, e.path), + .nixCode = NixCode { .errPos = pos } + }); + } string s = readFile(state.checkSourcePath(state.toRealPath(path, context))); if (s.find((char) 0) != string::npos) throw Error("the contents of the file '%1%' cannot be represented as a Nix string", path); @@ -989,11 +969,10 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va i = v2.attrs->find(state.symbols.create("path")); if (i == v2.attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("attribute 'path' missing"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("attribute 'path' missing"), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; string path = state.coerceToString(pos, *i->value, context, false, false); @@ -1001,12 +980,10 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va try { state.realiseContext(context); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot find '%1%', since path '%2%' is not valid", - path, e.path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } searchPath.emplace_back(prefix, path); @@ -1023,11 +1000,10 @@ static void prim_hashFile(EvalState & state, const Pos & pos, Value * * args, Va string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error( - ErrorInfo { - .hint = hintfmt("unknown hash type '%1%'", type), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("unknown hash type '%1%'", type), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; // discarded Path p = state.coerceToPath(pos, *args[1], context); @@ -1043,12 +1019,10 @@ static void prim_readDir(EvalState & state, const Pos & pos, Value * * args, Val try { state.realiseContext(ctx); } catch (InvalidPathError & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid", - path, e.path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("cannot read '%1%', since path '%2%' is not valid", path, e.path), + .nixCode = NixCode { .errPos = pos } + }); } DirEntries entries = readDirectory(state.checkSourcePath(path)); @@ -1118,15 +1092,13 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu for (auto path : context) { if (path.at(0) != '/') - throw EvalError( - ErrorInfo { - .hint = hintfmt( - "in 'toFile': the file named '%1%' must not contain a reference " - "to a derivation but contains (%2%)", - name, - path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError( { + .hint = hintfmt( + "in 'toFile': the file named '%1%' must not contain a reference " + "to a derivation but contains (%2%)", + name, path), + .nixCode = NixCode { .errPos = pos } + }); refs.insert(state.store->parseStorePath(path)); } @@ -1194,21 +1166,19 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args PathSet context; Path path = state.coerceToPath(pos, *args[1], context); if (!context.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("string '%1%' cannot refer to other paths", path), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("string '%1%' cannot refer to other paths", path), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*args[0], pos); if (args[0]->type != tLambda) - throw TypeError( - ErrorInfo { - .hint = hintfmt( - "first argument in call to 'filterSource' is not a function but %1%", - showType(*args[0])), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt( + "first argument in call to 'filterSource' is not a function but %1%", + showType(*args[0])), + .nixCode = NixCode { .errPos = pos } + }); addPath(state, pos, std::string(baseNameOf(path)), path, args[0], FileIngestionMethod::Recursive, Hash(), v); } @@ -1228,12 +1198,10 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value PathSet context; path = state.coerceToPath(*attr.pos, *attr.value, context); if (!context.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("string '%1%' cannot refer to other paths", - path), - .nixCode = NixCode { .errPos = *attr.pos } - }); + throw EvalError({ + .hint = hintfmt("string '%1%' cannot refer to other paths", path), + .nixCode = NixCode { .errPos = *attr.pos } + }); } else if (attr.name == state.sName) name = state.forceStringNoCtx(*attr.value, *attr.pos); else if (n == "filter") { @@ -1244,19 +1212,16 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value else if (n == "sha256") expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, *attr.pos), htSHA256); else - throw EvalError( - ErrorInfo { - .hint = hintfmt("unsupported argument '%1%' to 'addPath'", - attr.name), - .nixCode = NixCode { .errPos = *attr.pos } - }); + throw EvalError({ + .hint = hintfmt("unsupported argument '%1%' to 'addPath'", attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (path.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("'path' required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("'path' required"), + .nixCode = NixCode { .errPos = pos } + }); if (name.empty()) name = baseNameOf(path); @@ -1314,11 +1279,10 @@ void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v) // !!! Should we create a symbol here or just do a lookup? Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr)); if (i == args[1]->attrs->end()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("attribute '%1%' missing", attr), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("attribute '%1%' missing", attr), + .nixCode = NixCode { .errPos = pos } + }); // !!! add to stack trace? if (state.countCalls && i->pos) state.attrSelects[*i->pos]++; state.forceValue(*i->value, pos); @@ -1398,22 +1362,20 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args, Bindings::iterator j = v2.attrs->find(state.sName); if (j == v2.attrs->end()) - throw TypeError( - ErrorInfo { - .hint = hintfmt("'name' attribute missing in a call to 'listToAttrs'"), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt("'name' attribute missing in a call to 'listToAttrs'"), + .nixCode = NixCode { .errPos = pos } + }); string name = state.forceStringNoCtx(*j->value, pos); Symbol sym = state.symbols.create(name); if (seen.insert(sym).second) { Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue)); if (j2 == v2.attrs->end()) - throw TypeError( - ErrorInfo { - .hint = hintfmt("'value' attribute missing in a call to 'listToAttrs'"), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt("'value' attribute missing in a call to 'listToAttrs'"), + .nixCode = NixCode { .errPos = pos } + }); v.attrs->push_back(Attr(sym, j2->value, j2->pos)); } } @@ -1486,11 +1448,10 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args { state.forceValue(*args[0], pos); if (args[0]->type != tLambda) - throw TypeError( - ErrorInfo { - .hint = hintfmt("'functionArgs' requires a function"), - .nixCode = NixCode { .errPos = pos } - }); + throw TypeError({ + .hint = hintfmt("'functionArgs' requires a function"), + .nixCode = NixCode { .errPos = pos } + }); if (!args[0]->lambda.fun->matchAttrs) { state.mkAttrs(v, 0); @@ -1543,11 +1504,10 @@ static void elemAt(EvalState & state, const Pos & pos, Value & list, int n, Valu { state.forceList(list, pos); if (n < 0 || (unsigned int) n >= list.listSize()) - throw Error( - ErrorInfo { - .hint = hintfmt("list index %1% is out of bounds", n), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("list index %1% is out of bounds", n), + .nixCode = NixCode { .errPos = pos } + }); state.forceValue(*list.listElems()[n], pos); v = *list.listElems()[n]; } @@ -1574,11 +1534,10 @@ static void prim_tail(EvalState & state, const Pos & pos, Value * * args, Value { state.forceList(*args[0], pos); if (args[0]->listSize() == 0) - throw Error( - ErrorInfo { - .hint = hintfmt("'tail' called on an empty list"), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("'tail' called on an empty list"), + .nixCode = NixCode { .errPos = pos } + }); state.mkList(v, args[0]->listSize() - 1); for (unsigned int n = 0; n < v.listSize(); ++n) @@ -1720,12 +1679,10 @@ static void prim_genList(EvalState & state, const Pos & pos, Value * * args, Val auto len = state.forceInt(*args[1], pos); if (len < 0) - throw EvalError( - ErrorInfo { - .hint = hintfmt("cannot create list of size %1%", len), - .nixCode = NixCode { .errPos = pos } - }); - + throw EvalError({ + .hint = hintfmt("cannot create list of size %1%", len), + .nixCode = NixCode { .errPos = pos } + }); state.mkList(v, len); @@ -1883,12 +1840,11 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & state.forceValue(*args[1], pos); NixFloat f2 = state.forceFloat(*args[1], pos); - if (f2 == 0) - throw EvalError( - ErrorInfo { - .hint = hintfmt("division by zero"), - .nixCode = NixCode { .errPos = pos } - }); + if (f2 == 0) + throw EvalError({ + .hint = hintfmt("division by zero"), + .nixCode = NixCode { .errPos = pos } + }); if (args[0]->type == tFloat || args[1]->type == tFloat) { mkFloat(v, state.forceFloat(*args[0], pos) / state.forceFloat(*args[1], pos)); @@ -1897,11 +1853,10 @@ static void prim_div(EvalState & state, const Pos & pos, Value * * args, Value & NixInt i2 = state.forceInt(*args[1], pos); /* Avoid division overflow as it might raise SIGFPE. */ if (i1 == std::numeric_limits::min() && i2 == -1) - throw EvalError( - ErrorInfo { - .hint = hintfmt("overflow in integer division"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("overflow in integer division"), + .nixCode = NixCode { .errPos = pos } + }); mkInt(v, i1 / i2); } @@ -1958,12 +1913,11 @@ static void prim_substring(EvalState & state, const Pos & pos, Value * * args, V PathSet context; string s = state.coerceToString(pos, *args[2], context); - if (start < 0) - throw EvalError( - ErrorInfo { - .hint = hintfmt("negative start position in 'substring'"), - .nixCode = NixCode { .errPos = pos } - }); + if (start < 0) + throw EvalError({ + .hint = hintfmt("negative start position in 'substring'"), + .nixCode = NixCode { .errPos = pos } + }); mkString(v, (unsigned int) start >= s.size() ? "" : string(s, start, len), context); } @@ -1983,11 +1937,10 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args, string type = state.forceStringNoCtx(*args[0], pos); HashType ht = parseHashType(type); if (ht == htUnknown) - throw Error( - ErrorInfo { - .hint = hintfmt("unknown hash type '%1%'", type), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("unknown hash type '%1%'", type), + .nixCode = NixCode { .errPos = pos } + }); PathSet context; // discarded string s = state.forceString(*args[1], context, pos); @@ -2030,17 +1983,15 @@ void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v) } catch (std::regex_error &e) { if (e.code() == std::regex_constants::error_space) { // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ - throw EvalError( - ErrorInfo { - .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } else { - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } } } @@ -2105,17 +2056,15 @@ static void prim_split(EvalState & state, const Pos & pos, Value * * args, Value } catch (std::regex_error &e) { if (e.code() == std::regex_constants::error_space) { // limit is _GLIBCXX_REGEX_STATE_LIMIT for libstdc++ - throw EvalError( - ErrorInfo { - .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("memory limit exceeded by regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } else { - throw EvalError( - ErrorInfo { - .hint = hintfmt("invalid regular expression '%s'", re), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("invalid regular expression '%s'", re), + .nixCode = NixCode { .errPos = pos } + }); } } } @@ -2146,11 +2095,10 @@ static void prim_replaceStrings(EvalState & state, const Pos & pos, Value * * ar state.forceList(*args[0], pos); state.forceList(*args[1], pos); if (args[0]->listSize() != args[1]->listSize()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("'from' and 'to' arguments to 'replaceStrings' have different lengths"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("'from' and 'to' arguments to 'replaceStrings' have different lengths"), + .nixCode = NixCode { .errPos = pos } + }); vector from; from.reserve(args[0]->listSize()); diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 7f895fc01..efa2e9576 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -146,11 +146,10 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg auto sAllOutputs = state.symbols.create("allOutputs"); for (auto & i : *args[1]->attrs) { if (!state.store->isStorePath(i.name)) - throw EvalError( - ErrorInfo { - .hint = hintfmt("Context key '%s' is not a store path", i.name), - .nixCode = NixCode { .errPos = *i.pos } - }); + throw EvalError({ + .hint = hintfmt("Context key '%s' is not a store path", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); if (!settings.readOnlyMode) state.store->ensurePath(state.store->parseStorePath(i.name)); state.forceAttrs(*i.value, *i.pos); @@ -164,11 +163,10 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg if (iter != i.value->attrs->end()) { if (state.forceBool(*iter->value, *iter->pos)) { if (!isDerivation(i.name)) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", i.name), - .nixCode = NixCode { .errPos = *i.pos } - }); + throw EvalError({ + .hint = hintfmt("Tried to add all-outputs context of %s, which is not a derivation, to a string", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); } context.insert("=" + string(i.name)); } @@ -178,11 +176,10 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg if (iter != i.value->attrs->end()) { state.forceList(*iter->value, *iter->pos); if (iter->value->listSize() && !isDerivation(i.name)) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", i.name), - .nixCode = NixCode { .errPos = *i.pos } - }); + throw EvalError({ + .hint = hintfmt("Tried to add derivation output context of %s, which is not a derivation, to a string", i.name), + .nixCode = NixCode { .errPos = *i.pos } + }); } for (unsigned int n = 0; n < iter->value->listSize(); ++n) { auto name = state.forceStringNoCtx(*iter->value->listElems()[n], *iter->pos); diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 52826b56c..dd7229a3d 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -35,19 +35,17 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va else if (n == "submodules") fetchSubmodules = state.forceBool(*attr.value, *attr.pos); else - throw EvalError( - ErrorInfo { - .hint = hintfmt("unsupported argument '%s' to 'fetchGit'", attr.name), - .nixCode = NixCode { .errPos = *attr.pos } - }); + throw EvalError({ + .hint = hintfmt("unsupported argument '%s' to 'fetchGit'", attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (url.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("'url' argument required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index bb008ba6b..9bace8f89 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -38,19 +38,17 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError( - ErrorInfo { - .hint = hintfmt("unsupported argument '%s' to 'fetchMercurial'", attr.name), - .nixCode = NixCode { .errPos = *attr.pos } - }); + throw EvalError({ + .hint = hintfmt("unsupported argument '%s' to 'fetchMercurial'", attr.name), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (url.empty()) - throw EvalError( - ErrorInfo { - .hint = hintfmt("'url' argument required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.coerceToString(pos, *args[0], context, false, false); diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 62bc4f433..9be93710a 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -66,11 +66,10 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V } if (!attrs.count("type")) - throw Error( - ErrorInfo { - .hint = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), - .nixCode = NixCode { .errPos = pos } - }); + throw Error({ + .hint = hintfmt("attribute 'type' is missing in call to 'fetchTree'"), + .nixCode = NixCode { .errPos = pos } + }); input = fetchers::inputFromAttrs(attrs); } else @@ -111,20 +110,17 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, else if (n == "name") name = state.forceStringNoCtx(*attr.value, *attr.pos); else - throw EvalError( - ErrorInfo { - .hint = hintfmt("unsupported argument '%s' to '%s'", - attr.name, who), - .nixCode = NixCode { .errPos = *attr.pos } - }); + throw EvalError({ + .hint = hintfmt("unsupported argument '%s' to '%s'", attr.name, who), + .nixCode = NixCode { .errPos = *attr.pos } + }); } if (!url) - throw EvalError( - ErrorInfo { - .hint = hintfmt("'url' argument required"), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("'url' argument required"), + .nixCode = NixCode { .errPos = pos } + }); } else url = state.forceStringNoCtx(*args[0], pos); diff --git a/src/libexpr/primops/fromTOML.cc b/src/libexpr/primops/fromTOML.cc index 948069401..7615d1379 100644 --- a/src/libexpr/primops/fromTOML.cc +++ b/src/libexpr/primops/fromTOML.cc @@ -81,11 +81,10 @@ static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Va try { visit(v, parser(tomlStream).parse()); } catch (std::runtime_error & e) { - throw EvalError( - ErrorInfo { - .hint = hintfmt("while parsing a TOML string: %s", e.what()), - .nixCode = NixCode { .errPos = pos } - }); + throw EvalError({ + .hint = hintfmt("while parsing a TOML string: %s", e.what()), + .nixCode = NixCode { .errPos = pos } + }); } } diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index 6c493ed77..802fb87bc 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -22,10 +22,9 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, srcFiles = readDirectory(srcDir); } catch (SysError & e) { if (e.errNo == ENOTDIR) { - logWarning( - ErrorInfo { - .name = "Create links - directory", - .hint = hintfmt("not including '%s' in the user environment because it's not a directory", srcDir) + logWarning({ + .name = "Create links - directory", + .hint = hintfmt("not including '%s' in the user environment because it's not a directory", srcDir) }); return; } @@ -45,10 +44,9 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, throw SysError("getting status of '%1%'", srcFile); } catch (SysError & e) { if (e.errNo == ENOENT || e.errNo == ENOTDIR) { - logWarning( - ErrorInfo { - .name = "Create links - skipping symlink", - .hint = hintfmt("skipping dangling symlink '%s'", dstFile) + logWarning({ + .name = "Create links - skipping symlink", + .hint = hintfmt("skipping dangling symlink '%s'", dstFile) }); continue; } diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 92f9328c3..04e3849f7 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -129,12 +129,11 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, if (settings.checkRootReachability) { auto roots = findRoots(false); if (roots[storePath.clone()].count(gcRoot) == 0) - logWarning( - ErrorInfo { - .name = "GC root", - .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " - "therefore, '%2%' might be removed by the garbage collector", - gcRoot, printStorePath(storePath)) + logWarning({ + .name = "GC root", + .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " + "therefore, '%2%' might be removed by the garbage collector", + gcRoot, printStorePath(storePath)) }); } diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 16cdb6619..76c822c4e 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -204,10 +204,10 @@ void handleSQLiteBusy(const SQLiteBusy & e) if (now > lastWarned + 10) { lastWarned = now; - logWarning( - ErrorInfo { .name = "Sqlite busy", - .hint = hintfmt(e.what()) - }); + logWarning({ + .name = "Sqlite busy", + .hint = hintfmt(e.what()) + }); } /* Sleep for a while since retrying the transaction right away diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 8a48fa105..2ba3a3b33 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -22,7 +22,7 @@ namespace nix { -/* +/* This file defines two main structs/classes used in nix error handling. @@ -106,7 +106,7 @@ protected: mutable std::optional what_; const string& calcWhat() const; - + public: unsigned int status = 1; // exit status @@ -119,9 +119,9 @@ public: { } template - BaseError(const Args & ... args) + BaseError(const std::string & fs, const Args & ... args) : err { .level = lvlError, - .hint = hintfmt(args...) + .hint = hintfmt(fs, args...) } { } @@ -131,7 +131,11 @@ public: } { } - BaseError(ErrorInfo e) + BaseError(ErrorInfo && e) + : err(std::move(e)) + { } + + BaseError(const ErrorInfo & e) : err(e) { } diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 35f7ee917..c8b71188f 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -52,10 +52,10 @@ size_t threshold = 256 * 1024 * 1024; static void warnLargeDump() { - logWarning(ErrorInfo { + logWarning({ .name = "Large path", .description = "dumping very large path (> 256 MiB); this may run out of memory" - }); + }); } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 591fff999..da6f005a3 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -368,12 +368,11 @@ static void _main(int argc, char * * argv) shell = drv->queryOutPath() + "/bin/bash"; } catch (Error & e) { - logWarning( - ErrorInfo { - .name = "bashInteractive", - .hint = hintfmt("%s; will use bash from your environment", - (e.info().hint ? e.info().hint->str() : "")) - }); + logWarning({ + .name = "bashInteractive", + .hint = hintfmt("%s; will use bash from your environment", + (e.info().hint ? e.info().hint->str() : "")) + }); shell = "bash"; } } diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index fdf94e5a3..a880bdae0 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -68,10 +68,9 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand if (dryRun) { stopProgressBar(); - logWarning( - ErrorInfo { - .name = "Version update", - .hint = hintfmt("would upgrade to version %s", version) + logWarning({ + .name = "Version update", + .hint = hintfmt("would upgrade to version %s", version) }); return; } -- cgit v1.2.3 From e14e62fddde3b00ee82a8da29725f571ad8ecee1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 14:12:39 +0200 Subject: Remove trailing whitespace --- src/build-remote/build-remote.cc | 2 +- src/libexpr/attr-path.cc | 4 +-- src/libexpr/lexer.l | 1 - src/libexpr/nixexpr.cc | 2 +- src/libmain/progress-bar.cc | 2 +- src/libstore/daemon.cc | 2 +- src/libstore/filetransfer.cc | 4 +-- src/libstore/local-store.cc | 10 ++++---- src/libstore/optimise-store.cc | 6 ++--- src/libstore/store-api.cc | 2 +- src/libutil/error.cc | 2 +- src/libutil/logging.cc | 2 +- src/libutil/util.cc | 2 +- src/nix-daemon/nix-daemon.cc | 30 +++++++++++----------- src/nix-env/nix-env.cc | 8 +++--- src/nix-store/nix-store.cc | 4 +-- src/nix/verify.cc | 6 ++--- .../resolve-system-dependencies.cc | 8 +++--- 18 files changed, 48 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc index 49b35a4e9..e07117496 100644 --- a/src/build-remote/build-remote.cc +++ b/src/build-remote/build-remote.cc @@ -200,7 +200,7 @@ static int _main(int argc, char * * argv) } catch (std::exception & e) { auto msg = chomp(drainFD(5, false)); - logError({ + logError({ .name = "Remote build", .hint = hintfmt("cannot build on '%s': %s%s", bestMachine->storeUri, e.what(), diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index 9a9531a3f..8980bc09d 100644 --- a/src/libexpr/attr-path.cc +++ b/src/libexpr/attr-path.cc @@ -62,7 +62,7 @@ std::pair findAlongAttrPath(EvalState & state, const string & attr throw TypeError( "the expression selected by the selection path '%1%' should be a set but is %2%", attrPath, - showType(*v)); + showType(*v)); if (attr.empty()) throw Error("empty attribute name in selection path '%1%'", attrPath); @@ -79,7 +79,7 @@ std::pair findAlongAttrPath(EvalState & state, const string & attr throw TypeError( "the expression selected by the selection path '%1%' should be a list but is %2%", attrPath, - showType(*v)); + showType(*v)); if (attrIndex >= v->listSize()) throw AttrPathNotFound("list index %1% in selection path '%2%' is out of range", attrIndex, attrPath); diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 85376a08f..f6e83926b 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -219,4 +219,3 @@ or { return OR_KW; } } %% - diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 5b2dd9751..b4b65883d 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -267,7 +267,7 @@ void ExprVar::bindVars(const StaticEnv & env) /* Otherwise, the variable must be obtained from the nearest enclosing `with'. If there is no `with', then we can issue an "undefined variable" error now. */ - if (withLevel == -1) + if (withLevel == -1) throw UndefinedVarError({ .hint = hintfmt("undefined variable '%1%'", name), .nixCode = NixCode { .errPos = pos } diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index 20d9915a0..8d0421c2f 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -133,7 +133,7 @@ public: { auto state(state_.lock()); - std::stringstream oss; + std::stringstream oss; oss << ei; log(*state, ei.level, oss.str()); diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 172cfe3cb..620722516 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -77,7 +77,7 @@ struct TunnelLogger : public Logger { if (ei.level > verbosity) return; - std::stringstream oss; + std::stringstream oss; oss << ei; StringSink buf; diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 6ca3393ab..601cb858a 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -599,9 +599,9 @@ struct curlFileTransfer : public FileTransfer workerThreadMain(); } catch (nix::Interrupted & e) { } catch (std::exception & e) { - logError({ + logError({ .name = "File transfer", - .hint = hintfmt("unexpected error in download thread: %s", + .hint = hintfmt("unexpected error in download thread: %s", e.what()) }); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 5521b8633..f5c5bd9b7 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -87,7 +87,7 @@ LocalStore::LocalStore(const Params & params) struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); if (!gr) - logError({ + logError({ .name = "'build-users-group' not found", .hint = hintfmt( "warning: the group '%1%' specified in 'build-users-group' does not exist", @@ -1223,7 +1223,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) Path linkPath = linksDir + "/" + link.name; string hash = hashPath(htSHA256, linkPath).first.to_string(Base32, false); if (hash != link.name) { - logError({ + logError({ .name = "Invalid hash", .hint = hintfmt( "link '%s' was modified! expected hash '%s', got '%s'", @@ -1261,7 +1261,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) auto current = hashSink->finish(); if (info->narHash != nullHash && info->narHash != current.first) { - logError({ + logError({ .name = "Invalid hash - path modified", .hint = hintfmt("path '%s' was modified! expected hash '%s', got '%s'", printStorePath(i), info->narHash.to_string(Base32, true), current.first.to_string(Base32, true)) @@ -1316,7 +1316,7 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, if (!done.insert(pathS).second) return; if (!isStorePath(pathS)) { - logError({ + logError({ .name = "Nix path not found", .hint = hintfmt("path '%s' is not in the Nix store", pathS) }); @@ -1342,7 +1342,7 @@ void LocalStore::verifyPath(const Path & pathS, const StringSet & store, auto state(_state.lock()); invalidatePath(*state, path); } else { - logError({ + logError({ .name = "Missing path with referrers", .hint = hintfmt("path '%s' disappeared, but it still has valid referrers!", pathS) }); diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index d760d110c..b2b2412a3 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -130,7 +130,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, NixOS (example: $fontconfig/var/cache being modified). Skip those files. FIXME: check the modification time. */ if (S_ISREG(st.st_mode) && (st.st_mode & S_IWUSR)) { - logWarning({ + logWarning({ .name = "Suspicious file", .hint = hintfmt("skipping suspicious writable file '%1%'", path) }); @@ -197,7 +197,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, } if (st.st_size != stLink.st_size) { - logWarning({ + logWarning({ .name = "Corrupted link", .hint = hintfmt("removing corrupted link '%1%'", linkPath) }); @@ -235,7 +235,7 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, /* Atomically replace the old file with the new hard link. */ if (rename(tempLink.c_str(), path.c_str()) == -1) { if (unlink(tempLink.c_str()) == -1) - logError({ + logError({ .name = "Unlink error", .hint = hintfmt("unable to unlink '%1%'", tempLink) }); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 464261010..e23a9ca50 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -777,7 +777,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const auto warn = [&]() { logWarning( ErrorInfo{ - .name = "Path not content-addressed", + .name = "Path not content-addressed", .hint = hintfmt("path '%s' claims to be content-addressed but isn't", store.printStorePath(path)) }); }; diff --git a/src/libutil/error.cc b/src/libutil/error.cc index 1fcb8111c..cb5fe70bf 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -61,7 +61,7 @@ void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixC { // previous line of code. if (nixCode.prevLineOfCode.has_value()) { - out << std::endl + out << std::endl << fmt("%1% %|2$5d|| %3%", prefix, (nixCode.errPos.line - 1), diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 108dc3bd1..105fadb15 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -273,7 +273,7 @@ bool handleJSONLogMessage(const std::string & msg, } } catch (std::exception & e) { - logError({ + logError({ .name = "Json log message", .hint = hintfmt("bad log message from builder: %s", e.what()) }); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index a2281237b..667dd2edb 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -314,7 +314,7 @@ string readFile(const Path & path) void readFile(const Path & path, Sink & sink) { AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (!fd) + if (!fd) throw SysError("opening file '%s'", path); drainFD(fd.get(), sink); } diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 582c78d14..bcb86cbce 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -36,7 +36,7 @@ using namespace nix::daemon; #define SPLICE_F_MOVE 0 static ssize_t splice(int fd_in, void *off_in, int fd_out, void *off_out, size_t len, unsigned int flags) { - // We ignore most parameters, we just have them for conformance with the linux syscall + // We ignore most parameters, we just have them for conformance with the linux syscall std::vector buf(8192); auto read_count = read(fd_in, buf.data(), buf.size()); if (read_count == -1) @@ -57,7 +57,7 @@ static void sigChldHandler(int sigNo) { // Ensure we don't modify errno of whatever we've interrupted auto saved_errno = errno; - // Reap all dead children. + // Reap all dead children. while (waitpid(-1, 0, WNOHANG) > 0) ; errno = saved_errno; } @@ -106,7 +106,7 @@ struct PeerInfo }; -// Get the identity of the caller, if possible. +// Get the identity of the caller, if possible. static PeerInfo getPeerInfo(int remote) { PeerInfo peer = { false, 0, false, 0, false, 0 }; @@ -154,12 +154,12 @@ static void daemonLoop(char * * argv) if (chdir("/") == -1) throw SysError("cannot change current directory"); - // Get rid of children automatically; don't let them become zombies. + // Get rid of children automatically; don't let them become zombies. setSigChldAction(true); AutoCloseFD fdSocket; - // Handle socket-based activation by systemd. + // Handle socket-based activation by systemd. auto listenFds = getEnv("LISTEN_FDS"); if (listenFds) { if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1") @@ -168,17 +168,17 @@ static void daemonLoop(char * * argv) closeOnExec(fdSocket.get()); } - // Otherwise, create and bind to a Unix domain socket. + // Otherwise, create and bind to a Unix domain socket. else { createDirs(dirOf(settings.nixDaemonSocketFile)); fdSocket = createUnixDomainSocket(settings.nixDaemonSocketFile, 0666); } - // Loop accepting connections. + // Loop accepting connections. while (1) { try { - // Accept a connection. + // Accept a connection. struct sockaddr_un remoteAddr; socklen_t remoteAddrLen = sizeof(remoteAddr); @@ -214,7 +214,7 @@ static void daemonLoop(char * * argv) % (peer.pidKnown ? std::to_string(peer.pid) : "") % (peer.uidKnown ? user : "")); - // Fork a child to handle the connection. + // Fork a child to handle the connection. ProcessOptions options; options.errorPrefix = "unexpected Nix daemon error: "; options.dieWithParent = false; @@ -223,20 +223,20 @@ static void daemonLoop(char * * argv) startProcess([&]() { fdSocket = -1; - // Background the daemon. + // Background the daemon. if (setsid() == -1) throw SysError("creating a new session"); - // Restore normal handling of SIGCHLD. + // Restore normal handling of SIGCHLD. setSigChldAction(false); - // For debugging, stuff the pid into argv[1]. + // For debugging, stuff the pid into argv[1]. if (peer.pidKnown && argv[1]) { string processName = std::to_string(peer.pid); strncpy(argv[1], processName.c_str(), strlen(argv[1])); } - // Handle the connection. + // Handle the connection. FdSource from(remote.get()); FdSink to(remote.get()); processConnection(openUncachedStore(), from, to, trusted, NotRecursive, user, peer.uid); @@ -263,7 +263,7 @@ static int _main(int argc, char * * argv) parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { if (*arg == "--daemon") - ; // ignored for backwards compatibility + ; // ignored for backwards compatibility else if (*arg == "--help") showManPage("nix-daemon"); else if (*arg == "--version") @@ -278,7 +278,7 @@ static int _main(int argc, char * * argv) if (stdio) { if (getStoreType() == tDaemon) { - // Forward on this connection to the real daemon + // Forward on this connection to the real daemon auto socketPath = settings.nixDaemonSocketFile; auto s = socket(PF_UNIX, SOCK_STREAM, 0); if (s == -1) diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 7ab5ba500..2c27d97f5 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -123,7 +123,7 @@ static void getAllExprs(EvalState & state, if (hasSuffix(attrName, ".nix")) attrName = string(attrName, 0, attrName.size() - 4); if (!attrs.insert(attrName).second) { - logError({ + logError({ .name = "Name collision", .hint = hintfmt("warning: name collision in input Nix expressions, skipping '%1%'", path2) }); @@ -874,7 +874,7 @@ static void queryJSON(Globals & globals, vector & elems) auto placeholder = metaObj.placeholder(j); Value * v = i.queryMeta(j); if (!v) { - logError({ + logError({ .name = "Invalid meta attribute", .hint = hintfmt("derivation '%s' has invalid meta attribute '%s'", i.queryName(), j) @@ -1128,8 +1128,8 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) XMLAttrs attrs2; attrs2["name"] = j; Value * v = i.queryMeta(j); - if (!v) - logError({ + if (!v) + logError({ .name = "Invalid meta attribute", .hint = hintfmt( "derivation '%s' has invalid meta attribute '%s'", diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index dea53b52f..6d2139526 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -704,7 +704,7 @@ static void opVerify(Strings opFlags, Strings opArgs) else throw UsageError("unknown flag '%1%'", i); if (store->verifyStore(checkContents, repair)) { - logWarning({ + logWarning({ .name = "Store consistency", .description = "not all errors were fixed" }); @@ -729,7 +729,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) store->narFromPath(path, sink); auto current = sink.finish(); if (current.first != info->narHash) { - logError({ + logError({ .name = "Hash mismatch", .hint = hintfmt( "path '%s' was modified! expected hash '%s', got '%s'", diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 246b4b480..001401ac2 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -99,12 +99,12 @@ struct CmdVerify : StorePathsCommand if (hash.first != info->narHash) { corrupted++; act2.result(resCorruptedPath, store->printStorePath(info->path)); - logError({ + logError({ .name = "Hash error - path modified", .hint = hintfmt( "path '%s' was modified! expected hash '%s', got '%s'", store->printStorePath(info->path), - info->narHash.to_string(Base32, true), + info->narHash.to_string(Base32, true), hash.first.to_string(Base32, true)) }); } @@ -154,7 +154,7 @@ struct CmdVerify : StorePathsCommand if (!good) { untrusted++; act2.result(resUntrustedPath, store->printStorePath(info->path)); - logError({ + logError({ .name = "Untrusted path", .hint = hintfmt("path '%s' is untrusted", store->printStorePath(info->path)) diff --git a/src/resolve-system-dependencies/resolve-system-dependencies.cc b/src/resolve-system-dependencies/resolve-system-dependencies.cc index 82feacb3d..434ad80a6 100644 --- a/src/resolve-system-dependencies/resolve-system-dependencies.cc +++ b/src/resolve-system-dependencies/resolve-system-dependencies.cc @@ -39,7 +39,7 @@ std::set runResolver(const Path & filename) throw SysError("statting '%s'", filename); if (!S_ISREG(st.st_mode)) { - logError({ + logError({ .name = "Regular MACH file", .hint = hintfmt("file '%s' is not a regular file", filename) }); @@ -47,7 +47,7 @@ std::set runResolver(const Path & filename) } if (st.st_size < sizeof(mach_header_64)) { - logError({ + logError({ .name = "File too short", .hint = hintfmt("file '%s' is too short for a MACH binary", filename) }); @@ -72,7 +72,7 @@ std::set runResolver(const Path & filename) } } if (mach64_offset == 0) { - logError({ + logError({ .name = "No mach64 blobs", .hint = hintfmt("Could not find any mach64 blobs in file '%1%', continuing...", filename) }); @@ -81,7 +81,7 @@ std::set runResolver(const Path & filename) } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) { mach64_offset = 0; } else { - logError({ + logError({ .name = "Magic number", .hint = hintfmt("Object file has unknown magic number '%1%', skipping it...", magic) }); -- cgit v1.2.3 From 5ed5d7acbd00298df7b4e3a638d731143084da2e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 16:03:29 +0200 Subject: Improve "waiting for locks" messages These are now shown in the progress bar. Closes #3577. --- src/libmain/progress-bar.cc | 2 +- src/libstore/build.cc | 22 +++++++++++++++++++--- src/libutil/logging.hh | 1 + 3 files changed, 21 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index 8d0421c2f..6dfc3a4d3 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -156,7 +156,7 @@ public: { auto state(state_.lock()); - if (lvl <= verbosity && !s.empty()) + if (lvl <= verbosity && !s.empty() && type != actBuildWaiting) log(*state, lvl, s + "..."); state->activities.emplace_back(ActInfo()); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index de393e837..2eb78591b 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -869,6 +869,9 @@ private: std::unique_ptr act; + /* Activity that denotes waiting for a lock. */ + std::unique_ptr actLock; + std::map builderActivities; /* The remote machine on which we're building. */ @@ -1439,10 +1442,15 @@ void DerivationGoal::tryToBuild() lockFiles.insert(worker.store.Store::toRealPath(outPath)); if (!outputLocks.lockPaths(lockFiles, "", false)) { + if (!actLock) + actLock = std::make_unique(*logger, lvlWarn, actBuildWaiting, + fmt("waiting for lock on %s", yellowtxt(showPaths(lockFiles)))); worker.waitForAWhile(shared_from_this()); return; } + actLock.reset(); + /* Now check again whether the outputs are valid. This is because another process may have started building in parallel. After it has finished and released the locks, we can (and should) @@ -1481,6 +1489,7 @@ void DerivationGoal::tryToBuild() case rpAccept: /* Yes, it has started doing so. Wait until we get EOF from the hook. */ + actLock.reset(); result.startTime = time(0); // inexact state = &DerivationGoal::buildDone; started(); @@ -1488,6 +1497,9 @@ void DerivationGoal::tryToBuild() case rpPostpone: /* Not now; wait until at least one child finishes or the wake-up timeout expires. */ + if (!actLock) + actLock = std::make_unique(*logger, lvlWarn, actBuildWaiting, + fmt("waiting for a machine to build '%s'", yellowtxt(worker.store.printStorePath(drvPath)))); worker.waitForAWhile(shared_from_this()); outputLocks.unlock(); return; @@ -1497,6 +1509,8 @@ void DerivationGoal::tryToBuild() } } + actLock.reset(); + /* Make sure that we are allowed to start a build. If this derivation prefers to be done locally, do it even if maxBuildJobs is 0. */ @@ -1524,7 +1538,9 @@ void DerivationGoal::tryLocalBuild() { uid. */ buildUser->kill(); } else { - debug("waiting for build users"); + if (!actLock) + actLock = std::make_unique(*logger, lvlWarn, actBuildWaiting, + fmt("waiting for UID to build '%s'", yellowtxt(worker.store.printStorePath(drvPath)))); worker.waitForAWhile(shared_from_this()); return; } @@ -1535,6 +1551,8 @@ void DerivationGoal::tryLocalBuild() { #endif } + actLock.reset(); + try { /* Okay, we have to build. */ @@ -4863,8 +4881,6 @@ void Worker::waitForInput() up after a few seconds at most. */ if (!waitingForAWhile.empty()) { useTimeout = true; - if (lastWokenUp == steady_time_point::min()) - printInfo("waiting for locks, build slots or build users..."); if (lastWokenUp == steady_time_point::min() || lastWokenUp > before) lastWokenUp = before; timeout = std::max(1L, (long) std::chrono::duration_cast( diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index b99b246c3..b1583eced 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -18,6 +18,7 @@ typedef enum { actSubstitute = 108, actQueryPathInfo = 109, actPostBuildHook = 110, + actBuildWaiting = 111, } ActivityType; typedef enum { -- cgit v1.2.3 From ccfa6b3eee9f5e613152a4b373f67ff05696adf8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 16:12:27 +0200 Subject: Give better error message about <...> in pure eval mode --- src/libexpr/parser.y | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index a1188dec0..a639be64e 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -689,7 +689,10 @@ Path EvalState::findFile(SearchPath & searchPath, const string & path, const Pos if (pathExists(res)) return canonPath(res); } throw ThrownError({ - .hint = hintfmt("file '%1%' was not found in the Nix search path (add it using $NIX_PATH or -I)", path), + .hint = hintfmt(evalSettings.pureEval + ? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)" + : "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)", + path), .nixCode = NixCode { .errPos = pos } }); } -- cgit v1.2.3 From 31707735b699db6dfd78e8bb8e655c3d5e6e0ba5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 16:47:21 +0200 Subject: Remove unnecessary amDone() overrides --- src/libstore/build.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 2eb78591b..2a34cfbb7 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -187,7 +187,7 @@ public: protected: - virtual void amDone(ExitCode result); + void amDone(ExitCode result); }; @@ -1009,11 +1009,6 @@ private: void repairClosure(); - void amDone(ExitCode result) override - { - Goal::amDone(result); - } - void started(); void done(BuildResult::Status status, const string & msg = ""); @@ -4335,11 +4330,6 @@ public: void handleEOF(int fd) override; StorePath getStorePath() { return storePath.clone(); } - - void amDone(ExitCode result) override - { - Goal::amDone(result); - } }; -- cgit v1.2.3 From 4e995bc8a66e5486be83c935bd939726ac39cab3 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 18:01:05 +0200 Subject: Always hide the progress bar on exit --- src/libmain/progress-bar.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/libmain/progress-bar.cc b/src/libmain/progress-bar.cc index 6dfc3a4d3..95a9187de 100644 --- a/src/libmain/progress-bar.cc +++ b/src/libmain/progress-bar.cc @@ -111,10 +111,7 @@ public: auto state(state_.lock()); if (!state->active) return; state->active = false; - std::string status = getStatus(*state); writeToStderr("\r\e[K"); - if (status != "") - writeToStderr("[" + status + "]\n"); updateCV.notify_one(); quitCV.notify_one(); } -- cgit v1.2.3 From f20bb983cab168bd9fe4f4ad560a64aeb4b19f07 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 18:16:03 +0200 Subject: Cleanup --- src/libutil/error.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index cb5fe70bf..da11d1ffd 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -105,7 +105,7 @@ void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixC std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) { - int errwidth = 80; + size_t errwidth = 80; string prefix = ""; string levelString; @@ -158,12 +158,10 @@ std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) } } - int ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); - int dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; + auto ndl = prefix.length() + levelString.length() + 3 + einfo.name.length() + einfo.programName.value_or("").length(); + auto dashwidth = ndl > (errwidth - 3) ? 3 : errwidth - ndl; - string dashes; - for (int i = 0; i < dashwidth; ++i) - dashes.append("-"); + std::string dashes(dashwidth, '-'); // divider. if (einfo.name != "") -- cgit v1.2.3 From 8b099812eab7ccad9ebc6906450b637044de9369 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 18:18:02 +0200 Subject: Respect terminal width printing error messages --- src/libutil/error.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libutil/error.cc b/src/libutil/error.cc index da11d1ffd..0fad9ae42 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -105,7 +105,7 @@ void printCodeLines(std::ostream &out, const string &prefix, const NixCode &nixC std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) { - size_t errwidth = 80; + auto errwidth = std::max(getWindowSize().second, 20); string prefix = ""; string levelString; -- cgit v1.2.3 From 24a3208247c248956c5815554804da1bf9763ece Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 18:20:05 +0200 Subject: Include only the base name of the program in error messages --- src/libmain/shared.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 0f2c189a6..dc6d5e413 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -290,7 +290,7 @@ int handleExceptions(const string & programName, std::function fun) { ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this - ErrorInfo::programName = programName; + ErrorInfo::programName = baseNameOf(programName); string error = ANSI_RED "error:" ANSI_NORMAL " "; try { -- cgit v1.2.3 From a588b6b19d93fe80deb8518562b7a483fd4c50bc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 15 Jun 2020 19:25:35 +0200 Subject: Print only one error message if a build fails E.g. instead of error: --- BuildError ----------------------------------------------- nix builder for '/nix/store/03nk0a3n8h2948k4lqfgnnmym7knkcma-foo.drv' failed with exit code 1 error: --- Error ---------------------------------------------------- nix build of '/nix/store/03nk0a3n8h2948k4lqfgnnmym7knkcma-foo.drv' failed we now get error: --- Error ---------------------------------------------------- nix builder for '/nix/store/03nk0a3n8h2948k4lqfgnnmym7knkcma-foo.drv' failed with exit code 1 --- src/libstore/build.cc | 138 ++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 2a34cfbb7..8ad2ca4f3 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -104,13 +104,10 @@ typedef std::map WeakGoalMap; -class Goal : public std::enable_shared_from_this +struct Goal : public std::enable_shared_from_this { -public: typedef enum {ecBusy, ecSuccess, ecFailed, ecNoSubstituters, ecIncompleteClosure} ExitCode; -protected: - /* Backlink to the worker. */ Worker & worker; @@ -138,6 +135,9 @@ protected: /* Whether the goal is finished. */ ExitCode exitCode; + /* Exception containing an error message, if any. */ + std::optional ex; + Goal(Worker & worker) : worker(worker) { nrFailed = nrNoSubstituters = nrIncompleteClosure = 0; @@ -149,7 +149,6 @@ protected: trace("goal destroyed"); } -public: virtual void work() = 0; void addWaitee(GoalPtr waitee); @@ -173,21 +172,14 @@ public: return name; } - ExitCode getExitCode() - { - return exitCode; - } - /* Callback in case of a timeout. It should wake up its waiters, get rid of any running child processes that are being monitored by the worker (important!), etc. */ - virtual void timedOut() = 0; + virtual void timedOut(Error && ex) = 0; virtual string key() = 0; -protected: - - void amDone(ExitCode result); + void amDone(ExitCode result, std::optional ex = {}); }; @@ -392,8 +384,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result) assert(waitees.find(waitee) != waitees.end()); waitees.erase(waitee); - trace(format("waitee '%1%' done; %2% left") % - waitee->name % waitees.size()); + trace(fmt("waitee '%s' done; %d left", waitee->name, waitees.size())); if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed; @@ -418,12 +409,20 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result) } -void Goal::amDone(ExitCode result) +void Goal::amDone(ExitCode result, std::optional ex) { trace("done"); assert(exitCode == ecBusy); assert(result == ecSuccess || result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure); exitCode = result; + + if (ex) { + if (!waiters.empty()) + logError(ex->info()); + else + this->ex = std::move(*ex); + } + for (auto & i : waiters) { GoalPtr goal = i.lock(); if (goal) goal->waiteeDone(shared_from_this(), result); @@ -910,7 +909,7 @@ public: /* Whether we need to perform hash rewriting if there are valid output paths. */ bool needsHashRewrite(); - void timedOut() override; + void timedOut(Error && ex) override; string key() override { @@ -1011,7 +1010,9 @@ private: void started(); - void done(BuildResult::Status status, const string & msg = ""); + void done( + BuildResult::Status status, + std::optional ex = {}); StorePathSet exportReferences(const StorePathSet & storePaths); }; @@ -1105,10 +1106,10 @@ void DerivationGoal::killChild() } -void DerivationGoal::timedOut() +void DerivationGoal::timedOut(Error && ex) { killChild(); - done(BuildResult::TimedOut); + done(BuildResult::TimedOut, ex); } @@ -1156,11 +1157,7 @@ void DerivationGoal::loadDerivation() trace("loading derivation"); if (nrFailed != 0) { - logError({ - .name = "missing derivation during build", - .hint = hintfmt("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath)) - }); - done(BuildResult::MiscFailure); + done(BuildResult::MiscFailure, Error("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath))); return; } @@ -1349,13 +1346,9 @@ void DerivationGoal::inputsRealised() if (nrFailed != 0) { if (!useDerivation) throw Error("some dependencies of '%s' are missing", worker.store.printStorePath(drvPath)); - logError({ - .name = "Dependencies could not be built", - .hint = hintfmt( - "cannot build derivation '%s': %s dependencies couldn't be built", - worker.store.printStorePath(drvPath), nrFailed) - }); - done(BuildResult::DependencyFailed); + done(BuildResult::DependencyFailed, Error( + "%s dependencies of derivation '%s' failed to build", + nrFailed, worker.store.printStorePath(drvPath))); return; } @@ -1554,11 +1547,10 @@ void DerivationGoal::tryLocalBuild() { startBuilder(); } catch (BuildError & e) { - logError(e.info()); outputLocks.unlock(); buildUser.reset(); worker.permanentFailure = true; - done(BuildResult::InputRejected, e.msg()); + done(BuildResult::InputRejected, e); return; } @@ -1670,7 +1662,7 @@ void DerivationGoal::buildDone() } auto msg = fmt("builder for '%s' %s", - worker.store.printStorePath(drvPath), + yellowtxt(worker.store.printStorePath(drvPath)), statusToString(status)); if (!logger->isVerbose() && !logTail.empty()) { @@ -1771,8 +1763,6 @@ void DerivationGoal::buildDone() outputLocks.unlock(); } catch (BuildError & e) { - logError(e.info()); - outputLocks.unlock(); BuildResult::Status st = BuildResult::MiscFailure; @@ -1791,7 +1781,7 @@ void DerivationGoal::buildDone() BuildResult::PermanentFailure; } - done(st, e.msg()); + done(st, e); return; } @@ -3881,7 +3871,6 @@ void DerivationGoal::registerOutputs() .hint = hint }); - curRound = nrRounds; // we know enough, bail out early } } @@ -4145,14 +4134,11 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) { logSize += data.size(); if (settings.maxLogSize && logSize > settings.maxLogSize) { - logError({ - .name = "Max log size exceeded", - .hint = hintfmt( - "%1% killed after writing more than %2% bytes of log output", - getName(), settings.maxLogSize) - }); killChild(); - done(BuildResult::LogLimitExceeded); + done( + BuildResult::LogLimitExceeded, + Error("%s killed after writing more than %d bytes of log output", + getName(), settings.maxLogSize)); return; } @@ -4233,11 +4219,12 @@ void DerivationGoal::addHashRewrite(const StorePath & path) } -void DerivationGoal::done(BuildResult::Status status, const string & msg) +void DerivationGoal::done(BuildResult::Status status, std::optional ex) { result.status = status; - result.errorMsg = msg; - amDone(result.success() ? ecSuccess : ecFailed); + if (ex) + result.errorMsg = ex->what(); + amDone(result.success() ? ecSuccess : ecFailed, ex); if (result.status == BuildResult::TimedOut) worker.timedOut = true; if (result.status == BuildResult::PermanentFailure) @@ -4306,7 +4293,7 @@ public: SubstitutionGoal(StorePath && storePath, Worker & worker, RepairFlag repair = NoRepair); ~SubstitutionGoal(); - void timedOut() override { abort(); }; + void timedOut(Error && ex) override { abort(); }; string key() override { @@ -4693,7 +4680,7 @@ void Worker::removeGoal(GoalPtr goal) topGoals.erase(goal); /* If a top-level goal failed, then kill all other goals (unless keepGoing was set). */ - if (goal->getExitCode() == Goal::ecFailed && !settings.keepGoing) + if (goal->exitCode == Goal::ecFailed && !settings.keepGoing) topGoals.clear(); } @@ -4935,32 +4922,24 @@ void Worker::waitForInput() } } - if (goal->getExitCode() == Goal::ecBusy && + if (goal->exitCode == Goal::ecBusy && 0 != settings.maxSilentTime && j->respectTimeouts && after - j->lastOutput >= std::chrono::seconds(settings.maxSilentTime)) { - logError({ - .name = "Silent build timeout", - .hint = hintfmt( + goal->timedOut(Error( "%1% timed out after %2% seconds of silence", - goal->getName(), settings.maxSilentTime) - }); - goal->timedOut(); + goal->getName(), settings.maxSilentTime)); } - else if (goal->getExitCode() == Goal::ecBusy && + else if (goal->exitCode == Goal::ecBusy && 0 != settings.buildTimeout && j->respectTimeouts && after - j->timeStarted >= std::chrono::seconds(settings.buildTimeout)) { - logError({ - .name = "Build timeout", - .hint = hintfmt( + goal->timedOut(Error( "%1% timed out after %2% seconds", - goal->getName(), settings.buildTimeout) - }); - goal->timedOut(); + goal->getName(), settings.buildTimeout)); } } @@ -5066,16 +5045,28 @@ void LocalStore::buildPaths(const std::vector & drvPaths, worker.run(goals); StorePathSet failed; + std::optional ex; for (auto & i : goals) { - if (i->getExitCode() != Goal::ecSuccess) { + if (i->ex) { + if (ex) + logError(i->ex->info()); + else + ex = i->ex; + } + if (i->exitCode != Goal::ecSuccess) { DerivationGoal * i2 = dynamic_cast(i.get()); if (i2) failed.insert(i2->getDrvPath()); else failed.insert(dynamic_cast(i.get())->getStorePath()); } } - if (!failed.empty()) + if (failed.size() == 1 && ex) { + ex->status = worker.exitStatus(); + throw *ex; + } else if (!failed.empty()) { + if (ex) logError(ex->info()); throw Error(worker.exitStatus(), "build of %s failed", showPaths(failed)); + } } BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDerivation & drv, @@ -5111,8 +5102,13 @@ void LocalStore::ensurePath(const StorePath & path) worker.run(goals); - if (goal->getExitCode() != Goal::ecSuccess) - throw Error(worker.exitStatus(), "path '%s' does not exist and cannot be created", printStorePath(path)); + if (goal->exitCode != Goal::ecSuccess) { + if (goal->ex) { + goal->ex->status = worker.exitStatus(); + throw *goal->ex; + } else + throw Error(worker.exitStatus(), "path '%s' does not exist and cannot be created", printStorePath(path)); + } } @@ -5124,7 +5120,7 @@ void LocalStore::repairPath(const StorePath & path) worker.run(goals); - if (goal->getExitCode() != Goal::ecSuccess) { + if (goal->exitCode != Goal::ecSuccess) { /* Since substituting the path didn't work, if we have a valid deriver, then rebuild the deriver. */ auto info = queryPathInfo(path); -- cgit v1.2.3 From 7e7e3b71f33bfe4899d2cf735bf5e7a25bab11fd Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 15 Jun 2020 23:35:07 +0000 Subject: Add mising #include for strerror --- src/libutil/error.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 2ba3a3b33..1e6102ce1 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -4,6 +4,7 @@ #include "ref.hh" #include "types.hh" +#include #include #include #include -- cgit v1.2.3 From cd8214c39870cc37d10c439978c8cffc69db41e0 Mon Sep 17 00:00:00 2001 From: Tobias Pflug Date: Tue, 16 Jun 2020 09:44:19 +0200 Subject: Fix logging unit tests --- src/libutil/tests/logging.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/libutil/tests/logging.cc b/src/libutil/tests/logging.cc index fbdc91253..4cb54995b 100644 --- a/src/libutil/tests/logging.cc +++ b/src/libutil/tests/logging.cc @@ -22,7 +22,7 @@ namespace nix { logger->logEI(e.info()); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\nan error for testing purposes\n"); + ASSERT_STREQ(str.c_str(),"\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError --- error-unit-test\x1B[0m\nan error for testing purposes\n"); } } @@ -42,7 +42,7 @@ namespace nix { logger->logEI(ei); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError ------------------------------------ error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0minitial error\x1B[0m; subsequent error message.\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- TestError --- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0minitial error\x1B[0m; subsequent error message.\n"); } } @@ -60,7 +60,7 @@ namespace nix { logError(e.info()); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError ------------------------------------- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0mstatting file\x1B[0m: \x1B[33;1mBad file descriptor\x1B[0m\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- SysError --- error-unit-test\x1B[0m\n\x1B[33;1m\x1B[0mstatting file\x1B[0m: \x1B[33;1mBad file descriptor\x1B[0m\n"); } } @@ -74,7 +74,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name ------------------------------------- error-unit-test\x1B[0m\nInfo description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[32;1minfo:\x1B[0m\x1B[34;1m --- Info name --- error-unit-test\x1B[0m\nInfo description\n"); } TEST(logEI, loggingErrorOnTalkativeLevel) { @@ -88,7 +88,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[32;1mtalk:\x1B[0m\x1B[34;1m --- Talkative name -------------------------------- error-unit-test\x1B[0m\nTalkative description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mtalk:\x1B[0m\x1B[34;1m --- Talkative name --- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnChattyLevel) { @@ -102,7 +102,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[32;1mchat:\x1B[0m\x1B[34;1m --- Chatty name ----------------------------------- error-unit-test\x1B[0m\nTalkative description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mchat:\x1B[0m\x1B[34;1m --- Chatty name --- error-unit-test\x1B[0m\nTalkative description\n"); } TEST(logEI, loggingErrorOnDebugLevel) { @@ -116,7 +116,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[33;1mdebug:\x1B[0m\x1B[34;1m --- Debug name ----------------------------------- error-unit-test\x1B[0m\nDebug description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mdebug:\x1B[0m\x1B[34;1m --- Debug name --- error-unit-test\x1B[0m\nDebug description\n"); } TEST(logEI, loggingErrorOnVomitLevel) { @@ -130,7 +130,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[32;1mvomit:\x1B[0m\x1B[34;1m --- Vomit name ----------------------------------- error-unit-test\x1B[0m\nVomit description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[32;1mvomit:\x1B[0m\x1B[34;1m --- Vomit name --- error-unit-test\x1B[0m\nVomit description\n"); } /* ---------------------------------------------------------------------------- @@ -147,7 +147,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name ----------------------------------------- error-unit-test\x1B[0m\nerror description\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- name --- error-unit-test\x1B[0m\nerror description\n"); } TEST(logError, logErrorWithPreviousAndNextLinesOfCode) { @@ -171,7 +171,7 @@ namespace nix { auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror with code lines\n\n 39| previous line of code\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 41| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror with code lines\n\n 39| previous line of code\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n 41| next line of code\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); } TEST(logError, logErrorWithoutLinesOfCode) { @@ -190,7 +190,7 @@ namespace nix { }}); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nerror without any code lines.\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); } TEST(logError, logErrorWithOnlyHintAndName) { @@ -206,7 +206,7 @@ namespace nix { }}); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name ----------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nhint \x1B[33;1monly\x1B[0m\n"); + ASSERT_STREQ(str.c_str(), "\x1B[31;1merror:\x1B[0m\x1B[34;1m --- error name --- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nhint \x1B[33;1monly\x1B[0m\n"); } @@ -224,7 +224,7 @@ namespace nix { }); auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --------------------------------------- error-unit-test\x1B[0m\nerror description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n"); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- name --- error-unit-test\x1B[0m\nerror description\n\nthere was a \x1B[33;1mwarning\x1B[0m\n"); } TEST(logWarning, logWarningWithFileLineNumAndCode) { @@ -249,7 +249,7 @@ namespace nix { auto str = testing::internal::GetCapturedStderr(); - ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name ------------------------------- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nwarning description\n\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); + ASSERT_STREQ(str.c_str(), "\x1B[33;1mwarning:\x1B[0m\x1B[34;1m --- warning name --- error-unit-test\x1B[0m\nin file: \x1B[34;1mmyfile.nix (40:13)\x1B[0m\n\nwarning description\n\n 40| this is the problem line of code\n | \x1B[31;1m^\x1B[0m\n\nthis hint has \x1B[33;1myellow\x1B[0m templated \x1B[33;1mvalues\x1B[0m!!\n"); } } -- cgit v1.2.3 From 72e17290d457a8e911f126d21b74c315b034189d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Jun 2020 11:51:34 +0200 Subject: Fix FTP support Fixes #3618. --- src/libstore/filetransfer.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 601cb858a..c954ace7f 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -72,6 +72,17 @@ struct curlFileTransfer : public FileTransfer curl_off_t writtenToSink = 0; + /* Get the HTTP status code, or 0 for other protocols. */ + long getHTTPStatus() + { + long httpStatus = 0; + long protocol = 0; + curl_easy_getinfo(req, CURLINFO_PROTOCOL, &protocol); + if (protocol == CURLPROTO_HTTP || protocol == CURLPROTO_HTTPS) + curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &httpStatus); + return httpStatus; + } + TransferItem(curlFileTransfer & fileTransfer, const FileTransferRequest & request, Callback && callback) @@ -83,8 +94,7 @@ struct curlFileTransfer : public FileTransfer , callback(std::move(callback)) , finalSink([this](const unsigned char * data, size_t len) { if (this->request.dataCallback) { - long httpStatus = 0; - curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &httpStatus); + auto httpStatus = getHTTPStatus(); /* Only write data to the sink if this is a successful response. */ @@ -316,8 +326,7 @@ struct curlFileTransfer : public FileTransfer void finish(CURLcode code) { - long httpStatus = 0; - curl_easy_getinfo(req, CURLINFO_RESPONSE_CODE, &httpStatus); + auto httpStatus = getHTTPStatus(); char * effectiveUriCStr; curl_easy_getinfo(req, CURLINFO_EFFECTIVE_URL, &effectiveUriCStr); @@ -344,7 +353,7 @@ struct curlFileTransfer : public FileTransfer failEx(writeException); else if (code == CURLE_OK && - (httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 206 || httpStatus == 304 || httpStatus == 226 /* FTP */ || httpStatus == 0 /* other protocol */)) + (httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 206 || httpStatus == 304 || httpStatus == 0 /* other protocol */)) { result.cached = httpStatus == 304; act.progress(result.bodySize, result.bodySize); -- cgit v1.2.3 From 759947bf72c134592f0ce23d385e48095bd0a301 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Jun 2020 14:16:39 +0200 Subject: StorePath: Rewrite in C++ On nix-env -qa -f '', this reduces maximum RSS by 20970 KiB and runtime by 0.8%. This is mostly because we're not parsing the hash part as a hash anymore (just validating that it consists of base-32 characters). Also, replace storePathToHash() by StorePath::hashPart(). --- src/libexpr/local.mk | 2 +- src/libfetchers/local.mk | 2 +- src/libstore/binary-cache-store.cc | 6 +-- src/libstore/local-store.cc | 10 ++--- src/libstore/local.mk | 2 +- src/libstore/nar-info-disk-cache.cc | 6 +-- src/libstore/nar-info.cc | 4 +- src/libstore/path.cc | 66 ++++++++++++++---------------- src/libstore/path.hh | 70 ++++++++++++++++++++------------ src/libstore/remote-fs-accessor.cc | 2 +- src/libstore/store-api.cc | 14 ++----- src/libstore/store-api.hh | 4 -- src/libutil/local.mk | 2 - src/libutil/rust-ffi.cc | 2 + src/libutil/rust-ffi.hh | 2 + src/nix/local.mk | 2 +- src/nix/make-content-addressable.cc | 4 +- src/nix/verify.cc | 2 +- src/nix/why-depends.cc | 10 ++--- src/resolve-system-dependencies/local.mk | 2 +- 20 files changed, 107 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk index 917e8a1c7..9ed39e745 100644 --- a/src/libexpr/local.mk +++ b/src/libexpr/local.mk @@ -8,7 +8,7 @@ libexpr_SOURCES := $(wildcard $(d)/*.cc) $(wildcard $(d)/primops/*.cc) $(d)/lexe libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libmain -I src/libexpr -libexpr_LIBS = libutil libstore libfetchers libnixrust +libexpr_LIBS = libutil libstore libfetchers libexpr_LDFLAGS = ifneq ($(OS), FreeBSD) diff --git a/src/libfetchers/local.mk b/src/libfetchers/local.mk index d7143d8a6..cfd705e22 100644 --- a/src/libfetchers/local.mk +++ b/src/libfetchers/local.mk @@ -8,4 +8,4 @@ libfetchers_SOURCES := $(wildcard $(d)/*.cc) libfetchers_CXXFLAGS += -I src/libutil -I src/libstore -libfetchers_LIBS = libutil libstore libnixrust +libfetchers_LIBS = libutil libstore diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 649331495..1037b2e28 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -93,7 +93,7 @@ std::shared_ptr BinaryCacheStore::getFile(const std::string & path) std::string BinaryCacheStore::narInfoFileFor(const StorePath & storePath) { - return storePathToHash(printStorePath(storePath)) + ".narinfo"; + return std::string(storePath.hashPart()) + ".narinfo"; } void BinaryCacheStore::writeNarInfo(ref narInfo) @@ -102,7 +102,7 @@ void BinaryCacheStore::writeNarInfo(ref narInfo) upsertFile(narInfoFile, narInfo->to_string(*this), "text/x-nix-narinfo"); - auto hashPart = storePathToHash(printStorePath(narInfo->path)); + std::string hashPart(narInfo->path.hashPart()); { auto state_(state.lock()); @@ -164,7 +164,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, Source & narSource } } - upsertFile(storePathToHash(printStorePath(info.path)) + ".ls", jsonOut.str(), "application/json"); + upsertFile(std::string(info.path.to_string()) + ".ls", jsonOut.str(), "application/json"); } /* Compress the NAR. */ diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index f5c5bd9b7..e3b718e88 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -619,7 +619,7 @@ uint64_t LocalStore::addValidPath(State & state, { auto state_(Store::state.lock()); - state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)), + state_->pathInfoCache.upsert(std::string(info.path.hashPart()), PathInfoCacheValue{ .value = std::make_shared(info) }); } @@ -791,7 +791,7 @@ StorePathSet LocalStore::queryDerivationOutputs(const StorePath & path) std::optional LocalStore::queryPathFromHashPart(const std::string & hashPart) { - if (hashPart.size() != storePathHashLen) throw Error("invalid hash part"); + if (hashPart.size() != StorePath::HashLen) throw Error("invalid hash part"); Path prefix = storeDir + "/" + hashPart; @@ -942,7 +942,7 @@ void LocalStore::invalidatePath(State & state, const StorePath & path) { auto state_(Store::state.lock()); - state_->pathInfoCache.erase(storePathToHash(printStorePath(path))); + state_->pathInfoCache.erase(std::string(path.hashPart())); } } @@ -994,7 +994,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, if (info.ca == "" || !info.references.count(info.path)) hashSink = std::make_unique(htSHA256); else - hashSink = std::make_unique(htSHA256, storePathToHash(printStorePath(info.path))); + hashSink = std::make_unique(htSHA256, std::string(info.path.hashPart())); LambdaSource wrapperSource([&](unsigned char * data, size_t len) -> size_t { size_t n = source.read(data, len); @@ -1255,7 +1255,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) if (info->ca == "" || !info->references.count(info->path)) hashSink = std::make_unique(info->narHash.type); else - hashSink = std::make_unique(info->narHash.type, storePathToHash(printStorePath(info->path))); + hashSink = std::make_unique(info->narHash.type, std::string(info->path.hashPart())); dumpPath(Store::toRealPath(i), *hashSink); auto current = hashSink->finish(); diff --git a/src/libstore/local.mk b/src/libstore/local.mk index 91acef368..aec4ed493 100644 --- a/src/libstore/local.mk +++ b/src/libstore/local.mk @@ -6,7 +6,7 @@ libstore_DIR := $(d) libstore_SOURCES := $(wildcard $(d)/*.cc $(d)/builtins/*.cc) -libstore_LIBS = libutil libnixrust +libstore_LIBS = libutil libstore_LDFLAGS = $(SQLITE3_LIBS) -lbz2 $(LIBCURL_LIBS) $(SODIUM_LIBS) -pthread ifneq ($(OS), FreeBSD) diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index e8cf1d177..552970248 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -189,7 +189,7 @@ public: return {oInvalid, 0}; auto namePart = queryNAR.getStr(1); - auto narInfo = make_ref(StorePath::fromBaseName(hashPart + "-" + namePart)); + auto narInfo = make_ref(StorePath(hashPart + "-" + namePart)); narInfo->url = queryNAR.getStr(2); narInfo->compression = queryNAR.getStr(3); if (!queryNAR.isNull(4)) @@ -198,9 +198,9 @@ public: narInfo->narHash = Hash(queryNAR.getStr(6)); narInfo->narSize = queryNAR.getInt(7); for (auto & r : tokenizeString(queryNAR.getStr(8), " ")) - narInfo->references.insert(StorePath::fromBaseName(r)); + narInfo->references.insert(StorePath(r)); if (!queryNAR.isNull(9)) - narInfo->deriver = StorePath::fromBaseName(queryNAR.getStr(9)); + narInfo->deriver = StorePath(queryNAR.getStr(9)); for (auto & sig : tokenizeString(queryNAR.getStr(10), " ")) narInfo->sigs.insert(sig); narInfo->ca = queryNAR.getStr(11); diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 232284723..d7fc30e91 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -56,11 +56,11 @@ NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & auto refs = tokenizeString(value, " "); if (!references.empty()) corrupt(); for (auto & r : refs) - references.insert(StorePath::fromBaseName(r)); + references.insert(StorePath(r)); } else if (name == "Deriver") { if (value != "unknown-deriver") - deriver = StorePath::fromBaseName(value); + deriver = StorePath(value); } else if (name == "System") system = value; diff --git a/src/libstore/path.cc b/src/libstore/path.cc index 9a28aa96a..bb2089ea4 100644 --- a/src/libstore/path.cc +++ b/src/libstore/path.cc @@ -2,38 +2,38 @@ namespace nix { -extern "C" { - rust::Result ffi_StorePath_new(rust::StringSlice path, rust::StringSlice storeDir); - rust::Result ffi_StorePath_new2(unsigned char hash[20], rust::StringSlice storeDir); - rust::Result ffi_StorePath_fromBaseName(rust::StringSlice baseName); - rust::String ffi_StorePath_to_string(const StorePath & _this); - StorePath ffi_StorePath_clone(const StorePath & _this); - rust::StringSlice ffi_StorePath_name(const StorePath & _this); -} - -StorePath StorePath::make(std::string_view path, std::string_view storeDir) -{ - return ffi_StorePath_new((rust::StringSlice) path, (rust::StringSlice) storeDir).unwrap(); -} - -StorePath StorePath::make(unsigned char hash[20], std::string_view name) -{ - return ffi_StorePath_new2(hash, (rust::StringSlice) name).unwrap(); -} +MakeError(BadStorePath, Error); -StorePath StorePath::fromBaseName(std::string_view baseName) +static void checkName(std::string_view path, std::string_view name) { - return ffi_StorePath_fromBaseName((rust::StringSlice) baseName).unwrap(); + if (name.empty()) + throw BadStorePath("store path '%s' has an empty name", path); + if (name.size() > 211) + throw BadStorePath("store path '%s' has a name longer than 211 characters", path); + for (auto c : name) + if (!((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '=')) + throw BadStorePath("store path '%s' contains illegal character '%s'", path, c); } -rust::String StorePath::to_string() const +StorePath::StorePath(std::string_view _baseName) + : baseName(_baseName) { - return ffi_StorePath_to_string(*this); + if (baseName.size() < HashLen + 1) + throw BadStorePath("'%s' is too short to be a valid store path", baseName); + for (auto c : hashPart()) + if (c == 'e' || c == 'o' || c == 'u' || c == 't' + || !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z'))) + throw BadStorePath("store path '%s' contains illegal base-32 character '%s'", baseName, c); + checkName(baseName, name()); } -StorePath StorePath::clone() const +StorePath::StorePath(const Hash & hash, std::string_view _name) + : baseName((hash.to_string(Base32, false) + "-").append(std::string(_name))) { - return ffi_StorePath_clone(*this); + checkName(baseName, name()); } bool StorePath::isDerivation() const @@ -41,18 +41,14 @@ bool StorePath::isDerivation() const return hasSuffix(name(), drvExtension); } -std::string_view StorePath::name() const -{ - return ffi_StorePath_name(*this); -} - -StorePath StorePath::dummy( - StorePath::make( - (unsigned char *) "xxxxxxxxxxxxxxxxxxxx", "x")); +StorePath StorePath::dummy("ffffffffffffffffffffffffffffffff-x"); StorePath Store::parseStorePath(std::string_view path) const { - return StorePath::make(path, storeDir); + auto p = canonPath(std::string(path)); + if (dirOf(p) != storeDir) + throw BadStorePath("path '%s' is not in the Nix store", p); + return StorePath(baseNameOf(p)); } std::optional Store::maybeParseStorePath(std::string_view path) const @@ -78,9 +74,7 @@ StorePathSet Store::parseStorePathSet(const PathSet & paths) const std::string Store::printStorePath(const StorePath & path) const { - auto s = storeDir + "/"; - s += (std::string_view) path.to_string(); - return s; + return (storeDir + "/").append(path.to_string()); } PathSet Store::printStorePathSet(const StorePathSet & paths) const diff --git a/src/libstore/path.hh b/src/libstore/path.hh index 5122e7422..85c3d8e53 100644 --- a/src/libstore/path.hh +++ b/src/libstore/path.hh @@ -1,59 +1,78 @@ #pragma once -#include "rust-ffi.hh" +#include "types.hh" namespace nix { -/* See path.rs. */ -struct StorePath; - class Store; +struct Hash; -extern "C" { - void ffi_StorePath_drop(void *); - bool ffi_StorePath_less_than(const StorePath & a, const StorePath & b); - bool ffi_StorePath_eq(const StorePath & a, const StorePath & b); - unsigned char * ffi_StorePath_hash_data(const StorePath & p); -} - -struct StorePath : rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop> +class StorePath { + std::string baseName; + + StorePath(const StorePath & path) + : baseName(path.baseName) + { } + +public: + + /* Size of the hash part of store paths, in base-32 characters. */ + constexpr static size_t HashLen = 32; // i.e. 160 bits + StorePath() = delete; - static StorePath make(std::string_view path, std::string_view storeDir); + StorePath(std::string_view baseName); - static StorePath make(unsigned char hash[20], std::string_view name); + StorePath(const Hash & hash, std::string_view name); - static StorePath fromBaseName(std::string_view baseName); + StorePath(StorePath && path) + : baseName(std::move(path.baseName)) + { } - rust::String to_string() const; + StorePath & operator = (StorePath && path) + { + baseName = std::move(path.baseName); + return *this; + } + + std::string_view to_string() const + { + return baseName; + } bool operator < (const StorePath & other) const { - return ffi_StorePath_less_than(*this, other); + return baseName < other.baseName; } bool operator == (const StorePath & other) const { - return ffi_StorePath_eq(*this, other); + return baseName == other.baseName; } bool operator != (const StorePath & other) const { - return !(*this == other); + return baseName != other.baseName; } - StorePath clone() const; + StorePath clone() const + { + return StorePath(*this); + } /* Check whether a file name ends with the extension for derivations. */ bool isDerivation() const; - std::string_view name() const; + std::string_view name() const + { + return std::string_view(baseName).substr(HashLen + 1); + } - unsigned char * hashData() const + std::string_view hashPart() const { - return ffi_StorePath_hash_data(*this); + return std::string_view(baseName).substr(0, HashLen); } static StorePath dummy; @@ -67,9 +86,6 @@ StorePathSet storePathsToSet(const StorePaths & paths); StorePathSet singleton(const StorePath & path); -/* Size of the hash part of store paths, in base-32 characters. */ -const size_t storePathHashLen = 32; // i.e. 160 bits - /* Extension of derivations in the Nix store. */ const std::string drvExtension = ".drv"; @@ -107,7 +123,7 @@ namespace std { template<> struct hash { std::size_t operator()(const nix::StorePath & path) const noexcept { - return * (std::size_t *) path.hashData(); + return * (std::size_t *) path.to_string().data(); } }; diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc index 9277a8e6b..bd698d781 100644 --- a/src/libstore/remote-fs-accessor.cc +++ b/src/libstore/remote-fs-accessor.cc @@ -19,7 +19,7 @@ RemoteFSAccessor::RemoteFSAccessor(ref store, const Path & cacheDir) Path RemoteFSAccessor::makeCacheFile(const Path & storePath, const std::string & ext) { assert(cacheDir != ""); - return fmt("%s/%s.%s", cacheDir, storePathToHash(storePath), ext); + return fmt("%s/%s.%s", cacheDir, store->parseStorePath(storePath).hashPart(), ext); } void RemoteFSAccessor::addToCache(const Path & storePath, const std::string & nar, diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index e23a9ca50..42e26c427 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -59,14 +59,6 @@ StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view p } -string storePathToHash(const Path & path) -{ - auto base = baseNameOf(path); - assert(base.size() >= storePathHashLen); - return string(base, 0, storePathHashLen); -} - - /* Store paths have the following form: /- @@ -144,7 +136,7 @@ StorePath Store::makeStorePath(const string & type, /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */ string s = type + ":" + hash.to_string(Base16, true) + ":" + storeDir + ":" + std::string(name); auto h = compressHash(hashString(htSHA256, s), 20); - return StorePath::make(h.hash, name); + return StorePath(h, name); } @@ -243,7 +235,7 @@ bool Store::PathInfoCacheValue::isKnownNow() bool Store::isValidPath(const StorePath & storePath) { - auto hashPart = storePathToHash(printStorePath(storePath)); + std::string hashPart(storePath.hashPart()); { auto state_(state.lock()); @@ -311,7 +303,7 @@ void Store::queryPathInfo(const StorePath & storePath, std::string hashPart; try { - hashPart = storePathToHash(printStorePath(storePath)); + hashPart = storePath.hashPart(); { auto res = state.lock()->pathInfoCache.get(hashPart); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 5ef506326..251fc4638 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -731,10 +731,6 @@ public: }; -/* Extract the hash part of the given store path. */ -string storePathToHash(const Path & path); - - /* Copy a path from one store to another. */ void copyStorePath(ref srcStore, ref dstStore, const StorePath & storePath, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs); diff --git a/src/libutil/local.mk b/src/libutil/local.mk index 16c1fa03f..ae7eb67ad 100644 --- a/src/libutil/local.mk +++ b/src/libutil/local.mk @@ -7,5 +7,3 @@ libutil_DIR := $(d) libutil_SOURCES := $(wildcard $(d)/*.cc) libutil_LDFLAGS = $(LIBLZMA_LIBS) -lbz2 -pthread $(OPENSSL_LIBS) $(LIBBROTLI_LIBS) $(LIBARCHIVE_LIBS) $(BOOST_LDFLAGS) -lboost_context - -libutil_LIBS = libnixrust diff --git a/src/libutil/rust-ffi.cc b/src/libutil/rust-ffi.cc index 6f36b3192..67924568f 100644 --- a/src/libutil/rust-ffi.cc +++ b/src/libutil/rust-ffi.cc @@ -1,3 +1,4 @@ +#if 0 #include "logging.hh" #include "rust-ffi.hh" @@ -20,3 +21,4 @@ std::ostream & operator << (std::ostream & str, const String & s) } } +#endif diff --git a/src/libutil/rust-ffi.hh b/src/libutil/rust-ffi.hh index 228e2eead..cfbaf9dec 100644 --- a/src/libutil/rust-ffi.hh +++ b/src/libutil/rust-ffi.hh @@ -1,4 +1,5 @@ #pragma once +#if 0 #include "serialise.hh" @@ -185,3 +186,4 @@ struct Result }; } +#endif diff --git a/src/nix/local.mk b/src/nix/local.mk index 43b7754e3..b057b7cc6 100644 --- a/src/nix/local.mk +++ b/src/nix/local.mk @@ -17,7 +17,7 @@ nix_SOURCES := \ nix_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libexpr -I src/libmain -nix_LIBS = libexpr libmain libfetchers libstore libutil libnixrust +nix_LIBS = libexpr libmain libfetchers libstore libutil nix_LDFLAGS = -pthread $(SODIUM_LIBS) $(EDITLINE_LIBS) $(BOOST_LDFLAGS) -lboost_context -lboost_thread -lboost_system diff --git a/src/nix/make-content-addressable.cc b/src/nix/make-content-addressable.cc index 719ea4fd1..1211dad7b 100644 --- a/src/nix/make-content-addressable.cc +++ b/src/nix/make-content-addressable.cc @@ -48,7 +48,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON for (auto & path : paths) { auto pathS = store->printStorePath(path); auto oldInfo = store->queryPathInfo(path); - auto oldHashPart = storePathToHash(pathS); + std::string oldHashPart(path.hashPart()); StringSink sink; store->narFromPath(path, sink); @@ -88,7 +88,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON printInfo("rewrote '%s' to '%s'", pathS, store->printStorePath(info.path)); auto source = sinkToSource([&](Sink & nextSink) { - RewritingSink rsink2(oldHashPart, storePathToHash(store->printStorePath(info.path)), nextSink); + RewritingSink rsink2(oldHashPart, std::string(info.path.hashPart()), nextSink); rsink2((unsigned char *) sink.s->data(), sink.s->size()); rsink2.flush(); }); diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 001401ac2..ab83637dc 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -90,7 +90,7 @@ struct CmdVerify : StorePathsCommand if (info->ca == "") hashSink = std::make_unique(info->narHash.type); else - hashSink = std::make_unique(info->narHash.type, storePathToHash(store->printStorePath(info->path))); + hashSink = std::make_unique(info->narHash.type, std::string(info->path.hashPart())); store->narFromPath(info->path, *hashSink); diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index 6057beedb..a4ee2d971 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -76,7 +76,7 @@ struct CmdWhyDepends : SourceExprCommand auto packagePath = toStorePath(store, Build, package); auto dependency = parseInstallable(*this, store, _dependency, false); auto dependencyPath = toStorePath(store, NoBuild, dependency); - auto dependencyPathHash = storePathToHash(store->printStorePath(dependencyPath)); + auto dependencyPathHash = dependencyPath.hashPart(); StorePathSet closure; store->computeFSClosure({packagePath}, closure, false, false); @@ -175,7 +175,7 @@ struct CmdWhyDepends : SourceExprCommand auto & node2 = graph.at(ref); if (node2.dist == inf) continue; refs.emplace(node2.dist, &node2); - hashes.insert(storePathToHash(store->printStorePath(node2.path))); + hashes.insert(std::string(node2.path.hashPart())); } /* For each reference, find the files and symlinks that @@ -211,7 +211,7 @@ struct CmdWhyDepends : SourceExprCommand p2, hilite(filterPrintable( std::string(contents, pos2, pos - pos2 + hash.size() + margin)), - pos - pos2, storePathHashLen, + pos - pos2, StorePath::HashLen, getColour(hash)))); } } @@ -224,7 +224,7 @@ struct CmdWhyDepends : SourceExprCommand auto pos = target.find(hash); if (pos != std::string::npos) hits[hash].emplace_back(fmt("%s -> %s\n", p2, - hilite(target, pos, storePathHashLen, getColour(hash)))); + hilite(target, pos, StorePath::HashLen, getColour(hash)))); } } }; @@ -235,7 +235,7 @@ struct CmdWhyDepends : SourceExprCommand RunPager pager; for (auto & ref : refs) { - auto hash = storePathToHash(store->printStorePath(ref.second->path)); + std::string hash(ref.second->path.hashPart()); bool last = all ? ref == *refs.rbegin() : true; diff --git a/src/resolve-system-dependencies/local.mk b/src/resolve-system-dependencies/local.mk index f0e82e023..054ae01cb 100644 --- a/src/resolve-system-dependencies/local.mk +++ b/src/resolve-system-dependencies/local.mk @@ -8,6 +8,6 @@ resolve-system-dependencies_INSTALL_DIR := $(libexecdir)/nix resolve-system-dependencies_CXXFLAGS += -I src/libutil -I src/libstore -I src/libmain -resolve-system-dependencies_LIBS := libstore libmain libutil libnixrust +resolve-system-dependencies_LIBS := libstore libmain libutil resolve-system-dependencies_SOURCES := $(d)/resolve-system-dependencies.cc -- cgit v1.2.3 From fbf90bd693f09e6ce6e0725563c7996cba4da896 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 16 Jun 2020 14:19:49 +0000 Subject: Add another missing #include --- src/libutil/config.hh | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/libutil/config.hh b/src/libutil/config.hh index 5c7a70a2e..66073546e 100644 --- a/src/libutil/config.hh +++ b/src/libutil/config.hh @@ -1,3 +1,4 @@ +#include #include #include -- cgit v1.2.3 From 29542865cee37ab22efe1bd142900b69f6c59f0d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Jun 2020 22:20:18 +0200 Subject: Remove StorePath::clone() and related functions --- src/libexpr/primops.cc | 12 ++-- src/libstore/binary-cache-store.cc | 6 +- src/libstore/build.cc | 110 ++++++++++++++++++------------------ src/libstore/daemon.cc | 8 +-- src/libstore/derivations.cc | 42 +++++--------- src/libstore/derivations.hh | 8 --- src/libstore/export-import.cc | 2 +- src/libstore/gc.cc | 24 ++++---- src/libstore/legacy-ssh-store.cc | 2 +- src/libstore/local-fs-store.cc | 4 +- src/libstore/local-store.cc | 24 ++++---- src/libstore/misc.cc | 36 ++++++------ src/libstore/nar-info.cc | 2 +- src/libstore/parsed-derivations.cc | 4 +- src/libstore/parsed-derivations.hh | 2 +- src/libstore/path.cc | 23 -------- src/libstore/path.hh | 36 ------------ src/libstore/remote-store.cc | 10 ++-- src/libstore/store-api.cc | 21 +------ src/libstore/store-api.hh | 3 +- src/nix-build/nix-build.cc | 8 +-- src/nix-env/nix-env.cc | 12 ++-- src/nix-env/user-env.cc | 2 +- src/nix-store/dotgraph.cc | 4 +- src/nix-store/graphml.cc | 4 +- src/nix-store/nix-store.cc | 36 ++++++------ src/nix/command.cc | 10 ++-- src/nix/copy.cc | 2 +- src/nix/develop.cc | 6 +- src/nix/installables.cc | 22 ++++---- src/nix/make-content-addressable.cc | 6 +- src/nix/path-info.cc | 2 +- src/nix/run.cc | 6 +- src/nix/why-depends.cc | 6 +- 34 files changed, 201 insertions(+), 304 deletions(-) (limited to 'src') diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 62e5163c9..907f15246 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -55,7 +55,7 @@ void EvalState::realiseContext(const PathSet & context) if (!store->isValidPath(ctx)) throw InvalidPathError(store->printStorePath(ctx)); if (!decoded.second.empty() && ctx.isDerivation()) { - drvs.push_back(StorePathWithOutputs{ctx.clone(), {decoded.second}}); + drvs.push_back(StorePathWithOutputs{ctx, {decoded.second}}); /* Add the output of this derivation to the allowed paths. */ @@ -723,9 +723,9 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * StorePathSet refs; state.store->computeFSClosure(state.store->parseStorePath(std::string_view(path).substr(1)), refs); for (auto & j : refs) { - drv.inputSrcs.insert(j.clone()); + drv.inputSrcs.insert(j); if (j.isDerivation()) - drv.inputDrvs[j.clone()] = state.store->readDerivation(j).outputNames(); + drv.inputDrvs[j] = state.store->readDerivation(j).outputNames(); } } @@ -792,7 +792,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * for (auto & i : outputs) { if (!jsonObject) drv.env[i] = ""; drv.outputs.insert_or_assign(i, - DerivationOutput(StorePath::dummy.clone(), "", "")); + DerivationOutput { StorePath::dummy, "", "" }); } Hash h = hashDerivationModulo(*state.store, Derivation(drv), true); @@ -801,7 +801,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * auto outPath = state.store->makeOutputPath(i, h, drvName); if (!jsonObject) drv.env[i] = state.store->printStorePath(outPath); drv.outputs.insert_or_assign(i, - DerivationOutput(std::move(outPath), "", "")); + DerivationOutput { std::move(outPath), "", "" }); } } @@ -814,7 +814,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * /* Optimisation, but required in read-only mode! because in that case we don't actually write store derivations, so we can't read them later. */ - drvHashes.insert_or_assign(drvPath.clone(), + drvHashes.insert_or_assign(drvPath, hashDerivationModulo(*state.store, Derivation(drv), false)); state.mkAttrs(v, 1 + drv.outputs.size()); diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 1037b2e28..f8eff508c 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -360,7 +360,7 @@ StorePath BinaryCacheStore::addTextToStore(const string & name, const string & s const StorePathSet & references, RepairFlag repair) { ValidPathInfo info(computeStorePathForText(name, s, references)); - info.references = cloneStorePathSet(references); + info.references = references; if (repair || !isValidPath(info.path)) { StringSink sink; @@ -395,14 +395,14 @@ void BinaryCacheStore::addSignatures(const StorePath & storePath, const StringSe std::shared_ptr BinaryCacheStore::getBuildLog(const StorePath & path) { - auto drvPath = path.clone(); + auto drvPath = path; if (!path.isDerivation()) { try { auto info = queryPathInfo(path); // FIXME: add a "Log" field to .narinfo if (!info->deriver) return nullptr; - drvPath = info->deriver->clone(); + drvPath = *info->deriver; } catch (InvalidPath &) { return nullptr; } diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 8ad2ca4f3..53a0958aa 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -295,7 +295,7 @@ public: /* Make a goal (with caching). */ GoalPtr makeDerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, BuildMode buildMode = bmNormal); - std::shared_ptr makeBasicDerivationGoal(StorePath && drvPath, + std::shared_ptr makeBasicDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, BuildMode buildMode = bmNormal); GoalPtr makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair); @@ -347,7 +347,7 @@ public: contents. */ bool pathContentsGood(const StorePath & path); - void markContentsGood(StorePath && path); + void markContentsGood(const StorePath & path); void updateProgress() { @@ -900,9 +900,9 @@ private: friend struct RestrictedStore; public: - DerivationGoal(StorePath && drvPath, const StringSet & wantedOutputs, + DerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, Worker & worker, BuildMode buildMode = bmNormal); - DerivationGoal(StorePath && drvPath, const BasicDerivation & drv, + DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, Worker & worker, BuildMode buildMode = bmNormal); ~DerivationGoal(); @@ -924,7 +924,7 @@ public: StorePath getDrvPath() { - return drvPath.clone(); + return drvPath; } /* Add wanted outputs to an already existing derivation goal. */ @@ -1021,11 +1021,11 @@ private: const Path DerivationGoal::homeDir = "/homeless-shelter"; -DerivationGoal::DerivationGoal(StorePath && drvPath, const StringSet & wantedOutputs, +DerivationGoal::DerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, Worker & worker, BuildMode buildMode) : Goal(worker) , useDerivation(true) - , drvPath(std::move(drvPath)) + , drvPath(drvPath) , wantedOutputs(wantedOutputs) , buildMode(buildMode) { @@ -1038,11 +1038,11 @@ DerivationGoal::DerivationGoal(StorePath && drvPath, const StringSet & wantedOut } -DerivationGoal::DerivationGoal(StorePath && drvPath, const BasicDerivation & drv, +DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, Worker & worker, BuildMode buildMode) : Goal(worker) , useDerivation(false) - , drvPath(std::move(drvPath)) + , drvPath(drvPath) , buildMode(buildMode) { this->drv = std::make_unique(BasicDerivation(drv)); @@ -1193,7 +1193,7 @@ void DerivationGoal::haveDerivation() return; } - parsedDrv = std::make_unique(drvPath.clone(), *drv); + parsedDrv = std::make_unique(drvPath, *drv); /* We are first going to try to create the invalid output paths through substitutes. If that doesn't work, we'll build @@ -1301,7 +1301,7 @@ void DerivationGoal::repairClosure() if (i.isDerivation()) { Derivation drv = worker.store.derivationFromPath(i); for (auto & j : drv.outputs) - outputsToDrv.insert_or_assign(j.second.path.clone(), i.clone()); + outputsToDrv.insert_or_assign(j.second.path, i); } /* Check each path (slow!). */ @@ -1454,7 +1454,7 @@ void DerivationGoal::tryToBuild() return; } - missingPaths = cloneStorePathSet(drv->outputPaths()); + missingPaths = drv->outputPaths(); if (buildMode != bmCheck) for (auto & i : validPaths) missingPaths.erase(i); @@ -1901,14 +1901,14 @@ StorePathSet DerivationGoal::exportReferences(const StorePathSet & storePaths) if (!inputPaths.count(storePath)) throw BuildError("cannot export references of path '%s' because it is not in the input closure of the derivation", worker.store.printStorePath(storePath)); - worker.store.computeFSClosure(singleton(storePath), paths); + worker.store.computeFSClosure({storePath}, paths); } /* If there are derivations in the graph, then include their outputs as well. This is useful if you want to do things like passing all build-time dependencies of some path to a derivation that builds a NixOS DVD image. */ - auto paths2 = cloneStorePathSet(paths); + auto paths2 = paths; for (auto & j : paths2) { if (j.isDerivation()) { @@ -2037,7 +2037,7 @@ void DerivationGoal::startBuilder() /* Write closure info to . */ writeFile(tmpDir + "/" + fileName, worker.store.makeValidityRegistration( - exportReferences(singleton(storePath)), false, false)); + exportReferences({storePath}), false, false)); } } @@ -2222,7 +2222,7 @@ void DerivationGoal::startBuilder() for (auto & i : missingPaths) if (worker.store.isValidPath(i) && pathExists(worker.store.printStorePath(i))) { addHashRewrite(i); - redirectedBadOutputs.insert(i.clone()); + redirectedBadOutputs.insert(i); } } @@ -2717,8 +2717,8 @@ struct RestrictedStore : public LocalFSStore StorePathSet queryAllValidPaths() override { StorePathSet paths; - for (auto & p : goal.inputPaths) paths.insert(p.clone()); - for (auto & p : goal.addedPaths) paths.insert(p.clone()); + for (auto & p : goal.inputPaths) paths.insert(p); + for (auto & p : goal.addedPaths) paths.insert(p); return paths; } @@ -2806,7 +2806,7 @@ struct RestrictedStore : public LocalFSStore auto drv = derivationFromPath(path.path); for (auto & output : drv.outputs) if (wantOutput(output.first, path.outputs)) - newPaths.insert(output.second.path.clone()); + newPaths.insert(output.second.path); } else if (!goal.isAllowed(path.path)) throw InvalidPath("cannot build unknown path '%s' in recursive Nix", printStorePath(path.path)); } @@ -2851,7 +2851,7 @@ struct RestrictedStore : public LocalFSStore if (goal.isAllowed(path.path)) allowed.emplace_back(path); else - unknown.insert(path.path.clone()); + unknown.insert(path.path); } next->queryMissing(allowed, willBuild, willSubstitute, @@ -2946,7 +2946,7 @@ void DerivationGoal::addDependency(const StorePath & path) { if (isAllowed(path)) return; - addedPaths.insert(path.clone()); + addedPaths.insert(path); /* If we're doing a sandbox build, then we have to make the path appear in the sandbox. */ @@ -3568,7 +3568,7 @@ StorePathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv if (store.isStorePath(i)) result.insert(store.parseStorePath(i)); else if (drv.outputs.count(i)) - result.insert(drv.outputs.find(i)->second.path.clone()); + result.insert(drv.outputs.find(i)->second.path); else throw BuildError("derivation contains an illegal reference specifier '%s'", i); } return result; @@ -3626,9 +3626,9 @@ void DerivationGoal::registerOutputs() output paths, and any paths that have been built via recursive Nix calls. */ StorePathSet referenceablePaths; - for (auto & p : inputPaths) referenceablePaths.insert(p.clone()); - for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path.clone()); - for (auto & p : addedPaths) referenceablePaths.insert(p.clone()); + for (auto & p : inputPaths) referenceablePaths.insert(p); + for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path); + for (auto & p : addedPaths) referenceablePaths.insert(p); /* Check whether the output paths were created, and grep each output path to determine what other paths it references. Also make all @@ -3827,7 +3827,7 @@ void DerivationGoal::registerOutputs() info.narHash = hash.first; info.narSize = hash.second; info.references = std::move(references); - info.deriver = drvPath.clone(); + info.deriver = drvPath; info.ultimate = true; info.ca = ca; worker.store.signPathInfo(info); @@ -3942,23 +3942,23 @@ void DerivationGoal::checkOutputs(const std::map & outputs) uint64_t closureSize = 0; StorePathSet pathsDone; std::queue pathsLeft; - pathsLeft.push(path.clone()); + pathsLeft.push(path); while (!pathsLeft.empty()) { - auto path = pathsLeft.front().clone(); + auto path = pathsLeft.front(); pathsLeft.pop(); - if (!pathsDone.insert(path.clone()).second) continue; + if (!pathsDone.insert(path).second) continue; auto i = outputsByPath.find(worker.store.printStorePath(path)); if (i != outputsByPath.end()) { closureSize += i->second.narSize; for (auto & ref : i->second.references) - pathsLeft.push(ref.clone()); + pathsLeft.push(ref); } else { auto info = worker.store.queryPathInfo(path); closureSize += info->narSize; for (auto & ref : info->references) - pathsLeft.push(ref.clone()); + pathsLeft.push(ref); } } @@ -3985,8 +3985,8 @@ void DerivationGoal::checkOutputs(const std::map & outputs) auto spec = parseReferenceSpecifiers(worker.store, *drv, *value); auto used = recursive - ? cloneStorePathSet(getClosure(info.path).first) - : cloneStorePathSet(info.references); + ? getClosure(info.path).first + : info.references; if (recursive && checks.ignoreSelfRefs) used.erase(info.path); @@ -3996,10 +3996,10 @@ void DerivationGoal::checkOutputs(const std::map & outputs) for (auto & i : used) if (allowed) { if (!spec.count(i)) - badPaths.insert(i.clone()); + badPaths.insert(i); } else { if (spec.count(i)) - badPaths.insert(i.clone()); + badPaths.insert(i); } if (!badPaths.empty()) { @@ -4199,7 +4199,7 @@ StorePathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash) bool good = worker.store.isValidPath(i.second.path) && (!checkHash || worker.pathContentsGood(i.second.path)); - if (good == returnValid) result.insert(i.second.path.clone()); + if (good == returnValid) result.insert(i.second.path); } return result; } @@ -4215,7 +4215,7 @@ void DerivationGoal::addHashRewrite(const StorePath & path) deletePath(worker.store.printStorePath(p)); inputRewrites[h1] = h2; outputRewrites[h2] = h1; - redirectedOutputs.insert_or_assign(path.clone(), std::move(p)); + redirectedOutputs.insert_or_assign(path, std::move(p)); } @@ -4290,7 +4290,7 @@ private: GoalState state; public: - SubstitutionGoal(StorePath && storePath, Worker & worker, RepairFlag repair = NoRepair); + SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair); ~SubstitutionGoal(); void timedOut(Error && ex) override { abort(); }; @@ -4316,13 +4316,13 @@ public: void handleChildOutput(int fd, const string & data) override; void handleEOF(int fd) override; - StorePath getStorePath() { return storePath.clone(); } + StorePath getStorePath() { return storePath; } }; -SubstitutionGoal::SubstitutionGoal(StorePath && storePath, Worker & worker, RepairFlag repair) +SubstitutionGoal::SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair) : Goal(worker) - , storePath(std::move(storePath)) + , storePath(storePath) , repair(repair) { state = &SubstitutionGoal::init; @@ -4556,7 +4556,7 @@ void SubstitutionGoal::finished() return; } - worker.markContentsGood(storePath.clone()); + worker.markContentsGood(storePath); printMsg(lvlChatty, "substitution of path '%s' succeeded", worker.store.printStorePath(storePath)); @@ -4626,10 +4626,10 @@ Worker::~Worker() GoalPtr Worker::makeDerivationGoal(const StorePath & path, const StringSet & wantedOutputs, BuildMode buildMode) { - GoalPtr goal = derivationGoals[path.clone()].lock(); // FIXME + GoalPtr goal = derivationGoals[path].lock(); // FIXME if (!goal) { - goal = std::make_shared(path.clone(), wantedOutputs, *this, buildMode); - derivationGoals.insert_or_assign(path.clone(), goal); + goal = std::make_shared(path, wantedOutputs, *this, buildMode); + derivationGoals.insert_or_assign(path, goal); wakeUp(goal); } else (dynamic_cast(goal.get()))->addWantedOutputs(wantedOutputs); @@ -4637,10 +4637,10 @@ GoalPtr Worker::makeDerivationGoal(const StorePath & path, } -std::shared_ptr Worker::makeBasicDerivationGoal(StorePath && drvPath, +std::shared_ptr Worker::makeBasicDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, BuildMode buildMode) { - auto goal = std::make_shared(std::move(drvPath), drv, *this, buildMode); + auto goal = std::make_shared(drvPath, drv, *this, buildMode); wakeUp(goal); return goal; } @@ -4648,10 +4648,10 @@ std::shared_ptr Worker::makeBasicDerivationGoal(StorePath && drv GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair) { - GoalPtr goal = substitutionGoals[path.clone()].lock(); // FIXME + GoalPtr goal = substitutionGoals[path].lock(); // FIXME if (!goal) { - goal = std::make_shared(path.clone(), *this, repair); - substitutionGoals.insert_or_assign(path.clone(), goal); + goal = std::make_shared(path, *this, repair); + substitutionGoals.insert_or_assign(path, goal); wakeUp(goal); } return goal; @@ -4996,7 +4996,7 @@ bool Worker::pathContentsGood(const StorePath & path) Hash nullHash(htSHA256); res = info->narHash == nullHash || info->narHash == current.first; } - pathContentsGoodCache.insert_or_assign(path.clone(), res); + pathContentsGoodCache.insert_or_assign(path, res); if (!res) logError({ .name = "Corrupted path", @@ -5006,9 +5006,9 @@ bool Worker::pathContentsGood(const StorePath & path) } -void Worker::markContentsGood(StorePath && path) +void Worker::markContentsGood(const StorePath & path) { - pathContentsGoodCache.insert_or_assign(std::move(path), true); + pathContentsGoodCache.insert_or_assign(path, true); } @@ -5073,7 +5073,7 @@ BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDe BuildMode buildMode) { Worker worker(*this); - auto goal = worker.makeBasicDerivationGoal(drvPath.clone(), drv, buildMode); + auto goal = worker.makeBasicDerivationGoal(drvPath, drv, buildMode); BuildResult result; @@ -5094,7 +5094,7 @@ void LocalStore::ensurePath(const StorePath & path) /* If the path is already valid, we're done. */ if (isValidPath(path)) return; - primeCache(*this, {StorePathWithOutputs(path)}); + primeCache(*this, {{path}}); Worker worker(*this); GoalPtr goal = worker.makeSubstitutionGoal(path); diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 620722516..e370e278c 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -293,7 +293,7 @@ static void performOp(TunnelLogger * logger, ref store, auto path = store->parseStorePath(readString(from)); logger->startWork(); StorePathSet paths; // FIXME - paths.insert(path.clone()); + paths.insert(path); auto res = store->querySubstitutablePaths(paths); logger->stopWork(); to << (res.count(path) != 0); @@ -327,7 +327,7 @@ static void performOp(TunnelLogger * logger, ref store, StorePathSet paths; if (op == wopQueryReferences) for (auto & i : store->queryPathInfo(path)->references) - paths.insert(i.clone()); + paths.insert(i); else if (op == wopQueryReferrers) store->queryReferrers(path, paths); else if (op == wopQueryValidDerivers) @@ -593,9 +593,7 @@ static void performOp(TunnelLogger * logger, ref store, auto path = store->parseStorePath(readString(from)); logger->startWork(); SubstitutablePathInfos infos; - StorePathSet paths; - paths.insert(path.clone()); // FIXME - store->querySubstitutablePathInfos(paths, infos); + store->querySubstitutablePathInfos({path}, infos); logger->stopWork(); auto i = infos.find(path); if (i == infos.end()) diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 915e02eed..b95f7bfdc 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -27,28 +27,6 @@ void DerivationOutput::parseHashInfo(FileIngestionMethod & recursive, Hash & has } -BasicDerivation::BasicDerivation(const BasicDerivation & other) - : platform(other.platform) - , builder(other.builder) - , args(other.args) - , env(other.env) -{ - for (auto & i : other.outputs) - outputs.insert_or_assign(i.first, - DerivationOutput(i.second.path.clone(), std::string(i.second.hashAlgo), std::string(i.second.hash))); - for (auto & i : other.inputSrcs) - inputSrcs.insert(i.clone()); -} - - -Derivation::Derivation(const Derivation & other) - : BasicDerivation(other) -{ - for (auto & i : other.inputDrvs) - inputDrvs.insert_or_assign(i.first.clone(), i.second); -} - - const StorePath & BasicDerivation::findOutput(const string & id) const { auto i = outputs.find(id); @@ -67,9 +45,9 @@ bool BasicDerivation::isBuiltin() const StorePath writeDerivation(ref store, const Derivation & drv, std::string_view name, RepairFlag repair) { - auto references = cloneStorePathSet(drv.inputSrcs); + auto references = drv.inputSrcs; for (auto & i : drv.inputDrvs) - references.insert(i.first.clone()); + references.insert(i.first); /* Note that the outputs of a derivation are *not* references (that can be missing (of course) and should not necessarily be held during a garbage collection). */ @@ -155,7 +133,11 @@ static Derivation parseDerivation(const Store & store, const string & s) expect(str, ","); auto hashAlgo = parseString(str); expect(str, ","); auto hash = parseString(str); expect(str, ")"); - drv.outputs.emplace(id, DerivationOutput(std::move(path), std::move(hashAlgo), std::move(hash))); + drv.outputs.emplace(id, DerivationOutput { + .path = std::move(path), + .hashAlgo = std::move(hashAlgo), + .hash = std::move(hash) + }); } /* Parse the list of input derivations. */ @@ -383,7 +365,7 @@ Hash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutput auto h = drvHashes.find(i.first); if (h == drvHashes.end()) { assert(store.isValidPath(i.first)); - h = drvHashes.insert_or_assign(i.first.clone(), hashDerivationModulo(store, + h = drvHashes.insert_or_assign(i.first, hashDerivationModulo(store, store.readDerivation(i.first), false)).first; } inputs2.insert_or_assign(h->second.to_string(Base16, false), i.second); @@ -411,7 +393,7 @@ StorePathSet BasicDerivation::outputPaths() const { StorePathSet paths; for (auto & i : outputs) - paths.insert(i.second.path.clone()); + paths.insert(i.second.path); return paths; } @@ -434,7 +416,11 @@ Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv) auto path = store.parseStorePath(readString(in)); auto hashAlgo = readString(in); auto hash = readString(in); - drv.outputs.emplace(name, DerivationOutput(std::move(path), std::move(hashAlgo), std::move(hash))); + drv.outputs.emplace(name, DerivationOutput { + .path = std::move(path), + .hashAlgo = std::move(hashAlgo), + .hash = std::move(hash) + }); } drv.inputSrcs = readStorePaths(store, in); diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 88aed66bf..d349c6d4d 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -17,11 +17,6 @@ struct DerivationOutput StorePath path; std::string hashAlgo; /* hash used for expected hash computation */ std::string hash; /* expected hash, may be null */ - DerivationOutput(StorePath && path, std::string && hashAlgo, std::string && hash) - : path(std::move(path)) - , hashAlgo(std::move(hashAlgo)) - , hash(std::move(hash)) - { } void parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const; }; @@ -43,7 +38,6 @@ struct BasicDerivation StringPairs env; BasicDerivation() { } - explicit BasicDerivation(const BasicDerivation & other); virtual ~BasicDerivation() { }; /* Return the path corresponding to the output identifier `id' in @@ -71,8 +65,6 @@ struct Derivation : BasicDerivation std::map * actualInputs = nullptr) const; Derivation() { } - Derivation(Derivation && other) = default; - explicit Derivation(const Derivation & other); }; diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc index 54471d4a3..cb9da027d 100644 --- a/src/libstore/export-import.cc +++ b/src/libstore/export-import.cc @@ -105,7 +105,7 @@ StorePaths Store::importPaths(Source & source, std::shared_ptr acces auto source = StringSource { *tee.source.data }; addToStore(info, source, NoRepair, checkSigs, accessor); - res.push_back(info.path.clone()); + res.push_back(info.path); } return res; diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 04e3849f7..57fb20845 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -128,7 +128,7 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath, gcroots directory. */ if (settings.checkRootReachability) { auto roots = findRoots(false); - if (roots[storePath.clone()].count(gcRoot) == 0) + if (roots[storePath].count(gcRoot) == 0) logWarning({ .name = "GC root", .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; " @@ -478,9 +478,9 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor) if (!isValidPath(path)) continue; debug("got additional root '%1%'", pathS); if (censor) - roots[path.clone()].insert(censored); + roots[path].insert(censored); else - roots[path.clone()].insert(links.begin(), links.end()); + roots[path].insert(links.begin(), links.end()); } } @@ -592,11 +592,11 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto if (state.roots.count(path)) { debug("cannot delete '%1%' because it's a root", printStorePath(path)); - state.alive.insert(path.clone()); + state.alive.insert(path); return true; } - visited.insert(path.clone()); + visited.insert(path); if (!isValidPath(path)) return false; @@ -610,7 +610,7 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto if (state.gcKeepDerivations && path.isDerivation()) { for (auto & i : queryDerivationOutputs(path)) if (isValidPath(i) && queryPathInfo(i)->deriver == path) - incoming.insert(i.clone()); + incoming.insert(i); } /* If keep-outputs is set, then don't delete this path if there @@ -618,13 +618,13 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto if (state.gcKeepOutputs) { auto derivers = queryValidDerivers(path); for (auto & i : derivers) - incoming.insert(i.clone()); + incoming.insert(i); } for (auto & i : incoming) if (i != path) if (canReachRoot(state, visited, i)) { - state.alive.insert(path.clone()); + state.alive.insert(path); return true; } @@ -668,7 +668,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path) ‘nix-store --delete’ doesn't have the unexpected effect of recursing into derivations and outputs. */ for (auto & i : visited) - state.dead.insert(i.clone()); + state.dead.insert(i); if (state.shouldDelete) deletePathRecursive(state, path); } @@ -754,7 +754,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) if (!options.ignoreLiveness) findRootsNoTemp(rootMap, true); - for (auto & i : rootMap) state.roots.insert(i.first.clone()); + for (auto & i : rootMap) state.roots.insert(i.first); /* Read the temporary roots. This acquires read locks on all per-process temporary root files. So after this point no paths @@ -763,8 +763,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) Roots tempRoots; findTempRoots(fds, tempRoots, true); for (auto & root : tempRoots) { - state.tempRoots.insert(root.first.clone()); - state.roots.insert(root.first.clone()); + state.tempRoots.insert(root.first); + state.roots.insert(root.first); } /* After this point the set of roots or temporary roots cannot diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index af20d389b..45c70fad6 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -256,7 +256,7 @@ struct LegacySSHStore : public Store conn->to.flush(); for (auto & i : readStorePaths(*this, conn->from)) - out.insert(i.clone()); + out.insert(i); } StorePathSet queryValidPaths(const StorePathSet & paths, diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index 2d564a0d7..dd96d2578 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -90,13 +90,13 @@ const string LocalFSStore::drvsLogDir = "drvs"; std::shared_ptr LocalFSStore::getBuildLog(const StorePath & path_) { - auto path = path_.clone(); + auto path = path_; if (!path.isDerivation()) { try { auto info = queryPathInfo(path); if (!info->deriver) return nullptr; - path = info->deriver->clone(); + path = *info->deriver; } catch (InvalidPath &) { return nullptr; } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index e3b718e88..0df4374b9 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -631,7 +631,7 @@ void LocalStore::queryPathInfoUncached(const StorePath & path, Callback> callback) noexcept { try { - auto info = std::make_shared(path.clone()); + auto info = std::make_shared(path); callback(retrySQLite>([&]() { auto state(_state.lock()); @@ -721,7 +721,7 @@ StorePathSet LocalStore::queryValidPaths(const StorePathSet & paths, SubstituteF { StorePathSet res; for (auto & i : paths) - if (isValidPath(i)) res.insert(i.clone()); + if (isValidPath(i)) res.insert(i); return res; } @@ -816,7 +816,7 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths) StorePathSet remaining; for (auto & i : paths) - remaining.insert(i.clone()); + remaining.insert(i); StorePathSet res; @@ -830,9 +830,9 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths) StorePathSet remaining2; for (auto & path : remaining) if (valid.count(path)) - res.insert(path.clone()); + res.insert(path); else - remaining2.insert(path.clone()); + remaining2.insert(path); std::swap(remaining, remaining2); } @@ -854,9 +854,9 @@ void LocalStore::querySubstitutablePathInfos(const StorePathSet & paths, auto info = sub->queryPathInfo(path); auto narInfo = std::dynamic_pointer_cast( std::shared_ptr(info)); - infos.insert_or_assign(path.clone(), SubstitutablePathInfo{ - info->deriver ? info->deriver->clone() : std::optional(), - cloneStorePathSet(info->references), + infos.insert_or_assign(path, SubstitutablePathInfo{ + info->deriver, + info->references, narInfo ? narInfo->fileSize : 0, info->narSize}); } catch (InvalidPath &) { @@ -900,7 +900,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) updatePathInfo(*state, i); else addValidPath(*state, i, false); - paths.insert(i.path.clone()); + paths.insert(i.path); } for (auto & i : infos) { @@ -1074,7 +1074,7 @@ StorePath LocalStore::addToStoreFromDump(const string & dump, const string & nam optimisePath(realPath); // FIXME: combine with hashPath() - ValidPathInfo info(dstPath.clone()); + ValidPathInfo info(dstPath); info.narHash = hash.first; info.narSize = hash.second; info.ca = makeFixedOutputCA(method, h); @@ -1137,10 +1137,10 @@ StorePath LocalStore::addTextToStore(const string & name, const string & s, optimisePath(realPath); - ValidPathInfo info(dstPath.clone()); + ValidPathInfo info(dstPath); info.narHash = narHash; info.narSize = sink.s->size(); - info.references = cloneStorePathSet(references); + info.references = references; info.ca = "text:" + hash.to_string(Base32, true); registerValidPath(info); } diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 9c47fe524..e68edb38c 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -103,7 +103,7 @@ void Store::computeFSClosure(const StorePath & startPath, StorePathSet & paths_, bool flipDirection, bool includeOutputs, bool includeDerivers) { StorePathSet paths; - paths.insert(startPath.clone()); + paths.insert(startPath); computeFSClosure(paths, paths_, flipDirection, includeOutputs, includeDerivers); } @@ -141,11 +141,11 @@ void Store::queryMissing(const std::vector & targets, auto mustBuildDrv = [&](const StorePath & drvPath, const Derivation & drv) { { auto state(state_.lock()); - state->willBuild.insert(drvPath.clone()); + state->willBuild.insert(drvPath); } for (auto & i : drv.inputDrvs) - pool.enqueue(std::bind(doPath, StorePathWithOutputs(i.first, i.second))); + pool.enqueue(std::bind(doPath, StorePathWithOutputs { i.first, i.second })); }; auto checkOutput = [&]( @@ -157,9 +157,7 @@ void Store::queryMissing(const std::vector & targets, auto outPath = parseStorePath(outPathS); SubstitutablePathInfos infos; - StorePathSet paths; // FIXME - paths.insert(outPath.clone()); - querySubstitutablePathInfos(paths, infos); + querySubstitutablePathInfos({outPath}, infos); if (infos.empty()) { drvState_->lock()->done = true; @@ -170,10 +168,10 @@ void Store::queryMissing(const std::vector & targets, if (drvState->done) return; assert(drvState->left); drvState->left--; - drvState->outPaths.insert(outPath.clone()); + drvState->outPaths.insert(outPath); if (!drvState->left) { for (auto & path : drvState->outPaths) - pool.enqueue(std::bind(doPath, StorePathWithOutputs(path.clone()))); + pool.enqueue(std::bind(doPath, StorePathWithOutputs { path } )); } } } @@ -190,12 +188,12 @@ void Store::queryMissing(const std::vector & targets, if (!isValidPath(path.path)) { // FIXME: we could try to substitute the derivation. auto state(state_.lock()); - state->unknown.insert(path.path.clone()); + state->unknown.insert(path.path); return; } auto drv = make_ref(derivationFromPath(path.path)); - ParsedDerivation parsedDrv(path.path.clone(), *drv); + ParsedDerivation parsedDrv(StorePath(path.path), *drv); PathSet invalid; for (auto & j : drv->outputs) @@ -216,13 +214,11 @@ void Store::queryMissing(const std::vector & targets, if (isValidPath(path.path)) return; SubstitutablePathInfos infos; - StorePathSet paths; // FIXME - paths.insert(path.path.clone()); - querySubstitutablePathInfos(paths, infos); + querySubstitutablePathInfos({path.path}, infos); if (infos.empty()) { auto state(state_.lock()); - state->unknown.insert(path.path.clone()); + state->unknown.insert(path.path); return; } @@ -231,13 +227,13 @@ void Store::queryMissing(const std::vector & targets, { auto state(state_.lock()); - state->willSubstitute.insert(path.path.clone()); + state->willSubstitute.insert(path.path); state->downloadSize += info->second.downloadSize; state->narSize += info->second.narSize; } for (auto & ref : info->second.references) - pool.enqueue(std::bind(doPath, StorePathWithOutputs(ref))); + pool.enqueue(std::bind(doPath, StorePathWithOutputs { ref })); } }; @@ -260,12 +256,12 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths) throw BuildError("cycle detected in the references of '%s' from '%s'", printStorePath(path), printStorePath(*parent)); - if (!visited.insert(path.clone()).second) return; - parents.insert(path.clone()); + if (!visited.insert(path).second) return; + parents.insert(path); StorePathSet references; try { - references = cloneStorePathSet(queryPathInfo(path)->references); + references = queryPathInfo(path)->references; } catch (InvalidPath &) { } @@ -275,7 +271,7 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths) if (i != path && paths.count(i)) dfsVisit(i, &path); - sorted.push_back(path.clone()); + sorted.push_back(path); parents.erase(path); }; diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index d7fc30e91..bb4448c90 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -4,7 +4,7 @@ namespace nix { NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence) - : ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack + : ValidPathInfo(StorePath(StorePath::dummy)) // FIXME: hack { auto corrupt = [&]() { throw Error("NAR info file '%1%' is corrupt", whence); diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc index 45c033c66..24f848e46 100644 --- a/src/libstore/parsed-derivations.cc +++ b/src/libstore/parsed-derivations.cc @@ -4,8 +4,8 @@ namespace nix { -ParsedDerivation::ParsedDerivation(StorePath && drvPath, BasicDerivation & drv) - : drvPath(std::move(drvPath)), drv(drv) +ParsedDerivation::ParsedDerivation(const StorePath & drvPath, BasicDerivation & drv) + : drvPath(drvPath), drv(drv) { /* Parse the __json attribute, if any. */ auto jsonAttr = drv.env.find("__json"); diff --git a/src/libstore/parsed-derivations.hh b/src/libstore/parsed-derivations.hh index f4df5dd54..7621342d7 100644 --- a/src/libstore/parsed-derivations.hh +++ b/src/libstore/parsed-derivations.hh @@ -12,7 +12,7 @@ class ParsedDerivation public: - ParsedDerivation(StorePath && drvPath, BasicDerivation & drv); + ParsedDerivation(const StorePath & drvPath, BasicDerivation & drv); ~ParsedDerivation(); diff --git a/src/libstore/path.cc b/src/libstore/path.cc index bb2089ea4..b3d8ce95c 100644 --- a/src/libstore/path.cc +++ b/src/libstore/path.cc @@ -84,29 +84,6 @@ PathSet Store::printStorePathSet(const StorePathSet & paths) const return res; } -StorePathSet cloneStorePathSet(const StorePathSet & paths) -{ - StorePathSet res; - for (auto & p : paths) - res.insert(p.clone()); - return res; -} - -StorePathSet storePathsToSet(const StorePaths & paths) -{ - StorePathSet res; - for (auto & p : paths) - res.insert(p.clone()); - return res; -} - -StorePathSet singleton(const StorePath & path) -{ - StorePathSet res; - res.insert(path.clone()); - return res; -} - std::pair parsePathWithOutputs(std::string_view s) { size_t n = s.find("!"); diff --git a/src/libstore/path.hh b/src/libstore/path.hh index 85c3d8e53..aaebd3ec3 100644 --- a/src/libstore/path.hh +++ b/src/libstore/path.hh @@ -11,10 +11,6 @@ class StorePath { std::string baseName; - StorePath(const StorePath & path) - : baseName(path.baseName) - { } - public: /* Size of the hash part of store paths, in base-32 characters. */ @@ -26,16 +22,6 @@ public: StorePath(const Hash & hash, std::string_view name); - StorePath(StorePath && path) - : baseName(std::move(path.baseName)) - { } - - StorePath & operator = (StorePath && path) - { - baseName = std::move(path.baseName); - return *this; - } - std::string_view to_string() const { return baseName; @@ -56,11 +42,6 @@ public: return baseName != other.baseName; } - StorePath clone() const - { - return StorePath(*this); - } - /* Check whether a file name ends with the extension for derivations. */ bool isDerivation() const; @@ -81,11 +62,6 @@ public: typedef std::set StorePathSet; typedef std::vector StorePaths; -StorePathSet cloneStorePathSet(const StorePathSet & paths); -StorePathSet storePathsToSet(const StorePaths & paths); - -StorePathSet singleton(const StorePath & path); - /* Extension of derivations in the Nix store. */ const std::string drvExtension = ".drv"; @@ -99,18 +75,6 @@ struct StorePathWithOutputs StorePath path; std::set outputs; - StorePathWithOutputs(const StorePath & path, const std::set & outputs = {}) - : path(path.clone()), outputs(outputs) - { } - - StorePathWithOutputs(StorePath && path, std::set && outputs) - : path(std::move(path)), outputs(std::move(outputs)) - { } - - StorePathWithOutputs(const StorePathWithOutputs & other) - : path(other.path.clone()), outputs(other.outputs) - { } - std::string to_string(const Store & store) const; }; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 99fee8150..fc5ab5865 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -268,7 +268,7 @@ StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, Substitute if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) { StorePathSet res; for (auto & i : paths) - if (isValidPath(i)) res.insert(i.clone()); + if (isValidPath(i)) res.insert(i); return res; } else { conn->to << wopQueryValidPaths; @@ -296,7 +296,7 @@ StorePathSet RemoteStore::querySubstitutablePaths(const StorePathSet & paths) for (auto & i : paths) { conn->to << wopHasSubstitutes << printStorePath(i); conn.processStderr(); - if (readInt(conn->from)) res.insert(i.clone()); + if (readInt(conn->from)) res.insert(i); } return res; } else { @@ -329,7 +329,7 @@ void RemoteStore::querySubstitutablePathInfos(const StorePathSet & paths, info.references = readStorePaths(*this, conn->from); info.downloadSize = readLongLong(conn->from); info.narSize = readLongLong(conn->from); - infos.insert_or_assign(i.clone(), std::move(info)); + infos.insert_or_assign(i, std::move(info)); } } else { @@ -372,7 +372,7 @@ void RemoteStore::queryPathInfoUncached(const StorePath & path, bool valid; conn->from >> valid; if (!valid) throw InvalidPath("path '%s' is not valid", printStorePath(path)); } - info = std::make_shared(path.clone()); + info = std::make_shared(StorePath(path)); auto deriver = readString(conn->from); if (deriver != "") info->deriver = parseStorePath(deriver); info->narHash = Hash(readString(conn->from), htSHA256); @@ -396,7 +396,7 @@ void RemoteStore::queryReferrers(const StorePath & path, conn->to << wopQueryReferrers << printStorePath(path); conn.processStderr(); for (auto & i : readStorePaths(*this, conn->from)) - referrers.insert(i.clone()); + referrers.insert(i); } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 42e26c427..aae227bae 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -55,7 +55,7 @@ StorePath Store::followLinksToStorePath(std::string_view path) const StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view path) const { auto [path2, outputs] = nix::parsePathWithOutputs(path); - return StorePathWithOutputs(followLinksToStorePath(path2), std::move(outputs)); + return StorePathWithOutputs { followLinksToStorePath(path2), std::move(outputs) }; } @@ -545,7 +545,7 @@ void Store::buildPaths(const std::vector & paths, BuildMod for (auto & path : paths) { if (path.path.isDerivation()) unsupported("buildPaths"); - paths2.insert(path.path.clone()); + paths2.insert(path.path); } if (queryValidPaths(paths2).size() != paths2.size()) @@ -685,21 +685,6 @@ void copyClosure(ref srcStore, ref dstStore, } -ValidPathInfo::ValidPathInfo(const ValidPathInfo & other) - : path(other.path.clone()) - , deriver(other.deriver ? other.deriver->clone(): std::optional{}) - , narHash(other.narHash) - , references(cloneStorePathSet(other.references)) - , registrationTime(other.registrationTime) - , narSize(other.narSize) - , id(other.id) - , ultimate(other.ultimate) - , sigs(other.sigs) - , ca(other.ca) -{ -} - - std::optional decodeValidPathInfo(const Store & store, std::istream & str, bool hashGiven) { std::string path; @@ -785,7 +770,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const else if (hasPrefix(ca, "fixed:")) { FileIngestionMethod recursive { ca.compare(6, 2, "r:") == 0 }; Hash hash(ca.substr(recursive == FileIngestionMethod::Recursive ? 8 : 6)); - auto refs = cloneStorePathSet(references); + auto refs = references; bool hasSelfReference = false; if (refs.count(path)) { hasSelfReference = true; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 251fc4638..6f4dd959c 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -189,8 +189,9 @@ struct ValidPathInfo Strings shortRefs() const; + ValidPathInfo(const StorePath & path) : path(path) { } + ValidPathInfo(StorePath && path) : path(std::move(path)) { } - explicit ValidPathInfo(const ValidPathInfo & other); virtual ~ValidPathInfo() { } }; diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index da6f005a3..a224d635d 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -363,7 +363,7 @@ static void _main(int argc, char * * argv) if (!drv) throw Error("the 'bashInteractive' attribute in did not evaluate to a derivation"); - pathsToBuild.emplace_back(store->parseStorePath(drv->queryDrvPath())); + pathsToBuild.push_back({store->parseStorePath(drv->queryDrvPath())}); shell = drv->queryOutPath() + "/bin/bash"; @@ -381,9 +381,9 @@ static void _main(int argc, char * * argv) for (const auto & input : drv.inputDrvs) if (std::all_of(envExclude.cbegin(), envExclude.cend(), [&](const string & exclude) { return !std::regex_search(store->printStorePath(input.first), std::regex(exclude)); })) - pathsToBuild.emplace_back(input.first, input.second); + pathsToBuild.push_back({input.first, input.second}); for (const auto & src : drv.inputSrcs) - pathsToBuild.emplace_back(src); + pathsToBuild.push_back({src}); buildPaths(pathsToBuild); @@ -499,7 +499,7 @@ static void _main(int argc, char * * argv) if (outputName == "") throw Error("derivation '%s' lacks an 'outputName' attribute", drvPath); - pathsToBuild.emplace_back(store->parseStorePath(drvPath), StringSet{outputName}); + pathsToBuild.push_back({store->parseStorePath(drvPath), {outputName}}); std::string drvPrefix; auto i = drvPrefixes.find(drvPath); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 2c27d97f5..8b0692035 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -212,9 +212,7 @@ static bool isPrebuilt(EvalState & state, DrvInfo & elem) { auto path = state.store->parseStorePath(elem.queryOutPath()); if (state.store->isValidPath(path)) return true; - StorePathSet paths; - paths.insert(path.clone()); // FIXME: why doesn't StorePathSet{path.clone()} work? - return state.store->querySubstitutablePaths(paths).count(path); + return state.store->querySubstitutablePaths({path}).count(path); } @@ -425,9 +423,9 @@ static void printMissing(EvalState & state, DrvInfos & elems) for (auto & i : elems) { Path drvPath = i.queryDrvPath(); if (drvPath != "") - targets.emplace_back(state.store->parseStorePath(drvPath)); + targets.push_back({state.store->parseStorePath(drvPath)}); else - targets.emplace_back(state.store->parseStorePath(i.queryOutPath())); + targets.push_back({state.store->parseStorePath(i.queryOutPath())}); } printMissing(state.store, targets); @@ -697,13 +695,13 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs) drv.setName(globals.forceName); if (drv.queryDrvPath() != "") { - std::vector paths{globals.state->store->parseStorePath(drv.queryDrvPath())}; + std::vector paths{{globals.state->store->parseStorePath(drv.queryDrvPath())}}; printMissing(globals.state->store, paths); if (globals.dryRun) return; globals.state->store->buildPaths(paths, globals.state->repair ? bmRepair : bmNormal); } else { printMissing(globals.state->store, - {globals.state->store->parseStorePath(drv.queryOutPath())}); + {{globals.state->store->parseStorePath(drv.queryOutPath())}}); if (globals.dryRun) return; globals.state->store->ensurePath(globals.state->store->parseStorePath(drv.queryOutPath())); } diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc index f804b77a0..8e7f09e12 100644 --- a/src/nix-env/user-env.cc +++ b/src/nix-env/user-env.cc @@ -134,7 +134,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, /* Realise the resulting store expression. */ debug("building user environment"); std::vector topLevelDrvs; - topLevelDrvs.push_back(StorePathWithOutputs{topLevelDrv.clone()}); + topLevelDrvs.push_back({topLevelDrv}); state.store->buildPaths(topLevelDrvs, state.repair ? bmRepair : bmNormal); /* Switch the current user environment to the output path. */ diff --git a/src/nix-store/dotgraph.cc b/src/nix-store/dotgraph.cc index 667d917f5..8b699f39b 100644 --- a/src/nix-store/dotgraph.cc +++ b/src/nix-store/dotgraph.cc @@ -54,13 +54,13 @@ void printDotGraph(ref store, StorePathSet && roots) while (!workList.empty()) { auto path = std::move(workList.extract(workList.begin()).value()); - if (!doneSet.insert(path.clone()).second) continue; + if (!doneSet.insert(path).second) continue; cout << makeNode(std::string(path.to_string()), path.name(), "#ff0000"); for (auto & p : store->queryPathInfo(path)->references) { if (p != path) { - workList.insert(p.clone()); + workList.insert(p); cout << makeEdge(std::string(p.to_string()), std::string(path.to_string())); } } diff --git a/src/nix-store/graphml.cc b/src/nix-store/graphml.cc index 347708851..8ca5c9c8d 100644 --- a/src/nix-store/graphml.cc +++ b/src/nix-store/graphml.cc @@ -65,7 +65,7 @@ void printGraphML(ref store, StorePathSet && roots) while (!workList.empty()) { auto path = std::move(workList.extract(workList.begin()).value()); - ret = doneSet.insert(path.clone()); + ret = doneSet.insert(path); if (ret.second == false) continue; auto info = store->queryPathInfo(path); @@ -73,7 +73,7 @@ void printGraphML(ref store, StorePathSet && roots) for (auto & p : info->references) { if (p != path) { - workList.insert(p.clone()); + workList.insert(p); cout << makeEdge(path.to_string(), p.to_string()); } } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 6d2139526..5c5afd5ec 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -49,11 +49,11 @@ ref ensureLocalStore() static StorePath useDeriver(const StorePath & path) { - if (path.isDerivation()) return path.clone(); + if (path.isDerivation()) return path; auto info = store->queryPathInfo(path); if (!info->deriver) throw Error("deriver of path '%s' is not known", store->printStorePath(path)); - return info->deriver->clone(); + return *info->deriver; } @@ -214,15 +214,15 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs) static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput, bool forceRealise) { - if (forceRealise) realisePath(storePath); + if (forceRealise) realisePath({storePath}); if (useOutput && storePath.isDerivation()) { auto drv = store->derivationFromPath(storePath); StorePathSet outputs; for (auto & i : drv.outputs) - outputs.insert(i.second.path.clone()); + outputs.insert(i.second.path); return outputs; } - else return singleton(storePath.clone()); + else return {storePath}; } @@ -232,7 +232,7 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput, static void printTree(const StorePath & path, const string & firstPad, const string & tailPad, StorePathSet & done) { - if (!done.insert(path.clone()).second) { + if (!done.insert(path).second) { cout << fmt("%s%s [...]\n", firstPad, store->printStorePath(path)); return; } @@ -310,7 +310,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qOutputs: { for (auto & i : opArgs) { auto i2 = store->followLinksToStorePath(i); - if (forceRealise) realisePath(i2); + if (forceRealise) realisePath({i2}); Derivation drv = store->derivationFromPath(i2); for (auto & j : drv.outputs) cout << fmt("%1%\n", store->printStorePath(j.second.path)); @@ -329,13 +329,13 @@ static void opQuery(Strings opFlags, Strings opArgs) if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs); else if (query == qReferences) { for (auto & p : store->queryPathInfo(j)->references) - paths.insert(p.clone()); + paths.insert(p); } else if (query == qReferrers) { StorePathSet tmp; store->queryReferrers(j, tmp); for (auto & i : tmp) - paths.insert(i.clone()); + paths.insert(i); } else if (query == qReferrersClosure) store->computeFSClosure(j, paths, true); } @@ -391,7 +391,7 @@ static void opQuery(Strings opFlags, Strings opArgs) StorePathSet roots; for (auto & i : opArgs) for (auto & j : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise)) - roots.insert(j.clone()); + roots.insert(j); printDotGraph(ref(store), std::move(roots)); break; } @@ -400,7 +400,7 @@ static void opQuery(Strings opFlags, Strings opArgs) StorePathSet roots; for (auto & i : opArgs) for (auto & j : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise)) - roots.insert(j.clone()); + roots.insert(j); printGraphML(ref(store), std::move(roots)); break; } @@ -415,7 +415,7 @@ static void opQuery(Strings opFlags, Strings opArgs) StorePathSet args; for (auto & i : opArgs) for (auto & p : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise)) - args.insert(p.clone()); + args.insert(p); StorePathSet referrers; store->computeFSClosure( @@ -482,10 +482,10 @@ static void opDumpDB(Strings opFlags, Strings opArgs) if (!opFlags.empty()) throw UsageError("unknown flag"); if (!opArgs.empty()) { for (auto & i : opArgs) - cout << store->makeValidityRegistration(singleton(store->followLinksToStorePath(i)), true, true); + cout << store->makeValidityRegistration({store->followLinksToStorePath(i)}, true, true); } else { for (auto & i : store->queryAllValidPaths()) - cout << store->makeValidityRegistration(singleton(i), true, true); + cout << store->makeValidityRegistration({i}, true, true); } } @@ -586,7 +586,7 @@ static void opGC(Strings opFlags, Strings opArgs) // Transpose and sort the roots. for (auto & [target, links] : roots) for (auto & link : links) - roots2.emplace(link, target.clone()); + roots2.emplace(link, target); for (auto & [link, target] : roots2) std::cout << link << " -> " << store->printStorePath(target) << "\n"; } @@ -830,7 +830,7 @@ static void opServe(Strings opFlags, Strings opArgs) std::vector paths2; for (auto & path : paths) if (!path.isDerivation()) - paths2.emplace_back(path.clone()); + paths2.push_back({path}); unsigned long long downloadSize, narSize; StorePathSet willBuild, willSubstitute, unknown; store->queryMissing(paths2, @@ -840,7 +840,7 @@ static void opServe(Strings opFlags, Strings opArgs) if (!willSubstitute.empty()) try { std::vector subs; - for (auto & p : willSubstitute) subs.emplace_back(p.clone()); + for (auto & p : willSubstitute) subs.push_back({p}); store->buildPaths(subs); } catch (Error & e) { logWarning(e.info()); @@ -895,7 +895,7 @@ static void opServe(Strings opFlags, Strings opArgs) std::vector paths; for (auto & s : readStrings(in)) - paths.emplace_back(store->parsePathWithOutputs(s)); + paths.push_back(store->parsePathWithOutputs(s)); getBuildSettings(); diff --git a/src/nix/command.cc b/src/nix/command.cc index 71b027719..d62626c26 100644 --- a/src/nix/command.cc +++ b/src/nix/command.cc @@ -59,19 +59,19 @@ void StorePathsCommand::run(ref store) if (installables.size()) throw UsageError("'--all' does not expect arguments"); for (auto & p : store->queryAllValidPaths()) - storePaths.push_back(p.clone()); + storePaths.push_back(p); } else { for (auto & p : toStorePaths(store, realiseMode, installables)) - storePaths.push_back(p.clone()); + storePaths.push_back(p); if (recursive) { StorePathSet closure; - store->computeFSClosure(storePathsToSet(storePaths), closure, false, false); + store->computeFSClosure(StorePathSet(storePaths.begin(), storePaths.end()), closure, false, false); storePaths.clear(); for (auto & p : closure) - storePaths.push_back(p.clone()); + storePaths.push_back(p); } } @@ -133,7 +133,7 @@ void MixProfile::updateProfile(const Buildables & buildables) for (auto & output : buildable.outputs) { if (result) throw Error("'--profile' requires that the arguments produce a single store path, but there are multiple"); - result = output.second.clone(); + result = output.second; } } diff --git a/src/nix/copy.cc b/src/nix/copy.cc index c7c38709d..64099f476 100644 --- a/src/nix/copy.cc +++ b/src/nix/copy.cc @@ -94,7 +94,7 @@ struct CmdCopy : StorePathsCommand ref dstStore = dstUri.empty() ? openStore() : openStore(dstUri); - copyPaths(srcStore, dstStore, storePathsToSet(storePaths), + copyPaths(srcStore, dstStore, StorePathSet(storePaths.begin(), storePaths.end()), NoRepair, checkSigs, substitute); } }; diff --git a/src/nix/develop.cc b/src/nix/develop.cc index 3045d7dc3..05a9b9cd9 100644 --- a/src/nix/develop.cc +++ b/src/nix/develop.cc @@ -135,12 +135,12 @@ StorePath getDerivationEnvironment(ref store, const StorePath & drvPath) drv.inputSrcs.insert(std::move(getEnvShPath)); Hash h = hashDerivationModulo(*store, drv, true); auto shellOutPath = store->makeOutputPath("out", h, drvName); - drv.outputs.insert_or_assign("out", DerivationOutput(shellOutPath.clone(), "", "")); + drv.outputs.insert_or_assign("out", DerivationOutput { shellOutPath, "", "" }); drv.env["out"] = store->printStorePath(shellOutPath); auto shellDrvPath2 = writeDerivation(store, drv, drvName); /* Build the derivation. */ - store->buildPaths({shellDrvPath2}); + store->buildPaths({{shellDrvPath2}}); assert(store->isValidPath(shellOutPath)); @@ -205,7 +205,7 @@ struct Common : InstallableCommand, MixProfile { auto path = installable->getStorePath(); if (path && hasSuffix(path->to_string(), "-env")) - return path->clone(); + return *path; else { auto drvs = toDerivations(store, {installable}); diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 937d69206..708a0dc88 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -102,9 +102,9 @@ struct InstallableStorePath : Installable Buildables toBuildables() override { std::map outputs; - outputs.insert_or_assign("out", storePath.clone()); + outputs.insert_or_assign("out", storePath); Buildable b{ - .drvPath = storePath.isDerivation() ? storePath.clone() : std::optional(), + .drvPath = storePath.isDerivation() ? storePath : std::optional(), .outputs = std::move(outputs) }; Buildables bs; @@ -114,7 +114,7 @@ struct InstallableStorePath : Installable std::optional getStorePath() override { - return storePath.clone(); + return storePath; } }; @@ -141,7 +141,7 @@ struct InstallableValue : Installable for (auto & drv : drvs) { Buildable b{.drvPath = state->store->parseStorePath(drv.queryDrvPath())}; - drvPaths.insert(b.drvPath->clone()); + drvPaths.insert(*b.drvPath); auto outputName = drv.queryOutputName(); if (outputName == "") @@ -155,10 +155,10 @@ struct InstallableValue : Installable // Hack to recognize .all: if all drvs have the same drvPath, // merge the buildables. if (drvPaths.size() == 1) { - Buildable b{.drvPath = drvPaths.begin()->clone()}; + Buildable b{.drvPath = *drvPaths.begin()}; for (auto & b2 : res) for (auto & output : b2.outputs) - b.outputs.insert_or_assign(output.first, output.second.clone()); + b.outputs.insert_or_assign(output.first, output.second); Buildables bs; bs.push_back(std::move(b)); return bs; @@ -273,7 +273,7 @@ Buildables build(ref store, RealiseMode mode, pathsToBuild.push_back({*b.drvPath, outputNames}); } else for (auto & output : b.outputs) - pathsToBuild.push_back({output.second.clone()}); + pathsToBuild.push_back({output.second}); buildables.push_back(std::move(b)); } } @@ -293,7 +293,7 @@ StorePathSet toStorePaths(ref store, RealiseMode mode, for (auto & b : build(store, mode, installables)) for (auto & output : b.outputs) - outPaths.insert(output.second.clone()); + outPaths.insert(output.second); return outPaths; } @@ -306,7 +306,7 @@ StorePath toStorePath(ref store, RealiseMode mode, if (paths.size() != 1) throw Error("argument '%s' should evaluate to one store path", installable->what()); - return paths.begin()->clone(); + return *paths.begin(); } StorePathSet toDerivations(ref store, @@ -324,10 +324,10 @@ StorePathSet toDerivations(ref store, if (derivers.empty()) throw Error("'%s' does not have a known deriver", i->what()); // FIXME: use all derivers? - drvPaths.insert(derivers.begin()->clone()); + drvPaths.insert(*derivers.begin()); } } else - drvPaths.insert(b.drvPath->clone()); + drvPaths.insert(*b.drvPath); } return drvPaths; diff --git a/src/nix/make-content-addressable.cc b/src/nix/make-content-addressable.cc index 1211dad7b..0ebb8f13b 100644 --- a/src/nix/make-content-addressable.cc +++ b/src/nix/make-content-addressable.cc @@ -36,7 +36,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON void run(ref store, StorePaths storePaths) override { - auto paths = store->topoSortPaths(storePathsToSet(storePaths)); + auto paths = store->topoSortPaths(StorePathSet(storePaths.begin(), storePaths.end())); std::reverse(paths.begin(), paths.end()); @@ -62,7 +62,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON hasSelfReference = true; else { auto i = remappings.find(ref); - auto replacement = i != remappings.end() ? i->second.clone() : ref.clone(); + auto replacement = i != remappings.end() ? i->second : ref; // FIXME: warn about unremapped paths? if (replacement != ref) rewrites.insert_or_assign(store->printStorePath(ref), store->printStorePath(replacement)); @@ -79,7 +79,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, path.name(), references, hasSelfReference)); info.references = std::move(references); - if (hasSelfReference) info.references.insert(info.path.clone()); + if (hasSelfReference) info.references.insert(info.path); info.narHash = narHash; info.narSize = sink.s->size(); info.ca = makeFixedOutputCA(FileIngestionMethod::Recursive, info.narHash); diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc index 88d7fffd4..fb7bacc4c 100644 --- a/src/nix/path-info.cc +++ b/src/nix/path-info.cc @@ -90,7 +90,7 @@ struct CmdPathInfo : StorePathsCommand, MixJSON JSONPlaceholder jsonRoot(std::cout); store->pathInfoToJSON(jsonRoot, // FIXME: preserve order? - storePathsToSet(storePaths), + StorePathSet(storePaths.begin(), storePaths.end()), true, showClosureSize, SRI, AllowInvalid); } diff --git a/src/nix/run.cc b/src/nix/run.cc index c9b69aec7..321ee1d11 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -111,16 +111,16 @@ struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment std::unordered_set done; std::queue todo; - for (auto & path : outPaths) todo.push(path.clone()); + for (auto & path : outPaths) todo.push(path); setEnviron(); auto unixPath = tokenizeString(getEnv("PATH").value_or(""), ":"); while (!todo.empty()) { - auto path = todo.front().clone(); + auto path = todo.front(); todo.pop(); - if (!done.insert(path.clone()).second) continue; + if (!done.insert(path).second) continue; if (true) unixPath.push_front(store->printStorePath(path) + "/bin"); diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index a4ee2d971..167c974ee 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -106,16 +106,16 @@ struct CmdWhyDepends : SourceExprCommand std::map graph; for (auto & path : closure) - graph.emplace(path.clone(), Node { .path = path.clone(), .refs = cloneStorePathSet(store->queryPathInfo(path)->references) }); + graph.emplace(path, Node { .path = path, .refs = store->queryPathInfo(path)->references }); // Transpose the graph. for (auto & node : graph) for (auto & ref : node.second.refs) - graph.find(ref)->second.rrefs.insert(node.first.clone()); + graph.find(ref)->second.rrefs.insert(node.first); /* Run Dijkstra's shortest path algorithm to get the distance of every path in the closure to 'dependency'. */ - graph.emplace(dependencyPath.clone(), Node { .path = dependencyPath.clone(), .dist = 0 }); + graph.emplace(dependencyPath, Node { .path = dependencyPath, .dist = 0 }); std::priority_queue queue; -- cgit v1.2.3 From c9d06558b6cfb30cb6ad7d872ec1046434645b3b Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Wed, 17 Jun 2020 03:15:47 +0100 Subject: replaced uncaught_exception with uncaught_exceptions --- src/libstore/remote-store.cc | 2 +- src/libutil/json.cc | 2 +- src/libutil/util.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index fc5ab5865..f5f2ab7fd 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -228,7 +228,7 @@ struct ConnectionHandle ~ConnectionHandle() { - if (!daemonException && std::uncaught_exception()) { + if (!daemonException && std::uncaught_exceptions()) { handle.markBad(); debug("closing daemon connection because of an exception"); } diff --git a/src/libutil/json.cc b/src/libutil/json.cc index 74e37b4c4..01331947e 100644 --- a/src/libutil/json.cc +++ b/src/libutil/json.cc @@ -173,7 +173,7 @@ JSONObject JSONPlaceholder::object() JSONPlaceholder::~JSONPlaceholder() { - assert(!first || std::uncaught_exception()); + assert(!first || std::uncaught_exceptions()); } } diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 667dd2edb..6ca9013a4 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1199,7 +1199,7 @@ void _interrupted() /* Block user interrupts while an exception is being handled. Throwing an exception while another exception is being handled kills the program! */ - if (!interruptThrown && !std::uncaught_exception()) { + if (!interruptThrown && !std::uncaught_exceptions()) { interruptThrown = true; throw Interrupted("interrupted by the user"); } -- cgit v1.2.3 From e9970a34e8841faaecd39ba18e0913101beca592 Mon Sep 17 00:00:00 2001 From: p01arst0rm Date: Wed, 17 Jun 2020 03:19:15 +0100 Subject: appended ' __attribute__((weak)); ' to 'extern char * * environ ' --- src/libutil/util.cc | 2 +- src/nix-build/nix-build.cc | 2 +- src/nix/command.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 667dd2edb..85246ced6 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -35,7 +35,7 @@ #endif -extern char * * environ; +extern char * * environ __attribute__((weak)); namespace nix { diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index a224d635d..f77de56ea 100755 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -21,7 +21,7 @@ using namespace nix; using namespace std::string_literals; -extern char * * environ; +extern char * * environ __attribute__((weak)); /* Recreate the effect of the perl shellwords function, breaking up a * string into arguments like a shell word, including escapes diff --git a/src/nix/command.cc b/src/nix/command.cc index d62626c26..3651a9e9c 100644 --- a/src/nix/command.cc +++ b/src/nix/command.cc @@ -4,7 +4,7 @@ #include "nixexpr.hh" #include "profiles.hh" -extern char * * environ; +extern char * * environ __attribute__((weak)); namespace nix { -- cgit v1.2.3 From 56d75bf4fcb06da1a577c6e381f4afef57f30243 Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 17 Jun 2020 15:39:10 +0200 Subject: Reserve the `__contentAddressed` derivation parameter Not implementing anything here, just throwing an error if a derivation sets `__contentAddressed = true` without `--experimental-features content-addressed-paths` (and also with it as there's nothing implemented yet) --- src/libstore/build.cc | 11 +++++++++++ src/libstore/parsed-derivations.cc | 5 +++++ src/libstore/parsed-derivations.hh | 2 ++ 3 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 53a0958aa..9b72175c7 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -809,6 +809,9 @@ private: /* Whether this is a fixed-output derivation. */ bool fixedOutput; + /* Whether this is a content adressed derivation */ + bool contentAddressed = false; + /* Whether to run the build in a private network namespace. */ bool privateNetwork = false; @@ -1195,6 +1198,14 @@ void DerivationGoal::haveDerivation() parsedDrv = std::make_unique(drvPath, *drv); + contentAddressed = parsedDrv->contentAddressed(); + + if (this->contentAddressed) { + settings.requireExperimentalFeature("content-addressed-paths"); + throw Error("content-addressed-paths isn't implemented yet"); + } + + /* We are first going to try to create the invalid output paths through substitutes. If that doesn't work, we'll build them. */ diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc index 24f848e46..c7797b730 100644 --- a/src/libstore/parsed-derivations.cc +++ b/src/libstore/parsed-derivations.cc @@ -117,4 +117,9 @@ bool ParsedDerivation::substitutesAllowed() const return getBoolAttr("allowSubstitutes", true); } +bool ParsedDerivation::contentAddressed() const +{ + return getBoolAttr("__contentAddressed", false); +} + } diff --git a/src/libstore/parsed-derivations.hh b/src/libstore/parsed-derivations.hh index 7621342d7..d24d1eb4f 100644 --- a/src/libstore/parsed-derivations.hh +++ b/src/libstore/parsed-derivations.hh @@ -34,6 +34,8 @@ public: bool willBuildLocally() const; bool substitutesAllowed() const; + + bool contentAddressed() const; }; } -- cgit v1.2.3 From 6403508f5a2fcf073b2a0d4e5fcf5f5ebb890384 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 17 Jun 2020 15:13:00 +0000 Subject: Use `ansicolor.hh` in `nix repl` rather than duplicates --- src/libutil/ansicolor.hh | 2 ++ src/nix/repl.cc | 33 +++++++++++++-------------------- 2 files changed, 15 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/libutil/ansicolor.hh b/src/libutil/ansicolor.hh index 8ae07b092..a38c2d798 100644 --- a/src/libutil/ansicolor.hh +++ b/src/libutil/ansicolor.hh @@ -11,5 +11,7 @@ namespace nix { #define ANSI_GREEN "\e[32;1m" #define ANSI_YELLOW "\e[33;1m" #define ANSI_BLUE "\e[34;1m" +#define ANSI_MAGENTA "\e[35m;1m" +#define ANSI_CYAN "\e[36m;1m" } diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 4bcaaeebf..617d49614 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -19,6 +19,7 @@ extern "C" { } #endif +#include "ansicolor.hh" #include "shared.hh" #include "eval.hh" #include "eval-inline.hh" @@ -37,14 +38,6 @@ extern "C" { namespace nix { -#define ESC_RED "\033[31m" -#define ESC_GRE "\033[32m" -#define ESC_YEL "\033[33m" -#define ESC_BLU "\033[34;1m" -#define ESC_MAG "\033[35m" -#define ESC_CYA "\033[36m" -#define ESC_END "\033[0m" - struct NixRepl : gc { string curDir; @@ -645,25 +638,25 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m switch (v.type) { case tInt: - str << ESC_CYA << v.integer << ESC_END; + str << ANSI_CYAN << v.integer << ANSI_NORMAL; break; case tBool: - str << ESC_CYA << (v.boolean ? "true" : "false") << ESC_END; + str << ANSI_CYAN << (v.boolean ? "true" : "false") << ANSI_NORMAL; break; case tString: - str << ESC_YEL; + str << ANSI_YELLOW; printStringValue(str, v.string.s); - str << ESC_END; + str << ANSI_NORMAL; break; case tPath: - str << ESC_GRE << v.path << ESC_END; // !!! escaping? + str << ANSI_GREEN << v.path << ANSI_NORMAL; // !!! escaping? break; case tNull: - str << ESC_CYA "null" ESC_END; + str << ANSI_CYAN "null" ANSI_NORMAL; break; case tAttrs: { @@ -699,7 +692,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m try { printValue(str, *i.second, maxDepth - 1, seen); } catch (AssertionError & e) { - str << ESC_RED "«error: " << e.msg() << "»" ESC_END; + str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL; } str << "; "; } @@ -725,7 +718,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m try { printValue(str, *v.listElems()[n], maxDepth - 1, seen); } catch (AssertionError & e) { - str << ESC_RED "«error: " << e.msg() << "»" ESC_END; + str << ANSI_RED "«error: " << e.msg() << "»" ANSI_NORMAL; } str << " "; } @@ -737,16 +730,16 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m case tLambda: { std::ostringstream s; s << v.lambda.fun->pos; - str << ESC_BLU "«lambda @ " << filterANSIEscapes(s.str()) << "»" ESC_END; + str << ANSI_BLUE "«lambda @ " << filterANSIEscapes(s.str()) << "»" ANSI_NORMAL; break; } case tPrimOp: - str << ESC_MAG "«primop»" ESC_END; + str << ANSI_MAGENTA "«primop»" ANSI_NORMAL; break; case tPrimOpApp: - str << ESC_BLU "«primop-app»" ESC_END; + str << ANSI_BLUE "«primop-app»" ANSI_NORMAL; break; case tFloat: @@ -754,7 +747,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m break; default: - str << ESC_RED "«unknown»" ESC_END; + str << ANSI_RED "«unknown»" ANSI_NORMAL; break; } -- cgit v1.2.3 From 480b54e1c6a200a2d4a39c1fa24fa195db12953f Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 17 Jun 2020 17:36:33 +0200 Subject: fixup! Reserve the `__contentAddressed` derivation parameter --- src/libstore/build.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 9b72175c7..e1d812b09 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -809,9 +809,6 @@ private: /* Whether this is a fixed-output derivation. */ bool fixedOutput; - /* Whether this is a content adressed derivation */ - bool contentAddressed = false; - /* Whether to run the build in a private network namespace. */ bool privateNetwork = false; @@ -1198,9 +1195,7 @@ void DerivationGoal::haveDerivation() parsedDrv = std::make_unique(drvPath, *drv); - contentAddressed = parsedDrv->contentAddressed(); - - if (this->contentAddressed) { + if (parsedDrv->contentAddressed()) { settings.requireExperimentalFeature("content-addressed-paths"); throw Error("content-addressed-paths isn't implemented yet"); } -- cgit v1.2.3