By: Tom Sydney Kerckhove <syd@cs-syd.eu>
config: exclude DeprecatedWarnSetting names from GlobalConfig::toKeyValue()
Since nix 2.34 (commit 5184f844b, "New diagnostics infra"), every `nix`
command run inside a post-build-hook emits a spurious deprecation warning:
warning: 'warn-short-path-literals' is deprecated,
use 'lint-short-path-literals = ignore' instead
even when the user never set `warn-short-path-literals`. The cause:
`DeprecatedWarnSetting` registers the deprecated name via `addSetting()`
with `isAlias = false`, making it a primary setting. `Config::getSettings()`
skips aliases but includes primary settings. `GlobalConfig::toKeyValue()`
calls `getSettings()` and serialises the result into `NIX_CONFIG`. The
daemon injects this into every post-build-hook subprocess environment
(`derivation-goal.cc`) and into `nix repl` subprocesses (`repl.cc`). Any
`nix` command in the hook then reads `NIX_CONFIG`, hits
`DeprecatedWarnSetting::assign()`, and fires the warning.
Fix: add an `excludeFromKeyValue` flag to `Config::SettingData`. When set,
`getSettings()` skips the setting, removing it from `GlobalConfig::toKeyValue()`
/ `NIX_CONFIG`. A new `Config::excludeSettingFromKeyValue()` method (which
asserts the name exists, to catch misuse) sets the flag. `DeprecatedWarnSetting`
calls it immediately after `addSetting()`.
This is preferable to making the setting a true alias (`isAlias = true`),
which would also drop the `--warn-short-path-literals` /
`--no-warn-short-path-literals` CLI flags since `convertToArgs()` skips
aliases. With `excludeFromKeyValue`, reading the setting from `nix.conf` /
`NIX_CONFIG` still works and still emits the deprecation warning when
explicitly set by the user; CLI flags are unaffected.
Add a regression test in `tests/functional/short-path-literals.sh` that
builds a derivation with a post-build-hook capturing `$NIX_CONFIG` and
asserts `warn-short-path-literals` is absent.
Fixes: https://github.com/NixOS/nix/issues/15819