# flakelight -- Framework for simplifying flake setup # Copyright (C) 2023 Archit Gupta # SPDX-License-Identifier: MIT { config, lib, flakelight, genSystems, moduleArgs, ... }: let inherit (lib) filterAttrs functionArgs mapAttrs mkIf mkMerge mkOption; inherit (lib.types) attrs coercedTo functionTo lazyAttrsOf lines listOf package str submodule; inherit (flakelight) supportedSystem; inherit (flakelight.types) function nullable optCallWith optFunctionTo; devShellModule.options = { inputsFrom = mkOption { type = optFunctionTo (listOf package); default = [ ]; }; packages = mkOption { type = optFunctionTo (listOf package); default = [ ]; }; shellHook = mkOption { type = optFunctionTo lines; default = ""; }; env = mkOption { type = optFunctionTo (lazyAttrsOf str); default = { }; }; stdenv = mkOption { type = optFunctionTo package; default = pkgs: pkgs.stdenv; }; overrideShell = mkOption { type = nullable package; internal = true; default = null; }; }; wrapFn = fn: pkgs: let val = pkgs.callPackage fn { }; in if (functionArgs fn == { }) || !(package.check val) then fn pkgs else { overrideShell = val; }; devShellType = coercedTo function wrapFn (coercedTo attrs (x: _: x) (functionTo (submodule devShellModule))); genDevShell = pkgs: cfg: if cfg.overrideShell != null then cfg.overrideShell else let cfg' = mapAttrs (_: v: v pkgs) cfg; in pkgs.mkShell.override { inherit (cfg') stdenv; } (cfg'.env // { inherit (cfg') inputsFrom packages shellHook; }); in { options = { devShell = mkOption { default = null; type = nullable devShellType; }; devShells = mkOption { type = optCallWith moduleArgs (lazyAttrsOf devShellType); default = { }; }; }; config = mkMerge [ (mkIf (config.devShell != null) { devShells.default = config.devShell; }) (mkIf (config.devShells != { }) { outputs.devShells = genSystems (pkgs: filterAttrs (_: supportedSystem pkgs) (mapAttrs (_: v: genDevShell pkgs (v pkgs)) config.devShells)); }) ]; }