mirror of
https://github.com/NixOS/nix.git
synced 2025-12-07 01:21:00 +01:00
Apply clang-format universally.
* It is tough to contribute to a project that doesn't use a formatter, * It is extra hard to contribute to a project which has configured the formatter, but ignores it for some files * Code formatting makes it harder to hide obscure / weird bugs by accident or on purpose, Let's rip the bandaid off? Note that PRs currently in flight should be able to be merged relatively easily by applying `clang-format` to their tip prior to merge.
This commit is contained in:
parent
41bf87ec70
commit
e4f62e4608
587 changed files with 23258 additions and 23135 deletions
|
|
@ -51,15 +51,16 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
|
|||
warn(e.what());
|
||||
}
|
||||
}},
|
||||
.completer = [](AddCompletions & completions, size_t index, std::string_view prefix) {
|
||||
if (index == 0) {
|
||||
std::map<std::string, Config::SettingInfo> settings;
|
||||
globalConfig.getSettings(settings);
|
||||
for (auto & s : settings)
|
||||
if (hasPrefix(s.first, prefix))
|
||||
completions.add(s.first, fmt("Set the `%s` setting.", s.first));
|
||||
}
|
||||
},
|
||||
.completer =
|
||||
[](AddCompletions & completions, size_t index, std::string_view prefix) {
|
||||
if (index == 0) {
|
||||
std::map<std::string, Config::SettingInfo> settings;
|
||||
globalConfig.getSettings(settings);
|
||||
for (auto & s : settings)
|
||||
if (hasPrefix(s.first, prefix))
|
||||
completions.add(s.first, fmt("Set the `%s` setting.", s.first));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
|
|
@ -75,16 +76,15 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
|
|||
.shortName = 'j',
|
||||
.description = "The maximum number of parallel builds.",
|
||||
.labels = Strings{"jobs"},
|
||||
.handler = {[=](std::string s) {
|
||||
settings.set("max-jobs", s);
|
||||
}},
|
||||
.handler = {[=](std::string s) { settings.set("max-jobs", s); }},
|
||||
});
|
||||
|
||||
std::string cat = "Options to override configuration settings";
|
||||
globalConfig.convertToArgs(*this, cat);
|
||||
|
||||
// Backward compatibility hack: nix-env already had a --system flag.
|
||||
if (programName == "nix-env") longFlags.erase("system");
|
||||
if (programName == "nix-env")
|
||||
longFlags.erase("system");
|
||||
|
||||
hiddenCategories.insert(cat);
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ void MixCommonArgs::initialFlagsProcessed()
|
|||
pluginsInited();
|
||||
}
|
||||
|
||||
template <typename T, typename>
|
||||
template<typename T, typename>
|
||||
void MixPrintJSON::printJSON(const T /* nlohmann::json */ & json)
|
||||
{
|
||||
auto suspension = logger->suspend();
|
||||
|
|
@ -108,5 +108,4 @@ void MixPrintJSON::printJSON(const T /* nlohmann::json */ & json)
|
|||
|
||||
template void MixPrintJSON::printJSON(const nlohmann::json & json);
|
||||
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
//static constexpr auto commonArgsCategory = "Miscellaneous common options";
|
||||
// static constexpr auto commonArgsCategory = "Miscellaneous common options";
|
||||
static constexpr auto loggingCategory = "Logging-related options";
|
||||
static constexpr auto miscCategory = "Miscellaneous global options";
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ struct MixPrintJSON : virtual Args
|
|||
* but you _can_ print a sole JSON string by explicitly coercing it to
|
||||
* `nlohmann::json` first.
|
||||
*/
|
||||
template <typename T, typename = std::enable_if_t<std::is_same_v<T, nlohmann::json>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_same_v<T, nlohmann::json>>>
|
||||
void printJSON(const T & json);
|
||||
};
|
||||
|
||||
|
|
@ -113,13 +113,12 @@ struct MixRepair : virtual Args
|
|||
{
|
||||
addFlag({
|
||||
.longName = "repair",
|
||||
.description =
|
||||
"During evaluation, rewrite missing or corrupted files in the Nix store. "
|
||||
"During building, rebuild missing or corrupted store paths.",
|
||||
.description = "During evaluation, rewrite missing or corrupted files in the Nix store. "
|
||||
"During building, rebuild missing or corrupted store paths.",
|
||||
.category = miscCategory,
|
||||
.handler = {&repair, Repair},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@
|
|||
namespace nix {
|
||||
|
||||
enum class LogFormat {
|
||||
raw,
|
||||
rawWithLogs,
|
||||
internalJSON,
|
||||
bar,
|
||||
barWithLogs,
|
||||
raw,
|
||||
rawWithLogs,
|
||||
internalJSON,
|
||||
bar,
|
||||
barWithLogs,
|
||||
};
|
||||
|
||||
void setLogFormat(const std::string & logFormatStr);
|
||||
void setLogFormat(const LogFormat & logFormat);
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
///@file
|
||||
|
||||
namespace nix {
|
||||
|
|
@ -9,4 +10,4 @@ namespace nix {
|
|||
*/
|
||||
void initPlugins();
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -21,10 +21,12 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
|
|||
*/
|
||||
void initNix(bool loadConfig = true);
|
||||
|
||||
void parseCmdLine(int argc, char * * argv,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
void parseCmdLine(
|
||||
int argc, char ** argv, std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
void parseCmdLine(const std::string & programName, const Strings & args,
|
||||
void parseCmdLine(
|
||||
const std::string & programName,
|
||||
const Strings & args,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
void printVersion(const std::string & programName);
|
||||
|
|
@ -37,33 +39,27 @@ void printGCWarning();
|
|||
class Store;
|
||||
struct MissingPaths;
|
||||
|
||||
void printMissing(
|
||||
ref<Store> store,
|
||||
const std::vector<DerivedPath> & paths,
|
||||
Verbosity lvl = lvlInfo);
|
||||
void printMissing(ref<Store> store, const std::vector<DerivedPath> & paths, Verbosity lvl = lvlInfo);
|
||||
|
||||
void printMissing(
|
||||
ref<Store> store,
|
||||
const MissingPaths & missing,
|
||||
Verbosity lvl = lvlInfo);
|
||||
void printMissing(ref<Store> store, const MissingPaths & missing, Verbosity lvl = lvlInfo);
|
||||
|
||||
std::string getArg(const std::string & opt,
|
||||
Strings::iterator & i, const Strings::iterator & end);
|
||||
std::string getArg(const std::string & opt, Strings::iterator & i, const Strings::iterator & end);
|
||||
|
||||
template<class N> N getIntArg(const std::string & opt,
|
||||
Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
||||
template<class N>
|
||||
N getIntArg(const std::string & opt, Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
|
||||
{
|
||||
++i;
|
||||
if (i == end) throw UsageError("'%1%' requires an argument", opt);
|
||||
if (i == end)
|
||||
throw UsageError("'%1%' requires an argument", opt);
|
||||
return string2IntWithUnitPrefix<N>(*i);
|
||||
}
|
||||
|
||||
|
||||
struct LegacyArgs : public MixCommonArgs, public RootArgs
|
||||
{
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg;
|
||||
|
||||
LegacyArgs(const std::string & programName,
|
||||
LegacyArgs(
|
||||
const std::string & programName,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
bool processFlag(Strings::iterator & pos, Strings::iterator end) override;
|
||||
|
|
@ -71,7 +67,6 @@ struct LegacyArgs : public MixCommonArgs, public RootArgs
|
|||
bool processArgs(const Strings & args, bool finish) override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The constructor of this class starts a pager if standard output is a
|
||||
* terminal and $PAGER is set. Standard output is redirected to the
|
||||
|
|
@ -92,7 +87,6 @@ private:
|
|||
|
||||
extern volatile ::sig_atomic_t blockInt;
|
||||
|
||||
|
||||
/* GC helpers. */
|
||||
|
||||
std::string showBytes(uint64_t bytes);
|
||||
|
|
@ -103,12 +97,16 @@ struct PrintFreed
|
|||
{
|
||||
bool show;
|
||||
const GCResults & results;
|
||||
|
||||
PrintFreed(bool show, const GCResults & results)
|
||||
: show(show), results(results) { }
|
||||
: show(show)
|
||||
, results(results)
|
||||
{
|
||||
}
|
||||
|
||||
~PrintFreed();
|
||||
};
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* Install a SIGSEGV handler to detect stack overflows.
|
||||
|
|
@ -141,4 +139,4 @@ extern std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler;
|
|||
void defaultStackOverflowHandler(siginfo_t * info, void * ctx);
|
||||
#endif
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -53,4 +53,4 @@ void setLogFormat(const LogFormat & logFormat)
|
|||
logger = makeDefaultLogger();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -117,4 +117,4 @@ void initPlugins()
|
|||
pluginSettings.pluginFiles.pluginsLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -133,8 +133,9 @@ public:
|
|||
updateThread.join();
|
||||
}
|
||||
|
||||
void pause() override {
|
||||
auto state (state_.lock());
|
||||
void pause() override
|
||||
{
|
||||
auto state(state_.lock());
|
||||
state->suspensions++;
|
||||
if (state->suspensions > 1) {
|
||||
// already paused
|
||||
|
|
@ -145,8 +146,9 @@ public:
|
|||
writeToStderr("\r\e[K");
|
||||
}
|
||||
|
||||
void resume() override {
|
||||
auto state (state_.lock());
|
||||
void resume() override
|
||||
{
|
||||
auto state(state_.lock());
|
||||
if (state->suspensions == 0) {
|
||||
log(lvlError, "nix::ProgressBar: resume() called without a matching preceding pause(). This is a bug.");
|
||||
return;
|
||||
|
|
@ -168,7 +170,8 @@ public:
|
|||
|
||||
void log(Verbosity lvl, std::string_view s) override
|
||||
{
|
||||
if (lvl > verbosity) return;
|
||||
if (lvl > verbosity)
|
||||
return;
|
||||
auto state(state_.lock());
|
||||
log(*state, lvl, s);
|
||||
}
|
||||
|
|
@ -193,20 +196,21 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
||||
const std::string & s, const Fields & fields, ActivityId parent) override
|
||||
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() && type != actBuildWaiting)
|
||||
log(*state, lvl, s + "...");
|
||||
|
||||
state->activities.emplace_back(ActInfo {
|
||||
.s = s,
|
||||
.type = type,
|
||||
.parent = parent,
|
||||
.startTime = std::chrono::steady_clock::now()
|
||||
});
|
||||
state->activities.emplace_back(
|
||||
ActInfo{.s = s, .type = type, .parent = parent, .startTime = std::chrono::steady_clock::now()});
|
||||
auto i = std::prev(state->activities.end());
|
||||
state->its.emplace(act, i);
|
||||
state->activitiesByType[type].its.emplace(act, i);
|
||||
|
|
@ -231,11 +235,11 @@ public:
|
|||
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);
|
||||
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) {
|
||||
|
|
@ -265,8 +269,10 @@ public:
|
|||
{
|
||||
while (act != 0) {
|
||||
auto i = state.its.find(act);
|
||||
if (i == state.its.end()) break;
|
||||
if (i->second->type == type) return true;
|
||||
if (i == state.its.end())
|
||||
break;
|
||||
if (i->second->type == type)
|
||||
return true;
|
||||
act = i->second->parent;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -400,7 +406,8 @@ public:
|
|||
auto nextWakeup = std::chrono::milliseconds::max();
|
||||
|
||||
state.haveUpdate = false;
|
||||
if (state.isPaused() || !state.active) return nextWakeup;
|
||||
if (state.isPaused() || !state.active)
|
||||
return nextWakeup;
|
||||
|
||||
std::string line;
|
||||
|
||||
|
|
@ -414,7 +421,8 @@ public:
|
|||
auto now = std::chrono::steady_clock::now();
|
||||
|
||||
if (!state.activities.empty()) {
|
||||
if (!status.empty()) line += " ";
|
||||
if (!status.empty())
|
||||
line += " ";
|
||||
auto i = state.activities.rbegin();
|
||||
|
||||
while (i != state.activities.rend()) {
|
||||
|
|
@ -426,7 +434,9 @@ public:
|
|||
if (i->startTime + delay < now)
|
||||
break;
|
||||
else
|
||||
nextWakeup = std::min(nextWakeup, std::chrono::duration_cast<std::chrono::milliseconds>(delay - (now - i->startTime)));
|
||||
nextWakeup = std::min(
|
||||
nextWakeup,
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(delay - (now - i->startTime)));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
|
@ -439,14 +449,16 @@ public:
|
|||
line += ")";
|
||||
}
|
||||
if (!i->lastLine.empty()) {
|
||||
if (!i->s.empty()) line += ": ";
|
||||
if (!i->s.empty())
|
||||
line += ": ";
|
||||
line += i->lastLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto width = getWindowSize().second;
|
||||
if (width <= 0) width = std::numeric_limits<decltype(width)>::max();
|
||||
if (width <= 0)
|
||||
width = std::numeric_limits<decltype(width)>::max();
|
||||
|
||||
redraw("\r" + filterANSIEscapes(line, false, width) + ANSI_NORMAL + "\e[K");
|
||||
|
||||
|
|
@ -459,51 +471,60 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
expected = std::max(expected, act.expected);
|
||||
|
||||
std::string s;
|
||||
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);
|
||||
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(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);
|
||||
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);
|
||||
}
|
||||
if (failed)
|
||||
s += fmt(" (" ANSI_RED "%d failed" ANSI_NORMAL ")", failed / unit);
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
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;
|
||||
};
|
||||
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");
|
||||
|
||||
|
|
@ -511,9 +532,17 @@ public:
|
|||
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 += ')'; }
|
||||
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);
|
||||
|
|
@ -522,7 +551,8 @@ public:
|
|||
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 += ", ";
|
||||
if (!res.empty())
|
||||
res += ", ";
|
||||
res += s;
|
||||
}
|
||||
}
|
||||
|
|
@ -531,12 +561,14 @@ public:
|
|||
showActivity(actVerifyPaths, "%s paths verified");
|
||||
|
||||
if (state.corruptedPaths) {
|
||||
if (!res.empty()) res += ", ";
|
||||
if (!res.empty())
|
||||
res += ", ";
|
||||
res += fmt(ANSI_RED "%d corrupted" ANSI_NORMAL, state.corruptedPaths);
|
||||
}
|
||||
|
||||
if (state.untrustedPaths) {
|
||||
if (!res.empty()) res += ", ";
|
||||
if (!res.empty())
|
||||
res += ", ";
|
||||
res += fmt(ANSI_RED "%d untrusted" ANSI_NORMAL, state.untrustedPaths);
|
||||
}
|
||||
|
||||
|
|
@ -558,10 +590,12 @@ public:
|
|||
std::optional<char> ask(std::string_view msg) override
|
||||
{
|
||||
auto state(state_.lock());
|
||||
if (!state->active) return {};
|
||||
if (!state->active)
|
||||
return {};
|
||||
std::cerr << fmt("\r\e[K%s ", msg);
|
||||
auto s = trim(readLine(getStandardInput(), true));
|
||||
if (s.size() != 1) return {};
|
||||
if (s.size() != 1)
|
||||
return {};
|
||||
draw(*state);
|
||||
return s[0];
|
||||
}
|
||||
|
|
@ -577,4 +611,4 @@ std::unique_ptr<Logger> makeProgressBar()
|
|||
return std::make_unique<ProgressBar>(isTTY());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#ifdef __linux__
|
||||
#include <features.h>
|
||||
# include <features.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
|
@ -30,30 +30,27 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
char * * savedArgv;
|
||||
char ** savedArgv;
|
||||
|
||||
static bool gcWarning = true;
|
||||
|
||||
void printGCWarning()
|
||||
{
|
||||
if (!gcWarning) return;
|
||||
if (!gcWarning)
|
||||
return;
|
||||
static bool haveWarned = false;
|
||||
warnOnce(haveWarned,
|
||||
warnOnce(
|
||||
haveWarned,
|
||||
"you did not specify '--add-root'; "
|
||||
"the result might be removed by the garbage collector");
|
||||
}
|
||||
|
||||
|
||||
void printMissing(ref<Store> store, const std::vector<DerivedPath> & paths, Verbosity lvl)
|
||||
{
|
||||
printMissing(store, store->queryMissing(paths), lvl);
|
||||
}
|
||||
|
||||
|
||||
void printMissing(
|
||||
ref<Store> store,
|
||||
const MissingPaths & missing,
|
||||
Verbosity lvl)
|
||||
void printMissing(ref<Store> store, const MissingPaths & missing, Verbosity lvl)
|
||||
{
|
||||
if (!missing.willBuild.empty()) {
|
||||
if (missing.willBuild.size() == 1)
|
||||
|
|
@ -70,51 +67,53 @@ void printMissing(
|
|||
const float downloadSizeMiB = missing.downloadSize / (1024.f * 1024.f);
|
||||
const float narSizeMiB = missing.narSize / (1024.f * 1024.f);
|
||||
if (missing.willSubstitute.size() == 1) {
|
||||
printMsg(lvl, "this path will be fetched (%.2f MiB download, %.2f MiB unpacked):",
|
||||
downloadSizeMiB,
|
||||
narSizeMiB);
|
||||
printMsg(
|
||||
lvl, "this path will be fetched (%.2f MiB download, %.2f MiB unpacked):", downloadSizeMiB, narSizeMiB);
|
||||
} else {
|
||||
printMsg(lvl, "these %d paths will be fetched (%.2f MiB download, %.2f MiB unpacked):",
|
||||
printMsg(
|
||||
lvl,
|
||||
"these %d paths will be fetched (%.2f MiB download, %.2f MiB unpacked):",
|
||||
missing.willSubstitute.size(),
|
||||
downloadSizeMiB,
|
||||
narSizeMiB);
|
||||
}
|
||||
std::vector<const StorePath *> willSubstituteSorted = {};
|
||||
std::for_each(missing.willSubstitute.begin(), missing.willSubstitute.end(),
|
||||
[&](const StorePath &p) { willSubstituteSorted.push_back(&p); });
|
||||
std::sort(willSubstituteSorted.begin(), willSubstituteSorted.end(),
|
||||
[](const StorePath *lhs, const StorePath *rhs) {
|
||||
if (lhs->name() == rhs->name())
|
||||
return lhs->to_string() < rhs->to_string();
|
||||
else
|
||||
return lhs->name() < rhs->name();
|
||||
});
|
||||
std::for_each(missing.willSubstitute.begin(), missing.willSubstitute.end(), [&](const StorePath & p) {
|
||||
willSubstituteSorted.push_back(&p);
|
||||
});
|
||||
std::sort(
|
||||
willSubstituteSorted.begin(), willSubstituteSorted.end(), [](const StorePath * lhs, const StorePath * rhs) {
|
||||
if (lhs->name() == rhs->name())
|
||||
return lhs->to_string() < rhs->to_string();
|
||||
else
|
||||
return lhs->name() < rhs->name();
|
||||
});
|
||||
for (auto p : willSubstituteSorted)
|
||||
printMsg(lvl, " %s", store->printStorePath(*p));
|
||||
}
|
||||
|
||||
if (!missing.unknown.empty()) {
|
||||
printMsg(lvl, "don't know how to build these paths%s:",
|
||||
(settings.readOnlyMode ? " (may be caused by read-only store access)" : ""));
|
||||
printMsg(
|
||||
lvl,
|
||||
"don't know how to build these paths%s:",
|
||||
(settings.readOnlyMode ? " (may be caused by read-only store access)" : ""));
|
||||
for (auto & i : missing.unknown)
|
||||
printMsg(lvl, " %s", store->printStorePath(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string getArg(const std::string & opt,
|
||||
Strings::iterator & i, const Strings::iterator & end)
|
||||
std::string getArg(const std::string & opt, Strings::iterator & i, const Strings::iterator & end)
|
||||
{
|
||||
++i;
|
||||
if (i == end) throw UsageError("'%1%' requires an argument", opt);
|
||||
if (i == end)
|
||||
throw UsageError("'%1%' requires an argument", opt);
|
||||
return *i;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static void sigHandler(int signo) { }
|
||||
static void sigHandler(int signo) {}
|
||||
#endif
|
||||
|
||||
|
||||
void initNix(bool loadConfig)
|
||||
{
|
||||
/* Turn on buffering for cerr. */
|
||||
|
|
@ -139,7 +138,8 @@ void initNix(bool loadConfig)
|
|||
|
||||
/* Install a dummy SIGUSR1 handler for use with pthread_kill(). */
|
||||
act.sa_handler = sigHandler;
|
||||
if (sigaction(SIGUSR1, &act, 0)) throw SysError("handling SIGUSR1");
|
||||
if (sigaction(SIGUSR1, &act, 0))
|
||||
throw SysError("handling SIGUSR1");
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
|
@ -147,19 +147,26 @@ void initNix(bool loadConfig)
|
|||
* Instead, add a dummy sigaction handler, and signalHandlerThread
|
||||
* can handle the rest. */
|
||||
act.sa_handler = sigHandler;
|
||||
if (sigaction(SIGWINCH, &act, 0)) throw SysError("handling SIGWINCH");
|
||||
if (sigaction(SIGWINCH, &act, 0))
|
||||
throw SysError("handling SIGWINCH");
|
||||
|
||||
/* Disable SA_RESTART for interrupts, so that system calls on this thread
|
||||
* error with EINTR like they do on Linux.
|
||||
* Most signals on BSD systems default to SA_RESTART on, but Nix
|
||||
* expects EINTR from syscalls to properly exit. */
|
||||
act.sa_handler = SIG_DFL;
|
||||
if (sigaction(SIGINT, &act, 0)) throw SysError("handling SIGINT");
|
||||
if (sigaction(SIGTERM, &act, 0)) throw SysError("handling SIGTERM");
|
||||
if (sigaction(SIGHUP, &act, 0)) throw SysError("handling SIGHUP");
|
||||
if (sigaction(SIGPIPE, &act, 0)) throw SysError("handling SIGPIPE");
|
||||
if (sigaction(SIGQUIT, &act, 0)) throw SysError("handling SIGQUIT");
|
||||
if (sigaction(SIGTRAP, &act, 0)) throw SysError("handling SIGTRAP");
|
||||
if (sigaction(SIGINT, &act, 0))
|
||||
throw SysError("handling SIGINT");
|
||||
if (sigaction(SIGTERM, &act, 0))
|
||||
throw SysError("handling SIGTERM");
|
||||
if (sigaction(SIGHUP, &act, 0))
|
||||
throw SysError("handling SIGHUP");
|
||||
if (sigaction(SIGPIPE, &act, 0))
|
||||
throw SysError("handling SIGPIPE");
|
||||
if (sigaction(SIGQUIT, &act, 0))
|
||||
throw SysError("handling SIGQUIT");
|
||||
if (sigaction(SIGTRAP, &act, 0))
|
||||
throw SysError("handling SIGTRAP");
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
@ -176,52 +183,52 @@ void initNix(bool loadConfig)
|
|||
umask(0022);
|
||||
}
|
||||
|
||||
|
||||
LegacyArgs::LegacyArgs(const std::string & programName,
|
||||
LegacyArgs::LegacyArgs(
|
||||
const std::string & programName,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
: MixCommonArgs(programName), parseArg(parseArg)
|
||||
: MixCommonArgs(programName)
|
||||
, parseArg(parseArg)
|
||||
{
|
||||
addFlag({
|
||||
.longName = "no-build-output",
|
||||
.shortName = 'Q',
|
||||
.description = "Do not show build output.",
|
||||
.handler = {[&]() {setLogFormat(LogFormat::raw); }},
|
||||
.handler = {[&]() { setLogFormat(LogFormat::raw); }},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "keep-failed",
|
||||
.shortName ='K',
|
||||
.shortName = 'K',
|
||||
.description = "Keep temporary directories of failed builds.",
|
||||
.handler = {&(bool&) settings.keepFailed, true},
|
||||
.handler = {&(bool &) settings.keepFailed, true},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "keep-going",
|
||||
.shortName ='k',
|
||||
.shortName = 'k',
|
||||
.description = "Keep going after a build fails.",
|
||||
.handler = {&(bool&) settings.keepGoing, true},
|
||||
.handler = {&(bool &) settings.keepGoing, true},
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName = "fallback",
|
||||
.description = "Build from source if substitution fails.",
|
||||
.handler = {&(bool&) settings.tryFallback, true},
|
||||
.handler = {&(bool &) settings.tryFallback, true},
|
||||
});
|
||||
|
||||
auto intSettingAlias = [&](char shortName, const std::string & longName,
|
||||
const std::string & description, const std::string & dest)
|
||||
{
|
||||
addFlag({
|
||||
.longName = longName,
|
||||
.shortName = shortName,
|
||||
.description = description,
|
||||
.labels = {"n"},
|
||||
.handler = {[=](std::string s) {
|
||||
auto n = string2IntWithUnitPrefix<uint64_t>(s);
|
||||
settings.set(dest, std::to_string(n));
|
||||
}},
|
||||
});
|
||||
};
|
||||
auto intSettingAlias =
|
||||
[&](char shortName, const std::string & longName, const std::string & description, const std::string & dest) {
|
||||
addFlag({
|
||||
.longName = longName,
|
||||
.shortName = shortName,
|
||||
.description = description,
|
||||
.labels = {"n"},
|
||||
.handler = {[=](std::string s) {
|
||||
auto n = string2IntWithUnitPrefix<uint64_t>(s);
|
||||
settings.set(dest, std::to_string(n));
|
||||
}},
|
||||
});
|
||||
};
|
||||
|
||||
intSettingAlias(0, "cores", "Maximum number of CPU cores to use inside a build.", "cores");
|
||||
intSettingAlias(0, "max-silent-time", "Number of seconds of silence before a build is killed.", "max-silent-time");
|
||||
|
|
@ -243,23 +250,24 @@ LegacyArgs::LegacyArgs(const std::string & programName,
|
|||
.longName = "store",
|
||||
.description = "The URL of the Nix store to use.",
|
||||
.labels = {"store-uri"},
|
||||
.handler = {&(std::string&) settings.storeUri},
|
||||
.handler = {&(std::string &) settings.storeUri},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool LegacyArgs::processFlag(Strings::iterator & pos, Strings::iterator end)
|
||||
{
|
||||
if (MixCommonArgs::processFlag(pos, end)) return true;
|
||||
if (MixCommonArgs::processFlag(pos, end))
|
||||
return true;
|
||||
bool res = parseArg(pos, end);
|
||||
if (res) ++pos;
|
||||
if (res)
|
||||
++pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool LegacyArgs::processArgs(const Strings & args, bool finish)
|
||||
{
|
||||
if (args.empty()) return true;
|
||||
if (args.empty())
|
||||
return true;
|
||||
assert(args.size() == 1);
|
||||
Strings ss(args);
|
||||
auto pos = ss.begin();
|
||||
|
|
@ -268,21 +276,20 @@ bool LegacyArgs::processArgs(const Strings & args, bool finish)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void parseCmdLine(int argc, char * * argv,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
void parseCmdLine(
|
||||
int argc, char ** argv, std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
{
|
||||
parseCmdLine(std::string(baseNameOf(argv[0])), argvToStrings(argc, argv), parseArg);
|
||||
}
|
||||
|
||||
|
||||
void parseCmdLine(const std::string & programName, const Strings & args,
|
||||
void parseCmdLine(
|
||||
const std::string & programName,
|
||||
const Strings & args,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
{
|
||||
LegacyArgs(programName, parseArg).parseCmdline(args);
|
||||
}
|
||||
|
||||
|
||||
void printVersion(const std::string & programName)
|
||||
{
|
||||
std::cout << fmt("%1% (Nix) %2%", programName, nixVersion) << std::endl;
|
||||
|
|
@ -296,9 +303,7 @@ void printVersion(const std::string & programName)
|
|||
std::cout << "Additional system types: " << concatStringsSep(", ", settings.extraPlatforms.get()) << "\n";
|
||||
std::cout << "Features: " << concatStringsSep(", ", cfg) << "\n";
|
||||
std::cout << "System configuration file: " << settings.nixConfDir + "/nix.conf" << "\n";
|
||||
std::cout << "User configuration files: " <<
|
||||
concatStringsSep(":", settings.nixUserConfFiles)
|
||||
<< "\n";
|
||||
std::cout << "User configuration files: " << concatStringsSep(":", settings.nixUserConfFiles) << "\n";
|
||||
std::cout << "Store directory: " << settings.nixStore << "\n";
|
||||
std::cout << "State directory: " << settings.nixStateDir << "\n";
|
||||
std::cout << "Data directory: " << settings.nixDataDir << "\n";
|
||||
|
|
@ -349,13 +354,15 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RunPager::RunPager()
|
||||
{
|
||||
if (!isatty(STDOUT_FILENO)) return;
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
return;
|
||||
char * pager = getenv("NIX_PAGER");
|
||||
if (!pager) pager = getenv("PAGER");
|
||||
if (pager && ((std::string) pager == "" || (std::string) pager == "cat")) return;
|
||||
if (!pager)
|
||||
pager = getenv("PAGER");
|
||||
if (pager && ((std::string) pager == "" || (std::string) pager == "cat"))
|
||||
return;
|
||||
|
||||
logger->stop();
|
||||
|
||||
|
|
@ -386,7 +393,6 @@ RunPager::RunPager()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
RunPager::~RunPager()
|
||||
{
|
||||
try {
|
||||
|
|
@ -402,13 +408,10 @@ RunPager::~RunPager()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
PrintFreed::~PrintFreed()
|
||||
{
|
||||
if (show)
|
||||
std::cout << fmt("%d store paths deleted, %s freed\n",
|
||||
results.paths.size(),
|
||||
showBytes(results.bytesFreed));
|
||||
std::cout << fmt("%d store paths deleted, %s freed\n", results.paths.size(), showBytes(results.bytesFreed));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
|
||||
static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
|
||||
{
|
||||
/* Detect stack overflows by comparing the faulting address with
|
||||
|
|
@ -28,7 +27,8 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
|
|||
|
||||
if (haveSP) {
|
||||
ptrdiff_t diff = (char *) info->si_addr - sp;
|
||||
if (diff < 0) diff = -diff;
|
||||
if (diff < 0)
|
||||
diff = -diff;
|
||||
if (diff < 4096) {
|
||||
nix::stackOverflowHandler(info, ctx);
|
||||
}
|
||||
|
|
@ -39,13 +39,13 @@ static void sigsegvHandler(int signo, siginfo_t * info, void * ctx)
|
|||
sigfillset(&act.sa_mask);
|
||||
act.sa_handler = SIG_DFL;
|
||||
act.sa_flags = 0;
|
||||
if (sigaction(SIGSEGV, &act, 0)) abort();
|
||||
if (sigaction(SIGSEGV, &act, 0))
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
void detectStackOverflow()
|
||||
{
|
||||
#if defined(SA_SIGINFO) && defined (SA_ONSTACK)
|
||||
#if defined(SA_SIGINFO) && defined(SA_ONSTACK)
|
||||
/* Install a SIGSEGV handler to detect stack overflows. This
|
||||
requires an alternative stack, otherwise the signal cannot be
|
||||
delivered when we're out of stack space. */
|
||||
|
|
@ -53,9 +53,11 @@ void detectStackOverflow()
|
|||
stack.ss_size = 4096 * 4 + MINSIGSTKSZ;
|
||||
static auto stackBuf = std::make_unique<std::vector<char>>(stack.ss_size);
|
||||
stack.ss_sp = stackBuf->data();
|
||||
if (!stack.ss_sp) throw Error("cannot allocate alternative stack");
|
||||
if (!stack.ss_sp)
|
||||
throw Error("cannot allocate alternative stack");
|
||||
stack.ss_flags = 0;
|
||||
if (sigaltstack(&stack, 0) == -1) throw SysError("cannot set alternative stack");
|
||||
if (sigaltstack(&stack, 0) == -1)
|
||||
throw SysError("cannot set alternative stack");
|
||||
|
||||
struct sigaction act;
|
||||
sigfillset(&act.sa_mask);
|
||||
|
|
@ -68,10 +70,11 @@ void detectStackOverflow()
|
|||
|
||||
std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler(defaultStackOverflowHandler);
|
||||
|
||||
void defaultStackOverflowHandler(siginfo_t * info, void * ctx) {
|
||||
void defaultStackOverflowHandler(siginfo_t * info, void * ctx)
|
||||
{
|
||||
char msg[] = "error: stack overflow (possible infinite recursion)\n";
|
||||
[[gnu::unused]] auto res = write(2, msg, strlen(msg));
|
||||
_exit(1); // maybe abort instead?
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue