Filtering out working nixpkgs expressions

Hello,

For some project, I’d like to be able to go through all the packages, and extract some information. Unfortunately, using lib.attrsets.mapAttrsToList, I keep running into errors because of:

  • Broken packages
  • Unsupported packages for my system
  • Packages that are not marked broken but still seem to break?

For instance, on OSX:

let
  nixpkgs = import <nixpkgs> {};
  isValid = d:
  let r = builtins.tryEval (nixpkgs.lib.isDerivation d && ! (nixpkgs.lib.attrByPath [ "meta" "broken" ] false r));
  in r.success && r.value;
  validPkgs = nixpkgs.lib.filterAttrs (k: v: isValid v) nixpkgs.pkgs;
in
nixpkgs.lib.attrsets.mapAttrsToList (k: v: v.name) validPkgs

has a bunch of errors:

«error: Package ‘libdbusmenu-gtk3-16.04.0’ in /nix/store/ncawd0mgp0f7y8qv3jx7sqgydaafaf5d-nixpkgs-19.03.172530.096e2f137b6/nixpkgs/pkgs/development/libraries/libdbusmenu/default.nix:58 is not supported on ‘x86_64-apple-darwin’, refusing to evaluate.

a) For `nixos-rebuild` you can set
  { nixpkgs.config.allowUnsupportedSystem = true; }
in configuration.nix to override this.

b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  { allowUnsupportedSystem = true; }
to ~/.config/nixpkgs/config.nix.
»
«error: assertion failed at /nix/store/ncawd0mgp0f7y8qv3jx7sqgydaafaf5d-nixpkgs-19.03.172530.096e2f137b6/nixpkgs/pkgs/os-specific/linux/kernel/generic.nix:53:1» "rtl_433-18.12" «error: assertion failed at /nix/store/ncawd0mgp0f7y8qv3jx7sqgydaafaf5d-nixpkgs-19.03.172530.096e2f137b6/nixpkgs/pkgs/os-specific/linux/kernel/generic.nix:53:1»

Is there a better way of traversing the available, working packages?

1 Like

It looks like the error is being thrown from the access to v.name. You could try and wrap access to that with tryEval, but I figure it’s simpler just to force evaluation of d.name in isValid as that’s already wrapped in tryEval.

You also have a typo in isValid where you’re running nixpkgs.lib.attrByPath on r instead of d.

Fixing these two issues, I get the following, which evaluates without error when passed to nix-instantiate --eval --strict:

let
  nixpkgs = import <nixpkgs> {};
  isValid = d:
    let r = builtins.tryEval (nixpkgs.lib.isDerivation d && builtins.seq d.name (! (nixpkgs.lib.attrByPath [ "meta" "broken" ] false d)));
    in r.success && r.value;
  validPkgs = nixpkgs.lib.filterAttrs (k: v: isValid v) nixpkgs.pkgs;
in
nixpkgs.lib.attrsets.mapAttrsToList (k: v: v.name) validPkgs

This will technically force the evaluation of name for all packages even when they are otherwise broken, which you could fix but it would be slightly more awkward. Without actually testing it, I would expect that to look something like let r = builtins.tryEval (nixpkgs.lib.isDerivation d && ! (nixpkgs.lib.attrByPath [ "meta" "broken" ] false d) && builtins.seq d.name true);.

It’s also worth pointing out that this script isn’t going to recurse into nested package collections. I know collections (that you’re supposed to recurse into) are marked specially with recurseIntoAttrs but I don’t know the details of actually traversing these.

2 Likes