{ pkgs, adios, rustOverlay ? null, # optional: rust-overlay.lib.mkRustBin {} pkgs, for languages.rust.channel/version }: let inherit (pkgs) lib; # Passthrough DI module: no `impl`, so it's excluded from the per-language # fold below. nixpkgsModule = { options = { pkgs = { type = adios.types.attrs; }; lib = { type = adios.types.attrs; defaultFunc = {options}: options.pkgs.lib; }; }; meta.maintainers = ["poacherGoneWild@proton.me"]; }; # Passthrough DI module for the optional rust-overlay input (null unless a # consumer overrode ezshell's `rust-overlay.follows` default -- see flake.nix). rustOverlayModule = { options.packages = { type = adios.types.nullOr adios.types.attrs; }; meta.maintainers = ["poacherGoneWild@proton.me"]; }; # Passed as each module's function argument because `options` schemas must # exist before the tree's `inputs` fixpoint resolves languageModules = adios.lib.importModules { directory = ../languages; args = adios // {types = adios.types // {hook = import ./hookType.nix {inherit (adios) types;};};}; }; languageNames = builtins.attrNames languageModules; tree = adios { modules = languageModules // { nixpkgs = nixpkgsModule; rustOverlay = rustOverlayModule; }; } { options."/nixpkgs" = {inherit pkgs;}; options."/rustOverlay" = {packages = rustOverlay;}; }; mkLangs = { languages ? {}, }: let # Catches typos in top-level `languages` keys unknownLanguages = builtins.filter (name: !builtins.elem name languageNames) (builtins.attrNames languages); typoCheck = if unknownLanguages != [] then throw '' ezshell: unknown language(s) ${builtins.concatStringsSep ", " unknownLanguages}. Known languages: ${builtins.concatStringsSep ", " languageNames} '' else true; # Every discovered language module is realized with the caller's config # for that name, or `{}` if unmentioned realized = builtins.listToAttrs ( map (name: { inherit name; value = tree.modules.${name} (languages.${name} or {}); }) languageNames ); results = builtins.attrValues realized; allHookPresets = lib.foldl' (acc: r: acc // (r.hookPresets or {})) {} results; duplicateCheck = let names = lib.concatMap (r: builtins.attrNames (r.hookPresets or {})) results; dupes = lib.subtractLists (lib.unique names) names; in if dupes != [] then throw "ezshell: duplicate hook names across language modules: ${toString dupes}" else true; allOptions = builtins.mapAttrs (_name: r: r.options or {}) realized; in { packages = assert typoCheck; lib.concatMap (r: r.packages or []) results; hookPresets = assert duplicateCheck; allHookPresets; languages = allOptions; }; in { inherit mkLangs; }