Access inputs via specialArgs in mkShell

I like the idea of passing specialArgs to nixosConfigurations when using flakes.

Is this supposed to work with devShells too ?

Asking bc I suppose devenv let’s me use:

inputs.devenv.lib.mkShell {
  inherit inputs pkgs;
  modules = [
    ({ unstable, ... }: {}
  )]
};

had I specialArgs = forEachSystem (system: { inherit system; unstable = inputs.unstable.legacyPackages.${system}; }); defined.

Now my question would be is that possible using mkShell {} too ?

Where would the module parameter unstable in

let
  inherit system specialArgs;
in pkgs.mkShell {}

go ?

Trying currently (Nixpkgs Reference Manual):

{ unstable }:
pkgs.mkShell {}

No, that’s specifical to lib.evalModules:

and mkShell is just a derivation (special case of stdenv.mkDerivation) which doesn’t use the module system.

It wouldn’t, derivations are not modules.

I’m unclear what you intend to accomplish, I don’t use devenv.
But if you want the module system in flakes, I’ve only used flake-parts before.
(I never considered devenv as they require impurity by design.)

2 Likes

I’ll post a rough sketch of a minimal flake here ASAP to illustrate.

Not working (as @waffle8946 pointed out) example (nix develop .#devShells.x86_64-linux."devenv specialArgs" --impure):

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
   unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
   devenv = {
      url = "github:cachix/devenv";
      inputs.nixpkgs.follows = "unstable";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs: 
    let
      forEachSystem = nixpkgs.lib.genAttrs [ "x86_64-linux" ];
 
      inherit (nixpkgs.lib) listToAttrs;
      specialArgs = forEachSystem (system: {
        inherit system;
        unstable = inputs.unstable.legacyPackages.${system};
      });
in  {

      devShells = forEachSystem (system: listToAttrs [
         ( 
          let
            pkgs = inputs.nixpkgs.legacyPackages.${system};
          in
	  {
            name = "devenv specialArgs";
            value = inputs.devenv.lib.mkShell {
              inherit inputs pkgs;
              modules = [
                ({ specialArgs, unstable, ... }: {
                  packages = builtins.attrValues {
		    inherit (specialArgs.unstable) eza;
		    };
                  enterShell = ''
		  eza  --version
                '';
                })
              ];
            };
          }
	  )
	]);
  };
}

What’s of interest for me would be reusing this unstable attribute as analogous in specialArgs all over some dev shells I might have. Don’t know what idiom to use exactly for that.

flake-parts was pointed out, do you have an example how to utilize ?

To provide at least a working example of what I want functionally and answering half of my question here is:

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.05";
   unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
   devenv = {
      url = "github:cachix/devenv";
      inputs.nixpkgs.follows = "unstable";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs: 
    let
      forEachSystem = nixpkgs.lib.genAttrs [ "x86_64-linux" ];
 
      inherit (nixpkgs.lib) listToAttrs;
      specialArgs = forEachSystem (system: {
        inherit system;
        unstable = inputs.unstable.legacyPackages.${system};
      });
in  {

      devShells = forEachSystem (system: listToAttrs [
         ( 
          let
            pkgs = inputs.nixpkgs.legacyPackages.${system};
	    inherit specialArgs;
          in
	  {
            name = "devenv specialArgs";
            value = inputs.devenv.lib.mkShell {
              inherit inputs pkgs;
              modules = [
                ({ ... }: {
                  packages = builtins.attrValues {
		    inherit (specialArgs.${system}.unstable.pkgs) eza;
		    };
                  enterShell = ''
		  eza  --version
                '';
                })
              ];
            };
          }
	  )
	]);
  };
}

Second half question remains, what would a more nix-like solution look like ?

I’m not sure why you’d need specialArgs here, you already have unstable in scope, so something like this should work:

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-24.05";
    unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    devenv = {
      url = "github:cachix/devenv";
      inputs.nixpkgs.follows = "unstable";
    };
  };

  outputs = { self, nixpkgs, ... }@inputs: 
  let
    forEachSystem = nixpkgs.lib.genAttrs [ "x86_64-linux" ];

    inherit (nixpkgs.lib) listToAttrs;
  in  {

    devShells = forEachSystem (system: listToAttrs [
      ( 
      let
        pkgs = inputs.nixpkgs.legacyPackages.${system};
        # we make unstable just another let-binding
        unstable = inputs.unstable.legacyPackages.${system};
      in
      {
        name = "devenv specialArgs";
        value = inputs.devenv.lib.mkShell {
          inherit inputs pkgs;
          modules = [
            ({ ... }: {
              packages = builtins.attrValues {
                inherit (unstable.pkgs) eza; # use unstable from the outer scope
              };
              enterShell = ''
                eza  --version
              '';
            })
          ];
        };
      }
      )
    ]);
  };
}