Code Monkey home page Code Monkey logo

nix-tree's Introduction

nix-tree

Build Status Packaging status

Interactively browse dependency graphs of Nix derivations.

asciicast

Installation

nix-tree is on nixpkgs since 20.09, so just use your preferred method for adding packages to your system, eg:

nix-env -iA nix-tree

Or, for flake enabled systems:

nix profile install 'nixpkgs#nix-tree'

To run the current development version:

nix run github:utdemir/nix-tree -- --help

Usage

$ nix-tree --help
Usage: nix-tree [INSTALLABLE] [--store STORE] [--version] [--derivation] [--impure] [--dot]

  Interactively browse dependency graphs of Nix derivations.

Available options:
  INSTALLABLE              A store path or a flake reference.
                           Paths default to "~/.nix-profile" and "/var/run/current-system"
  --store STORE            The URL of the Nix store, e.g. "daemon" or "https://cache.nixos.org"
                           See "nix help-stores" for supported store types and settings.
  --version                Show the nix-tree version
  --derivation             Operate on the store derivation rather than its outputs
  --impure                 Allow access to mutable paths and repositories
  --dot                    Print the dependency graph in dot format
  -h,--help                Show this help text

Keybindings:
  hjkl/Arrow Keys : Navigate
  w               : Open why-depends mode
  /               : Open search mode
  s               : Change sort order
  y               : Yank selected path to clipboard
  ?               : Show help
  q/Esc           : Quit / close modal

Glossary

  • NAR Size: Size of the store path itself.
  • Closure size: Total size of the store path and all its transitive dependencies.
  • Added size: Size of the store path, and all its unique transitive dependencies. In other words, the cost of having that store path on top of all other paths. See issue #14 for a better explanation.

Tips

nix-build prints built paths to stdout, which can be piped conveniently with | xargs -o nix-tree. Examples:

# Output of a local derivation
nix-build . --no-out-link | xargs -o nix-tree

# Build time dependencies (passing a `.drv` path)
nix-instantiate . | xargs -o nix-tree --derivation

# Dependencies from shell.nix
nix-build shell.nix -A inputDerivation | xargs -o nix-tree

# All outputs of a derivation in nixpkgs
nix-build '<nixpkgs>' -A openssl.all --no-out-link | xargs -o nix-tree

nix-tree also supports flake references:

# Build time dependencies of a flake on the current directory
nix-tree --derivation '.#'

# Same thing works for any flake reference
nix-tree --derivation 'nixpkgs#asciiquarium'

Run nix-tree on your current nixos system:

nix-tree /nix/var/nix/profiles/system

Query the binary cache before download, with the --store option:

# Query the runtime dependency of `stellarium` (2 GiB closure) without download
nix eval --raw 'nixpkgs#stellarium.outPath' | xargs -o nix-tree --store https://cache.nixos.org

For valid --store options, see nix help-stores. For example,

# Build in a temporary chroot store and examine the output
nix build --store /tmp/chroot-store 'nixpkgs#hello' --print-out-paths | xargs -o nix-tree --store /tmp/chroot-store

Contributing

All contributions, issues and feature requests are welcome.

To hack on it, simply run nix-shell and use cabal as usual. Please run ./format.sh before sending a PR.

Related tools

  • nix-du: Visualise which gc-roots to delete to free some space in your nix store
  • nix-melt: A ranger-like flake.lock viewer
  • nix-query-tree-viewer: GTK viewer for the output of nix-store --query --tree
  • nix-visualize: Uses the Nix package manager to visualize the dependencies of a given package

nix-tree's People

Contributors

bryango avatar figsoda avatar github-actions[bot] avatar grigorenkopv avatar markus1189 avatar ncfavier avatar utdemir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

nix-tree's Issues

Feature request: Have the ability to show closure size when using --derivation

I was trying to find why a derivation was taking up so much space. The best way I could figure out how to do it, with any tools, was to use nix-tree --derivation (without derivation I got basically no information). Unfortunately, when I use --derivation, the sizes nix-tree displays are the size of the .drv files, not the size of the outputs they correspond to, so I had to go through the tree and manually check each one with nix path-info -sh. I would really like it if there was a feature where I could see all derivations needed by a particular derivations, and how big their closures were.

show version

please add a command to check for the package version (--version)

Restore flakes support?

Utku,

First off, thank you for having built nix-tree; I have found it very valuable in the past for verifying that certain dependencies have been completely updated (or purged).

Second, regarding flakes support: while I know there may have been no way for you to know this, fyi, I had been relying on flakes support in nix-tree and in fact, I had chosen nix-tree from among competing tools in part because it supported flakes — and so you can imagine I was somewhat caught by surprise yesterday when I found that 415a0ac had removed this capability.

Anyway, regarding what to do: in the short term, I and any other flakes users who run into this will be fine since we can simply nix run github:utdemir/nix-tree?rev=e313e84e474d03b29ff63d05ba813994da2f6a1e and move on with our day — and I completely understand if flakes are too burdensome to support, in which case documenting a workaround like this may be the best move.

Alternatively, though, if you’re open to it: have you given thought to what would it take to bring back flakes support in a way that was comfortable and sustainable for you (and for any other relevant maintainers)?

Thanks in advance for considering,

Michael

Better understanding transitive sizes

Would it be possible to track 3 sizes: the package size and closure size like now, and the "single-owner" closure size?

Right now, if two packages depend on the same thing, the ownership is muddled. So I wonder if it would be more obvious if we could see the closure size of things that are not shared with other closures at the same or closer distance from the root?

Given this tree:

A -> D
B -> D
C -> A, E
D
E -> D
F -> A,C
root -> F,B

the sizes would be

pkg size closure single-owner
A A AD 0
B B BD B
C C ACDE E
D D D 0
E E ED 0
F F ACDEF ACEF
root 0 ABCDEF ABCDEF

This would show us that F is the biggest package, and while C has a big closure, removing it will only remove E

Feature request: display bindings in the lower right corner of `nix-tree`.

It's rather complicated to find the menu if you are not aware of its existence. Therefore I propose that we add shortcuts which could hint at the existence of such menu in the lower right corner of nix-tree.

Something similar to gitui's approach could prove to be helpful: (forgive the horrible theming)
image

Feature request: inspect raw derivation

Would be very cool if nix-tree would allow to quickly view the selected derivation. Right now it can be done by switching to a different terminal to run nix show-derivation manually, but that's not so convenient.

[feature-request] nix-tree as a library

Hi, it would be nice if you offered to use nix-tree as a library as follows:

  • move the other-modules to a library
  • have the executable only contain the main module

Thanks in advance :)

Unable to see the dependencies of pandoc flake

I am unable to use the tool with the pandoc development flake.

Here's the error message:

user@host ~/pandoc (main) [1]> nix-tree --derivation '.#'

error: attribute 'pandoc' missing

       at /nix/store/rw4gbrv5y2m59am2m1zc253hv1mbw1fs-source/flake.nix:42:28:

           41|         # Default package.
           42|         packages.default = self'.packages.pandoc;
             |                            ^
           43|
(use '--show-trace' to show detailed location information)
nix-tree: Received ExitFailure 1 when running
Raw command: nix path-info --json --derivation --extra-experimental-features "nix-command flakes" .#

Here's the nix-info output:

 - system: `"x86_64-linux"`
 - host os: `Linux 6.1.26, NixOS, 23.05 (Stoat), 23.05.20230430.da45bf6`
 - multi-user?: `no`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.13.3`
 - channels(root): `""`
 - nixpkgs: `not found`

And here are the steps to reproduce:

git clone https://github.com/jgm/pandoc
cd pandoc
nix-tree --derivation '.#'

To mention it, this is something I try in order to fix jgm/pandoc#8818. There's also a nixpkgs update request for pandoc: NixOS/nixpkgs#221165

Reproducible hanging

I've run into a specific case where nix-tree will lock up.
What I'm doing is:

  • run nix-shell -p nix-tree --run "nix-tree --derivation /nix/store/aq69wwnfqb5c62kk6vaafc3x9kj37cjp-newsboat-2.28-vendor.tar.gz.drv"
  • use / to search for headers
  • select the second linux-headers-5.18.drv entry
  • press w

The process becomes unresponsive. This is repeatable.
I'm not sure what's specific about that dependency - others open the "why-depends" window without issues.

Case-insensitive search

Currently the search modal searches case-sensitively, and I think case-insensitive search is more convenient.

find a specific package - and which pkgs use it as dependency

Hello,

is it possible to search for a certain package without to navigate through the tree?
like libspatialindex

  • and it would go directly to that/those packages found in that hierarchy

and / or
searching for libspatialindex it would get me python3.7-rtree-0.9.3 and other which use it as dependency

Feature request: Manage gcroots interactively

I have the problem that I have been executing nix builds in many different directories over time and therefore there are tons of result files and corresponding gcroots in /nix/var/nix/gcroots/auto.

I know there is nix-du for gcroot visualization. I have never really used it, but as I understand it, you have to execute the program, pipe it into a renderer, inspect the graph and then execute command manually to free the space. Sounds still quite inconvenient to me.

I have the feeling, a UI like the one of nix-tree would be perfectly suited. It's already possible to inspect individual gcroots via nix-tree.
I can, for example execute nix-tree /nix/var/nix/gcroots/auto/0k6bnn1z76mfddabj8b1pmfkvygms6m3 which will show me the tree and closure size of that single gcroot.

It would be nice if I could zoom out one more step and see all my gcroots listed (preferably sorted by closure size).
Then I can conveniently scroll through them and hit the delete button on the ones which I'd like to delete.

I'm aware of the fact, that finding out how much space a gcroot can actually free is not trivial, since some of it's dependencies could also be blocked by another root.
But I'd guess that the total closure size would already give a good enough estimate.

Feature request: man-page which program + terminology?

Why would this help improve the project?

Reason: to shed light on the new terminology for someone who has previously not encountered these terms prior to their first interaction with nix-tree.

Also, a man-page similar to nix would be appreciated. That is to say that nix-tree --help redirects the user to the man-page itself.

Alternative solution: create a "man page" that an be accessed inside the application through ? + m or something of that sort.

Freeze when using "yank" function

Whenever I use the yank function, the store path is copied to the clipboard correctly, but nix-tree stops responding to any further input. I'm not sure how to debug any further, any suggestions?

how to use nix-tree - nixos / home-manager

nix-tree

error: --- Error --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
experimental Nix feature 'nix-command' is disabled; use '--experimental-features nix-command' to override
nix-tree: Received ExitFailure 1 when running
Raw command: nix path-info --recursive --json /nix/store/qs3lsq6ggyii84hpi4k6mkczqw713ipp-user-environment /nix/store/y8kc459plbj2g3s50mbz1nlxcv104zcy-nixos-system-nixosP33-20.03.2652.076c67fdea6

Feature request: Help diagnose packages with file collisions

Thanks for nix-tree! It's great. I love these tools that take advantage of all the great information available from the Nix packaging system.

One thing I'd really like to use nix-tree for is to help better understand file collisions (in particular, when building Python environments).

From time to time I accidentally build a Python environment that includes two derivations of the same Python package. Sometimes this is because two upstream versions of the Python package are being included but more often the upstream version is the same and something about the Nix derivation has changed (eg, versions of dependencies).

If I use nix-tree to inspect this situation then I don't learn much because nix-tree convenient chops off the output hash portion of the store object name. Thus, I see that my Python environment includes "python3.7-autobahn-21.3.1.drv" and "python3.7-autobahn-21.3.1.drv".

It would be great if I could tell these apart in nix-tree. Perhaps if nix-tree notices there are duplicates after constructing the short versions of the names, it could append the minimum hash prefix necessary to disambiguate? For example, if one python3.7-autobahn-21.3.1.drv has an output path of /nix/store/z7zhlhp2jqiza7kwa3kdbw7vvd918gyz-python3.7-autobahn-21.3.1 and the other has an output path of /nix/store/z86hmnd5hiyqy4y2p96macy2v6qz84bn-python3.7-autobahn-21.3.1 then they could be displayed in nix-tree as "python3.7-autobahn-21.3.1.drv (z7)" and "python3.7-autobahn-21.3.1.drv (z8)".

Handle symlinks to .drv files

Currently, passing a symlink to a store path only works if it is a an output, rather than a derivation (*.drv). This is because we pass a special flag to nix path-info to handle derivations (see the commit 321d213 for details), and we only do that if the given path ends with .drv; which is not the case if it is hidden behind a symlink.

We should resolve the symlinks and check if the symlink target ends with .drv instead.

Reverse dependencies (`--query --referrers`)

Hi!

Thank you for developing this tool!

I was wondering if it is feasible to include a way to inspect reverse dependencies? Specifially, I was thinking about a way to add information obtained from nix-store --query --referrers. I need this command quite often, and it is very long (and hard to remember).

Thanks for you input!

Dominik

Segmentation fault when hitting key binding before progress bar starts

When hitting a bound key like / before the progress bar starts crashes the application.

$ nix-tree
    <----- hit / here
[================================================================] 100/1000
Segmentation fault (core dumped)
$ coredumpctl info
           PID: 940334 (nix-tree)
           UID: 1000 (sandro)
           GID: 100 (users)
        Signal: 11 (SEGV)
     Timestamp: Wed 2023-10-11 21:07:43 CEST (10min ago)
  Command Line: nix-tree
    Executable: /nix/store/yzx1qnx565xf503d5dl8i2jaxdjmrm8k-nix-tree-0.3.1/bin/nix-tree
 Control Group: /user.slice/user-1000.slice/[email protected]/app.slice/app-org.wezfurlong.wezterm-e1338bfae42347a4a4856fe3dfe4e330.scope
          Unit: [email protected]
     User Unit: app-org.wezfurlong.wezterm-e1338bfae42347a4a4856fe3dfe4e330.scope
         Slice: user-1000.slice
     Owner UID: 1000 (sandro)
       Boot ID: ee11cac9e3a3481fb94c71275e6636df
    Machine ID: 8e73d0d11fdd49d7978013517a64a46f
      Hostname: magnesium
       Storage: /var/lib/systemd/coredump/core.nix-tree.1000.ee11cac9e3a3481fb94c71275e6636df.940334.1697051263000000.zst (present)
  Size on Disk: 13.1M
       Message: Process 940334 (nix-tree) of user 1000 dumped core.
                
                Module libffi.so.8 without build-id.
                Module libgmp.so.10 without build-id.
                Module libncursesw.so.6 without build-id.
                Module nix-tree without build-id.
                Stack trace of thread 940344:
                #0  0x00007f681a882dfe free (libc.so.6 + 0x95dfe)
                #1  0x00007f681aab61fe really_free_termtype (libncursesw.so.6 + 0x401fe)
                #2  0x00007f681aab6ad5 del_curterm_sp (libncursesw.so.6 + 0x40ad5)
                #3  0x00000000007b3ac7 n/a (nix-tree + 0x3b3ac7)
                #4  0x00000000007b3d61 n/a (nix-tree + 0x3b3d61)
                #5  0x00000000007aae1d n/a (nix-tree + 0x3aae1d)
                #6  0x00000000007ac37c n/a (nix-tree + 0x3ac37c)
                #7  0x00000000007b155c n/a (nix-tree + 0x3b155c)
                #8  0x00007f681a872dd4 start_thread (libc.so.6 + 0x85dd4)
                #9  0x00007f681a8f49b0 __clone3 (libc.so.6 + 0x1079b0)
                
                Stack trace of thread 940335:
                #0  0x00007f681a8e374c read (libc.so.6 + 0xf674c)
                #1  0x00000000007caaae n/a (nix-tree + 0x3caaae)
                #2  0x00007f681a872dd4 start_thread (libc.so.6 + 0x85dd4)
                #3  0x00007f681a8f49b0 __clone3 (libc.so.6 + 0x1079b0)
                
                Stack trace of thread 940334:
                #0  0x00000000006daeac n/a (nix-tree + 0x2daeac)
                ELF object binary architecture: AMD x86-64

Feature request: Support non-standard store paths

The store path is not always "/nix/store". Nix has the default value set via a compilation option:

nix = prev.nix.override {
  storeDir = "/path/to/nix/store";
  stateDir = "/path/to/nix/var";
};

And can be overridden at runtime by setting the NIX_STORE_DIR environment variable.

The current value can be learned by running

# nix eval --raw '(builtins.storeDir)'
/path/to/nix/store

Cannot copy to clipboard

Cannot copy to clipboard:
Running ("pbcopy",[]) failed with exception: pbcopy: startProcess: posix_spawnp: does not exist (No such file or directory).
Running ("wl-copy",[]) failed with exception: wl-copy: startProcess: posix_spawnp: does not exist (No such file or directory).
Running ("xclip",["-selection","clipboard"]) failed with exception: xclip: startProcess: posix_spawnp: does not exist (No such file or directory).
Running ("xsel",["-i","-b"]) failed with exception: xsel: startProcess: posix_spawnp: does not exist (No such file or directory).
Please report this as a bug.
> nix-tree --version
nix-tree 0.4.0

nixpkgs revision = 23ff7d9dc4f3d553939e7bfe0d2667198f993536

Feature request: graphviz export

Hi! I don't know if nix-tree would be an appropriate place for this kind of a "generic" feature, but I think it'd be lovely to be able to do something like this:

❯ nix shell nixpkgs#nix-du nixpkgs#xdot
❯ nix-tree --derivation .#nixosConfigurations.$(hostname).config.system.build.toplevel --graphviz | xdot -i

...and nix-tree already provides the convenient interface of "installables" for the task of enumerating the full closure

Just to give an idea of what output I'm looking for, here's a screenshot for

nix-du -s=500MB | xdot -

image

Feature request: show only tree that depends on regex

I'd like to be able to see the packages that depend on e.g. Perl, and their parents.

Ideally, you'd be able to search for "perl", and then the tree makes it obvious which packages transitively and which directly depend on it. Perhaps just don't show the ones that don't depend?

Add support for flake syntax, like `nixpkgs#hello`

Hello, first of all: thanks for this tool, it's really nice to get some insight on a derivation :)

It's been some time that I switched completely to flakes, and recently I tried to run:
nix run unstable#python3.pkgs.ipython
which downloaded a lot of packages before working.

I wanted to get some insight with nix-tree and intuitively tried to do:
nix-tree unstable#python3.pkgs.ipython
⚠️ but that didn't work, basically saying that it's not a store path.

Would it be possible to add support for that?

nix-tree is broken with nix 2.19

nix-tree --derivation 'github:pwndbg/pwndbg#pwndbg'
warning: Ignoring setting 'auto-allocate-uids' because experimental feature 'auto-allocate-uids' is not enabled
warning: Ignoring setting 'impure-env' because experimental feature 'configurable-impure-env' is not enabled
nix-tree: user error (Failed parsing nix path-info output.)

$ nix-tree --version
nix-tree 0.3.1

$ nix --version
nix (Nix) 2.19.2

Unrecognised flag '--derivation' on Nix 2.3.10

The latest stable release of Nix doesn't recognize the --derivation option passed to path-info. I assume this is only available in Nix 3.0?

$ nix-tree $(nix-instantiate --expr "let pkgs = import <nixpkgs> {}; in pkgs.hello")
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
error: unrecognised flag '--derivation'
Try 'nix --help' for more information.
nix-tree: Received ExitFailure 1 when running
Raw command: nix path-info --recursive --json --derivation /nix/store/ivs7c8av0mpy3j6mwdd7z7gikips17m2-hello-2.10.drv

$ nix --version
nix (Nix) 2.3.10

Feature Request: ISO units for size (MB, GB)

I would like to have the sizes displayed in ISO/base 10 units (MB, GB, TB). All programs on my system use these units and it would be nice if i could set nix-tree to do the same, so that i have a homogenous display.

Could you please add a flag for that?

Feature request: Hide a closure from search results

Hey there! I sometimes use nix-tree to solve issues with duplicate Python dependencies, and it can be quite hard to keep track of which specific versions of a dependency I've already checked out (especially if there are many different versions in the closure).

It would be great if there was a keybind to hide/"cross out" the currently selected closure for the remainder of the session (or perhaps until restored through a keybind) so that it or anything it closes over does not show up in search results anymore. That would really help a lot!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.