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.
This doesn't do the right thing here, because it evaluates
the test with nix that is evaluating the `nixpkgs-lib-tests-nix-${nix.version}`
derivation, not the Nix/Lix under test. This was just really busted for a long
time.
`fromHexString` is backed by `builtins.fromTOML`. Per [the TOML
v1.0.0 specification]:
> Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be
> accepted and handled losslessly. If an integer cannot be represented
> losslessly, an error must be thrown.
[the TOML v1.0.0 specification]: <https://toml.io/en/v1.0.0#integer>
The saturating behaviour of the toml11 version currently used
by Nix is not lossless, and is therefore a violation of the TOML
specification. We should not be relying on it. This blocks the update
of toml11, as it became stricter about reporting this condition.
This, yes, is arguably an evaluation compatibility break. However,
integer overflow was recently explicitly defined as an error by
both Nix and Lix, as opposed to the C++ undefined behaviour it was
previously implemented as:
* <https://nix.dev/manual/nix/stable/release-notes/rl-2.25>
* <https://docs.lix.systems/manual/lix/stable/release-notes/rl-2.91.html#fixes>
This included changing `builtins.fromJSON` to explicitly
reject overflowing integer literals. I believe that the case for
`builtins.fromTOML` is comparable, and that we are effectively testing
undefined behaviour in TOML and the Nix language here, in the same way
that we would have been if we had tests relying on overflowing integer
arithmetic. I am not aware of any use of this behaviour outside of
these tests; the reverted toml11 bump in Nix did not break the 23.11
evaluation regression test, for example.
C++ undefined behaviour is not involved here, as toml11 used the C++
formatted input functions that are specified to saturate on invalid
values. But it’s still a violation of the TOML specification caused
by insufficient error checking in the old version of the library,
and inconsistent with the handling of overflowing literals in the
rest of Nix.
Let’s fix this so that Nix implementations can correctly flag up
this error and we can unblock the toml11 update.
This was cherry‐picked from
<https://github.com/NixOS/nixpkgs/pull/266705> and merged as part of
<https://github.com/NixOS/nixpkgs/pull/318712>, despite there being
a blocking review on the former pointing out these kinds of issues.
This documents some of the dodgy behaviour. It also can’t handle
negative literals. It might be worth considering deprecating and
dropping this, by inlining it into `lib.network.ipv6.fromString`,
its only in‐tree user.
This allows individual types to add attributes that would be discarded during normal evaluation.
Some examples:
types.submodule performs a submodule evluation which yields an 'evalModules' result.
It returns '.config' but makes the original result accessible via 'valueMeta' allowing introspection of '.options' and all other kinds of module evaluation results
types.attrsOf returns an attribute set of the nestedType.
It makes each valueMeta available under the corresponding attribute name.
This has been marked insecure a while ago, as some CVEs have not been
backported. Even if *some* CVEs are fixed, we'd need **all** of them to
be, to get it back into the cache.
Not having it in the cache means, we can not test it in CI. This means
we can't make sure to actually support this version to evaluate Nixpkgs.