aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/experimental-features.cc209
-rw-r--r--src/libutil/experimental-features.hh5
-rw-r--r--src/libutil/util.hh10
3 files changed, 142 insertions, 82 deletions
diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc
index fc8590674..305b0cb11 100644
--- a/src/libutil/experimental-features.cc
+++ b/src/libutil/experimental-features.cc
@@ -5,75 +5,131 @@
namespace nix {
-std::map<ExperimentalFeature, std::pair<std::string, std::string>> stringifiedXpFeatures = {
- { Xp::CaDerivations, {"ca-derivations", R"(
- Allows derivations to be content-addressed in order to prevent rebuilds
- when changes to the derivation do not result in changes to the
- derivation's output. See
- [__contentAddressed](../language/advanced-attributes.md#adv-attr-__contentAddressed)
- for more info.
- )"} },
- { Xp::ImpureDerivations, {"impure-derivations", R"(
- Allows derivations to produce non-fixed outputs by setting the `__impure`
- derivation attribute to `true`. See [these release
- notes](../release-notes/rl-2.8.md) for an example.
- )"} },
- { Xp::Flakes, {"flakes", R"(
- Allows for derivations to be packaged in flakes. See the manual entry for
- [`nix flake`](../command-ref/new-cli/nix3-flake.md) or this [detailed
- introduction](https://www.tweag.io/blog/2020-05-25-flakes/) for more info.
- )"} },
- { Xp::NixCommand, {"nix-command", R"(
- Allows the usage of the new `nix` CLI subcommands, such as `nix build`, `nix
- develop`, `nix run`, etc. See the manual for
- [`nix`](../command-ref/new-cli/nix.md) for more info.
- )"} },
- { Xp::RecursiveNix, {"recursive-nix", R"(
- Allow Nix derivations to call Nix in order to recursively build derivations.
- See [this
- commit](https://github.com/edolstra/nix/commit/1a27aa7d64ffe6fc36cfca4d82bdf51c4d8cf717)
- for more info.
- )"} },
- { Xp::NoUrlLiterals, {"no-url-literals", R"(
- Disallows unquoted URLs as part of the Nix language syntax. See [RFC
- 45](https://github.com/NixOS/rfcs/pull/45) for more info.
- )"} },
- { Xp::FetchClosure, {"fetch-closure", R"(
- Enables the use of the `fetchClosure` function in the standard library. See
- the docs for [`fetchClosure`](../language/builtins.md#builtins-fetchClosure)
- for more info.
- )"} },
- { Xp::ReplFlake, {"repl-flake", R"(
- Allows the user to enter a Nix REPL within a flake, e.g. `nix repl nixpkgs`
- or `nix repl .#foo`.
- )"} },
- { Xp::AutoAllocateUids, {"auto-allocate-uids", R"(
- Allows Nix to automatically pick UIDs for builds, rather than creating
- `nixbld*` user accounts. See [here](#conf-auto-allocate-uids) for more info.
- )"} },
- { Xp::Cgroups, {"cgroups", R"(
- Allows Nix to execute builds inside cgroups. See
- [`use-cgroups`](#conf-use-cgroups) for more info.
- )"} },
- { Xp::DiscardReferences, {"discard-references", R"(
- Enables the use of the `unsafeDiscardReferences` attribute in derivations
- that use structured attributes. This disables scanning of outputs for
- runtime dependencies.
- )"} },
+struct ExperimentalFeatureDetails
+{
+ ExperimentalFeature tag;
+ std::string_view name;
+ std::string_view description;
};
+constexpr std::array<ExperimentalFeatureDetails, 11> xpFeatureDetails = {{
+ {
+ .tag = Xp::CaDerivations,
+ .name = "ca-derivations",
+ .description = R"(
+ Allows derivations to be content-addressed in order to prevent rebuilds
+ when changes to the derivation do not result in changes to the
+ derivation's output. See
+ [__contentAddressed](../language/advanced-attributes.md#adv-attr-__contentAddressed)
+ for more info.
+ )",
+ },
+ {
+ .tag = Xp::ImpureDerivations,
+ .name = "impure-derivations",
+ .description = R"(
+ Allows derivations to produce non-fixed outputs by setting the `__impure`
+ derivation attribute to `true`. See [these release
+ notes](../release-notes/rl-2.8.md) for an example.
+ )",
+ },
+ {
+ .tag = Xp::Flakes,
+ .name = "flakes",
+ .description = R"(
+ Allows for derivations to be packaged in flakes. See the manual entry for
+ [`nix flake`](../command-ref/new-cli/nix3-flake.md) or this [detailed
+ introduction](https://www.tweag.io/blog/2020-05-25-flakes/) for more info.
+ )",
+ },
+ {
+ .tag = Xp::NixCommand,
+ .name = "nix-command",
+ .description = R"(
+ Allows the usage of the new `nix` CLI subcommands, such as `nix build`, `nix
+ develop`, `nix run`, etc. See the manual for
+ [`nix`](../command-ref/new-cli/nix.md) for more info.
+ )",
+ },
+ {
+ .tag = Xp::RecursiveNix,
+ .name = "recursive-nix",
+ .description = R"(
+ Allow Nix derivations to call Nix in order to recursively build derivations.
+ See [this
+ commit](https://github.com/edolstra/nix/commit/1a27aa7d64ffe6fc36cfca4d82bdf51c4d8cf717)
+ for more info.
+ )",
+ },
+ {
+ .tag = Xp::NoUrlLiterals,
+ .name = "no-url-literals",
+ .description = R"(
+ Disallows unquoted URLs as part of the Nix language syntax. See [RFC
+ 45](https://github.com/NixOS/rfcs/pull/45) for more info.
+ )",
+ },
+ {
+ .tag = Xp::FetchClosure,
+ .name = "fetch-closure",
+ .description = R"(
+ Enables the use of the `fetchClosure` function in the standard library. See
+ the docs for [`fetchClosure`](../language/builtins.md#builtins-fetchClosure)
+ for more info.
+ )",
+ },
+ {
+ .tag = Xp::ReplFlake,
+ .name = "repl-flake",
+ .description = R"(
+ Allows the user to enter a Nix REPL within a flake, e.g. `nix repl nixpkgs`
+ or `nix repl .#foo`.
+ )",
+ },
+ {
+ .tag = Xp::AutoAllocateUids,
+ .name = "auto-allocate-uids",
+ .description = R"(
+ Allows Nix to automatically pick UIDs for builds, rather than creating
+ `nixbld*` user accounts. See [here](#conf-auto-allocate-uids) for more info.
+ )",
+ },
+ {
+ .tag = Xp::Cgroups,
+ .name = "cgroups",
+ .description = R"(
+ Allows Nix to execute builds inside cgroups. See
+ [`use-cgroups`](#conf-use-cgroups) for more info.
+ )",
+ },
+ {
+ .tag = Xp::DiscardReferences,
+ .name = "discard-references",
+ .description = R"(
+ Enables the use of the `unsafeDiscardReferences` attribute in derivations
+ that use structured attributes. This disables scanning of outputs for
+ runtime dependencies.
+ )",
+ },
+}};
+
+static_assert(
+ []() constexpr {
+ for (auto [index, feature] : enumerate(xpFeatureDetails))
+ if (index != (size_t)feature.tag)
+ return false;
+ return true;
+ }(),
+ "array order does not match enum tag order");
+
const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name)
{
using ReverseXpMap = std::map<std::string_view, ExperimentalFeature>;
- static auto reverseXpMap = []()
- {
+ static std::unique_ptr<ReverseXpMap> reverseXpMap = [](){
auto reverseXpMap = std::make_unique<ReverseXpMap>();
- std::string_view name;
- for (auto & [feature, featureStringPair] : stringifiedXpFeatures) {
- name = featureStringPair.first;
- (*reverseXpMap)[name] = feature;
- }
+ for (auto & xpFeature : xpFeatureDetails)
+ (*reverseXpMap)[xpFeature.name] = xpFeature.tag;
return reverseXpMap;
}();
@@ -83,25 +139,29 @@ const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::str
return std::nullopt;
}
-std::string_view showExperimentalFeature(const ExperimentalFeature feature)
+std::string_view showExperimentalFeature(const ExperimentalFeature tag)
{
- const auto ret = get(stringifiedXpFeatures, feature);
- assert(ret);
- return ret->first;
+ assert((size_t)tag < xpFeatureDetails.size());
+ return xpFeatureDetails[(size_t)tag].name;
}
std::string getExperimentalFeaturesList() {
std::string experimentalFeaturesList = R"(
- Experimental Nix features to enable.
- Current experimental features are the following:
+ Experimental Nix features to enable.
+ Current experimental features are the following:
)";
- std::string experimentalFeatureString;
- for (auto& [feature, featureStringPair] : stringifiedXpFeatures) {
- experimentalFeatureString = " - `" + featureStringPair.first + "`\n";
- experimentalFeatureString += featureStringPair.second + "\n\n";
- experimentalFeaturesList += experimentalFeatureString;
+ for (auto & xpFeature : xpFeatureDetails) {
+ experimentalFeaturesList += std::string {}
+ /* length of this first string must be 12, matching the indent of
+ the descriptions in the xpFeatureDetails literal. FIXME compute
+ markdown in a less hacky way. */
+ + " - "
+ + "`" + xpFeature.name + "`"
+ + "\n"
+ + xpFeature.description
+ + "\n\n";
}
return experimentalFeaturesList;
@@ -110,10 +170,9 @@ std::string getExperimentalFeaturesList() {
std::set<ExperimentalFeature> parseFeatures(const std::set<std::string> & rawFeatures)
{
std::set<ExperimentalFeature> res;
- for (auto & rawFeature : rawFeatures) {
+ for (auto & rawFeature : rawFeatures)
if (auto feature = parseExperimentalFeature(rawFeature))
res.insert(*feature);
- }
return res;
}
diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh
index 7c2f872c5..650fa6533 100644
--- a/src/libutil/experimental-features.hh
+++ b/src/libutil/experimental-features.hh
@@ -11,8 +11,9 @@ namespace nix {
/**
* The list of available experimental features.
*
- * If you update this, don’t forget to also change the map defining their string
- * representation and documentation in the corresponding `.cc` file as well.
+ * If you update this, don’t forget to also change the map defining
+ * their string representation and documentation in the corresponding
+ * `.cc` file as well.
*/
enum struct ExperimentalFeature
{
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 6c2706cc1..94c9efb74 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -730,16 +730,16 @@ constexpr auto enumerate(T && iterable)
{
size_t i;
TIter iter;
- bool operator != (const iterator & other) const { return iter != other.iter; }
- void operator ++ () { ++i; ++iter; }
- auto operator * () const { return std::tie(i, *iter); }
+ constexpr bool operator != (const iterator & other) const { return iter != other.iter; }
+ constexpr void operator ++ () { ++i; ++iter; }
+ constexpr auto operator * () const { return std::tie(i, *iter); }
};
struct iterable_wrapper
{
T iterable;
- auto begin() { return iterator{ 0, std::begin(iterable) }; }
- auto end() { return iterator{ 0, std::end(iterable) }; }
+ constexpr auto begin() { return iterator{ 0, std::begin(iterable) }; }
+ constexpr auto end() { return iterator{ 0, std::end(iterable) }; }
};
return iterable_wrapper{ std::forward<T>(iterable) };