Any way to get a derivation's inputDrvs from within Nix?

If I instantiate a derivation, the resulting .drv file declares a list of inputDrvs, which AFAICT is a complete set of all derivations that this one depends on prior to building. I can also use nix show-derivation to get a JSON equivalent. However, what I can’t figure out how to do is reconstruct this same list from within Nix itself. Is there any way to do this?

The use-case here is I’m trying to write a tool to help me explore dependencies and I thought it would be really handy to be able to write it in Nix directly, if only I could get at this data, rather than wrapping nix show-derivation.


Not a direct answer to your question, but if you haven’t seen it already you may want to read this:

They share the source code for how it’s all produced, including some nix expressions to walk the graph, so it might help for drawing inspiration.


I use something similar to this to ensure that my CI has all build time deps cached:


Both of these are useful. Looks like the “Mapping a Universe” approach is to evaluate all of the packages into a custom store in order to produce the .drv files, then walk the store with Haskell and parse them using Nix.Derivation.parseDerivation. That’s cute, and I didn’t realize Nix had a Haskell library for parsing derivations. The build-time dependencies approach is pure Nix but is using regular expressions to parse the derivation >_<

I ended up writing my tool around nix show-derivation with a scripting language after all, which is irritating, but it works reasonably enough. If I were more competent with Haskell I would have been tempted to use that, but I’m not.

1 Like

@lilyball Besides the already proposed super interesting ideas (see also blog post), which I had no idea of, I’ve implemented a pure Nix function that gets all of the propagatedBuildInputs and buildInputs of a derivation here:

It’s also a sort of hack because you can reach infinite recursion with it, unless you pass it a list of known packages you don’t want it to iterate.

I noted my self to try the other methods once I’ll have more time to work on that PR.