diff --git a/API_GUIDE.md b/API_GUIDE.md index 9322cad..b3ee125 100644 --- a/API_GUIDE.md +++ b/API_GUIDE.md @@ -541,12 +541,36 @@ To override the devShell, you can use a package definition as such: ### devShells ``` -Type: (AttrsOf PackageDef) | (ModuleArgs -> (AttrsOf PackageDef)) +Type: + devShells: (AttrsOf (PackageDef | Cfg | (Pkgs -> Cfg)) | + (ModuleArgs -> (AttrsOf (PackageDef | Cfg | (Pkgs -> Cfg)))) + Cfg.packages: [Derivation] | (Pkgs -> [Derivation]) + Cfg.inputsFrom: [Derivation] | (Pkgs -> [Derivation]) + Cfg.shellHook: Str | (Pkgs -> Str) + Cfg.env: (AttrsOf Str) | (Pkgs -> (AttrsOf Str)) + Cfg.stdenv: Stdenv | (Pkgs -> Stdenv) ``` -The `devShells` option allows you to set additional `devShell` outputs. +The `devShells` option allows you to set additional `devShell` outputs. The +values each shell can be set to are the same as described above for the +`devShell` option. -For example: +For example, using the configuration options: + +```nix +{ + inputs.flakelight.url = "github:nix-community/flakelight"; + outputs = { flakelight, ... }: + flakelight ./. { + devShells.testing = { + packages = pkgs: [ pkgs.coreutils ]; + env.TEST_VAR = "in testing shell"; + }; + }; +} +``` + +For example, using a package definition: ```nix { @@ -562,7 +586,7 @@ For example: } ``` -The above exports `devShells.${system}.testing` outputs. +The above flakes export `devShells.${system}.testing` outputs. ### overlays diff --git a/builtinModules/devShells.nix b/builtinModules/devShells.nix index 976f43a..85ca49c 100644 --- a/builtinModules/devShells.nix +++ b/builtinModules/devShells.nix @@ -4,13 +4,11 @@ { config, lib, flakelight, genSystems, moduleArgs, ... }: let - inherit (lib) filterAttrs functionArgs mapAttrs mkDefault mkIf mkMerge - mkOption; + 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 - packageDef; + inherit (flakelight.types) function nullable optCallWith optFunctionTo; devShellModule.options = { inputsFrom = mkOption { @@ -39,48 +37,51 @@ let }; overrideShell = mkOption { - type = nullable packageDef; + type = nullable package; internal = true; default = null; }; }; wrapFn = fn: pkgs: - if (functionArgs fn == { }) || !(package.check (pkgs.callPackage fn { })) + let val = pkgs.callPackage fn { }; in + if (functionArgs fn == { }) || !(package.check val) then fn pkgs - else { overrideShell = fn; }; + 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 (coercedTo function wrapFn - (coercedTo attrs (x: _: x) - (functionTo (submodule devShellModule)))); + type = nullable devShellType; }; devShells = mkOption { - type = optCallWith moduleArgs (lazyAttrsOf packageDef); + type = optCallWith moduleArgs (lazyAttrsOf devShellType); default = { }; }; }; config = mkMerge [ (mkIf (config.devShell != null) { - devShells.default = mkDefault ({ pkgs, mkShell }: - let cfg = mapAttrs (_: v: v pkgs) (config.devShell pkgs); in - mkShell.override { inherit (cfg) stdenv; } - (cfg.env // { inherit (cfg) inputsFrom packages shellHook; })); - }) - - (mkIf (config.devShell.overrideShell or null != null) { - devShells.default = config.devShell.overrideShell; + devShells.default = config.devShell; }) (mkIf (config.devShells != { }) { outputs.devShells = genSystems (pkgs: filterAttrs (_: supportedSystem pkgs) - (mapAttrs (_: v: pkgs.callPackage v { }) config.devShells)); + (mapAttrs (_: v: genDevShell pkgs (v pkgs)) config.devShells)); }) ]; } diff --git a/default.nix b/default.nix index 9b8b9d5..d953fb8 100644 --- a/default.nix +++ b/default.nix @@ -94,8 +94,7 @@ let optFunctionTo = elemType: coercedTo elemType (x: _: x) (functionTo elemType); - optCallWith = args: elemType: coercedTo (functionTo elemType) (x: x args) - elemType; + optCallWith = args: elemType: coercedTo function (x: x args) elemType; nullable = elemType: mkOptionType { name = "nullable"; diff --git a/tests/default.nix b/tests/default.nix index ca34a94..5a0bc2b 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -370,12 +370,16 @@ in devShell.inputsFrom = pkgs: [ pkgs.emacs ]; devShells = { shell1 = { mkShell }: mkShell { }; - shell2 = { mkShell }: mkShell { }; + shell2 = { packages = pkgs: [ pkgs.emacs ]; }; + shell3 = pkgs: { packages = [ pkgs.emacs ]; }; + shell4 = { emacs, ... }: { packages = [ emacs ]; }; }; }) - (f: (f ? devShells.x86_64-linux.default) - && (f ? devShells.x86_64-linux.shell1) - && (f ? devShells.x86_64-linux.shell2)); + (f: (lib.isDerivation f.devShells.x86_64-linux.default) + && (lib.isDerivation f.devShells.x86_64-linux.shell1) + && (lib.isDerivation f.devShells.x86_64-linux.shell2) + && (lib.isDerivation f.devShells.x86_64-linux.shell3) + && (lib.isDerivation f.devShells.x86_64-linux.shell4)); devShells-override = test (flakelight ./empty {