Skip to content

Commit

Permalink
Stabilize the rename-dependency feature
Browse files Browse the repository at this point in the history
This commit stabilizes Cargo's `rename-dependency` feature which allows
renaming packages in `Cargo.toml`, enabling importing multiple versions
of a single crate or simply avoiding a `use foo as bar` in `src/lib.rs`.

Closes rust-lang#5653
  • Loading branch information
alexcrichton committed Nov 16, 2018
1 parent 569507e commit 5d6504d
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 150 deletions.
2 changes: 1 addition & 1 deletion src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ features! {
[stable] edition: bool,

// Renaming a package in the manifest via the `package` key
[unstable] rename_dependency: bool,
[stable] rename_dependency: bool,

// Whether a lock file is published with this crate
[unstable] publish_lockfile: bool,
Expand Down
59 changes: 59 additions & 0 deletions src/doc/src/reference/specifying-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,62 @@ features = ["secure-password", "civet"]

More information about features can be found in the
[manifest documentation](reference/manifest.html#the-features-section).

### Renaming dependencies in `Cargo.toml`

When writing a `[dependencies]` section in `Cargo.toml` the key you write for a
dependency typically matches up to the name of the crate you import from in the
code. For some projects, though, you may wish to reference the crate with a
different name in the code regardless of how it's published on crates.io. For
example you may wish to:

* Avoid the need to `use foo as bar` in Rust source.
* Depend on multiple versions of a crate.
* Depend on crates with the same name from different registries.

To support this Cargo supports a `package` key in the `[dependencies]` section
of which package should be depended on:

```toml
[package]
name = "mypackage"
version = "0.0.1"

[dependencies]
foo = "0.1"
bar = { git = "https://github.com/example/project", package = "foo" }
baz = { version = "0.1", registry = "custom", package = "foo" }
```

In this example, three crates are now available in your Rust code:

```rust
extern crate foo; // crates.io
extern crate bar; // git repository
extern crate baz; // registry `custom`
```

All three of these crates have the package name of `foo` in their own
`Cargo.toml`, so we're explicitly using the `package` key to inform Cargo that
we want the `foo` package even though we're calling it something else locally.
The `package` key, if not specified, defaults to the name of the dependency
being requested.

Note that if you have an optional dependency like:

```toml
[dependencies]
foo = { version = "0.1", package = 'bar', optional = true }
```

you're depending on the crate `bar` from crates.io, but your crate has a `foo`
feature instead of a `bar` feature. That is, names of features take after the
name of the dependency, not the package name, when renamed.

Enabling transitive dependencies works similarly, for example we could add the
following to the above manifest:

```toml
[features]
log-debug = ['foo/log-debug'] # using 'bar/log-debug' would be an error!
```
55 changes: 0 additions & 55 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,61 +63,6 @@ publish = ["my-registry"]
```


### rename-dependency
* Original Issue: [#1311](https://github.com/rust-lang/cargo/issues/1311)
* PR: [#4953](https://github.com/rust-lang/cargo/pull/4953)
* Tracking Issue: [#5653](https://github.com/rust-lang/cargo/issues/5653)

The rename-dependency feature allows you to import a dependency
with a different name from the source. This can be useful in a few scenarios:

* Depending on crates with the same name from different registries.
* Depending on multiple versions of a crate.
* Avoid needing `extern crate foo as bar` in Rust source.

Just include the `package` key to specify the actual name of the dependency.
You must include `cargo-features` at the top of your `Cargo.toml`.

```toml
cargo-features = ["rename-dependency"]

[package]
name = "mypackage"
version = "0.0.1"

[dependencies]
foo = "0.1"
bar = { version = "0.1", registry = "custom", package = "foo" }
baz = { git = "https://github.com/example/project", package = "foo" }
```

In this example, three crates are now available in your Rust code:

```rust
extern crate foo; // crates.io
extern crate bar; // registry `custom`
extern crate baz; // git repository
```

Note that if you have an optional dependency like:

```toml
[dependencies]
foo = { version = "0.1", package = 'bar', optional = true }
```

you're depending on the crate `bar` from crates.io, but your crate has a `foo`
feature instead of a `bar` feature. That is, names of features take after the
name of the dependency, not the package name, when renamed.

Enabling transitive dependencies works similarly, for example we could add the
following to the above manifest:

```toml
[features]
log-debug = ['foo/log-debug'] # using 'bar/log-debug' would be an error!
```

### publish-lockfile
* Original Issue: [#2263](https://github.com/rust-lang/cargo/issues/2263)
* PR: [#5093](https://github.com/rust-lang/cargo/pull/5093)
Expand Down
100 changes: 6 additions & 94 deletions tests/testsuite/rename_deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,6 @@ use support::paths;
use support::registry::Package;
use support::{basic_manifest, project};

#[test]
fn gated() {
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = { package = "foo", version = "0.1" }
"#,
).file("src/lib.rs", "")
.build();

p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
error: failed to parse manifest at `[..]`
Caused by:
feature `rename-dependency` is required
consider adding `cargo-features = [\"rename-dependency\"]` to the manifest
",
).run();

let p = project()
.at("bar")
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = { version = "0.1", package = "baz" }
"#,
).file("src/lib.rs", "")
.build();

p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
error: failed to parse manifest at `[..]`
Caused by:
feature `rename-dependency` is required
consider adding `cargo-features = [\"rename-dependency\"]` to the manifest
",
).run();
}

#[test]
fn rename_dependency() {
Package::new("bar", "0.1.0").publish();
Expand All @@ -74,8 +12,6 @@ fn rename_dependency() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[project]
name = "foo"
version = "0.0.1"
Expand All @@ -88,7 +24,7 @@ fn rename_dependency() {
).file("src/lib.rs", "extern crate bar; extern crate baz;")
.build();

p.cargo("build").masquerade_as_nightly_cargo().run();
p.cargo("build").run();
}

#[test]
Expand All @@ -97,8 +33,6 @@ fn rename_with_different_names() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[project]
name = "foo"
version = "0.0.1"
Expand All @@ -122,7 +56,7 @@ fn rename_with_different_names() {
).file("bar/src/lib.rs", "")
.build();

p.cargo("build").masquerade_as_nightly_cargo().run();
p.cargo("build").run();
}

#[test]
Expand All @@ -148,8 +82,7 @@ fn lots_of_names() {
"Cargo.toml",
&format!(
r#"
cargo-features = ["alternative-registries", "rename-dependency"]
cargo-features = ["alternative-registries"]
[package]
name = "test"
version = "0.1.0"
Expand Down Expand Up @@ -196,8 +129,6 @@ fn rename_and_patch() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
Expand All @@ -216,7 +147,7 @@ fn rename_and_patch() {
.file("foo/src/lib.rs", "pub fn foo() {}")
.build();

p.cargo("build -v").masquerade_as_nightly_cargo().run();
p.cargo("build -v").run();
}

#[test]
Expand All @@ -227,8 +158,6 @@ fn rename_twice() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
Expand All @@ -243,7 +172,6 @@ fn rename_twice() {
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
Expand All @@ -264,8 +192,6 @@ fn rename_affects_fingerprint() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
Expand All @@ -277,13 +203,11 @@ fn rename_affects_fingerprint() {
).file("src/lib.rs", "extern crate foo;")
.build();

p.cargo("build -v").masquerade_as_nightly_cargo().run();
p.cargo("build -v").run();

p.change_file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
Expand All @@ -295,7 +219,6 @@ fn rename_affects_fingerprint() {
);

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101)
.run();
}
Expand All @@ -309,8 +232,6 @@ fn can_run_doc_tests() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[project]
name = "foo"
version = "0.0.1"
Expand All @@ -328,7 +249,6 @@ fn can_run_doc_tests() {
).build();

foo.cargo("test -v")
.masquerade_as_nightly_cargo()
.with_stderr_contains(
"\
[DOCTEST] foo
Expand Down Expand Up @@ -363,8 +283,6 @@ fn features_still_work() {
.file(
"a/Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "p1"
version = "0.1.0"
Expand All @@ -377,8 +295,6 @@ fn features_still_work() {
.file(
"b/Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "p2"
version = "0.1.0"
Expand All @@ -393,7 +309,7 @@ fn features_still_work() {
).file("b/src/lib.rs", "extern crate b;")
.build();

p.cargo("build -v").masquerade_as_nightly_cargo().run();
p.cargo("build -v").run();
}

#[test]
Expand All @@ -405,7 +321,6 @@ fn features_not_working() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "test"
version = "0.1.0"
Expand All @@ -422,7 +337,6 @@ fn features_not_working() {
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
Expand All @@ -440,7 +354,6 @@ fn rename_with_dash() {
.file(
"Cargo.toml",
r#"
cargo-features = ["rename-dependency"]
[package]
name = "qwerty"
version = "0.1.0"
Expand All @@ -455,6 +368,5 @@ fn rename_with_dash() {
.build();

p.cargo("build")
.masquerade_as_nightly_cargo()
.run();
}

0 comments on commit 5d6504d

Please sign in to comment.