1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 23:12:44 +01:00

Merge pull request #14232 from roberth/dyndrv-messages

Better dyndrv messages
This commit is contained in:
John Ericson 2025-10-14 15:40:27 +00:00 committed by GitHub
commit 1fb4ff8c0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 154 additions and 15 deletions

View file

@ -500,10 +500,10 @@ bool ExperimentalFeatureSettings::isEnabled(const ExperimentalFeature & feature)
return std::find(f.begin(), f.end(), feature) != f.end();
}
void ExperimentalFeatureSettings::require(const ExperimentalFeature & feature) const
void ExperimentalFeatureSettings::require(const ExperimentalFeature & feature, std::string reason) const
{
if (!isEnabled(feature))
throw MissingExperimentalFeature(feature);
throw MissingExperimentalFeature(feature, std::move(reason));
}
bool ExperimentalFeatureSettings::isEnabled(const std::optional<ExperimentalFeature> & feature) const

View file

@ -1,5 +1,6 @@
#include "nix/util/experimental-features.hh"
#include "nix/util/fmt.hh"
#include "nix/util/strings.hh"
#include "nix/util/util.hh"
#include <nlohmann/json.hpp>
@ -376,11 +377,13 @@ std::set<ExperimentalFeature> parseFeatures(const StringSet & rawFeatures)
return res;
}
MissingExperimentalFeature::MissingExperimentalFeature(ExperimentalFeature feature)
MissingExperimentalFeature::MissingExperimentalFeature(ExperimentalFeature feature, std::string reason)
: Error(
"experimental Nix feature '%1%' is disabled; add '--extra-experimental-features %1%' to enable it",
showExperimentalFeature(feature))
"experimental Nix feature '%1%' is disabled%2%; add '--extra-experimental-features %1%' to enable it",
showExperimentalFeature(feature),
Uncolored(optionalBracket(" (", reason, ")")))
, missingFeature(feature)
, reason{reason}
{
}

View file

@ -463,7 +463,20 @@ struct ExperimentalFeatureSettings : Config
* Require an experimental feature be enabled, throwing an error if it is
* not.
*/
void require(const ExperimentalFeature &) const;
void require(const ExperimentalFeature &, std::string reason = "") const;
/**
* Require an experimental feature be enabled, throwing an error if it is
* not. The reason is lazily evaluated only if the feature is disabled.
*/
template<typename GetReason>
requires std::invocable<GetReason> && std::convertible_to<std::invoke_result_t<GetReason>, std::string>
void require(const ExperimentalFeature & feature, GetReason && getReason) const
{
if (isEnabled(feature))
return;
require(feature, getReason());
}
/**
* `std::nullopt` pointer means no feature, which means there is nothing that could be

View file

@ -88,7 +88,9 @@ public:
*/
ExperimentalFeature missingFeature;
MissingExperimentalFeature(ExperimentalFeature missingFeature);
std::string reason;
MissingExperimentalFeature(ExperimentalFeature missingFeature, std::string reason = "");
};
/**

View file

@ -3,6 +3,7 @@
#include "nix/util/types.hh"
#include <list>
#include <optional>
#include <set>
#include <string_view>
#include <string>
@ -93,6 +94,44 @@ extern template std::string dropEmptyInitThenConcatStringsSep(std::string_view,
*/
std::list<std::string> shellSplitString(std::string_view s);
/**
* Conditionally wrap a string with prefix and suffix brackets.
*
* If `content` is empty, returns an empty string.
* Otherwise, returns `prefix + content + suffix`.
*
* Example:
* optionalBracket(" (", "foo", ")") == " (foo)"
* optionalBracket(" (", "", ")") == ""
*
* Design note: this would have been called `optionalParentheses`, except this
* function is more general and more explicit. Parentheses typically *also* need
* to be prefixed with a space in order to fit nicely in a piece of natural
* language.
*/
std::string optionalBracket(std::string_view prefix, std::string_view content, std::string_view suffix);
/**
* Overload for optional content.
*
* If `content` is nullopt or contains an empty string, returns an empty string.
* Otherwise, returns `prefix + *content + suffix`.
*
* Example:
* optionalBracket(" (", std::optional<std::string>("foo"), ")") == " (foo)"
* optionalBracket(" (", std::nullopt, ")") == ""
* optionalBracket(" (", std::optional<std::string>(""), ")") == ""
*/
template<typename T>
requires std::convertible_to<T, std::string_view>
std::string optionalBracket(std::string_view prefix, const std::optional<T> & content, std::string_view suffix)
{
if (!content || std::string_view(*content).empty()) {
return "";
}
return optionalBracket(prefix, std::string_view(*content), suffix);
}
/**
* Hash implementation that can be used for zero-copy heterogenous lookup from
* P1690R1[1] in unordered containers.

View file

@ -138,4 +138,18 @@ std::list<std::string> shellSplitString(std::string_view s)
return result;
}
std::string optionalBracket(std::string_view prefix, std::string_view content, std::string_view suffix)
{
if (content.empty()) {
return "";
}
std::string result;
result.reserve(prefix.size() + content.size() + suffix.size());
result.append(prefix);
result.append(content);
result.append(suffix);
return result;
}
} // namespace nix