mirror of
https://github.com/rust-lang/cargo
synced 2024-10-30 22:57:17 +00:00
1157 lines
26 KiB
Rust
1157 lines
26 KiB
Rust
//! Tests for supporting older versions of the Cargo.lock file format.
|
|
|
|
use cargo_test_support::compare::assert_match_exact;
|
|
use cargo_test_support::git;
|
|
use cargo_test_support::registry::Package;
|
|
use cargo_test_support::{basic_lib_manifest, basic_manifest, project};
|
|
|
|
#[cargo_test]
|
|
fn oldest_lockfile_still_works() {
|
|
let cargo_commands = vec!["build", "update"];
|
|
for cargo_command in cargo_commands {
|
|
oldest_lockfile_still_works_with_command(cargo_command);
|
|
}
|
|
}
|
|
|
|
fn oldest_lockfile_still_works_with_command(cargo_command: &str) {
|
|
Package::new("bar", "0.1.0").publish();
|
|
|
|
let expected_lockfile = r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "[..]"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar",
|
|
]
|
|
"#;
|
|
|
|
let old_lockfile = r#"
|
|
[root]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
"#;
|
|
|
|
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("Cargo.lock", old_lockfile)
|
|
.build();
|
|
|
|
p.cargo(cargo_command).run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(expected_lockfile, &lock);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn frozen_flag_preserves_old_lockfile() {
|
|
let cksum = Package::new("bar", "0.1.0").publish();
|
|
|
|
let old_lockfile = format!(
|
|
r#"[root]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[metadata]
|
|
"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "{}"
|
|
"#,
|
|
cksum,
|
|
);
|
|
|
|
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("Cargo.lock", &old_lockfile)
|
|
.build();
|
|
|
|
p.cargo("check --locked").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&old_lockfile, &lock);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn totally_wild_checksums_works() {
|
|
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(
|
|
"Cargo.lock",
|
|
r#"
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[metadata]
|
|
"checksum baz 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum"
|
|
"checksum bar 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum"
|
|
"#,
|
|
);
|
|
|
|
let p = p.build();
|
|
|
|
p.cargo("check").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "[..]"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar",
|
|
]
|
|
"#,
|
|
&lock,
|
|
);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn wrong_checksum_is_an_error() {
|
|
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(
|
|
"Cargo.lock",
|
|
r#"
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[metadata]
|
|
"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "checksum"
|
|
"#,
|
|
);
|
|
|
|
let p = p.build();
|
|
|
|
p.cargo("check")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[UPDATING] `[..]` index
|
|
error: checksum for `bar v0.1.0` changed between lock files
|
|
|
|
this could be indicative of a few possible errors:
|
|
|
|
* the lock file is corrupt
|
|
* a replacement source in use (e.g., a mirror) returned a different checksum
|
|
* the source itself may be corrupt in one way or another
|
|
|
|
unable to verify that `bar v0.1.0` is the same as when the lockfile was generated
|
|
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
// If the checksum is unlisted in the lock file (e.g., <none>) yet we can
|
|
// calculate it (e.g., it's a registry dep), then we should in theory just fill
|
|
// it in.
|
|
#[cargo_test]
|
|
fn unlisted_checksum_is_bad_if_we_calculate() {
|
|
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(
|
|
"Cargo.lock",
|
|
r#"
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[metadata]
|
|
"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "<none>"
|
|
"#,
|
|
);
|
|
let p = p.build();
|
|
|
|
p.cargo("fetch")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[UPDATING] `[..]` index
|
|
error: checksum for `bar v0.1.0` was not previously calculated, but a checksum \
|
|
could now be calculated
|
|
|
|
this could be indicative of a few possible situations:
|
|
|
|
* the source `[..]` did not previously support checksums,
|
|
but was replaced with one that does
|
|
* newer Cargo implementations know how to checksum this source, but this
|
|
older implementation does not
|
|
* the lock file is corrupt
|
|
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
// If the checksum is listed in the lock file yet we cannot calculate it (e.g.,
|
|
// Git dependencies as of today), then make sure we choke.
|
|
#[cargo_test]
|
|
fn listed_checksum_bad_if_we_cannot_compute() {
|
|
let git = git::new("bar", |p| {
|
|
p.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
|
|
.file("src/lib.rs", "")
|
|
});
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
bar = {{ git = '{}' }}
|
|
"#,
|
|
git.url()
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"Cargo.lock",
|
|
&format!(
|
|
r#"
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (git+{0})"
|
|
]
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "git+{0}"
|
|
|
|
[metadata]
|
|
"checksum bar 0.1.0 (git+{0})" = "checksum"
|
|
"#,
|
|
git.url()
|
|
),
|
|
);
|
|
|
|
let p = p.build();
|
|
|
|
p.cargo("fetch")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[UPDATING] git repository `[..]`
|
|
error: checksum for `bar v0.1.0 ([..])` could not be calculated, but a \
|
|
checksum is listed in the existing lock file[..]
|
|
|
|
this could be indicative of a few possible situations:
|
|
|
|
* the source `[..]` supports checksums,
|
|
but was replaced with one that doesn't
|
|
* the lock file is corrupt
|
|
|
|
unable to verify that `bar v0.1.0 ([..])` is the same as when the lockfile was generated
|
|
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn current_lockfile_format() {
|
|
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", "");
|
|
let p = p.build();
|
|
|
|
p.cargo("check").run();
|
|
|
|
let actual = p.read_lockfile();
|
|
|
|
let expected = "\
|
|
# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = \"bar\"
|
|
version = \"0.1.0\"
|
|
source = \"registry+https://github.com/rust-lang/crates.io-index\"
|
|
checksum = \"[..]\"
|
|
|
|
[[package]]
|
|
name = \"foo\"
|
|
version = \"0.0.1\"
|
|
dependencies = [
|
|
\"bar\",
|
|
]
|
|
";
|
|
assert_match_exact(expected, &actual);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn lockfile_without_root() {
|
|
Package::new("bar", "0.1.0").publish();
|
|
|
|
let lockfile = r#"
|
|
# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar",
|
|
]
|
|
"#;
|
|
|
|
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("Cargo.lock", lockfile);
|
|
|
|
let p = p.build();
|
|
|
|
p.cargo("check").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(
|
|
r#"# [..]
|
|
# [..]
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "[..]"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar",
|
|
]
|
|
"#,
|
|
&lock,
|
|
);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn locked_correct_error() {
|
|
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", "");
|
|
let p = p.build();
|
|
|
|
p.cargo("check --locked")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[UPDATING] `[..]` index
|
|
error: the lock file [CWD]/Cargo.lock needs to be updated but --locked was passed to prevent this
|
|
If you want to try to generate the lock file without accessing the network, \
|
|
remove the --locked flag and use --offline instead.
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v2_format_preserved() {
|
|
let cksum = Package::new("bar", "0.1.0").publish();
|
|
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "{}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar",
|
|
]
|
|
"#,
|
|
cksum
|
|
);
|
|
|
|
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("Cargo.lock", &lockfile)
|
|
.build();
|
|
|
|
p.cargo("fetch").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&lockfile, &lock);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v2_path_and_crates_io() {
|
|
let cksum010 = Package::new("a", "0.1.0").publish();
|
|
let cksum020 = Package::new("a", "0.2.0").publish();
|
|
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
[[package]]
|
|
name = "a"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "{}"
|
|
|
|
[[package]]
|
|
name = "a"
|
|
version = "0.2.0"
|
|
|
|
[[package]]
|
|
name = "a"
|
|
version = "0.2.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "{}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"a 0.1.0",
|
|
"a 0.2.0",
|
|
"a 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
"#,
|
|
cksum010, cksum020,
|
|
);
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
a = { path = 'a' }
|
|
b = { version = "0.1", package = 'a' }
|
|
c = { version = "0.2", package = 'a' }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"a/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "a"
|
|
version = "0.2.0"
|
|
"#,
|
|
)
|
|
.file("a/src/lib.rs", "")
|
|
.file("Cargo.lock", &lockfile)
|
|
.build();
|
|
|
|
p.cargo("fetch").run();
|
|
p.cargo("fetch").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&lockfile, &lock);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v3_and_git() {
|
|
let (git_project, repo) = git::new_repo("dep1", |project| {
|
|
project
|
|
.file("Cargo.toml", &basic_lib_manifest("dep1"))
|
|
.file("src/lib.rs", "")
|
|
});
|
|
let head_id = repo.head().unwrap().target().unwrap();
|
|
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "dep1"
|
|
version = "0.5.0"
|
|
source = "git+{}?branch=master#{}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"dep1",
|
|
]
|
|
"#,
|
|
git_project.url(),
|
|
head_id,
|
|
);
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
dep1 = {{ git = '{}', branch = 'master' }}
|
|
"#,
|
|
git_project.url(),
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", "version = 3")
|
|
.build();
|
|
|
|
p.cargo("fetch").run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&lockfile, &lock);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn lock_from_the_future() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
authors = []
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", "version = 10000000")
|
|
.build();
|
|
|
|
p.cargo("fetch")
|
|
.with_stderr(
|
|
"\
|
|
error: failed to parse lock file at: [..]
|
|
|
|
Caused by:
|
|
lock file version `10000000` was found, but this version of Cargo does not \
|
|
understand this lock file, perhaps Cargo needs to be updated?
|
|
",
|
|
)
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn preserve_old_format_if_no_update_needed() {
|
|
let cksum = Package::new("bar", "0.1.0").publish();
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
]
|
|
|
|
[metadata]
|
|
"checksum bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "{}"
|
|
"#,
|
|
cksum
|
|
);
|
|
|
|
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("Cargo.lock", &lockfile)
|
|
.build();
|
|
|
|
p.cargo("check --locked").run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn same_name_version_different_sources() {
|
|
let cksum = Package::new("foo", "0.1.0").publish();
|
|
let (git_project, repo) = git::new_repo("dep1", |project| {
|
|
project
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
});
|
|
let head_id = repo.head().unwrap().target().unwrap();
|
|
|
|
// Lockfile was generated with Rust 1.51
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
dependencies = [
|
|
"foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
"foo 0.1.0 (git+{url})",
|
|
]
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "{cksum}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
source = "git+{url}#{sha}"
|
|
"#,
|
|
sha = head_id,
|
|
url = git_project.url(),
|
|
cksum = cksum
|
|
);
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
|
|
[dependencies]
|
|
foo = "0.1.0"
|
|
foo2 = {{ git = '{}', package = 'foo' }}
|
|
"#,
|
|
git_project.url(),
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", &lockfile)
|
|
.build();
|
|
|
|
p.cargo("check").run();
|
|
|
|
assert_eq!(p.read_file("Cargo.lock"), lockfile);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn bad_data_in_lockfile_error_meg() {
|
|
Package::new("bar", "0.0.1").publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "test"
|
|
version = "0.0.0"
|
|
|
|
[dependencies]
|
|
bar = "*"
|
|
"#,
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file(
|
|
"Cargo.lock",
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "8e1b9346248cf3391ead604c4407258d327c28e37209f6d56127598165165dda"
|
|
|
|
[[package]]
|
|
name = "test"
|
|
version = "0.0.0"
|
|
dependencies = [
|
|
"bar",
|
|
]"#,
|
|
)
|
|
.build();
|
|
p.cargo("check")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
[..]
|
|
[ERROR] failed to select a version for the requirement `bar = \"*\"` (locked to 0.1.0)
|
|
candidate versions found which didn't match: 0.0.1
|
|
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
|
|
required by package `test v0.0.0 ([..])`
|
|
perhaps a crate was updated and forgotten to be re-vendored?
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn next_version_is_always_unstable() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", "version = 5")
|
|
.build();
|
|
|
|
p.cargo("fetch")
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
error: failed to parse lock file at: [CWD]/Cargo.lock
|
|
|
|
Caused by:
|
|
lock file version `5` was found, but this version of Cargo does not \
|
|
understand this lock file, perhaps Cargo needs to be updated?
|
|
",
|
|
)
|
|
.run();
|
|
|
|
// On nightly, let the user know about the `-Z` flag.
|
|
p.cargo("fetch")
|
|
.masquerade_as_nightly_cargo(&["-Znext-lockfile-bump"])
|
|
.with_status(101)
|
|
.with_stderr(
|
|
"\
|
|
error: failed to parse lock file at: [CWD]/Cargo.lock
|
|
|
|
Caused by:
|
|
lock file version `5` requires `-Znext-lockfile-bump`
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v4_cannot_be_created_from_scratch() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("fetch").run();
|
|
|
|
let lockfile = r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
"#;
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(lockfile, &lock);
|
|
}
|
|
|
|
fn create_branch(repo: &git2::Repository, branch: &str, head_id: git2::Oid) {
|
|
repo.branch(branch, &repo.find_commit(head_id).unwrap(), true)
|
|
.unwrap();
|
|
}
|
|
|
|
fn create_tag(repo: &git2::Repository, tag: &str, head_id: git2::Oid) {
|
|
repo.tag(
|
|
tag,
|
|
&repo.find_object(head_id, None).unwrap(),
|
|
&repo.signature().unwrap(),
|
|
"make a new tag",
|
|
false,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn v3_and_git_url_encoded(ref_kind: &str, f: impl FnOnce(&git2::Repository, &str, git2::Oid)) {
|
|
let (git_project, repo) = git::new_repo("dep1", |project| {
|
|
project
|
|
.file("Cargo.toml", &basic_lib_manifest("dep1"))
|
|
.file("src/lib.rs", "")
|
|
});
|
|
let url = git_project.url();
|
|
let head_id = repo.head().unwrap().target().unwrap();
|
|
// Ref name with special characters
|
|
let git_ref = "a-_+#$)";
|
|
f(&repo, git_ref, head_id);
|
|
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "dep1"
|
|
version = "0.5.0"
|
|
source = "git+{url}?{ref_kind}={git_ref}#{head_id}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"dep1",
|
|
]
|
|
"#,
|
|
);
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
|
|
[dependencies]
|
|
dep1 = {{ git = '{url}', {ref_kind} = '{git_ref}' }}
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", "version = 3")
|
|
.build();
|
|
|
|
p.cargo("check")
|
|
.with_stderr(format!(
|
|
"\
|
|
[UPDATING] git repository `{url}`
|
|
[CHECKING] dep1 v0.5.0 ({url}?{ref_kind}={git_ref}#[..])
|
|
[CHECKING] foo v0.0.1 ([CWD])
|
|
[FINISHED] dev [..]
|
|
"
|
|
))
|
|
.run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&lockfile, &lock);
|
|
|
|
// v3 doesn't URL-encode URL parameters, but `url` crate does decode as it
|
|
// was URL-encoded. Therefore Cargo thinks they are from different source
|
|
// and clones the repository again.
|
|
p.cargo("check")
|
|
.with_stderr(format!(
|
|
"\
|
|
[UPDATING] git repository `{url}`
|
|
[FINISHED] dev [..]
|
|
"
|
|
))
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v3_and_git_url_encoded_branch() {
|
|
v3_and_git_url_encoded("branch", create_branch);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v3_and_git_url_encoded_tag() {
|
|
v3_and_git_url_encoded("tag", create_tag);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v3_and_git_url_encoded_rev() {
|
|
v3_and_git_url_encoded("rev", create_tag);
|
|
}
|
|
|
|
fn v4_and_git_url_encoded(ref_kind: &str, f: impl FnOnce(&git2::Repository, &str, git2::Oid)) {
|
|
let (git_project, repo) = git::new_repo("dep1", |project| {
|
|
project
|
|
.file("Cargo.toml", &basic_lib_manifest("dep1"))
|
|
.file("src/lib.rs", "")
|
|
});
|
|
let url = git_project.url();
|
|
let head_id = repo.head().unwrap().target().unwrap();
|
|
// Ref name with special characters
|
|
let git_ref = "a-_+#$)";
|
|
let encoded_ref = "a-_%2B%23%24%29";
|
|
f(&repo, git_ref, head_id);
|
|
|
|
let lockfile = format!(
|
|
r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 4
|
|
|
|
[[package]]
|
|
name = "dep1"
|
|
version = "0.5.0"
|
|
source = "git+{url}?{ref_kind}={encoded_ref}#{head_id}"
|
|
|
|
[[package]]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
dependencies = [
|
|
"dep1",
|
|
]
|
|
"#,
|
|
);
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
|
|
[dependencies]
|
|
dep1 = {{ git = '{url}', {ref_kind} = '{git_ref}' }}
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("Cargo.lock", "version = 4")
|
|
.build();
|
|
|
|
p.cargo("check")
|
|
.with_stderr(format!(
|
|
"\
|
|
[UPDATING] git repository `{url}`
|
|
[CHECKING] dep1 v0.5.0 ({url}?{ref_kind}={git_ref}#[..])
|
|
[CHECKING] foo v0.0.1 ([CWD])
|
|
[FINISHED] dev [..]
|
|
"
|
|
))
|
|
.run();
|
|
|
|
let lock = p.read_lockfile();
|
|
assert_match_exact(&lockfile, &lock);
|
|
|
|
// Unlike v3_and_git_url_encoded, v4 encodes URL parameters so no git
|
|
// repository re-clone happen.
|
|
p.cargo("check").with_stderr("[FINISHED] dev [..]").run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v4_and_git_url_encoded_branch() {
|
|
v4_and_git_url_encoded("branch", create_branch);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v4_and_git_url_encoded_tag() {
|
|
v4_and_git_url_encoded("tag", create_tag);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn v4_and_git_url_encoded_rev() {
|
|
v4_and_git_url_encoded("rev", create_tag)
|
|
}
|