lib.packagesFromDirectoryRecursive: use explicit recursion, support nested scopes

This commit is contained in:
nicoo 2024-11-28 21:42:04 +00:00 committed by Paul Meyer
parent fdd2c6f80f
commit 6b7576b0cf
4 changed files with 50 additions and 35 deletions

View File

@ -116,6 +116,9 @@
"sec-nixpkgs-release-25.05-lib-deprecations": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-deprecations"
],
"sec-nixpkgs-release-25.05-lib-additions-improvements": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-additions-improvements"
],
"sec-overlays-install": [
"index.html#sec-overlays-install"
],

View File

@ -84,3 +84,7 @@
- Plasma 5 and Qt 5 based versions of associated software are deprecated in NixOS 25.05, and will be removed in NixOS 25.11. Users are encouraged to upgrade to Plasma 6.
- `rustPlatform.buildRustPackage` stops handling the deprecated argument `cargoSha256`. Out-of-tree packages that haven't migrated from `cargoSha256` to `cargoHash` now receive errors.
### Other notable changes {#sec-release-25.05-lib-notable-changes}
- `lib.packagesFromDirectoryRecursive` can now construct nested scopes matching the directory tree passed as input.

View File

@ -306,11 +306,12 @@ in
# Type
```
packagesFromDirectoryRecursive :: {
packagesFromDirectoryRecursive :: (args :: {
callPackage :: Path -> {} -> a,
directory :: Path,
recurseIntoDirectory? :: (args -> AttrSet) -> args -> AttrSet,
...
} -> AttrSet
}) -> AttrSet
```
# Inputs
@ -322,6 +323,10 @@ in
`directory`
: The directory to read package files from.
`recurseIntoDirectory`
: This argument is applied to the function which processes directories.
: Equivalently, this function takes `processDir` and `args`, and can modify arguments passed to `processDir`
(same as above) before calling it, as well as modify its output (which is then returned by `recurseIntoDirectory`).
# Examples
:::{.example}
@ -342,12 +347,16 @@ in
::::{.example}
## Create a scope for the nix files found in a directory
```nix
lib.makeScope pkgs.newScope (
self: packagesFromDirectoryRecursive {
inherit (self) callPackage;
directory = ./my-packages;
}
)
packagesFromDirectoryRecursive {
inherit (pkgs) callPackage newScope;
recurseIntoDirectory = f: { newScope, ... }@args:
lib.recurseIntoAttrset (lib.makeScope newScope (self:
f (args // {
inherit (self) callPackage newScope;
})
));
directory = ./my-packages;
}
=> { ... }
```
@ -366,22 +375,15 @@ in
:::{.note}
`a.nix` cannot directly take as inputs packages defined in a child directory, such as `b1`.
:::
:::{.warning}
As of now, `lib.packagesFromDirectoryRecursive` cannot create nested scopes for sub-directories.
In particular, files under `b/` can only require (as inputs) other files under `my-packages`,
but not to those in the same directory, nor those in a parent directory; e.g, `b2.nix` cannot directly
require `b1`.
:::
::::
*/
packagesFromDirectoryRecursive =
{
callPackage,
directory,
recurseIntoDirectory ? lib.id,
...
}:
}@args:
let
inherit (lib) concatMapAttrs removeSuffix;
inherit (lib.path) append;
@ -390,22 +392,25 @@ in
if pathExists defaultPath then
# if `${directory}/package.nix` exists, call it directly
callPackage defaultPath {}
else concatMapAttrs (name: type:
# otherwise, for each directory entry
let path = append directory name; in
if type == "directory" then {
# recurse into directories
"${name}" = packagesFromDirectoryRecursive {
inherit callPackage;
directory = path;
};
} else if type == "regular" && hasSuffix ".nix" name then {
# call .nix files
"${removeSuffix ".nix" name}" = callPackage path {};
} else if type == "regular" then {
# ignore non-nix files
} else throw ''
lib.filesystem.packagesFromDirectoryRecursive: Unsupported file type ${type} at path ${toString path}
''
) (builtins.readDir directory);
else let
f = { callPackage, ... }@newArgs:
concatMapAttrs (name: type:
# otherwise, for each directory entry
let path = append directory name; in
if type == "directory" then {
# recurse into directories
"${name}" = packagesFromDirectoryRecursive (newArgs // {
directory = path;
});
} else if type == "regular" && hasSuffix ".nix" name then {
# call .nix files
"${removeSuffix ".nix" name}" = callPackage path {};
} else if type == "regular" then {
# ignore non-nix files
} else throw ''
lib.filesystem.packagesFromDirectoryRecursive: Unsupported file type ${type} at path ${toString path}
''
) (builtins.readDir directory);
in
recurseIntoDirectory f args;
}

View File

@ -1946,6 +1946,9 @@
"sec-nixpkgs-release-25.05-lib-deprecations": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-deprecations"
],
"sec-nixpkgs-release-25.05-lib-additions-improvements": [
"release-notes.html#sec-nixpkgs-release-25.05-lib-additions-improvements"
],
"sec-release-24.11": [
"release-notes.html#sec-release-24.11"
],