How to convert this nix.shell file into a buildFHSUserEnv?

I have this nix.shell which is close to what I want:

with import <nixpkgs> {};

stdenv.mkDerivation {
    name = "node";
    buildInputs = [
        nodejs-16_x
        nodePackages.firebase-tools
        nodePackages.node-gyp
    ];
    shellHook = ''
        export PATH="$PWD/node_modules/.bin/:$PATH"
        export NPM_PACKAGES="$HOME/.npm-packages"
    '';
}

I want to convert it to buildFHSUserEnv. Reading the documentation, they indicate the following example:

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "simple-x11-env";
  targetPkgs = pkgs: (with pkgs;
    [ udev
      alsaLib
    ]) ++ (with pkgs.xorg;
    [ libX11
      libXcursor
      libXrandr
    ]);
  multiPkgs = pkgs: (with pkgs;
    [ udev
      alsaLib
    ]);
  runScript = "bash";
}).env

How to introduce my nix.shell content into a FHS-compatible lightweight sandbox?

1 Like
stdenv.mkDerivation {
  buildInputs = [
    (pkgs.buildFHSUserEnv {
      ...
    }).env
  ];
}
1 Like

Thanks, @Sandro.

Unfortunately, the system is retrieving the following error:

You need to tell it where stdenv comes from, eg:

let
  pkgs = import <nixpkgs> {};
  inherit (pkgs) stdenv; # and what else you need
in stdenv.mkDerivation { … }

Though for a shell using mkShell is much more common.

You probably wan to use with pkgs to not maintain a useless list of attributes.

I am not a friend of with.

And it also is a documented antipattern.

https://nix.dev/anti-patterns/language#with-attrset-expression

Perhaps something like:

{ pkgs ? import <nixpkgs> {} }:

(pkgs.buildFHSUserEnv {
  name = "node";
  targetPkgs = pkgs: [
    pkgs.nodejs-16_x
    pkgs.nodePackages.firebase-tools
    pkgs.nodePackages.node-gyp
  ];
  
  runScript = pkgs.writeScript "init.sh" ''
    export PATH="$PWD/node_modules/.bin/:$PATH"
    export NPM_PACKAGES="$HOME/.npm-packages"
    exec bash
  '';
}).env
1 Like

You don’t have the same inputs in a shell.nix as in a normal package’s default.nix. and emulating that with inherit has no real benefits except that you need to maintain that inherit.

And it also is a documented antipattern.

That’s not an official documentation. Also rec is fine to use and the example given on the page is almost twice in size of lines for nothing really.

1 Like

Let’s agree to disagree, though I have to be honest, regardless of the language, whether you call it with, import or use, doing it “unqualified” or with a broad glob is considered an antipattern by the respective communities.

I will continue to not use with, and I will continue to propose alternatives. Of course I will not force anyone to use one or the other.

1 Like