Merge #361424: refactor lib.packagesFromDirectoryRecursive (v2)

authored by nicoo and committed by GitHub f91fbd16 42b2d9e7

+27 -46
+27 -46
lib/filesystem.nix
··· 18 18 ; 19 19 20 20 inherit (lib.filesystem) 21 + pathIsDirectory 22 + pathIsRegularFile 21 23 pathType 24 + packagesFromDirectoryRecursive 22 25 ; 23 26 24 27 inherit (lib.strings) ··· 386 389 ... 387 390 }: 388 391 let 389 - # Determine if a directory entry from `readDir` indicates a package or 390 - # directory of packages. 391 - directoryEntryIsPackage = basename: type: 392 - type == "directory" || hasSuffix ".nix" basename; 393 - 394 - # List directory entries that indicate packages in the given `path`. 395 - packageDirectoryEntries = path: 396 - filterAttrs directoryEntryIsPackage (readDir path); 397 - 398 - # Transform a directory entry (a `basename` and `type` pair) into a 399 - # package. 400 - directoryEntryToAttrPair = subdirectory: basename: type: 401 - let 402 - path = subdirectory + "/${basename}"; 403 - in 404 - if type == "regular" 405 - then 406 - { 407 - name = removeSuffix ".nix" basename; 408 - value = callPackage path { }; 409 - } 410 - else 411 - if type == "directory" 412 - then 413 - { 414 - name = basename; 415 - value = packagesFromDirectory path; 416 - } 417 - else 418 - throw 419 - '' 420 - lib.filesystem.packagesFromDirectoryRecursive: Unsupported file type ${type} at path ${toString subdirectory} 421 - ''; 422 - 423 - # Transform a directory into a package (if there's a `package.nix`) or 424 - # set of packages (otherwise). 425 - packagesFromDirectory = path: 426 - let 427 - defaultPackagePath = path + "/package.nix"; 428 - in 429 - if pathExists defaultPackagePath 430 - then callPackage defaultPackagePath { } 431 - else mapAttrs' 432 - (directoryEntryToAttrPair path) 433 - (packageDirectoryEntries path); 392 + inherit (lib) concatMapAttrs removeSuffix; 393 + inherit (lib.path) append; 394 + defaultPath = append directory "package.nix"; 434 395 in 435 - packagesFromDirectory directory; 396 + if pathExists defaultPath then 397 + # if `${directory}/package.nix` exists, call it directly 398 + callPackage defaultPath {} 399 + else concatMapAttrs (name: type: 400 + # otherwise, for each directory entry 401 + let path = append directory name; in 402 + if type == "directory" then { 403 + # recurse into directories 404 + "${name}" = packagesFromDirectoryRecursive { 405 + inherit callPackage; 406 + directory = path; 407 + }; 408 + } else if type == "regular" && hasSuffix ".nix" name then { 409 + # call .nix files 410 + "${removeSuffix ".nix" name}" = callPackage path {}; 411 + } else if type == "regular" then { 412 + # ignore non-nix files 413 + } else throw '' 414 + lib.filesystem.packagesFromDirectoryRecursive: Unsupported file type ${type} at path ${toString path} 415 + '' 416 + ) (builtins.readDir directory); 436 417 }