rust-lang / cargo

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

Add PackageId to "dependencies" in cargo metadata #7289

Open jsgf opened 5 years ago

jsgf commented 5 years ago

Problem In cargo metadata, the name field in deps has - transformed to _, which means you need to normalize -/_ in order to compare it with the name field in dependencies.

For example:

      "dependencies": [
        {
          "name": "proc-macro2",
          "source": "registry+https://github.com/rust-lang/crates.io-index",
          "req": "^0.4",
          "kind": null,
[...]
        "deps": [
          {
            "name": "proc_macro2",
            "pkg": "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)"
          },

Steps

  1. Have a Cargo.toml with proc-macro2 as a dependency
  2. Run cargo metadata and compare the dependency and deps fields

Possible Solution(s) The deps entries should have some field which directly corresponds to a field in dependencies.

Notes

Output of cargo version: cargo 1.38.0-nightly (e853aa976 2019-08-09)

jsgf commented 5 years ago

Possibly related to #5583?

ehuss commented 5 years ago

This is the expected behavior. The name field in deps is the name of the library target, which is not the same as the name of the package (they can be completely different).

It may be possible to place the resolved package ID into the package dependencies value, but it will likely be difficult.

Can you say more about what you're trying to do? Why do you need to correlate the resolve with the Dependency? More information is being added in #7132, which may help.

jsgf commented 5 years ago

Hm, yeah, it looks like my scheme isn't working for rust-crypto (main library crypto). So I think my only recourse for the moment is to take the first word of the deps pkg and match it against the dependency name.

The specific goal is to match the resolved dependencies to a particular target by matching up the dep kind against the target kind. #7132 will help with that, but it would still be nice to be able to unambiguously match the resolved dependency with its corresponding unresolved dependency.

jsgf commented 5 years ago

I guess I can map the resolved dep's pkgid -> manifest -> name, and match that against dependency -> name.

ehuss commented 5 years ago

The specific goal is to match the resolved dependencies to a particular target by matching up the dep kind against the target kind.

Can you say more about why you want to match them up? Perhaps explain your use case?

jsgf commented 5 years ago

I'm writing a tool to automatically generate Buck build rules from Cargo.toml so we can import things from crates.io and build from source with Buck. I need the target info so I can generate the appropriate corresponding Buck rule. In general I've found it useful to fully grok the Cargo metadata in doing this.

alexcrichton commented 5 years ago

I think the best solution here may be too add something like a package_id in the dependencies listings for each package. Ideally that'd make it so you don't need to do any matching/inference yourself, you just hook things up as the strings match. I think that's also more robust in that it handles [patch] nicely as well for consumers using that.

poliorcetics commented 2 years ago

I would like that as well to be able to operate over all the packages at once regardless of whether they are dependencies or local crates.

I'm currently parsing the Cargo.lock myself to build a tool to see what dependency is brought through whom as in:

Crate name (8)       | Other | Shared | Unique |
================================================
proc-macro2 1.0.43   |     6 |      0 |      2 |
quote 1.0.21         |     5 |      1 |      2 |
serde 1.0.143        |     2 |      4 |      2 |
serde_derive 1.0.143 |     3 |      3 |      2 |
syn 1.0.99           |     4 |      2 |      2 |
toml 0.5.9           |     1 |      5 |      2 |
unicode-ident 1.0.3  |     7 |      0 |      1 |
whose-deps 0.1.0     |     0 |      6 |      2 |

But building the dependency graph that way doesn't account for features and target and is quite error-prone. Being able to ask cargo metadata for the graph would be very nice