| //! Tests for `[patch]` table source replacement. |
| |
| use cargo_test_support::git; |
| use cargo_test_support::paths; |
| use cargo_test_support::registry::{self, Package}; |
| use cargo_test_support::{basic_manifest, project}; |
| use std::fs; |
| |
| #[cargo_test] |
| fn replace() { |
| Package::new("bar", "0.1.0").publish(); |
| Package::new("baz", "0.1.0") |
| .file( |
| "src/lib.rs", |
| "extern crate bar; pub fn baz() { bar::bar(); }", |
| ) |
| .dep("bar", "0.1.0") |
| .publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| baz = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file( |
| "src/lib.rs", |
| " |
| extern crate bar; |
| extern crate baz; |
| pub fn bar() { |
| bar::bar(); |
| baz::baz(); |
| } |
| ", |
| ) |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", "pub fn bar() {}") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] baz v0.1.0 ([..]) |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] baz v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn from_config() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file( |
| ".cargo/config.toml", |
| r#" |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn from_config_relative() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file( |
| "../.cargo/config.toml", |
| r#" |
| [patch.crates-io] |
| bar = { path = 'foo/bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn from_config_precedence() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'no-such-path' } |
| "#, |
| ) |
| .file( |
| ".cargo/config.toml", |
| r#" |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn nonexistent() { |
| Package::new("baz", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file( |
| "src/lib.rs", |
| "extern crate bar; pub fn foo() { bar::bar(); }", |
| ) |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", "pub fn bar() {}") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn patch_git() { |
| let bar = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = {{ git = '{}' }} |
| |
| [patch.'{0}'] |
| bar = {{ path = "bar" }} |
| "#, |
| bar.url() |
| ), |
| ) |
| .file( |
| "src/lib.rs", |
| "extern crate bar; pub fn foo() { bar::bar(); }", |
| ) |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", "pub fn bar() {}") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] git repository `file://[..]` |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn patch_to_git() { |
| 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(); |
| |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = {{ git = '{}' }} |
| "#, |
| bar.url() |
| ), |
| ) |
| .file( |
| "src/lib.rs", |
| "extern crate bar; pub fn foo() { bar::bar(); }", |
| ) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] git repository `file://[..]` |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.0 (file://[..]) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn unused() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) |
| .file("bar/src/lib.rs", "not rust code") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // unused patch should be in the lock file |
| let lock = p.read_lockfile(); |
| let toml: toml::Table = toml::from_str(&lock).unwrap(); |
| assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1); |
| assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar")); |
| assert_eq!( |
| toml["patch"]["unused"][0]["version"].as_str(), |
| Some("0.2.0") |
| ); |
| } |
| |
| #[cargo_test] |
| fn unused_with_mismatch_source_being_patched() { |
| registry::alt_init(); |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.alternative] |
| bar = { path = "bar" } |
| |
| [patch.crates-io] |
| bar = { path = "baz" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) |
| .file("bar/src/lib.rs", "not rust code") |
| .file("baz/Cargo.toml", &basic_manifest("bar", "0.3.0")) |
| .file("baz/src/lib.rs", "not rust code") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. |
| Perhaps you misspelled the source URL being patched. |
| Possible URLs for `[patch.<URL>]`: |
| crates-io |
| [WARNING] Patch `bar v0.3.0 ([CWD]/baz)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn prefer_patch_version() { |
| Package::new("bar", "0.1.2").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // there should be no patch.unused in the toml file |
| let lock = p.read_lockfile(); |
| let toml: toml::Table = toml::from_str(&lock).unwrap(); |
| assert!(toml.get("patch").is_none()); |
| } |
| |
| #[cargo_test] |
| fn unused_from_config() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file( |
| ".cargo/config.toml", |
| r#" |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) |
| .file("bar/src/lib.rs", "not rust code") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // unused patch should be in the lock file |
| let lock = p.read_lockfile(); |
| let toml: toml::Table = toml::from_str(&lock).unwrap(); |
| assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1); |
| assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar")); |
| assert_eq!( |
| toml["patch"]["unused"][0]["version"].as_str(), |
| Some("0.2.0") |
| ); |
| } |
| |
| #[cargo_test] |
| fn unused_git() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let foo = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("bar", "0.2.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = {{ git = '{}' }} |
| "#, |
| foo.url() |
| ), |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] git repository `file://[..]` |
| [UPDATING] `dummy-registry` index |
| [WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn add_patch() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn add_patch_from_config() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| p.change_file( |
| ".cargo/config.toml", |
| r#" |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn add_ignored_patch() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 [..] |
| [CHECKING] bar v0.1.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph. |
| Check that [..] |
| with the [..] |
| what is [..] |
| version. [..] |
| [FINISHED] [..]", |
| ) |
| .run(); |
| |
| p.cargo("update").run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [CHECKING] bar v0.1.1 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn add_patch_with_features() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar', features = ["some_feature"] } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] patch for `bar` uses the features mechanism. \ |
| default-features and features will not take effect because the patch dependency does not support this mechanism |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] patch for `bar` uses the features mechanism. \ |
| default-features and features will not take effect because the patch dependency does not support this mechanism |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn add_patch_with_setting_default_features() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar', default-features = false, features = ["none_default_feature"] } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] patch for `bar` uses the features mechanism. \ |
| default-features and features will not take effect because the patch dependency does not support this mechanism |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.0 ([CWD]/bar) |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [WARNING] patch for `bar` uses the features mechanism. \ |
| default-features and features will not take effect because the patch dependency does not support this mechanism |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn no_warn_ws_patch() { |
| Package::new("c", "0.1.0").publish(); |
| |
| // Don't issue an unused patch warning when the patch isn't used when |
| // partially building a workspace. |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [workspace] |
| members = ["a", "b", "c"] |
| |
| [patch.crates-io] |
| c = { path = "c" } |
| "#, |
| ) |
| .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) |
| .file("a/src/lib.rs", "") |
| .file( |
| "b/Cargo.toml", |
| r#" |
| [package] |
| name = "b" |
| version = "0.1.0" |
| [dependencies] |
| c = "0.1.0" |
| "#, |
| ) |
| .file("b/src/lib.rs", "") |
| .file("c/Cargo.toml", &basic_manifest("c", "0.1.0")) |
| .file("c/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -p a") |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| [CHECKING] a [..] |
| [FINISHED] [..]", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn new_minor() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 [..] |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn transitive_new_minor() { |
| Package::new("baz", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = { path = 'bar' } |
| |
| [patch.crates-io] |
| baz = { path = 'baz' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| authors = [] |
| |
| [dependencies] |
| baz = '0.1.0' |
| "#, |
| ) |
| .file("bar/src/lib.rs", r#""#) |
| .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.1")) |
| .file("baz/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] baz v0.1.1 [..] |
| [CHECKING] bar v0.1.0 [..] |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn new_major() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.2.0" |
| |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.2.0 [..] |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| |
| Package::new("bar", "0.2.0").publish(); |
| p.cargo("update").run(); |
| p.cargo("check") |
| .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") |
| .run(); |
| |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.2.0" |
| "#, |
| ); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.2.0 [..] |
| [CHECKING] bar v0.2.0 |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn transitive_new_major() { |
| Package::new("baz", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = { path = 'bar' } |
| |
| [patch.crates-io] |
| baz = { path = 'baz' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| authors = [] |
| |
| [dependencies] |
| baz = '0.2.0' |
| "#, |
| ) |
| .file("bar/src/lib.rs", r#""#) |
| .file("baz/Cargo.toml", &basic_manifest("baz", "0.2.0")) |
| .file("baz/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] baz v0.2.0 [..] |
| [CHECKING] bar v0.1.0 [..] |
| [CHECKING] foo v0.0.1 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn shared_by_transitive() { |
| Package::new("baz", "0.1.1").publish(); |
| |
| let baz = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("baz", "0.1.2")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = " 0.1.0" |
| |
| [dependencies] |
| bar = {{ path = "bar" }} |
| baz = "0.1" |
| |
| [patch.crates-io] |
| baz = {{ git = "{}", version = "0.1" }} |
| "#, |
| baz.url(), |
| ), |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| |
| [dependencies] |
| baz = "0.1.1" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] git repository `file://[..]` |
| [UPDATING] `dummy-registry` index |
| [CHECKING] baz v0.1.2 [..] |
| [CHECKING] bar v0.1.0 [..] |
| [CHECKING] foo v0.1.0 ([CWD]) |
| [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn remove_patch() { |
| Package::new("foo", "0.1.0").publish(); |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| foo = { path = 'foo' } |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0")) |
| .file("foo/src/lib.rs", r#""#) |
| .build(); |
| |
| // Generate a lock file where `foo` is unused |
| p.cargo("check").run(); |
| let lock_file1 = p.read_lockfile(); |
| |
| // Remove `foo` and generate a new lock file form the old one |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = { path = 'bar' } |
| "#, |
| ); |
| p.cargo("check").run(); |
| let lock_file2 = p.read_lockfile(); |
| |
| // Remove the lock file and build from scratch |
| fs::remove_file(p.root().join("Cargo.lock")).unwrap(); |
| p.cargo("check").run(); |
| let lock_file3 = p.read_lockfile(); |
| |
| assert!(lock_file1.contains("foo")); |
| assert_eq!(lock_file2, lock_file3); |
| assert_ne!(lock_file1, lock_file2); |
| } |
| |
| #[cargo_test] |
| fn non_crates_io() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [patch.some-other-source] |
| bar = { path = 'bar' } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| error: failed to parse manifest at `[..]` |
| |
| Caused by: |
| [patch] entry `some-other-source` should be a URL or registry name |
| |
| Caused by: |
| invalid url `some-other-source`: relative URL without a base |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn replace_with_crates_io() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| authors = [] |
| |
| [patch.crates-io] |
| bar = "0.1" |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| error: failed to resolve patches for `[..]` |
| |
| Caused by: |
| patch for `bar` in `[..]` points to the same source, but patches must point \ |
| to different sources |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn patch_in_virtual() { |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [workspace] |
| members = ["foo"] |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", r#""#) |
| .file( |
| "foo/Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| "#, |
| ) |
| .file("foo/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check").run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn patch_depends_on_another_patch() { |
| Package::new("bar", "0.1.0") |
| .file("src/lib.rs", "broken code") |
| .publish(); |
| |
| Package::new("baz", "0.1.0") |
| .dep("bar", "0.1") |
| .file("src/lib.rs", "broken code") |
| .publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| authors = [] |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| baz = "0.1" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| baz = { path = "baz" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", r#""#) |
| .file( |
| "baz/Cargo.toml", |
| r#" |
| [package] |
| name = "baz" |
| version = "0.1.1" |
| authors = [] |
| |
| [dependencies] |
| bar = "0.1" |
| "#, |
| ) |
| .file("baz/src/lib.rs", r#""#) |
| .build(); |
| |
| p.cargo("check").run(); |
| |
| // Nothing should be rebuilt, no registry should be updated. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn replace_prerelease() { |
| Package::new("baz", "1.1.0-pre.1").publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [workspace] |
| members = ["bar"] |
| |
| [patch.crates-io] |
| baz = { path = "./baz" } |
| "#, |
| ) |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.5.0" |
| authors = [] |
| |
| [dependencies] |
| baz = "1.1.0-pre.1" |
| "#, |
| ) |
| .file( |
| "bar/src/main.rs", |
| "extern crate baz; fn main() { baz::baz() }", |
| ) |
| .file( |
| "baz/Cargo.toml", |
| r#" |
| [package] |
| name = "baz" |
| version = "1.1.0-pre.1" |
| authors = [] |
| [workspace] |
| "#, |
| ) |
| .file("baz/src/lib.rs", "pub fn baz() {}") |
| .build(); |
| |
| p.cargo("check").run(); |
| } |
| |
| #[cargo_test] |
| fn patch_older() { |
| Package::new("baz", "1.0.2").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = { path = 'bar' } |
| baz = "=1.0.1" |
| |
| [patch.crates-io] |
| baz = { path = "./baz" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.5.0" |
| authors = [] |
| |
| [dependencies] |
| baz = "1.0.0" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "") |
| .file( |
| "baz/Cargo.toml", |
| r#" |
| [package] |
| name = "baz" |
| version = "1.0.1" |
| authors = [] |
| "#, |
| ) |
| .file("baz/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| [CHECKING] baz v1.0.1 [..] |
| [CHECKING] bar v0.5.0 [..] |
| [CHECKING] foo v0.1.0 [..] |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn cycle() { |
| Package::new("a", "1.0.0").publish(); |
| Package::new("b", "1.0.0").publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [workspace] |
| members = ["a", "b"] |
| |
| [patch.crates-io] |
| a = {path="a"} |
| b = {path="b"} |
| "#, |
| ) |
| .file( |
| "a/Cargo.toml", |
| r#" |
| [package] |
| name = "a" |
| version = "1.0.0" |
| |
| [dependencies] |
| b = "1.0" |
| "#, |
| ) |
| .file("a/src/lib.rs", "") |
| .file( |
| "b/Cargo.toml", |
| r#" |
| [package] |
| name = "b" |
| version = "1.0.0" |
| |
| [dependencies] |
| a = "1.0" |
| "#, |
| ) |
| .file("b/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| [ERROR] cyclic package dependency: [..] |
| package `[..]` |
| ... which satisfies dependency `[..]` of package `[..]` |
| ... which satisfies dependency `[..]` of package `[..]` |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn multipatch() { |
| Package::new("a", "1.0.0").publish(); |
| Package::new("a", "2.0.0").publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| |
| [dependencies] |
| a1 = { version = "1", package = "a" } |
| a2 = { version = "2", package = "a" } |
| |
| [patch.crates-io] |
| b1 = { path = "a1", package = "a" } |
| b2 = { path = "a2", package = "a" } |
| "#, |
| ) |
| .file("src/lib.rs", "pub fn foo() { a1::f1(); a2::f2(); }") |
| .file( |
| "a1/Cargo.toml", |
| r#" |
| [package] |
| name = "a" |
| version = "1.0.0" |
| "#, |
| ) |
| .file("a1/src/lib.rs", "pub fn f1() {}") |
| .file( |
| "a2/Cargo.toml", |
| r#" |
| [package] |
| name = "a" |
| version = "2.0.0" |
| "#, |
| ) |
| .file("a2/src/lib.rs", "pub fn f2() {}") |
| .build(); |
| |
| p.cargo("check").run(); |
| } |
| |
| #[cargo_test] |
| fn patch_same_version() { |
| let bar = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| cargo_test_support::registry::init(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| [dependencies] |
| bar = "0.1" |
| [patch.crates-io] |
| bar = {{ path = "bar" }} |
| bar2 = {{ git = '{}', package = 'bar' }} |
| "#, |
| bar.url(), |
| ), |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| error: cannot have two `[patch]` entries which both resolve to `bar v0.1.0` |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn two_semver_compatible() { |
| let bar = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| cargo_test_support::registry::init(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| [dependencies] |
| bar = "0.1" |
| [patch.crates-io] |
| bar = {{ path = "bar" }} |
| bar2 = {{ git = '{}', package = 'bar' }} |
| "#, |
| bar.url(), |
| ), |
| ) |
| .file("src/lib.rs", "pub fn foo() { bar::foo() }") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.2" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "pub fn foo() {}") |
| .build(); |
| |
| // assert the build succeeds and doesn't panic anywhere, and then afterwards |
| // assert that the build succeeds again without updating anything or |
| // building anything else. |
| p.cargo("check").run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| warning: Patch `bar v0.1.1 [..]` was not used in the crate graph. |
| Perhaps you misspelled the source URL being patched. |
| Possible URLs for `[patch.<URL>]`: |
| [CWD]/bar |
| [FINISHED] [..]", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn multipatch_select_big() { |
| let bar = git::repo(&paths::root().join("override")) |
| .file("Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| cargo_test_support::registry::init(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| [dependencies] |
| bar = "*" |
| [patch.crates-io] |
| bar = {{ path = "bar" }} |
| bar2 = {{ git = '{}', package = 'bar' }} |
| "#, |
| bar.url(), |
| ), |
| ) |
| .file("src/lib.rs", "pub fn foo() { bar::foo() }") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.2.0" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "pub fn foo() {}") |
| .build(); |
| |
| // assert the build succeeds, which is only possible if 0.2.0 is selected |
| // since 0.1.0 is missing the function we need. Afterwards assert that the |
| // build succeeds again without updating anything or building anything else. |
| p.cargo("check").run(); |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| warning: Patch `bar v0.1.0 [..]` was not used in the crate graph. |
| Perhaps you misspelled the source URL being patched. |
| Possible URLs for `[patch.<URL>]`: |
| [CWD]/bar |
| [FINISHED] [..]", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn canonicalize_a_bunch() { |
| let base = git::repo(&paths::root().join("base")) |
| .file("Cargo.toml", &basic_manifest("base", "0.1.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| let intermediate = git::repo(&paths::root().join("intermediate")) |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "intermediate" |
| version = "0.1.0" |
| |
| [dependencies] |
| # Note the lack of trailing slash |
| base = {{ git = '{}' }} |
| "#, |
| base.url(), |
| ), |
| ) |
| .file("src/lib.rs", "pub fn f() { base::f() }") |
| .build(); |
| |
| let newbase = git::repo(&paths::root().join("newbase")) |
| .file("Cargo.toml", &basic_manifest("base", "0.1.0")) |
| .file("src/lib.rs", "pub fn f() {}") |
| .build(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| |
| [dependencies] |
| # Note the trailing slashes |
| base = {{ git = '{base}/' }} |
| intermediate = {{ git = '{intermediate}/' }} |
| |
| [patch.'{base}'] # Note the lack of trailing slash |
| base = {{ git = '{newbase}' }} |
| "#, |
| base = base.url(), |
| intermediate = intermediate.url(), |
| newbase = newbase.url(), |
| ), |
| ) |
| .file("src/lib.rs", "pub fn a() { base::f(); intermediate::f() }") |
| .build(); |
| |
| // Once to make sure it actually works |
| p.cargo("check").run(); |
| |
| // Then a few more times for good measure to ensure no weird warnings about |
| // `[patch]` are printed. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| } |
| |
| #[cargo_test] |
| fn update_unused_new_version() { |
| // If there is an unused patch entry, and then you update the patch, |
| // make sure `cargo update` will be able to fix the lock file. |
| Package::new("bar", "0.1.5").publish(); |
| |
| // Start with a lock file to 0.1.5, and an "unused" patch because the |
| // version is too old. |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.1" |
| |
| [dependencies] |
| bar = "0.1.5" |
| |
| [patch.crates-io] |
| bar = { path = "../bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| // Patch is too old. |
| let bar = project() |
| .at("bar") |
| .file("Cargo.toml", &basic_manifest("bar", "0.1.4")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr_contains("[WARNING] Patch `bar v0.1.4 [..] was not used in the crate graph.") |
| .run(); |
| // unused patch should be in the lock file |
| let lock = p.read_lockfile(); |
| let toml: toml::Table = toml::from_str(&lock).unwrap(); |
| assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1); |
| assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar")); |
| assert_eq!( |
| toml["patch"]["unused"][0]["version"].as_str(), |
| Some("0.1.4") |
| ); |
| |
| // Oh, OK, let's update to the latest version. |
| bar.change_file("Cargo.toml", &basic_manifest("bar", "0.1.6")); |
| |
| // Create a backup so we can test it with different options. |
| fs::copy(p.root().join("Cargo.lock"), p.root().join("Cargo.lock.bak")).unwrap(); |
| |
| // Try to build again, this should automatically update Cargo.lock. |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.6 ([..]/bar) |
| [CHECKING] foo v0.0.1 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| // This should not update any registry. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| assert!(!p.read_lockfile().contains("unused")); |
| |
| // Restore the lock file, and see if `update` will work, too. |
| fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap(); |
| |
| // Try `update <pkg>`. |
| p.cargo("update bar") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [ADDING] bar v0.1.6 ([..]/bar) |
| [REMOVING] bar v0.1.5 |
| ", |
| ) |
| .run(); |
| |
| // Try with bare `cargo update`. |
| fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap(); |
| p.cargo("update") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [ADDING] bar v0.1.6 ([..]/bar) |
| [REMOVING] bar v0.1.5 |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn too_many_matches() { |
| // The patch locations has multiple versions that match. |
| registry::alt_init(); |
| Package::new("bar", "0.1.0").publish(); |
| Package::new("bar", "0.1.0").alternative(true).publish(); |
| Package::new("bar", "0.1.1").alternative(true).publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = { version = "0.1", registry = "alternative" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| // Picks 0.1.1, the most recent version. |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| [UPDATING] `alternative` index |
| [ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index` |
| |
| Caused by: |
| patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve |
| |
| Caused by: |
| patch for `bar` in `registry `alternative`` resolved to more than one candidate |
| Found versions: 0.1.0, 0.1.1 |
| Update the patch definition to select only one package. |
| For example, add an `=` version requirement to the patch definition, such as `version = \"=0.1.1\"`. |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn no_matches() { |
| // A patch to a location that does not contain the named package. |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("abc", "0.1.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index` |
| |
| Caused by: |
| patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve |
| |
| Caused by: |
| The patch location `[..]/foo/bar` does not appear to contain any packages matching the name `bar`. |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn mismatched_version() { |
| // A patch to a location that has an old version. |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1.1" |
| |
| [patch.crates-io] |
| bar = { path = "bar", version = "0.1.1" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| [ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index` |
| |
| Caused by: |
| patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve |
| |
| Caused by: |
| The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, \ |
| but the patch definition requires `^0.1.1`. |
| Check that the version in the patch location is what you expect, \ |
| and update the patch definition to match. |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn patch_walks_backwards() { |
| // Starting with a locked patch, change the patch so it points to an older version. |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = {path="bar"} |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // Somehow the user changes the version backwards. |
| p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.0 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn patch_walks_backwards_restricted() { |
| // This is the same as `patch_walks_backwards`, but the patch contains a |
| // `version` qualifier. This is unusual, just checking a strange edge case. |
| Package::new("bar", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = {path="bar", version="0.1.1"} |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // Somehow the user changes the version backwards. |
| p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")); |
| |
| p.cargo("check") |
| .with_status(101) |
| .with_stderr( |
| "\ |
| error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index` |
| |
| Caused by: |
| patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve |
| |
| Caused by: |
| The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, but the patch definition requires `^0.1.1`. |
| Check that the version in the patch location is what you expect, and update the patch definition to match. |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn patched_dep_new_version() { |
| // What happens when a patch is locked, and then one of the patched |
| // dependencies needs to be updated. In this case, the baz requirement |
| // gets updated from 0.1.0 to 0.1.1. |
| Package::new("bar", "0.1.0").dep("baz", "0.1.0").publish(); |
| Package::new("baz", "0.1.0").publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = {path="bar"} |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| |
| [dependencies] |
| baz = "0.1" |
| "#, |
| ) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| // Lock everything. |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] baz v0.1.0 [..] |
| [CHECKING] baz v0.1.0 |
| [CHECKING] bar v0.1.0 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| Package::new("baz", "0.1.1").publish(); |
| |
| // Just the presence of the new version should not have changed anything. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| // Modify the patch so it requires the new version. |
| p.change_file( |
| "bar/Cargo.toml", |
| r#" |
| [package] |
| name = "bar" |
| version = "0.1.0" |
| |
| [dependencies] |
| baz = "0.1.1" |
| "#, |
| ); |
| |
| // Should unlock and update cleanly. |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] baz v0.1.1 (registry `dummy-registry`) |
| [CHECKING] baz v0.1.1 |
| [CHECKING] bar v0.1.0 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn patch_update_doesnt_update_other_sources() { |
| // Very extreme edge case, make sure a patch update doesn't update other |
| // sources. |
| registry::alt_init(); |
| Package::new("bar", "0.1.0").publish(); |
| Package::new("bar", "0.1.0").alternative(true).publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| bar_alt = { version = "0.1", registry = "alternative", package = "bar" } |
| |
| [patch.crates-io] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr_unordered( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [UPDATING] `alternative` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.0 (registry `alternative`) |
| [CHECKING] bar v0.1.0 (registry `alternative`) |
| [CHECKING] bar v0.1.0 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| // Publish new versions in both sources. |
| Package::new("bar", "0.1.1").publish(); |
| Package::new("bar", "0.1.1").alternative(true).publish(); |
| |
| // Since it is locked, nothing should change. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| // Require new version on crates.io. |
| p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")); |
| |
| // This should not update bar_alt. |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `dummy-registry` index |
| [CHECKING] bar v0.1.1 ([..]/foo/bar) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn can_update_with_alt_reg() { |
| // A patch to an alt reg can update. |
| registry::alt_init(); |
| Package::new("bar", "0.1.0").publish(); |
| Package::new("bar", "0.1.0").alternative(true).publish(); |
| Package::new("bar", "0.1.1").alternative(true).publish(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = { version = "=0.1.1", registry = "alternative" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `alternative` index |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.1 (registry `alternative`) |
| [CHECKING] bar v0.1.1 (registry `alternative`) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| |
| Package::new("bar", "0.1.2").alternative(true).publish(); |
| |
| // Should remain locked. |
| p.cargo("check").with_stderr("[FINISHED] [..]").run(); |
| |
| // This does nothing, due to `=` requirement. |
| p.cargo("update bar") |
| .with_stderr( |
| "\ |
| [UPDATING] `alternative` index |
| [UPDATING] `dummy-registry` index |
| ", |
| ) |
| .run(); |
| |
| // Bump to 0.1.2. |
| p.change_file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1" |
| |
| [patch.crates-io] |
| bar = { version = "=0.1.2", registry = "alternative" } |
| "#, |
| ); |
| |
| p.cargo("check") |
| .with_stderr( |
| "\ |
| [UPDATING] `alternative` index |
| [UPDATING] `dummy-registry` index |
| [DOWNLOADING] crates ... |
| [DOWNLOADED] bar v0.1.2 (registry `alternative`) |
| [CHECKING] bar v0.1.2 (registry `alternative`) |
| [CHECKING] foo v0.1.0 ([..]/foo) |
| [FINISHED] [..] |
| ", |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn gitoxide_clones_shallow_old_git_patch() { |
| perform_old_git_patch(true) |
| } |
| |
| fn perform_old_git_patch(shallow: bool) { |
| // Example where an old lockfile with an explicit branch="master" in Cargo.toml. |
| Package::new("bar", "1.0.0").publish(); |
| let (bar, bar_repo) = git::new_repo("bar", |p| { |
| p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) |
| .file("src/lib.rs", "") |
| }); |
| |
| let bar_oid = bar_repo.head().unwrap().target().unwrap(); |
| |
| let p = project() |
| .file( |
| "Cargo.toml", |
| &format!( |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "1.0" |
| |
| [patch.crates-io] |
| bar = {{ git = "{}", branch = "master" }} |
| "#, |
| bar.url() |
| ), |
| ) |
| .file( |
| "Cargo.lock", |
| &format!( |
| r#" |
| # This file is automatically @generated by Cargo. |
| # It is not intended for manual editing. |
| [[package]] |
| name = "bar" |
| version = "1.0.0" |
| source = "git+{}#{}" |
| |
| [[package]] |
| name = "foo" |
| version = "0.1.0" |
| dependencies = [ |
| "bar", |
| ] |
| "#, |
| bar.url(), |
| bar_oid |
| ), |
| ) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| bar.change_file("Cargo.toml", &basic_manifest("bar", "2.0.0")); |
| git::add(&bar_repo); |
| git::commit(&bar_repo); |
| |
| // This *should* keep the old lock. |
| let mut cargo = p.cargo("tree"); |
| if shallow { |
| cargo |
| .arg("-Zgitoxide=fetch,shallow-deps") |
| .masquerade_as_nightly_cargo(&["unstable features must be available for -Z gitoxide"]); |
| } |
| cargo |
| // .env("CARGO_LOG", "trace") |
| .with_stderr( |
| "\ |
| [UPDATING] [..] |
| ", |
| ) |
| // .with_status(1) |
| .with_stdout(format!( |
| "\ |
| foo v0.1.0 [..] |
| └── bar v1.0.0 (file:///[..]branch=master#{}) |
| ", |
| &bar_oid.to_string()[..8] |
| )) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn old_git_patch() { |
| perform_old_git_patch(false) |
| } |
| |
| // From https://github.com/rust-lang/cargo/issues/7463 |
| #[cargo_test] |
| fn patch_eq_conflict_panic() { |
| Package::new("bar", "0.1.0").publish(); |
| Package::new("bar", "0.1.1").publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "=0.1.0" |
| |
| [dev-dependencies] |
| bar = "=0.1.1" |
| |
| [patch.crates-io] |
| bar = {path="bar"} |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("generate-lockfile") |
| .with_status(101) |
| .with_stderr( |
| r#"[UPDATING] `dummy-registry` index |
| [ERROR] failed to select a version for `bar`. |
| ... required by package `foo v0.1.0 ([..])` |
| versions that meet the requirements `=0.1.1` are: 0.1.1 |
| |
| all possible versions conflict with previously selected packages. |
| |
| previously selected package `bar v0.1.0` |
| ... which satisfies dependency `bar = "=0.1.0"` of package `foo v0.1.0 ([..])` |
| |
| failed to select a version for `bar` which could resolve this conflict |
| "#, |
| ) |
| .run(); |
| } |
| |
| // From https://github.com/rust-lang/cargo/issues/11336 |
| #[cargo_test] |
| fn mismatched_version2() { |
| Package::new("qux", "0.1.0-beta.1").publish(); |
| Package::new("qux", "0.1.0-beta.2").publish(); |
| Package::new("bar", "0.1.0") |
| .dep("qux", "=0.1.0-beta.1") |
| .publish(); |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| bar = "0.1.0" |
| qux = "0.1.0-beta.2" |
| |
| [patch.crates-io] |
| qux = { path = "qux" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "qux/Cargo.toml", |
| r#" |
| [package] |
| name = "qux" |
| version = "0.1.0-beta.1" |
| "#, |
| ) |
| .file("qux/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("generate-lockfile") |
| .with_status(101) |
| .with_stderr( |
| r#"[UPDATING] `dummy-registry` index |
| [ERROR] failed to select a version for `qux`. |
| ... required by package `bar v0.1.0` |
| ... which satisfies dependency `bar = "^0.1.0"` of package `foo v0.1.0 ([..])` |
| versions that meet the requirements `=0.1.0-beta.1` are: 0.1.0-beta.1 |
| |
| all possible versions conflict with previously selected packages. |
| |
| previously selected package `qux v0.1.0-beta.2` |
| ... which satisfies dependency `qux = "^0.1.0-beta.2"` of package `foo v0.1.0 ([..])` |
| |
| failed to select a version for `qux` which could resolve this conflict"#, |
| ) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn mismatched_version_with_prerelease() { |
| Package::new("prerelease-deps", "0.0.1").publish(); |
| // A patch to a location that has an prerelease version |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.1.0" |
| |
| [dependencies] |
| prerelease-deps = "0.1.0" |
| |
| [patch.crates-io] |
| prerelease-deps = { path = "./prerelease-deps" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file( |
| "prerelease-deps/Cargo.toml", |
| &basic_manifest("prerelease-deps", "0.1.1-pre1"), |
| ) |
| .file("prerelease-deps/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("generate-lockfile") |
| .with_status(101) |
| .with_stderr( |
| r#"[UPDATING] `dummy-registry` index |
| [ERROR] failed to select a version for the requirement `prerelease-deps = "^0.1.0"` |
| candidate versions found which didn't match: 0.1.1-pre1, 0.0.1 |
| location searched: `dummy-registry` index (which is replacing registry `crates-io`) |
| required by package `foo v0.1.0 [..]` |
| if you are looking for the prerelease package it needs to be specified explicitly |
| prerelease-deps = { version = "0.1.1-pre1" } |
| perhaps a crate was updated and forgotten to be re-vendored?"#, |
| ) |
| .run(); |
| } |