escargot icon indicating copy to clipboard operation
escargot copied to clipboard

Mismatch between `cargo pkgid` and `cargo metadata` (and human-readable names)

Open Techcable opened this issue 4 years ago • 1 comments

The "package_id" field in cargo metadata is not a valid package id specification.

Take the output of cargo metadata | jq '.packages[0].id' of your local crate. I get "abort_on_panic 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)"

This is not a valid package id specification (cargo pkgid fails). The correct equivalent is "https://github.com/rust-lang/crates.io-index#abort_on_panic:2.0.0".

How are we supposed to convert back and forth between these two seemingly incompatible formats? To go from cargo pkgid -> cargo metadata, I had to re-implement my own matching logic and search back over the metadata :(

Human Redable package ids

Say I have a cargo_metadata::PackageId.

How do I print this back to the user as a cargo pkgid?

The simple answer is to print back the crate's name. In most cases this is unambiguous. Right now (in my current crate) syn refers unambiguously to a single version. That's good

But that doesn't work if there are multiple versions of the crate. What if we have libc:0.1.12 and also libc:0.2.109?

At this point, a simple "print package name" is not a good way to output a PackageId, because libc would be ambiguous.

In addition cargo pkgid supports arbitrary urls like https://github.com/Techcable/my-library#0.2.0-alpha.5. Version + name could be ambiguous in the presence of git dependencies :(

You don't want to have to output a full https://github.com/rust-lang/crates.io-index#syn:1.0.82 when syn is unambiguous, but you also want to be able to handle the ambiguity when it comes out.

Workarounds

As a hack to workaround the lack of cargo pkgid --short <pkg> in my cargo outdir tool, I had to write a post-processing pass pass to analyze for potential conflicts. Then I had to normalize cargo metadata ids back to the minimal package id.

Once again this is made more difficult to cargo_metadata::PackageId using a non-standard format that is incompatible with cargo pkgid, it's also super difficult to go from package ids -> human readable "short" package ids.

So there are there two problems :(

Techcable avatar Jan 07 '22 08:01 Techcable

As far as I can tell, there is no way to map theses. package_id's format is internal to cargo and subject to change. It'd be convenient for us if they changed it to a fully qualified pkgid but I do not know what complications that involves.

The next best thing I can think of is trying to get cargo metadata to also output the pkgid. Unsure how receptive folks will be to that.

Internally, cargo does have a mechanism for converting between them, PackageSpecId::from_package_id. You could dig through that, the Displays and serde implementation of each, etc to work out how it does it. I see that only as a stopgap, if used at all.

epage avatar Jan 07 '22 14:01 epage