Importing shell.nix into a flake

I would like to wrap my shell.nix in a flake, as described in Flakes - NixOS Wiki. When I run nix develop with the flake example provided I get the error

error: attempt to call something which is not a function but a set: { type = "derivation"; __ignoreNulls = true; __structuredAttrs = «thunk»; all = «thunk»; args = «thunk»; buildInputs = «thunk»; buildPhase = "{ echo \"------------------------------------------------------------\";\n  echo \" WARNING: the existence of this path is not guaranteed.\";\n  echo \" It is an internal implementation detail for pkgs.mkShell.\";\n  echo \"------------------------------------------------------------\";\n  echo;\n  # Record all build inputs as runtime dependencies\n  export;\n} >> \"$out\"\n"; builder = «thunk»; cmakeFlags = «thunk»; configureFlags = «thunk»; «33 attributes elided» }
       at /nix/store/d8zhf3hcnz54j09xnlyidhl1xbfbv69i-source/flake.nix:11:31:
           10|         {
           11|           devShells.default = import ./shell.nix { inherit pkgs; };
             |                               ^
           12|         }

The flake example given in the article is:

{
  description = "my project description";

  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem
      (system:
        let pkgs = nixpkgs.legacyPackages.${system}; in
        {
          devShells.default = import ./shell.nix { inherit pkgs; };
        }
      );
}

Can someone tell me what I’m doing wrong here?

I don’t think it is necessary, but this is my shell.nix for reference:

let
  pkgs = import <nixpkgs> { config.allowUnfree = true; };
  myvscode = pkgs.vscode-with-extensions.override {
    vscodeExtensions = (with pkgs.vscode-extensions; [
      equinusocio.vsc-material-theme
      equinusocio.vsc-material-theme-icons
      james-yu.latex-workshop
      vscodevim.vim
      valentjn.vscode-ltex
    ]);
  };
  mytex = pkgs.texliveMedium.withPackages (ps: [ ps.mathdesign
        ps.verse
        ps.quotchap
        ps.biblatex]);
in
pkgs.mkShell {
  buildInputs = [ myvscode mytex ];
}

Not 100% sure and can not verify as I am writing this on my phone.

Actually the shell.nix part is the important obe to actually “see” the problem.

So you have something like import ./shell.nix {}
That can be splitted into the two things that it’s doing.

First. Importing the nix file, and second applying it as a function (in your case with passing pkgs).

But your shell.nix actually does not expect any arguments. It’s a pure static file.

You either can remove the {} part or make it accept arguments (which should turn it into a function)

Do you could change the top of the shell.nix to something like

 { pkgs ? import <nixpkgs> { config.allowUnfree = true;  } }:
let
  myvscode = ...

That should change your shell.nix into accepting pkgs as argument (you are passing it anyways) or if not given initialize an nixpkgs instance for it.
That should (hopefully) still be compatible with nix-shell.
You might notice that the unofficial wiki you liked has a similar example for that.

1 Like

Thanks a lot. I hadn’t noticed that line :slight_smile: