🏡 index : ~doyle/gitlab-cargo-shim.git

author Bastien Orivel <eijebong@bananium.fr> 2022-09-14 10:03:47.0 +00:00:00
committer Bastien Orivel <eijebong@bananium.fr> 2022-09-14 10:14:42.0 +00:00:00
commit
027bd44578b207f88229fdf404d5b7f894b55978 [patch]
tree
6e5236af4e6625276041d6393c23cd15f2bb8ce5
parent
19aafa0cf39306c063f9d1f7bc5638f9d7514d35
download
027bd44578b207f88229fdf404d5b7f894b55978.tar.gz

Fix dependency renaming in published crates

Turns out that when a crate uses a dependency with a `package` key, the
meaning of `name` and `rename` gets inverted. This is a bit confusing so
let's look at an example.

We have a package that depends on hyper through a `package` but that has
a local name that doesn't exist in the registry.

```
[package]
name = "test_dep_resolver"
...

[dependencies]
thisdoesntexist = { package = "hyper", version = "0.14" }
```

When published to crates.io, it will generate the following:
(visible here:
https://github.com/rust-lang/crates.io-index/blob/master/te/st/test_dep_resolver)

```
{
  "name": "test_dep_resolver",
  "vers": "0.1.1",
  "deps": [
    {
      "name": "thisdoesntexist",
      "req": "^0.14",
      "features": [],
      "optional": false,
      "default_features": true,
      "target": null,
      "kind": "normal",
      "package": "hyper"
    }
  ],
  "cksum": "1484b56f82049380557a5799807afd981e7d443d053710ff49494db34f151b5a",
  "features": {},
  "yanked": false,
  "links": null
}
```

As we can see, the hyper dependency has the name `thisdoesntexist` and
`package` hyper.

Now let's have a look at the `cargo metadata` output:

```
> cat local | jq '.packages[] | select(.name == "test_dep_resolver") | .dependencies[] | select (.name == "hyper")'
{
  "name": "hyper",
  "source": "registry+https://github.com/rust-lang/crates.io-index",
  "req": "^0.14",
  "kind": null,
  "rename": "thisdoesntexist",
  "optional": false,
  "uses_default_features": true,
  "features": [],
  "target": null,
  "registry": null
}
```

Here we can see `name` is `hyper` and `rename` is `thisdoesntexist`.

With the previous code, they were mapped 1-1 with `name` and `package`
but need to be inverted to match what cargo is expecting.

Diff

 src/metadata.rs | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/metadata.rs b/src/metadata.rs
index b6f39c7..aed0ce9 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -26,19 +26,27 @@ pub fn transform(
        deps: package
            .dependencies
            .into_iter()
            .map(|v| CargoIndexCrateMetadataDependency {
                name: v.name,
                req: v.req,
                features: v.features,
                optional: v.optional,
                default_features: v.uses_default_features,
                target: v.target,
                kind: v.kind,
                registry: Some(v.registry.map_or(
                    Cow::Borrowed("https://github.com/rust-lang/crates.io-index.git"),
                    Cow::Owned,
                )),
                package: v.rename,
            .map(|v| {
                let (name, package) = if let Some(rename) = v.rename {
                    (rename, Some(v.name))
                } else {
                    (v.name, None)
                };

                CargoIndexCrateMetadataDependency {
                    name,
                    req: v.req,
                    features: v.features,
                    optional: v.optional,
                    default_features: v.uses_default_features,
                    target: v.target,
                    kind: v.kind,
                    registry: Some(v.registry.map_or(
                        Cow::Borrowed("https://github.com/rust-lang/crates.io-index.git"),
                        Cow::Owned,
                    )),
                    package,
                }
            })
            .collect(),
        cksum,