Skip to content

Instantly share code, notes, and snippets.

@Mic92
Last active April 8, 2023 22:39
Show Gist options
  • Save Mic92/0a30fa6babd3eb9c8445fd877ae8781f to your computer and use it in GitHub Desktop.
Save Mic92/0a30fa6babd3eb9c8445fd877ae8781f to your computer and use it in GitHub Desktop.
# USAGE: nix-build nixpkgs-graph.nix
# fetch pinned commit of nixpkgs
with import (fetchTarball {
# https://github.com/NixOS/nixpkgs/pull/220455
url = "https://github.com/Mic92/nixpkgs/archive/refs/heads/fix-eval.tar.gz";
}) { };
let
inherit (pkgs) lib;
inherit (builtins) tryEval;
concatString = lib.concatMapStrings (x: (builtins.toString x) + " ");
# This is a white list of packages used for recursion.
packages = [
"darwinPackages"
"haskellPackages"
"dotnetPackages"
"emacsPackages"
"emscriptenPackages"
"javaPackages"
"luaPackages"
"ocamlPackages"
"perlPackages"
"phpPackages"
"pythonPackages"
"python3Packages"
"unixTools"
"winePackages"
];
# Here is the function that we use to extract information from one package. This function takes in a package and returns an attrset.
# @name : the name of the package (key); @value : the information of the package in set form
# Note that variables like buildInputs (set or list) need to be converted to string format first.
# Otherwise, you will encounter various types of errors with `nix-instantiate --eval --json --strict`
# We can use lib.strings.splitString to convert the long string into list but nix is not efficient enough.
extractInfo = depth: packagePath:
lib.mapAttrs (name: value:
let
res = tryEval (if lib.isDerivation value then rec {
type = "node";
pname = (tryEval (if value ? pname then value.pname else "")).value;
version =
(tryEval (if value ? version then value.version else "")).value;
package = packagePath ++ [ pname ];
path = (tryEval (builtins.toString value)).value;
id = (tryEval (if value ? name then value.name else "")).value;
buildInputs = (tryEval (if value ? buildInputs then
concatString value.buildInputs
else
"")).value;
propagatedBuildInputs = (tryEval
(if value ? propagatedBuildInputs then
concatString value.propagatedBuildInputs
else
"")).value;
nativeBuildInputs = (tryEval (if value ? nativeBuildInputs then concatString value.nativeBuildInputs else "")).value;
propagatedNativeBuildInputs = (tryEval (if value ? propagatedNativeBuildInputs then concatString value.propagatedNativeBuildInputs else "")).value;
} else if ((value.recurseForDerivations or false
|| value.recurseForRelease or false) || ((builtins.typeOf value)
== "set" && builtins.elem name packages && depth < 1)) then
extractInfo (depth + 1) (packagePath ++ [ name ]) value
else
null);
in if res.success then res.value else null);
json = builtins.toJSON (lib.collect (x: (x.type or null) == "node") (extractInfo 0 [ "nixpkgs" ] pkgs));
jsonWithoutDeps = builtins.unsafeDiscardStringContext json;
in pkgs.writeText "info.json" jsonWithoutDeps
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment