From 259a0076ab226c74cfc81a4b5da07da34a5075de 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 (WiP) --- lib/filesystem.nix | 60 +++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/filesystem.nix b/lib/filesystem.nix index f9fd4a981b2d6b..e2be4c7b1830fa 100644 --- a/lib/filesystem.nix +++ b/lib/filesystem.nix @@ -346,10 +346,16 @@ in } => { ... } - lib.makeScope pkgs.newScope ( - self: packagesFromDirectoryRecursive { - callPackage = 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; } ) => { ... } @@ -361,9 +367,12 @@ in { callPackage, directory, + recurseIntoDirectory ? lib.id, ... - }: - assert pathIsDirectory directory; + }@args: + if !pathIsDirectory directory then + throw "path ${toString directory} not a directory" + else let inherit (lib.path) append; defaultPath = append directory "package.nix"; @@ -371,22 +380,25 @@ in if pathIsRegularFile defaultPath then # if `${directory}/package.nix` exists, call it directly callPackage defaultPath {} - else lib.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 - "${lib.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: + lib.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 + "${lib.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; }