Change:
The current process for renames puts out-of-tree modules in a situation where users are confronted with warnings they can't solve, and neither can the maintainers. Steps to reproduce the behavior: one change, create the new option/package/..., create the alias with a deprecation warning that goes into effect immediately -of-tree modules, such as home-manager, nix-darwin, start emitting warnings reports warning -of-tree module maintainer can't do anything, because stable release does not have the new option All generated warnings can be resolved by the user. Suggested process: one change, create the new option/package/... and the alias but no deprecation warning 1-7 months pass. All current branches now support the new way. enable the warning on master (more on that) -of-tree modules, such as home-manager, nix-darwin, start emitting warnings warnings can now be fixed To facilitate the process, we can add an argument to functions like to indicate the first release that will support the change. We'll maintain two (hidden?) version numbers that we update during the NixOS release process. For example, at the time of writing, the only supported stable version is 21.11 and 22.05 has not been released yet. To enable warnings on , we only need to update . Interestingly, we'll be deprecating functions that deprecate without . Sounds meta, but it's not complicated. It just means that some old style deprecations will slip through the net for some more time. (also a big one, but no complaints yet)
This is also related to NixOS/rfcs, which was a previous attempt at establishing general such deprecation behaviors

Discussion:
- Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated). - Description, default and example should be provided. - Ensure that option changes are backward compatible. <del> - `mkRenamedOptionModule` and `mkAliasOptionModule` functions provide way to make option changes backward compatible. </del> <ins> - `mkRenamedOptionModuleWith` provides a way to make option changes backward compatible. </ins> - Ensure that removed options are declared with `mkRemovedOptionModule` - Ensure that changes that are not backward compatible are mentioned in release notes. - Ensure that documentations affected by the change is updated.

inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max importJSON importTOML warn warnIf throwIfNot checkListOfEnum <del> info showWarnings nixpkgsVersion version </del> <ins> info showWarnings nixpkgsVersion version isInOldestRelease </ins> mod compare splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; inherit (self.fixedPoints) fix fix' converge extends composeExtensions

mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule <del> mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule </del> <ins> mkRenamedOptionModule mkRenamedOptionModuleWith mkMergedOptionModule mkChangedOptionModule </ins> mkAliasOptionModule mkDerivedConfig doRename; inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption

use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; }; <ins> mkRenamedOptionModuleWith = { /* Old option path as list of strings. */ from, /* New option path as list of strings. */ to, /* Release number of the first release that contains the rename, ignoring backports. Set it to the upcoming release, matching the nixpkgs/.version file. */ sinceRelease, }: doRename { inherit from to; visible = false; warn = lib.isInOldestRelease sinceRelease; use = lib.warnIf (lib.isInOldestRelease sinceRelease) "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; }; </ins> /* Return a module that causes a warning to be shown if any of the "from" option is defined; the defined values can be used in the "mergeFn" to set the "to" value.

/* Returns the current nixpkgs release number as string. */ release = lib.strings.fileContents ../.version; <ins> /* The latest release that is supported, at the time of release branch-off, if applicable. Ideally, out-of-tree modules should be able to evaluate cleanly with all supported Nixpkgs versions (master, release and old release until EOL). So if possible, deprecation warnings should take effect only when all out-of-tree expressions/libs/modules can upgrade to the new way without losing support for supported Nixpkgs versions. This release number allows deprecation warnings to be implemented such that they take effect as soon as the oldest release reaches end of life. */ oldestSupportedRelease = # Update on master only. Do not backport. 2111; /* Whether a feature is supported in all supported releases (at the time of release branch-off, if applicable). See `oldestSupportedRelease`. */ isInOldestRelease = /* Release number of feature introduction as an integer, e.g. 2111 for 21.11. Set it to the upcoming release, matching the nixpkgs/.version file. */ release: release <= lib.trivial.oldestSupportedRelease; </ins> /* Returns the current nixpkgs release code name. On each release the first letter is bumped and a new animal is chosen

notes</link> for details. </para> </listitem> <ins> <listitem> <para> Module authors can use <literal>mkRenamedOptionModuleWith</literal> to automate the deprecation cycle without annoying out-of-tree module authors and their users. </para> </listitem> </ins> </itemizedlist> </section> <section xml:id="sec-release-22.05-new-services">

Legacy options have been mapped to the corresponding options under under <link xlink:href="options.html#opt-nix.settings">nix.settings</link> <del> but may be deprecated in the future. </del> <ins> and will be deprecated when NixOS 21.11 reaches end of life. </ins> </para> </listitem> <listitem>

- [`kops`](https://kops.sigs.k8s.io) defaults to 1.22.4, which will enable [Instance Metadata Service Version 2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) and require tokens on new clusters with Kubernetes 1.22. This will increase security by default, but may break some types of workloads. See the [release notes](https://kops.sigs.k8s.io/releases/1.22-notes/) for details. <ins> - Module authors can use `mkRenamedOptionModuleWith` to automate the deprecation cycle without annoying out-of-tree module authors and their users. </ins> ## New Services {#sec-release-22.05-new-services} - [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).

Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added. - The configuration portion of the `nix-daemon` module has been reworked and exposed as [nix.settings](options.html#opt-nix-settings): <del> * Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) but may be deprecated in the future. </del> <ins> * Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) and will be deprecated when NixOS 21.11 reaches end of life. </ins> * [nix.buildMachines.publicHostKey](options.html#opt-nix.buildMachines.publicHostKey) has been added. - The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.

{ imports = [ <del> (mkRenamedOptionModule [ "nix" "useChroot" ] [ "nix" "useSandbox" ]) (mkRenamedOptionModule [ "nix" "chrootDirs" ] [ "nix" "sandboxPaths" ]) (mkRenamedOptionModule [ "nix" "daemonIONiceLevel" ] [ "nix" "daemonIOSchedPriority" ]) </del> <ins> (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; }) (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; }) (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; }) </ins> (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.") <del> ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; </del> <ins> ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings; </ins> ###### interface