From 6b7576b0cf479f10b8c1153cfb97e19a2f3e87dd Mon Sep 17 00:00:00 2001 From: nicoo Date: Thu, 28 Nov 2024 21:42:04 +0000 Subject: [PATCH] lib.packagesFromDirectoryRecursive: use explicit recursion, support nested scopes --- doc/redirects.json | 3 ++ doc/release-notes/rl-2505.section.md | 4 ++ lib/filesystem.nix | 75 +++++++++++++++------------- nixos/doc/manual/redirects.json | 3 ++ 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/doc/redirects.json b/doc/redirects.json index 934c49877b97..2c44eb3ed4a9 100644 --- a/doc/redirects.json +++ b/doc/redirects.json @@ -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" ], diff --git a/doc/release-notes/rl-2505.section.md b/doc/release-notes/rl-2505.section.md index e386ead66797..4eeb8f1c76d3 100644 --- a/doc/release-notes/rl-2505.section.md +++ b/doc/release-notes/rl-2505.section.md @@ -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. diff --git a/lib/filesystem.nix b/lib/filesystem.nix index 5dfdde85b9d2..866eff710a20 100644 --- a/lib/filesystem.nix +++ b/lib/filesystem.nix @@ -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; } diff --git a/nixos/doc/manual/redirects.json b/nixos/doc/manual/redirects.json index 29f7f9d51996..de696eeab75b 100644 --- a/nixos/doc/manual/redirects.json +++ b/nixos/doc/manual/redirects.json @@ -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" ],