How to automatically generate the packages list for my nix config?


#1

Hello!

I have got this bit in my nixos config file, which installs all the software I used often:

  environment.systemPackages = with pkgs; [
    emacs
    p7zip
    xfce.xfce4-screenshooter
  ];

I generate this list using nix-env -q | sed -e 's/-[^-]*$//' | sed -e 's/^/ /' but the command isn’t perfect, I have to add xfce.

Any tips or tricks which can let me generate this packages list for my config file better? Thanks!


#2

The best I have for this is something like:

nix-env -q --json | jq -r '.[] | .name' | while read name; do nix-env -qaf '<nixpkgs>' --json "$name" | jq -r 'keys | .[]' | head -n1; done 2>/dev/null

Unfortunately, this is a pretty expensive operation. The problem comes from the fact that nix-env doesn’t remember which attribute or Nixpkgs version you used to install the software. Instead, it just keeps track of the derivation. So, you have to do a search for each name in your current nixpkgs to find the corresponding one. In many cases this will not work. For instance an installed package which is not in Nixpkgs or when two packages have identical names.

An alternative to the above would be keeping track of your software by attribute paths instead of package names. For instance, try this file called env.nix as a starter:

{ pkgs ? import <nixpkgs> {} }:

rec {
  packages = with pkgs; [ emacs p7zip xfce.xfce4-screenshooter ];

  env = pkgs.buildEnv {
    name = "env";
    paths = packages;
  };
}

You can install the environment by just running:

nix-env -iA env -f env.nix

and use it in your configuration as well with:

  environment.systemPackages = (import ./env.nix { inherit pkgs; }).packages;

#3

Use buildEnv in enviroment.systemPackages can make nixos-rebuild to update packages in it? I find nix-env cannot do this without a dufferent version for the buildEnv package.