From ab4281e9679ab820dcd4f98f1a20e5fdf8874b93 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Mon, 11 Aug 2025 19:05:50 +0200 Subject: [PATCH] lib/minfeatures: init from minver.nix The concept of having a "minimum supported Nix version" doesn't work anymore today, for the following reasons: - With multiple forks / implementations of Nix available, their feature sets and versions will differ. We'd need *multiple* minimum versions, one for each implementation. - Lix does not expose its real version. It only reports "2.18.3-lix", even though its real version is in the 2.90+ range. - A minimum version has the expectation that it could be *raised* in the future. That's not possible with Lix, because Lix will always and forever report the above version. - A minimum version has the expectation that *all* versions bigger than the minimum are supported. That was already quite a stretch when minver was 2.3 and none of the Nix versions between 2.4 and 2.23 were packed anymore. But it's impossible for us to test all these non-LTS versions anyway: We don't have Nix 2.18, 2.19, 2.20, 2.21, 2.22, 2.23, 2.25, 2.26 and 2.27 available in Nixpkgs at the time of this writing. With their policy around `builtins.nixVersion`, Lix forces our hand: We need to replace minver.nix with a "feature detection" mechanism. This PR introduces the first two features: - The availability of `builtins.nixVersion`: If this is not available, the version of Nix is so old, that we surely don't support it anymore. - The value of `builtins.nixVersion` being greater or equal to 2.18. Note, that this does **not** imply support for Nix 2.18. Instead, explicitly supported versions of Lix and Nix are only these that we actually test against. If, eventually, we realize that the supported versions have advanced and Nixpkgs has adopted a feature only available in newer versions, we will have to add a feature check for this. Put differently: The list of features in `minfeatures.nix` is not expected to be complete. It's a list of known-to-be-bad conditions that will cause problems when evaluating Nixpkgs. Their only purpose is to be able to show a helpful error message. Some other versions might also not be supported, but might fail with more subtle errors. That's just reality and has always been the case previously as well. --- default.nix | 10 ++++++---- lib/README.md | 2 +- lib/minfeatures.nix | 19 +++++++++++++++++++ lib/minver.nix | 2 -- 4 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 lib/minfeatures.nix delete mode 100644 lib/minver.nix diff --git a/default.nix b/default.nix index afba797b01fc..5f759c13014d 100644 --- a/default.nix +++ b/default.nix @@ -1,13 +1,15 @@ let - requiredVersion = import ./lib/minver.nix; + missingFeatures = map ({ description, ... }: description) (import ./lib/minfeatures.nix).missing; in -if !builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.nixVersion == 1 then +if missingFeatures != [ ] then abort '' - This version of Nixpkgs requires Nix >= ${requiredVersion} but it is being - evaluated with Nix ${builtins.nixVersion or "(too old to know)"}, please upgrade: + This version of Nixpkgs requires an implementation of Nix with the following features: + - ${builtins.concatStringsSep "\n- " missingFeatures} + + Your are evaluating with Nix ${builtins.nixVersion or "(too old to know)"}, please upgrade: - If you are running NixOS, `nixos-rebuild' can be used to upgrade your system. diff --git a/lib/README.md b/lib/README.md index 1cf10670ecb2..d7c757a15c8c 100644 --- a/lib/README.md +++ b/lib/README.md @@ -19,7 +19,7 @@ This file evaluates to an attribute set containing two separate kinds of attribu Example: `lib.take` is an alias for `lib.lists.take`. Most files in this directory are definitions of sub-libraries, but there are a few others: -- [`minver.nix`](minver.nix): A string of the minimum version of Nix that is required to evaluate Nixpkgs. +- [`minfeatures.nix`](minfeatures.nix): A list of conditions for the used Nix version to match that are required to evaluate Nixpkgs. - [`tests`](tests): Tests, see [Running tests](#running-tests) - [`release.nix`](tests/release.nix): A derivation aggregating all tests - [`misc.nix`](tests/misc.nix): Evaluation unit tests for most sub-libraries diff --git a/lib/minfeatures.nix b/lib/minfeatures.nix new file mode 100644 index 000000000000..da804a854942 --- /dev/null +++ b/lib/minfeatures.nix @@ -0,0 +1,19 @@ +let + features = [ + { + description = "the `nixVersion` builtin"; + condition = builtins ? nixVersion; + } + { + description = "`builtins.nixVersion` reports at least 2.18"; + condition = builtins ? nixVersion && builtins.compareVersions "2.18" builtins.nixVersion != 1; + } + ]; + + evaluated = builtins.partition ({ condition, ... }: condition) features; +in +{ + all = features; + supported = evaluated.right; + missing = evaluated.wrong; +} diff --git a/lib/minver.nix b/lib/minver.nix deleted file mode 100644 index c9fc45354d2e..000000000000 --- a/lib/minver.nix +++ /dev/null @@ -1,2 +0,0 @@ -# Expose the minimum required version for evaluating Nixpkgs -"2.18"