cargo/tests/testsuite/replace.rs

1301 lines
31 KiB
Rust
Raw Normal View History

2019-11-25 02:42:45 +00:00
//! Tests for `[replace]` table source replacement.
use cargo_test_support::git;
use cargo_test_support::paths;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, project};
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_simple() {
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let bar = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
bar.url()
2018-03-14 15:17:44 +00:00
),
2018-12-08 11:19:47 +00:00
)
.file(
"src/lib.rs",
"extern crate bar; pub fn foo() { bar::bar(); }",
2018-12-08 11:19:47 +00:00
)
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
[UPDATING] git repository `[..]`
2018-09-09 23:59:48 +00:00
[COMPILING] bar v0.1.0 (file://[..])
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_with_features() {
Package::new("bar", "0.1.0").publish();
let bar = git::repo(&paths::root().join("override"))
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = "0.1.0"
[replace]
"bar:0.1.0" = {{ git = '{}', features = ["some_feature"] }}
"#,
bar.url()
),
)
.file(
"src/lib.rs",
"extern crate bar; pub fn foo() { bar::bar(); }",
)
.build();
p.cargo("build")
.with_stderr(
"\
[UPDATING] [..] index
[UPDATING] git repository `[..]`
[WARNING] replacement for `bar` uses the features mechanism. default-features and features \
will not take effect because the replacement dependency does not support this mechanism
[COMPILING] bar v0.1.0 (file://[..])
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn override_with_setting_default_features() {
Package::new("bar", "0.1.0").publish();
let bar = git::repo(&paths::root().join("override"))
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = "0.1.0"
[replace]
"bar:0.1.0" = {{ git = '{}', default-features = false, features = ["none_default_feature"] }}
"#,
bar.url()
),
)
.file(
"src/lib.rs",
"extern crate bar; pub fn foo() { bar::bar(); }",
)
.build();
p.cargo("build")
.with_stderr(
"\
[UPDATING] [..] index
[UPDATING] git repository `[..]`
[WARNING] replacement for `bar` uses the features mechanism. default-features and features \
will not take effect because the replacement dependency does not support this mechanism
[COMPILING] bar v0.1.0 (file://[..])
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn missing_version() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
bar = { git = 'https://example.com' }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
error: failed to parse manifest at `[..]`
Caused by:
replacements must specify a version to replace, but `[..]bar` does not
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn invalid_semver_version() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "*"
2020-09-27 00:59:58 +00:00
[replace]
"bar:*" = { git = 'https://example.com' }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
error: failed to parse manifest at `[..]`
Caused by:
replacements must specify a valid semver version to replace, but `bar:*` does not
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn different_version() {
Package::new("bar", "0.2.0").publish();
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = "0.2.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
error: failed to parse manifest at `[..]`
Caused by:
replacements cannot specify a version requirement, but found one for [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn transitive() {
Package::new("bar", "0.1.0").publish();
Package::new("baz", "0.2.0")
.dep("bar", "0.1.0")
.file("src/lib.rs", "extern crate bar; fn baz() { bar::bar(); }")
2018-03-14 15:17:44 +00:00
.publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let foo = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
baz = "0.2.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
[UPDATING] git repository `[..]`
2018-09-14 20:33:18 +00:00
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.2.0 (registry [..])
2018-09-09 23:59:48 +00:00
[COMPILING] bar v0.1.0 (file://[..])
[COMPILING] baz v0.2.0
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").with_stdout("").run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn persists_across_rebuilds() {
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let foo = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file(
"src/lib.rs",
"extern crate bar; pub fn foo() { bar::bar(); }",
2018-12-08 11:19:47 +00:00
)
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
2018-09-09 23:59:48 +00:00
[UPDATING] git repository `file://[..]`
[COMPILING] bar v0.1.0 (file://[..])
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").with_stdout("").run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn replace_registry_with_path() {
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let _ = project()
.at("bar")
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
.build();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = { path = "../bar" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"src/lib.rs",
"extern crate bar; pub fn foo() { bar::bar(); }",
2018-12-08 11:19:47 +00:00
)
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
[COMPILING] bar v0.1.0 ([ROOT][..]/bar)
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn use_a_spec_to_select() {
Package::new("baz", "0.1.1")
.file("src/lib.rs", "pub fn baz1() {}")
2018-03-14 15:17:44 +00:00
.publish();
Package::new("baz", "0.2.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
Package::new("bar", "0.1.1")
.dep("baz", "0.2")
.file(
"src/lib.rs",
"extern crate baz; pub fn bar() { baz::baz3(); }",
2018-12-08 11:19:47 +00:00
)
.publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let foo = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("baz", "0.2.0"))
.file("src/lib.rs", "pub fn baz3() {}")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = "0.1"
baz = "0.1"
[replace]
"baz:0.2.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/lib.rs",
"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
extern crate bar;
extern crate baz;
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2016-05-20 11:47:39 +00:00
pub fn local() {
baz::baz1();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
bar::bar();
}
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
[UPDATING] git repository `[..]`
2018-09-14 20:33:18 +00:00
[DOWNLOADING] crates ...
[DOWNLOADED] [..]
[DOWNLOADED] [..]
[COMPILING] [..]
[COMPILING] [..]
[COMPILING] [..]
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_adds_some_deps() {
Package::new("baz", "0.1.1").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
Package::new("bar", "0.1.0").publish();
let foo = git::repo(&paths::root().join("override"))
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
baz = "0.1"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
[UPDATING] git repository `[..]`
2018-09-14 20:33:18 +00:00
[DOWNLOADING] crates ...
[DOWNLOADED] baz v0.1.1 (registry [..])
[COMPILING] baz v0.1.1
[COMPILING] bar v0.1.0 ([..])
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").with_stdout("").run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
Package::new("baz", "0.1.2").publish();
p.cargo("update -p")
.arg(&format!("{}#bar", foo.url()))
.with_stderr(
"\
2018-09-09 23:59:48 +00:00
[UPDATING] git repository `file://[..]`
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
",
2018-12-08 11:19:47 +00:00
)
.run();
p.cargo("update -p https://github.com/rust-lang/crates.io-index#bar")
.with_stderr(
"\
2021-06-27 19:18:36 +00:00
[UPDATING] `dummy-registry` index
",
2018-12-08 11:19:47 +00:00
)
.run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").with_stdout("").run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn locked_means_locked_yes_no_seriously_i_mean_locked() {
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
// this in theory exercises #2041
Package::new("baz", "0.1.0").publish();
Package::new("baz", "0.2.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
Package::new("bar", "0.1.0").publish();
let foo = git::repo(&paths::root().join("override"))
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
baz = "*"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = "0.1"
baz = "0.1"
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").run();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build").with_stdout("").run();
p.cargo("build").with_stdout("").run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_wrong_name() {
Package::new("baz", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let foo = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
baz = "0.1"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"baz:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[UPDATING] [..] index
2016-05-20 11:47:39 +00:00
[UPDATING] git repository [..]
[ERROR] failed to get `baz` as a dependency of package `foo v0.0.1 ([..])`
Caused by:
no matching package for override `[..]baz@0.1.0` found
location searched: file://[..]
version required: =0.1.0
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_with_nothing() {
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let foo = git::repo(&paths::root().join("override"))
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{}' }}
"#,
2018-03-14 15:17:44 +00:00
foo.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[UPDATING] [..] index
2016-05-20 11:47:39 +00:00
[UPDATING] git repository [..]
[ERROR] failed to get `bar` as a dependency of package `foo v0.0.1 ([..])`
Caused by:
failed to load source for dependency `bar`
Add flags to assert lock/cache behavior to Cargo If a lock file is generated and some equivalent of `cargo fetch` is run then Cargo shouldn't ever touch the network or modify `Cargo.lock` until any `Cargo.toml` later changes, but this often wants to be asserted in some build environments where it's a programmer error if Cargo attempts to access the network. The `--locked` flag added here will assert that `Cargo.lock` does not need to change to proceed. That is, if `Cargo.lock` would be modified (as it automatically is by default) this is turned into a hard error instead. This `--frozen` will not only assert that `Cargo.lock` doesn't change (the same behavior as `--locked`), but it will also will manually prevent Cargo from touching the network by ensuring that all network requests return an error. These flags can be used in environments where it is *expected* that no network access happens (or no lockfile changes happen) because it has been pre-arranged for Cargo to not happen. Examples of this include: * CI for projects want to pass `--locked` to ensure that `Cargo.lock` is up to date before changes are checked in. * Environments with vendored dependencies want to pass `--frozen` as touching the network indicates a programmer error that something wasn't vendored correctly. A crucial property of these two flags is that **they do not change the behavior of Cargo**. They are simply assertions at a few locations in Cargo to ensure that actions expected to not happen indeed don't happen. Some documentation has also been added to this effect. Closes #2111
2016-06-28 17:39:46 +00:00
Caused by:
2018-09-09 23:59:48 +00:00
Unable to update file://[..]
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
Caused by:
Could not find Cargo.toml in `[..]`
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn override_wrong_version() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = { git = 'https://example.com', version = '0.2.0' }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
error: failed to parse manifest at `[..]`
Caused by:
replacements cannot specify a version requirement, but found one for `[..]bar@0.1.0`
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
#[cargo_test]
fn multiple_specs() {
Package::new("bar", "0.1.0").publish();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let bar = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{0}' }}
Implement source redirection This commit implements a scheme for .cargo/config files where sources can be redirected to other sources. The purpose of this will be to override crates.io for a few use cases: * Replace it with a mirror site that is sync'd to crates.io * Replace it with a "directory source" or some other local source This major feature of this redirection, however, is that none of it is encoded into the lock file. If one source is redirected to another then it is assumed that packages from both are exactly the same (e.g. `foo v0.0.1` is the same in both location). The lock file simply encodes the canonical soure (e.g. crates.io) rather than the replacement source. In the end this means that Cargo.lock files can be generated from any replacement source and shipped to other locations without the lockfile oscillating about where packages came from. Eventually this support will be extended to `Cargo.toml` itself (which will be encoded into the lock file), but that support is not implemented today. The syntax for what was implemented today looks like: # .cargo/config [source.my-awesome-registry] registry = 'https://example.com/path/to/index' [source.crates-io] replace-with = 'my-awesome-registry' Each source will have a canonical name and will be configured with the various keys underneath it (today just 'registry' and 'directory' will be accepted). The global `crates-io` source represents crates from the standard registry, and this can be replaced with other mirror sources. All tests have been modified to use this new infrastructure instead of the old `registry.index` configuration. This configuration is now also deprecated and will emit an unconditional warning about how it will no longer be used in the future. Finally, all subcommands now use this "source map" except for `cargo publish`, which will always publish to the default registry (in this case crates.io).
2016-02-03 18:54:07 +00:00
2020-09-27 00:59:58 +00:00
[replace."https://github.com/rust-lang/crates.io-index#bar:0.1.0"]
git = '{0}'
"#,
bar.url()
2018-03-14 15:17:44 +00:00
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[UPDATING] [..] index
2016-05-20 11:47:39 +00:00
[UPDATING] git repository [..]
[ERROR] failed to get `bar` as a dependency of package `foo v0.0.1 ([..])`
Caused by:
overlapping replacement specifications found:
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
* [..]
* [..]
Implement top-level overrides This commit is an implementation of top-level overrides to be encoded into the manifest itself directly. This style of override is distinct from the existing `paths` support in `.cargo/config` in two important ways: * Top level overrides are intended to be checked in and shared amongst all developers of a project. * Top level overrides are reflected in `Cargo.lock`. The second point is crucially important here as it will ensure that an override on one machine behaves the same as an override on another machine. This solves many long-standing problems with `paths`-based overrides which suffer from some level of nondeterminism as they're not encoded. From a syntactical point of view, an override looks like: ```toml [replace] "libc:0.2.0" = { git = 'https://github.com/my-username/libc', branch = '0.2-fork' } ``` This declaration indicates that whenever resolution would otherwise encounter the `libc` package version 0.2.0 from crates.io, it should instead replace it with the custom git dependency on a specific branch. The key "libc:0.2.0" here is actually a package id specification which will allow selecting various components of a graph. For example the same named package coming from two distinct locations can be selected against, as well as multiple versions of one crate in a dependency graph. The replacement dependency has the same syntax as the `[dependencies]` section of Cargo.toml. One of the major uses of this syntax will be, for example, using a temporary fork of a crate while the changes are pushed upstream to the original repo. This will avoid the need to change the intermediate projects immediately, and over time once fixes have landed upstream the `[replace]` section in a `Cargo.toml` can be removed. There are also two crucial restrictions on overrides. * A crate with the name `foo` can only get overridden with packages also of the name `foo`. * A crate can only get overridden with a crate of the exact same version. A consequence of these restrictions is that crates.io cannot be used to replace anything from crates.io. There's only one version of something on crates.io, so there's nothing else to replace it with (name/version are a unique key). Closes #942
2016-02-09 23:42:17 +00:00
both specifications match: bar v0.1.0
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn test_override_dep() {
Package::new("bar", "0.1.0").publish();
let bar = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{0}' }}
"#,
bar.url()
2018-03-14 15:17:44 +00:00
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("test -p bar")
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
error: There are multiple `bar` packages in your project, and the [..]
Please re-run this command with [..]
[..]#bar@0.1.0
[..]#bar@0.1.0
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn update() {
Package::new("bar", "0.1.0").publish();
let bar = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "pub fn bar() {}")
.build();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = {{ git = '{0}' }}
"#,
bar.url()
2018-03-14 15:17:44 +00:00
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("generate-lockfile").run();
p.cargo("update")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[UPDATING] `[..]` index
[UPDATING] git repository `[..]`
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
// foo -> near -> far
// near is overridden with itself
#[cargo_test]
fn no_override_self() {
let deps = git::repo(&paths::root().join("override"))
2018-07-24 22:35:01 +00:00
.file("far/Cargo.toml", &basic_manifest("far", "0.1.0"))
.file("far/src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"near/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "near"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
far = { path = "../far" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("near/src/lib.rs", "#![no_std] pub extern crate far;")
.build();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
near = {{ git = '{0}' }}
2020-09-27 00:59:58 +00:00
[replace]
"near:0.1.0" = {{ git = '{0}' }}
"#,
2018-03-14 15:17:44 +00:00
deps.url()
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "#![no_std] pub extern crate near;")
.build();
p.cargo("build --verbose").run();
}
#[cargo_test]
fn override_an_override() {
2018-03-14 15:17:44 +00:00
Package::new("chrono", "0.2.0")
.dep("serde", "< 0.9")
.publish();
Package::new("serde", "0.7.0")
.file("src/lib.rs", "pub fn serde07() {}")
.publish();
Package::new("serde", "0.8.0")
.file("src/lib.rs", "pub fn serde08() {}")
.publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
chrono = "0.2"
serde = "0.8"
2020-09-27 00:59:58 +00:00
[replace]
"chrono:0.2.0" = { path = "chrono" }
"serde:0.8.0" = { path = "serde" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"Cargo.lock",
r#"
2020-09-27 00:59:58 +00:00
[[package]]
name = "foo"
version = "0.0.1"
dependencies = [
"chrono 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "chrono"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
replace = "chrono 0.2.0"
[[package]]
name = "chrono"
version = "0.2.0"
dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
replace = "serde 0.8.0"
[[package]]
name = "serde"
version = "0.8.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/lib.rs",
"
extern crate chrono;
extern crate serde;
pub fn foo() {
chrono::chrono();
serde::serde08_override();
}
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"chrono/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "chrono"
version = "0.2.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
serde = "< 0.9"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"chrono/src/lib.rs",
"
extern crate serde;
pub fn chrono() {
serde::serde07();
}
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.file("serde/Cargo.toml", &basic_manifest("serde", "0.8.0"))
.file("serde/src/lib.rs", "pub fn serde08_override() {}")
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn overriding_nonexistent_no_spurious() {
Package::new("bar", "0.1.0").dep("baz", "0.1").publish();
Package::new("baz", "0.1.0").publish();
let bar = git::repo(&paths::root().join("override"))
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
baz = { path = "baz" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn bar() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() {}")
.build();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
bar = "0.1.0"
[replace]
"bar:0.1.0" = {{ git = '{url}' }}
"baz:0.1.0" = {{ git = '{url}' }}
"#,
url = bar.url()
2018-03-14 15:17:44 +00:00
),
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build").run();
p.cargo("build")
.with_stderr(
"\
[WARNING] package replacement is not used: [..]baz@0.1.0
[FINISHED] [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.with_stdout("")
.run();
}
#[cargo_test]
fn no_warnings_when_replace_is_used_in_another_workspace_member() {
Package::new("bar", "0.1.0").publish();
Package::new("baz", "0.1.0").publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[workspace]
members = [ "first_crate", "second_crate"]
[replace]
2020-09-27 00:59:58 +00:00
"bar:0.1.0" = { path = "local_bar" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"first_crate/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "first_crate"
version = "0.1.0"
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("first_crate/src/lib.rs", "")
.file(
"second_crate/Cargo.toml",
&basic_manifest("second_crate", "0.1.0"),
2018-12-08 11:19:47 +00:00
)
.file("second_crate/src/lib.rs", "")
2018-07-24 22:35:01 +00:00
.file("local_bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("local_bar/src/lib.rs", "")
.build();
p.cargo("build")
.cwd("first_crate")
.with_stdout("")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[UPDATING] `[..]` index
[COMPILING] bar v0.1.0 ([..])
[COMPILING] first_crate v0.1.0 ([..])
2018-03-14 15:17:44 +00:00
[FINISHED] [..]",
2018-12-08 11:19:47 +00:00
)
.run();
2018-03-14 15:17:44 +00:00
p.cargo("build")
.cwd("second_crate")
.with_stdout("")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] second_crate v0.1.0 ([..])
2018-03-14 15:17:44 +00:00
[FINISHED] [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn replace_to_path_dep() {
Package::new("bar", "0.1.0").dep("baz", "0.1").publish();
Package::new("baz", "0.1.0").publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
2020-09-27 00:59:58 +00:00
[replace]
"bar:0.1.0" = { path = "bar" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "extern crate bar;")
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
2018-03-14 15:17:44 +00:00
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
baz = { path = "baz" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"bar/src/lib.rs",
"extern crate baz; pub fn bar() { baz::baz(); }",
2018-12-08 11:19:47 +00:00
)
.file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("bar/baz/src/lib.rs", "pub fn baz() {}")
.build();
p.cargo("build").run();
}
#[cargo_test]
fn override_with_default_feature() {
Package::new("another", "0.1.0").publish();
2018-03-14 15:17:44 +00:00
Package::new("another", "0.1.1").dep("bar", "0.1").publish();
Package::new("bar", "0.1.0").publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = { path = "bar", default-features = false }
another = "0.1"
another2 = { path = "another2" }
2020-09-27 00:59:58 +00:00
[replace]
'bar:0.1.0' = { path = "bar" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }")
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[features]
default = []
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
#[cfg(feature = "default")]
pub fn bar() {}
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"another2/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "another2"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = { version = "0.1", default-features = false }
"#,
2018-12-08 11:19:47 +00:00
)
.file("another2/src/lib.rs", "")
.build();
p.cargo("run").run();
}
#[cargo_test]
fn override_plus_dep() {
Package::new("bar", "0.1.0").publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1"
2020-09-27 00:59:58 +00:00
[replace]
'bar:0.1.0' = { path = "bar" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
[dependencies]
foo = { path = ".." }
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/src/lib.rs", "")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains("error: cyclic package dependency: [..]")
.run();
}