From 5416614eb4d1883a0c85f07a46441270f45c57fd Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Thu, 11 Sep 2025 11:21:03 +0200 Subject: [PATCH 1/6] lib.makeAlias: init with by-name support --- lib/customisation.nix | 29 ++++++++++++++++++++ lib/default.nix | 1 + pkgs/by-name/do/docker-sync/package.nix | 5 ++++ pkgs/by-name/fo/follow/package.nix | 5 ++++ pkgs/by-name/op/open-timeline-io/package.nix | 5 ++++ pkgs/by-name/po/postcss-cli/package.nix | 5 ++++ pkgs/top-level/aliases.nix | 4 --- pkgs/top-level/by-name-overlay.nix | 24 +++++++++++----- 8 files changed, 67 insertions(+), 11 deletions(-) create mode 100644 pkgs/by-name/do/docker-sync/package.nix create mode 100644 pkgs/by-name/fo/follow/package.nix create mode 100644 pkgs/by-name/op/open-timeline-io/package.nix create mode 100644 pkgs/by-name/po/postcss-cli/package.nix diff --git a/lib/customisation.nix b/lib/customisation.nix index 16f248cd1b207..1666477590e1f 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -365,6 +365,35 @@ rec { else mapAttrs mkAttrOverridable pkgs; + makeAlias = + let + currentRelease = lib.versions.majorMinor lib.version; + in + self: name: + { + type, + package ? null, + reason ? null, + release ? null, + }: + assert type == "alias"; + if release == null then + self.${package} + else if release != currentRelease then + if package == null then + abort "Throw for '${name}' was added in ${release}. The alias must now be removed." + else + abort "Warning for '${name}' was added in ${release}. The alias must now be converted to a throw." + else if package == null || !self.config.allowAliases then + { + type = "error"; + meta = throw "'${name}' was removed because it was ${reason}."; + } + else + lib.warnOnInstantiate + "'${name}' was renamed to '${package}'. The alias will be removed in the next release." + self.${package}; + /** Add attributes to each output of a derivation without changing the derivation itself and check a given condition when evaluating. diff --git a/lib/default.nix b/lib/default.nix index 1008025d8d181..2a7029c087359 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -394,6 +394,7 @@ let makeOverridable callPackageWith callPackagesWith + makeAlias extendDerivation hydraJob makeScope diff --git a/pkgs/by-name/do/docker-sync/package.nix b/pkgs/by-name/do/docker-sync/package.nix new file mode 100644 index 0000000000000..66715a3e4aace --- /dev/null +++ b/pkgs/by-name/do/docker-sync/package.nix @@ -0,0 +1,5 @@ +{ + type = "alias"; + release = "25.11"; + reason = "broken and unmaintained"; +} diff --git a/pkgs/by-name/fo/follow/package.nix b/pkgs/by-name/fo/follow/package.nix new file mode 100644 index 0000000000000..8c4287addc9a3 --- /dev/null +++ b/pkgs/by-name/fo/follow/package.nix @@ -0,0 +1,5 @@ +{ + type = "alias"; + release = "25.05"; + package = "folo"; +} diff --git a/pkgs/by-name/op/open-timeline-io/package.nix b/pkgs/by-name/op/open-timeline-io/package.nix new file mode 100644 index 0000000000000..c004808128f4a --- /dev/null +++ b/pkgs/by-name/op/open-timeline-io/package.nix @@ -0,0 +1,5 @@ +{ + type = "alias"; + release = "25.11"; + package = "opentimelineio"; +} diff --git a/pkgs/by-name/po/postcss-cli/package.nix b/pkgs/by-name/po/postcss-cli/package.nix new file mode 100644 index 0000000000000..5151ff4263045 --- /dev/null +++ b/pkgs/by-name/po/postcss-cli/package.nix @@ -0,0 +1,5 @@ +{ + type = "alias"; + release = "25.05"; + reason = "broken"; +} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index c0a8bebea550d..dedec70982d73 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -771,7 +771,6 @@ mapAliases { docker_27 = throw "'docker_27' has been removed because it has been unmaintained since May 2025. Use docker_28 or newer instead."; # Added 2025-06-15 docker-compose_1 = throw "'docker-compose_1' has been removed because it has been unmaintained since May 2021. Use docker-compose instead."; # Added 2024-07-29 docker-distribution = distribution; # Added 2023-12-26 - docker-sync = throw "'docker-sync' has been removed because it was broken and unmaintained"; # Added 2025-08-26 dolphin-emu-beta = dolphin-emu; # Added 2023-02-11 dolphinEmu = throw "'dolphinEmu' has been renamed to/replaced by 'dolphin-emu'"; # Converted to throw 2024-10-17 dolphinEmuMaster = throw "'dolphinEmuMaster' has been renamed to/replaced by 'dolphin-emu-beta'"; # Converted to throw 2024-10-17 @@ -926,7 +925,6 @@ mapAliases { fmt_8 = throw "fmt_8 has been removed as it is obsolete and was no longer used in the tree"; # Added 2024-11-12 fntsample = throw "fntsample has been removed as it is unmaintained upstream"; # Added 2025-04-21 foldingathome = throw "'foldingathome' has been renamed to/replaced by 'fahclient'"; # Converted to throw 2024-10-17 - follow = lib.warnOnInstantiate "follow has been renamed to folo" folo; # Added 2025-05-18 forgejo-actions-runner = forgejo-runner; # Added 2024-04-04 fornalder = throw "'fornalder' has been removed as it is unmaintained upstream"; # Added 2025-01-25 foundationdb71 = throw "foundationdb71 has been removed; please upgrade to foundationdb73"; # Added 2024-12-28 @@ -1839,7 +1837,6 @@ mapAliases { openssl_3_0 = openssl_3; # Added 2022-06-27 opensycl = lib.warnOnInstantiate "'opensycl' has been renamed to 'adaptivecpp'" adaptivecpp; # Added 2024-12-04 opensyclWithRocm = lib.warnOnInstantiate "'opensyclWithRocm' has been renamed to 'adaptivecppWithRocm'" adaptivecppWithRocm; # Added 2024-12-04 - open-timeline-io = lib.warnOnInstantiate "'open-timeline-io' has been renamed to 'opentimelineio'" opentimelineio; # Added 2025-08-10 opentofu-ls = lib.warnOnInstantiate "'opentofu-ls' has been renamed to 'tofu-ls'" tofu-ls; # Added 2025-06-10 openvdb_11 = throw "'openvdb_11' has been removed in favor of the latest version'"; # Added 2025-05-03 opera = throw "'opera' has been removed due to lack of maintenance in nixpkgs"; # Added 2025-05-19 @@ -1958,7 +1955,6 @@ mapAliases { pgroonga = throw "'pgroonga' has been removed. Use 'postgresqlPackages.pgroonga' instead."; # Added 2025-07-19 pgtap = throw "'pgtap' has been removed. Use 'postgresqlPackages.pgtap' instead."; # Added 2025-07-19 plv8 = throw "'plv8' has been removed. Use 'postgresqlPackages.plv8' instead."; # Added 2025-07-19 - postcss-cli = throw "postcss-cli has been removed because it was broken"; # added 2025-03-24 postgis = throw "'postgis' has been removed. Use 'postgresqlPackages.postgis' instead."; # Added 2025-07-19 tegaki-zinnia-japanese = throw "'tegaki-zinnia-japanese' has been removed due to lack of maintenance"; # Added 2025-09-10 tet = throw "'tet' has been removed for lack of maintenance"; # Added 2025-10-12 diff --git a/pkgs/top-level/by-name-overlay.nix b/pkgs/top-level/by-name-overlay.nix index 9a011439596a0..66ad4d40d9283 100644 --- a/pkgs/top-level/by-name-overlay.nix +++ b/pkgs/top-level/by-name-overlay.nix @@ -19,8 +19,12 @@ let mergeAttrsList ; - # Package files for a single shard - # Type: String -> String -> AttrsOf Path + inherit (lib.customisation) + makeAlias + ; + + # Package imports for a single shard + # Type: String -> String -> AttrsOf Any namesForShard = shard: type: if type != "directory" then @@ -32,14 +36,14 @@ let # Additionally in either of those alternatives, we would have to duplicate the hardcoding of "README.md" { } else - mapAttrs (name: _: baseDirectory + "/${shard}/${name}/package.nix") ( + mapAttrs (name: _: import (baseDirectory + "/${shard}/${name}/package.nix")) ( readDir (baseDirectory + "/${shard}") ); - # The attribute set mapping names to the package files defining them + # The attribute set mapping names to the package expressions defining them # This is defined up here in order to allow reuse of the value (it's kind of expensive to compute) # if the overlay has to be applied multiple times - packageFiles = mergeAttrsList (mapAttrsToList namesForShard (readDir baseDirectory)); + packages = mergeAttrsList (mapAttrsToList namesForShard (readDir baseDirectory)); in # TODO: Consider optimising this using `builtins.deepSeq packageFiles`, # which could free up the above thunks and reduce GC times. @@ -53,6 +57,12 @@ self: super: # and whether it's defined by this file here or `all-packages.nix`. # TODO: This can be removed once `pkgs/by-name` can handle custom `callPackage` arguments without `all-packages.nix` (or any other way of achieving the same result). # Because at that point the code in ./stage.nix can be changed to not allow definitions in `all-packages.nix` to override ones from `pkgs/by-name` anymore and throw an error if that happens instead. - _internalCallByNamePackageFile = file: self.callPackage file { }; + _internalCallByNamePackageFile = fn: self.callPackage fn { }; } -// mapAttrs (name: self._internalCallByNamePackageFile) packageFiles +// mapAttrs ( + name: value: + if value.type or null == "alias" then + makeAlias self name value + else + self._internalCallByNamePackageFile value +) packages From b12b23d15000f1a03889eeacffda6f2ccec48bf2 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Tue, 9 Sep 2025 20:50:05 +0200 Subject: [PATCH 2/6] lib.callPackageWith: refactor for more error handling This allows adding more error conditions easily. --- lib/customisation.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/customisation.nix b/lib/customisation.nix index 1666477590e1f..5c099b795dbd3 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -300,7 +300,7 @@ rec { else ", did you mean ${concatStringsSep ", " (lib.init suggestions)} or ${lib.last suggestions}?"; - errorForArg = + missingErrorForArg = arg: let loc = builtins.unsafeGetAttrPos arg fargs; @@ -309,17 +309,17 @@ rec { + "${loc.file}:${toString loc.line}${prettySuggestions (getSuggestions arg)}"; # Only show the error for the first missing argument - error = errorForArg (head (attrNames missingArgs)); + missingError = missingErrorForArg (head (attrNames missingArgs)); in - if missingArgs == { } then - makeOverridable f allArgs # This needs to be an abort so it can't be caught with `builtins.tryEval`, # which is used by nix-env and ofborg to filter out packages that don't evaluate. # This way we're forced to fix such errors in Nixpkgs, # which is especially relevant with allowAliases = false + if missingArgs != { } then + abort "lib.customisation.callPackageWith: ${missingError}" else - abort "lib.customisation.callPackageWith: ${error}"; + makeOverridable f allArgs; /** Like callPackage, but for a function that returns an attribute From 8fad5a40067499bda7f3d510f8105492a7430c3a Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Wed, 10 Sep 2025 16:04:32 +0200 Subject: [PATCH 3/6] lib.callPackageWith: throw when alias is used as argument --- lib/customisation.nix | 23 ++++++++++++++++++----- pkgs/top-level/by-name-overlay.nix | 2 ++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/customisation.nix b/lib/customisation.nix index 5c099b795dbd3..52d463602beee 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -261,6 +261,18 @@ rec { f = if isFunction fn then fn else import fn; fargs = functionArgs f; + aliasArgs = filterAttrs (name: _: autoArgs._isAlias or (_: false) name) fargs; + + aliasErrorForArg = + arg: + let + loc = builtins.unsafeGetAttrPos arg fargs; + in + "Function expects alias \"${arg}\" at ${loc.file}:${toString loc.line}."; + + # Only show the error for the first alias + aliasError = aliasErrorForArg (head (attrNames aliasArgs)); + # All arguments that will be passed to the function # This includes automatic ones and ones passed explicitly allArgs = intersectAttrs fargs autoArgs // args; @@ -312,11 +324,12 @@ rec { missingError = missingErrorForArg (head (attrNames missingArgs)); in - # This needs to be an abort so it can't be caught with `builtins.tryEval`, - # which is used by nix-env and ofborg to filter out packages that don't evaluate. - # This way we're forced to fix such errors in Nixpkgs, - # which is especially relevant with allowAliases = false - if missingArgs != { } then + # These need to be abort so they can't be caught with `builtins.tryEval`, + # which is used by nix-env and CI to filter out packages that don't evaluate. + # This way we're forced to fix such errors in Nixpkgs. + if aliasArgs != { } then + abort "lib.customisation.callPackageWith: ${aliasError}" + else if missingArgs != { } then abort "lib.customisation.callPackageWith: ${missingError}" else makeOverridable f allArgs; diff --git a/pkgs/top-level/by-name-overlay.nix b/pkgs/top-level/by-name-overlay.nix index 66ad4d40d9283..c39c330b211f9 100644 --- a/pkgs/top-level/by-name-overlay.nix +++ b/pkgs/top-level/by-name-overlay.nix @@ -51,6 +51,8 @@ in # and ideally https://github.com/NixOS/nix/pull/8895 self: super: { + _isAlias = name: packages.${name}.type or null == "alias"; + # This attribute is necessary to allow CI to ensure that all packages defined in `pkgs/by-name` # don't have an overriding definition in `all-packages.nix` with an empty (`{ }`) second `callPackage` argument. # It achieves that with an overlay that modifies both `callPackage` and this attribute to signal whether `callPackage` is used From a1b73489cd4e9e2f6b1df1fb7ef2e22dbdde2d70 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Thu, 11 Sep 2025 16:30:34 +0200 Subject: [PATCH 4/6] follow: convert to throw --- pkgs/by-name/fo/follow/package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/by-name/fo/follow/package.nix b/pkgs/by-name/fo/follow/package.nix index 8c4287addc9a3..df33f156fad13 100644 --- a/pkgs/by-name/fo/follow/package.nix +++ b/pkgs/by-name/fo/follow/package.nix @@ -1,5 +1,5 @@ { type = "alias"; - release = "25.05"; - package = "folo"; + release = "25.11"; + reason = "renamed to folo"; } From 2201a5f43ab87da14b3cbf9d066037efcc70e123 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Thu, 11 Sep 2025 16:31:54 +0200 Subject: [PATCH 5/6] postcss-cli: drop alias --- pkgs/by-name/po/postcss-cli/package.nix | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 pkgs/by-name/po/postcss-cli/package.nix diff --git a/pkgs/by-name/po/postcss-cli/package.nix b/pkgs/by-name/po/postcss-cli/package.nix deleted file mode 100644 index 5151ff4263045..0000000000000 --- a/pkgs/by-name/po/postcss-cli/package.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - type = "alias"; - release = "25.05"; - reason = "broken"; -} From 9a9f61eca5eadd0632515865004a66622d1e1fa8 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sun, 14 Sep 2025 17:37:00 +0200 Subject: [PATCH 6/6] linuxKernel.kernels: use lib.makeAlias This is not a scope, so the callPackage protection doesn't apply. Also, since these aliases are defined in the `linuxKernel.kernels` attribute set and not at the top-level, the inherited top-level aliases are not protected against inclusion in callPackage either. For this to work, these aliases would just need to be moved to the top-level instead. However, evaluation with and without config.allowAliases will be the same here, providing the same safety against actually using these attributes. Also, of course, they have metadata. This is mostly to show how a package set could use `lib.mkAlias` - it will work the same in a proper scope. --- pkgs/top-level/linux-kernels.nix | 135 +++++++++++++++++++++++++------ 1 file changed, 110 insertions(+), 25 deletions(-) diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix index d64f7f282c8e5..b1ca6e045a7e0 100644 --- a/pkgs/top-level/linux-kernels.nix +++ b/pkgs/top-level/linux-kernels.nix @@ -290,31 +290,116 @@ in linux_hardened = hardenedKernelFor packageAliases.linux_default.kernel { }; } - // lib.optionalAttrs config.allowAliases { - linux_4_19 = throw "linux 4.19 was removed because it will reach its end of life within 24.11"; - linux_6_9 = throw "linux 6.9 was removed because it has reached its end of life upstream"; - linux_6_10 = throw "linux 6.10 was removed because it has reached its end of life upstream"; - linux_6_11 = throw "linux 6.11 was removed because it has reached its end of life upstream"; - linux_6_13 = throw "linux 6.13 was removed because it has reached its end of life upstream"; - linux_6_14 = throw "linux 6.14 was removed because it has reached its end of life upstream"; - linux_6_15 = throw "linux 6.15 was removed because it has reached its end of life upstream"; - - linux_5_10_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; - linux_5_15_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; - linux_6_1_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; - linux_6_6_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS"; - - linux_4_19_hardened = throw "linux 4.19 was removed because it will reach its end of life within 24.11"; - linux_5_4_hardened = throw "linux_5_4_hardened was removed because it was broken"; - linux_6_9_hardened = throw "linux 6.9 was removed because it has reached its end of life upstream"; - linux_6_10_hardened = throw "linux 6.10 was removed because it has reached its end of life upstream"; - linux_6_11_hardened = throw "linux 6.11 was removed because it has reached its end of life upstream"; - linux_6_13_hardened = throw "linux 6.13 was removed because it has reached its end of life upstream"; - linux_6_14_hardened = throw "linux 6.14 was removed because it has reached its end of life upstream"; - linux_6_15_hardened = throw "linux 6.15 was removed because it has reached its end of life upstream"; - - linux_ham = throw "linux_ham has been removed in favour of the standard kernel packages"; - } + // ( + let + aliases = { + linux_4_19 = { + type = "alias"; + release = "25.11"; + reason = "it will reach its end of life within 24.11"; + }; + linux_6_9 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + linux_6_10 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + linux_6_11 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + linux_6_13 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + linux_6_14 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + linux_6_15 = { + type = "alias"; + release = "25.11"; + reason = "it has reached its end of life upstream"; + }; + + linux_5_10_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux_hardened on nixpkgs only contains latest stable and latest LTS"; + }; + linux_5_15_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux_hardened on nixpkgs only contains latest stable and latest LTS"; + }; + linux_6_1_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux_hardened on nixpkgs only contains latest stable and latest LTS"; + }; + linux_6_6_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux_hardened on nixpkgs only contains latest stable and latest LTS"; + }; + + linux_4_19_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 4.19 was removed because it will reach its end of life within 24.11"; + }; + linux_5_4_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux_5_4_hardened was removed because it was broken"; + }; + linux_6_9_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.9 was removed because it has reached its end of life upstream"; + }; + linux_6_10_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.10 was removed because it has reached its end of life upstream"; + }; + linux_6_11_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.11 was removed because it has reached its end of life upstream"; + }; + linux_6_13_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.13 was removed because it has reached its end of life upstream"; + }; + linux_6_14_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.14 was removed because it has reached its end of life upstream"; + }; + linux_6_15_hardened = { + type = "alias"; + release = "25.11"; + reason = "linux 6.15 was removed because it has reached its end of life upstream"; + }; + + linux_ham = { + type = "alias"; + release = "25.11"; + reason = "in favour of the standard kernel packages"; + }; + }; + in + (lib.mapAttrs (lib.makeAlias kernels) aliases) // { _isAlias = name: aliases ? ${name}; } + ) ) ); /*