aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/flake/config.cc2
-rw-r--r--src/libexpr/parser/parser.cc7
-rw-r--r--src/libstore/filetransfer.cc13
-rw-r--r--src/libstore/machines.cc2
-rw-r--r--src/libutil/archive.cc2
-rw-r--r--src/libutil/file-descriptor.cc2
-rw-r--r--src/libutil/hash.cc2
-rw-r--r--src/libutil/logging.cc2
-rw-r--r--src/libutil/shlex.cc2
-rw-r--r--src/libutil/terminal.cc23
-rw-r--r--src/libutil/terminal.hh12
-rw-r--r--src/libutil/url.cc2
-rw-r--r--src/nix/flake.cc24
-rw-r--r--src/nix/meson.build17
14 files changed, 79 insertions, 33 deletions
diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc
index adcf7fd10..558b3e9b9 100644
--- a/src/libexpr/flake/config.cc
+++ b/src/libexpr/flake/config.cc
@@ -53,7 +53,7 @@ void ConfigFile::apply()
bool trusted = whitelist.count(baseName);
if (!trusted) {
- switch (nix::fetchSettings.acceptFlakeConfig) {
+ switch (nix::fetchSettings.acceptFlakeConfig.get()) {
case AcceptFlakeConfig::True: {
trusted = true;
break;
diff --git a/src/libexpr/parser/parser.cc b/src/libexpr/parser/parser.cc
index a00586c36..b7a105fe7 100644
--- a/src/libexpr/parser/parser.cc
+++ b/src/libexpr/parser/parser.cc
@@ -12,7 +12,6 @@
#include "state.hh"
#include <charconv>
-#include <clocale>
#include <memory>
// flip this define when doing parser development to enable some g checks.
@@ -254,7 +253,8 @@ struct AttrState : SubexprState {
std::vector<AttrName> attrs;
- void pushAttr(auto && attr, PosIdx) { attrs.emplace_back(std::move(attr)); }
+ template <typename T>
+ void pushAttr(T && attr, PosIdx) { attrs.emplace_back(std::forward<T>(attr)); }
};
template<> struct BuildAST<grammar::attr::simple> {
@@ -290,7 +290,8 @@ struct InheritState : SubexprState {
std::unique_ptr<Expr> from;
PosIdx fromPos;
- void pushAttr(auto && attr, PosIdx pos) { attrs.emplace_back(std::move(attr), pos); }
+ template <typename T>
+ void pushAttr(T && attr, PosIdx pos) { attrs.emplace_back(std::forward<T>(attr), pos); }
};
template<> struct BuildAST<grammar::inherit::from> {
diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc
index fcb947f96..566dc65d4 100644
--- a/src/libstore/filetransfer.cc
+++ b/src/libstore/filetransfer.cc
@@ -477,8 +477,17 @@ struct curlFileTransfer : public FileTransfer
~curlFileTransfer()
{
- stopWorkerThread();
-
+ try {
+ stopWorkerThread();
+ } catch (nix::Error e) {
+ // This can only fail if a socket to our own process cannot be
+ // written to, so it is always a bug in the program if it fails.
+ //
+ // Joining the thread would probably only cause a deadlock if this
+ // happened, so just die on purpose.
+ printError("failed to join curl file transfer worker thread: %1%", e.what());
+ std::terminate();
+ }
workerThread.join();
if (curlm) curl_multi_cleanup(curlm);
diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc
index 833482815..d0897b81f 100644
--- a/src/libstore/machines.cc
+++ b/src/libstore/machines.cc
@@ -33,7 +33,7 @@ Machine::Machine(decltype(storeUri) storeUri,
systemTypes(systemTypes),
sshKey(sshKey),
maxJobs(maxJobs),
- speedFactor(speedFactor == 0.0f ? 1.0f : std::move(speedFactor)),
+ speedFactor(speedFactor == 0.0f ? 1.0f : speedFactor),
supportedFeatures(supportedFeatures),
mandatoryFeatures(mandatoryFeatures),
sshPublicHostKey(sshPublicHostKey)
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index 5fb33ef56..d4da18f14 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -192,7 +192,7 @@ static Generator<Entry> parseObject(Source & source, const Path & path)
#define EXPECT(raw, kind) \
do { \
const auto s = readString(source); \
- if (s != raw) { \
+ if (s != (raw)) { \
throw badArchive("expected " kind " tag"); \
} \
co_yield MetadataString{s}; \
diff --git a/src/libutil/file-descriptor.cc b/src/libutil/file-descriptor.cc
index ab69b5754..037cd5297 100644
--- a/src/libutil/file-descriptor.cc
+++ b/src/libutil/file-descriptor.cc
@@ -131,7 +131,7 @@ AutoCloseFD::AutoCloseFD(AutoCloseFD && that) : fd{that.fd}
}
-AutoCloseFD & AutoCloseFD::operator =(AutoCloseFD && that)
+AutoCloseFD & AutoCloseFD::operator =(AutoCloseFD && that) noexcept(false)
{
close();
fd = that.fd;
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index a762dc940..0ce82f273 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -229,7 +229,7 @@ Hash::Hash(std::string_view rest, HashType type, bool isSRI)
for (unsigned int n = 0; n < rest.size(); ++n) {
char c = rest[rest.size() - n - 1];
- unsigned char digit;
+ size_t digit;
for (digit = 0; digit < base32Chars.size(); ++digit) /* !!! slow */
if (base32Chars[digit] == c) break;
if (digit >= 32)
diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc
index 53460f729..cbeb7aa36 100644
--- a/src/libutil/logging.cc
+++ b/src/libutil/logging.cc
@@ -37,7 +37,7 @@ void Logger::warn(const std::string & msg)
void Logger::writeToStdout(std::string_view s)
{
- writeFull(STDOUT_FILENO, s);
+ writeFull(STDOUT_FILENO, filterANSIEscapes(s, !shouldANSI(), std::numeric_limits<unsigned int>::max(), false));
writeFull(STDOUT_FILENO, "\n");
}
diff --git a/src/libutil/shlex.cc b/src/libutil/shlex.cc
index 21fa0502a..b923fef65 100644
--- a/src/libutil/shlex.cc
+++ b/src/libutil/shlex.cc
@@ -62,6 +62,8 @@ std::vector<std::string> shell_split(const std::string & input)
begin = ++iterator;
}
break;
+ // no other relevant cases; silence exhaustiveness compiler warning
+ default: break;
}
}
diff --git a/src/libutil/terminal.cc b/src/libutil/terminal.cc
index b58331d04..2ba1cb81b 100644
--- a/src/libutil/terminal.cc
+++ b/src/libutil/terminal.cc
@@ -9,12 +9,25 @@ namespace nix {
bool shouldANSI()
{
- return isatty(STDERR_FILENO)
- && getEnv("TERM").value_or("dumb") != "dumb"
- && !(getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value());
+ // Implements the behaviour described by https://bixense.com/clicolors/
+ // As well as https://force-color.org/ for compatibility, since it fits in the same shape.
+ // NO_COLOR CLICOLOR CLICOLOR_FORCE Colours?
+ // set x x No
+ // unset x set Yes
+ // unset x unset If attached to a terminal
+ // [we choose the "modern" approach of colour-by-default]
+ auto compute = []() -> bool {
+ bool mustNotColour = getEnv("NO_COLOR").has_value() || getEnv("NOCOLOR").has_value();
+ bool shouldForce = getEnv("CLICOLOR_FORCE").has_value() || getEnv("FORCE_COLOR").has_value();
+ bool isTerminal = isatty(STDERR_FILENO) && getEnv("TERM").value_or("dumb") != "dumb";
+ return !mustNotColour && (shouldForce || isTerminal);
+ };
+ static bool cached = compute();
+ return cached;
}
-std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width)
+// FIXME(jade): replace with TerminalCodeEater. wowie this is evil code.
+std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int width, bool eatTabs)
{
std::string t, e;
size_t w = 0;
@@ -43,7 +56,7 @@ std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int w
t += e;
}
- else if (*i == '\t') {
+ else if (*i == '\t' && eatTabs) {
i++; t += ' '; w++;
while (w < (size_t) width && w % 8) {
t += ' '; w++;
diff --git a/src/libutil/terminal.hh b/src/libutil/terminal.hh
index 43df5bd70..2c422ecff 100644
--- a/src/libutil/terminal.hh
+++ b/src/libutil/terminal.hh
@@ -9,6 +9,15 @@ namespace nix {
/**
* Determine whether ANSI escape sequences are appropriate for the
* present output.
+ *
+ * This follows the rules described on https://bixense.com/clicolors/
+ * with CLICOLOR defaulted to enabled (and thus ignored).
+ *
+ * That is to say, the following procedure is followed in order:
+ * - NO_COLOR or NOCOLOR set -> always disable colour
+ * - CLICOLOR_FORCE or FORCE_COLOR set -> enable colour
+ * - The output is a tty; TERM != "dumb" -> enable colour
+ * - Otherwise -> disable colour
*/
bool shouldANSI();
@@ -21,7 +30,8 @@ bool shouldANSI();
*/
std::string filterANSIEscapes(std::string_view s,
bool filterAll = false,
- unsigned int width = std::numeric_limits<unsigned int>::max());
+ unsigned int width = std::numeric_limits<unsigned int>::max(),
+ bool eatTabs = true);
/**
* Recalculate the window size, updating a global variable. Used in the
diff --git a/src/libutil/url.cc b/src/libutil/url.cc
index 87146ca56..2de50dd4d 100644
--- a/src/libutil/url.cc
+++ b/src/libutil/url.cc
@@ -63,7 +63,7 @@ std::string percentDecode(std::string_view in)
if (i + 2 >= in.size())
throw BadURL("invalid URI parameter '%s'", in);
try {
- decoded += std::stoul(std::string(in, i + 1, 2), 0, 16);
+ decoded += char8_t(std::stoul(std::string(in, i + 1, 2), 0, 16));
i += 3;
} catch (...) {
throw BadURL("invalid URI parameter '%s'", in);
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 9d18b81b8..672930342 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -209,6 +209,11 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
{
auto lockedFlake = lockFlake();
auto & flake = lockedFlake.flake;
+ auto formatTime = [](time_t time) -> std::string {
+ std::ostringstream os{};
+ os << std::put_time(std::localtime(&time), "%F %T");
+ return os.str();
+ };
if (json) {
nlohmann::json j;
@@ -260,7 +265,7 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
if (auto lastModified = flake.lockedRef.input.getLastModified())
logger->cout(
ANSI_BOLD "Last modified:" ANSI_NORMAL " %s",
- std::put_time(std::localtime(&*lastModified), "%F %T"));
+ formatTime(*lastModified));
if (!lockedFlake.lockFile.root->inputs.empty())
logger->cout(ANSI_BOLD "Inputs:" ANSI_NORMAL);
@@ -275,16 +280,25 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
bool last = i + 1 == node.inputs.size();
if (auto lockedNode = std::get_if<0>(&input.second)) {
- logger->cout("%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s",
- prefix + (last ? treeLast : treeConn), input.first,
+ // ├───agenix: github:ryantm/agenix/8d37c5bdeade12b6479c85acd133063ab53187a0
+ logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s",
+ prefix, last ? treeLast : treeConn, input.first,
(*lockedNode)->lockedRef);
+ // ├───lix: https://git.lix.systems/api/v1/repos/lix-project <....>
+ // │ Last modified: 2024-07-31 21:01:34
+ if (auto lastModified = (*lockedNode)->lockedRef.input.getLastModified()) {
+ logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s",
+ prefix, last ? treeNull : treeLine, "Last modified", formatTime(*lastModified));
+ }
+
bool firstVisit = visited.insert(*lockedNode).second;
if (firstVisit) recurse(**lockedNode, prefix + (last ? treeNull : treeLine));
} else if (auto follows = std::get_if<1>(&input.second)) {
- logger->cout("%s" ANSI_BOLD "%s" ANSI_NORMAL " follows input '%s'",
- prefix + (last ? treeLast : treeConn), input.first,
+ // │ ├───darwin follows input 'flake-utils'
+ logger->cout("%s%s" ANSI_BOLD "%s" ANSI_NORMAL " follows input '%s'",
+ prefix, last ? treeLast : treeConn, input.first,
printInputPath(*follows));
}
}
diff --git a/src/nix/meson.build b/src/nix/meson.build
index 97387e402..80223a390 100644
--- a/src/nix/meson.build
+++ b/src/nix/meson.build
@@ -1,8 +1,8 @@
-generate_manpage_gen = gen_header.process(meson.project_source_root() / 'doc/manual/generate-manpage.nix')
-
-utils_gen = gen_header.process(meson.project_source_root() / 'doc/manual/utils.nix')
-
-get_env_gen = gen_header.process('get-env.sh')
+nix_generated_headers = [
+ gen_header.process(meson.project_source_root() / 'doc/manual/generate-manpage.nix'),
+ gen_header.process(meson.project_source_root() / 'doc/manual/utils.nix'),
+ gen_header.process('get-env.sh'),
+]
# src/nix/profile.cc includes src/nix/profile.md, which includes "doc/files/profiles.md.gen.hh".
# Unfortunately, https://github.com/mesonbuild/meson/issues/2320.
@@ -18,7 +18,7 @@ run_command(
meson.current_build_dir() / 'doc/files/profiles.md',
check : true,
)
-profiles_md_gen = gen_header.process(
+nix_generated_headers += gen_header.process(
meson.current_build_dir() / 'doc/files/profiles.md',
preserve_path_from : meson.current_build_dir(),
)
@@ -74,10 +74,7 @@ nix_sources = files(
nix = executable(
'nix',
nix_sources,
- generate_manpage_gen,
- utils_gen,
- get_env_gen,
- profiles_md_gen,
+ nix_generated_headers,
nix2_commands_sources,
dependencies : [
libasanoptions,