cargo-public-api icon indicating copy to clipboard operation
cargo-public-api copied to clipboard

Be able to diff workspace crate against published crate version

Open repi opened this issue 3 years ago • 6 comments

It would be great to have an alternative to --diff-git-checkouts that instead of syncing a previous commit of the same repo (which can be a quite heavy and complex operation on a large repo) you can compare against a previously published crate version on crates.io. Have there been any thoughts of such an alternative?

So something like --diff-published-crate x.y.z which downloads the crate from crates.io (or the registry it was specified to use), unpacks it, and compares it from that.

We have a monorepo that has rust-toolchain.toml and lots of forked dependencies so syncing previous git versions and comparing that can be a bit problematic and slow. Also makes it harder if you have pending staged changes etc.

repi avatar Aug 31 '22 10:08 repi

Something like this sounds good to me, and I have had similar thoughts. I think it would be good to make use of the cargo cache somehow though, so that repeated runs does not download the same crate over and over.

Enselic avatar Aug 31 '22 19:08 Enselic

Until this is implemented, you can use the following workaround. The example uses git clone but it of course works for existing repos too:

# Fetch rustdoc-types 0.15.0 from crates.io and build its rustdoc JSON
% curl -L "https://crates.io/api/v1/crates/rustdoc-types/0.15.0/download" | tar -zxf -
% cargo +nightly rustdoc --manifest-path rustdoc-types-0.15.0/Cargo.toml -- -Zunstable-options -wjson

# Fetch latest git code of rustdoc-types and build its rustdoc JSON
% git clone [email protected]:aDotInTheVoid/rustdoc-types.git
% cargo +nightly rustdoc --manifest-path rustdoc-types/Cargo.toml -- -Zunstable-options -wjson

# Now use cargo public-api to diff these APIs
% cargo public-api --diff-rustdoc-json rustdoc-types-0.15.0/target/doc/rustdoc_types.json rustdoc-types/target/doc/rustdoc_types.json
Removed items from the public API
=================================
(none)

Changed items in the public API
===============================
-pub const rustdoc_types::FORMAT_VERSION: u32 = 19u32
+pub const rustdoc_types::FORMAT_VERSION: u32 = 20u32
-pub enum variant rustdoc_types::Variant::Struct(Vec<Id>)
+pub enum variant rustdoc_types::Variant::Struct
-pub enum variant rustdoc_types::Variant::Tuple(Vec<Type>)
+pub enum variant rustdoc_types::Variant::Tuple(Vec<Option<Id>>)

Added items to the public API
=============================
+pub struct field rustdoc_types::Variant::Struct::fields: Vec<Id>
+pub struct field rustdoc_types::Variant::Struct::fields_stripped: bool

Enselic avatar Sep 07 '22 18:09 Enselic

if instead of using cargo rustdoc we used rustdoc we could do this directly with the cargo cache.

Emilgardis avatar Sep 11 '22 15:09 Emilgardis

Interesting idea! I don't fully understand it though. Would you mind elaborating a bit? But if we did that, wouldn't that mean we would have to start to parse Cargo.toml ourselves? That is probably quite a big amount of work for us?

Enselic avatar Sep 11 '22 19:09 Enselic

The idea being that we'd be able to do the same invocation that cargo doc does when building docs with deps.

rustdoc --crate-type lib --crate-name <crate> $CARGO_HOME/registry/src/<cache>/src/lib.rs --cap-lints warn -o /target/doc <features...> -L dependency=/target/debug/deps --crate-version <crate_version> <cfgs>

this of course means more of cargo has to be implemented or borrowed, as the flags used are derived from build-scripts and other metadata from rustc/cargo.

Emilgardis avatar Sep 11 '22 23:09 Emilgardis

Thanks for elaborating. Re-implementing cache logic seems like a much smaller task than re-implementing Cargo.toml-parsing though?

Enselic avatar Sep 12 '22 03:09 Enselic

For future reference: the package downloading code for cargo can be found here and below. Ideally that code would have lived in a crate that we could re-use, but we were not that lucky.

Enselic avatar Oct 22 '22 09:10 Enselic

I figured the easiest is simply to let cargo public-api create a dummy cargo project and add the crate in question as a dependency. Seems to work pretty well. Functional draft PR is here: #196

Enselic avatar Oct 31 '22 17:10 Enselic