rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.58k stars 2.39k forks source link

feature request: command to list the dependency tree #1211

Closed andrewrk closed 7 years ago

andrewrk commented 9 years ago

One use case: I have a failing to compile dependency and I want to know how exactly I depend on it.

As an example, npm has the npm ls command:

$ npm ls
groovebasin@1.5.0 /home/andy/dev/groovebasin
├── browserify-lite@0.2.4
├─┬ connect-static@1.4.0
│ ├── mime@1.2.11
│ └── streamsink@1.2.0
├── content-disposition@0.5.0
├─┬ cookies@0.5.0
│ └── keygrip@1.0.1
├── curlydiff@2.0.1
├─┬ express@4.10.6
│ ├─┬ accepts@1.1.4
│ │ ├─┬ mime-types@2.0.4
│ │ │ └── mime-db@1.3.1
│ │ └── negotiator@0.4.9
│ ├── cookie@0.1.2
│ ├── cookie-signature@1.0.5
│ ├─┬ debug@2.1.0
│ │ └── ms@0.6.2
│ ├── depd@1.0.0
│ ├── escape-html@1.0.1
│ ├─┬ etag@1.5.1
│ │ └── crc@3.2.1
│ ├── finalhandler@0.3.2
│ ├── fresh@0.2.4
│ ├── media-typer@0.3.0
│ ├── merge-descriptors@0.0.2
│ ├── methods@1.1.0
│ ├─┬ on-finished@2.1.1
│ │ └── ee-first@1.1.0
│ ├── parseurl@1.3.0
│ ├── path-to-regexp@0.1.3
│ ├─┬ proxy-addr@1.0.4
│ │ ├── forwarded@0.1.0
│ │ └── ipaddr.js@0.1.5
│ ├── qs@2.3.3
│ ├── range-parser@1.0.2
│ ├─┬ send@0.10.1
│ │ ├── destroy@1.0.3
│ │ ├── mime@1.2.11
│ │ └── ms@0.6.2
│ ├─┬ type-is@1.5.4
│ │ └─┬ mime-types@2.0.4
│ │   └── mime-db@1.3.1
│ ├── utils-merge@1.0.0
│ └── vary@1.0.0
├── findit2@2.2.3
├─┬ googleapis@1.0.21
│ ├── async@0.9.0
│ ├─┬ gapitoken@0.1.3
│ │ └─┬ jws@0.0.2
│ │   ├── base64url@0.0.3
│ │   └─┬ tap@0.3.3
│ │     ├── buffer-equal@0.0.1
│ │     ├── deep-equal@0.0.0
│ │     ├─┬ difflet@0.2.6
│ │     │ ├── charm@0.1.2
│ │     │ ├── deep-is@0.1.3
│ │     │ └── traverse@0.6.6
│ │     ├── inherits@1.0.0
│ │     ├── mkdirp@0.3.5
│ │     ├─┬ nopt@2.2.1
│ │     │ └── abbrev@1.0.5
│ │     ├─┬ runforcover@0.0.2
│ │     │ └─┬ bunker@0.1.2
│ │     │   └─┬ burrito@0.2.12
│ │     │     ├── traverse@0.5.2
│ │     │     └── uglify-js@1.1.1
│ │     ├── slide@1.1.6
│ │     └── yamlish@0.0.5
│ ├─┬ multipart-stream@1.0.0
│ │ ├── inherits@2.0.1
│ │ └── sandwich-stream@0.0.4
│ ├─┬ request@2.40.0
│ │ ├── aws-sign2@0.5.0
│ │ ├── forever-agent@0.5.2
│ │ ├─┬ form-data@0.1.4
│ │ │ ├─┬ combined-stream@0.0.7
│ │ │ │ └── delayed-stream@0.0.5
│ │ │ └── mime@1.2.11
│ │ ├─┬ hawk@1.1.1
│ │ │ ├── boom@0.4.2
│ │ │ ├── cryptiles@0.2.2
│ │ │ ├── hoek@0.9.1
│ │ │ └── sntp@0.2.4
│ │ ├─┬ http-signature@0.10.0
│ │ │ ├── asn1@0.1.11
│ │ │ ├── assert-plus@0.1.2
│ │ │ └── ctype@0.5.2
│ │ ├── json-stringify-safe@5.0.0
│ │ ├── mime-types@1.0.2
│ │ ├── node-uuid@1.4.2
│ │ ├── oauth-sign@0.3.0
│ │ ├── qs@1.0.2
│ │ ├── stringstream@0.0.4
│ │ ├─┬ tough-cookie@0.12.1
│ │ │ └── punycode@1.3.2
│ │ └── tunnel-agent@0.4.0
│ └─┬ string-template@0.2.0
│   └── js-string-escape@1.0.0
├─┬ groove@2.2.7
│ └── bindings@1.2.1
├── httpolyglot@0.1.0
├── human-size@1.1.0
├── keese@1.1.1
├─┬ lastfm@0.9.2
│ └── underscore@1.6.0
├─┬ leveldown@1.0.0
│ ├─┬ abstract-leveldown@2.0.3
│ │ └── xtend@3.0.0
│ ├── bindings@1.2.1
│ ├── fast-future@1.0.1
│ └── nan@1.3.0
├── mess@0.1.2
├─┬ mkdirp@0.5.0
│ └── minimist@0.0.8
├─┬ multiparty@4.1.0
│ └── fd-slicer@1.0.0
├─┬ music-library-index@1.3.0
│ └── diacritics@1.2.1
├─┬ mv@2.0.3
│ ├── ncp@0.6.0
│ └── rimraf@2.2.8
├── osenv@0.1.0
├── pend@1.2.0
├── semver@4.1.1
├─┬ serve-static@1.7.1
│ ├── escape-html@1.0.1
│ ├── parseurl@1.3.0
│ ├─┬ send@0.10.1
│ │ ├── debug@2.1.0
│ │ ├── depd@1.0.0
│ │ ├── destroy@1.0.3
│ │ ├─┬ etag@1.5.1
│ │ │ └── crc@3.2.1
│ │ ├── fresh@0.2.4
│ │ ├── mime@1.2.11
│ │ ├── ms@0.6.2
│ │ ├─┬ on-finished@2.1.1
│ │ │ └── ee-first@1.1.0
│ │ └── range-parser@1.0.2
│ └── utils-merge@1.0.0
├─┬ stylus@0.49.3
│ ├── css-parse@1.7.0
│ ├─┬ debug@2.1.0
│ │ └── ms@0.6.2
│ ├─┬ glob@3.2.11
│ │ ├── inherits@2.0.1
│ │ └─┬ minimatch@0.3.0
│ │   ├── lru-cache@2.5.0
│ │   └── sigmund@1.0.0
│ ├── mkdirp@0.3.5
│ ├── sax@0.5.8
│ └─┬ source-map@0.1.41
│   └── amdefine@0.1.0
├─┬ yauzl@2.2.0
│ └── fd-slicer@1.0.0
├─┬ yawl@1.0.1
│ └─┬ bl@0.9.3
│   └─┬ readable-stream@1.0.33
│     ├── core-util-is@1.0.1
│     ├── inherits@2.0.1
│     ├── isarray@0.0.1
│     └── string_decoder@0.10.31
├─┬ yazl@2.0.2
│ └── buffer-crc32@0.2.5
└─┬ ytdl-core@0.3.1
  ├─┬ jstream@0.2.7
  │ ├── clarinet@0.8.1
  │ └─┬ readable-stream@1.1.13
  │   ├── core-util-is@1.0.1
  │   ├── inherits@2.0.1
  │   ├── isarray@0.0.1
  │   └── string_decoder@0.10.31
  ├─┬ request@2.37.0
  │ ├── aws-sign2@0.5.0
  │ ├── forever-agent@0.5.2
  │ ├─┬ form-data@0.1.4
  │ │ ├── async@0.9.0
  │ │ ├─┬ combined-stream@0.0.7
  │ │ │ └── delayed-stream@0.0.5
  │ │ └── mime@1.2.11
  │ ├─┬ hawk@1.1.1
  │ │ ├── boom@0.4.2
  │ │ ├── cryptiles@0.2.2
  │ │ ├── hoek@0.9.1
  │ │ └── sntp@0.2.4
  │ ├─┬ http-signature@0.10.1
  │ │ ├── asn1@0.1.11
  │ │ ├── assert-plus@0.1.5
  │ │ └── ctype@0.5.3
  │ ├── json-stringify-safe@5.0.0
  │ ├── mime-types@1.0.2
  │ ├── node-uuid@1.4.2
  │ ├── oauth-sign@0.3.0
  │ ├── qs@0.6.6
  │ ├─┬ tough-cookie@0.12.1
  │ │ └── punycode@1.3.2
  │ └── tunnel-agent@0.4.0
  └── underscore@1.6.0
alexcrichton commented 9 years ago

Seems like a cool idea! (also wow that's a lot of dependencies)

Cargo does support custom subcommands by having cargo-foo located in your $PATH (allowing cargo foo), so we don't necessarily have to have this support in-tree.

ghost commented 9 years ago

I built one: https://github.com/jakub-/cargo-ls.

Happy to contribute it as a built-in command in case we think it has high enough utility to be included.

lilyball commented 9 years ago

I'd love to see this built-in. This is something I've wanted on multiple occasions. But I also want a bit more info about each dependency (this could be put behind a --verbose flag). Specifically, I want to know:

It would also be good to have some specific support for packages that are depended upon by multiple paths. In such a case, a package may be constrained to an older version, which isn't apparent when looking at one of the dependency paths, which can be confusing if the reader doesn't realize there's multiple dependencies on the same crate with different version requirements.

I guess what I'd actually like to see is a command cargo deps that by default just lists each crate in order, with the aforementioned info, along with a list of crates it depends on and crates that depend on it. The tree-like output in the ticket description could then be yielded with cargo deps --tree (but I'm not really a fan of that as the default output because it has to duplicate each crate that's depended-on by multiple other crates, e.g. in the example tree the npm package request is listed twice).

sbeckeriv commented 8 years ago

hey @kballard @andrewrk cargo-edit has a pretty nice tree view. its not all the information I think @kballard wants but its a good start. crates page

Also there is a new command metadata that is in master which might be of interest.

Output the resolved dependencies of a project, the concrete used versions including overrides, in machine-readable format.

Thanks! becker

mbrubeck commented 8 years ago

https://crates.io/crates/cargo-tree is another implementation of this.

alexcrichton commented 7 years ago

As implementations exist of this externally, closing.

philippludwig commented 5 years ago

@alexcrichton With "cargo ls" being gone and "cargo tree" not being able to compile,is there any chance that this is going to be reopened? I have a project where some dependencies pulls in tokio, which doesn't compile (as usual) and I would like to remove that dependency, but it's really not easy to figure out which one causes this.

ehuss commented 5 years ago

@philippludwig what issue are you having with cargo-tree not compiling? It seems to work for me.

lilyball commented 5 years ago

cargo-tree does not compile on macOS because it tries to install openssl-sys, which bails as macOS ships with a really old OpenSSL.

I'm rather curious as to why cargo-tree depends on this. If only there was some tool I could use to visualize its dependency graph...

lilyball commented 5 years ago

I'm guessing it pulls it in via the dependency on cargo, though that lists it as optional.

philippludwig commented 5 years ago

@philippludwig what issue are you having with cargo-tree not compiling? It seems to work for me.

It failed with some random linker error, but after I deleted the ~/.cargo folder, I can't reproduce it anymore. Now it compiles fine, thanks for your support!

cheapsteak commented 4 years ago

for anyone else stumbling on to this from google searching for "cargo list dependencies", this is now built into cargo, use via cargo tree - https://doc.rust-lang.org/cargo/commands/cargo-tree.html

(openssl still doesn't show up in the tree)