-use git2;
+//! Tests for git support.
+
use std::env;
-use std::fs::{self, File};
+use std::fs;
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::path::Path;
+use std::str;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
-use crate::support::paths::{self, CargoPathExt};
-use crate::support::sleep_ms;
-use crate::support::Project;
-use crate::support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project};
+use cargo_test_support::paths::{self, CargoPathExt};
+use cargo_test_support::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project};
+use cargo_test_support::{sleep_ms, t, Project};
fn disable_git_cli() -> bool {
// mingw git on Windows does not support Windows-style file URIs.
.file(
"src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- "#,
+ git = '{}'
+ "#,
git_project.url()
),
)
.file(
"src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- branch = "branchy"
+ git = '{}'
+ branch = "branchy"
- "#,
+ "#,
git_project.url()
),
)
.file(
"src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- tag = "v0.1.0"
- "#,
+ git = '{}'
+ tag = "v0.1.0"
+ "#,
git_project.url()
),
)
.file(
"Cargo.toml",
r#"
- [project]
+ [project]
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
- [dependencies.dep2]
+ [dependencies.dep2]
- version = "0.5.0"
- path = "vendor/dep2"
+ version = "0.5.0"
+ path = "vendor/dep2"
- [lib]
+ [lib]
- name = "dep1"
- "#,
+ name = "dep1"
+ "#,
)
.file(
"src/dep1.rs",
r#"
- extern crate dep2;
+ extern crate dep2;
- pub fn hello() -> &'static str {
- dep2::hello()
- }
- "#,
+ pub fn hello() -> &'static str {
+ dep2::hello()
+ }
+ "#,
)
.file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2"))
.file(
"vendor/dep2/src/dep2.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- version = "0.5.0"
- git = '{}'
+ version = "0.5.0"
+ git = '{}'
- [[bin]]
+ [[bin]]
- name = "foo"
- "#,
+ name = "foo"
+ "#,
git_project.url()
),
)
.file(
"src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
.file("vendor/dep2/Cargo.toml", "!INVALID!")
+ .file(
+ "vendor/dep3/Cargo.toml",
+ r#"
+ [project]
+ name = "dep3"
+ version = "0.5.0"
+ [dependencies]
+ subdep1 = { path = "../require-extra-build-step" }
+ "#,
+ )
+ .file("vendor/dep3/src/lib.rs", "")
});
let p = project()
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- version = "0.5.0"
- git = '{}'
+ version = "0.5.0"
+ git = '{}'
- [[bin]]
+ [[bin]]
- name = "foo"
- "#,
+ name = "foo"
+ "#,
git_project.url()
),
)
.file(
"dep1/src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "this is dep1"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "this is dep1"
+ }
+ "#,
)
.file("dep2/Cargo.toml", &basic_lib_manifest("dep2"))
.file(
"dep2/src/dep2.rs",
r#"
- pub fn hello() -> &'static str {
- "this is dep2"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "this is dep2"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- version = "0.5.0"
- git = '{}'
+ version = "0.5.0"
+ git = '{}'
- [dependencies.dep2]
+ [dependencies.dep2]
- version = "0.5.0"
- git = '{}'
+ version = "0.5.0"
+ git = '{}'
- [[bin]]
+ [[bin]]
- name = "foo"
- "#,
+ name = "foo"
+ "#,
git_project.url(),
git_project.url()
),
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep]
+ [dependencies.dep]
- git = "{}"
+ git = "{}"
- [[bin]]
+ [[bin]]
- name = "foo"
- "#,
+ name = "foo"
+ "#,
url
),
)
let rev1 = repo.revparse_single("HEAD").unwrap().id();
// Commit the changes and make sure we trigger a recompile
- File::create(&bar.root().join("src/lib.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() -> i32 { 2 }"#)
- .unwrap();
+ bar.change_file("src/lib.rs", "pub fn bar() -> i32 { 2 }");
git::add(&repo);
let rev2 = git::commit(&repo);
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.0.0"
- authors = []
+ [project]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
- [dependencies.bar]
- git = '{}'
- rev = "{}"
+ [dependencies.bar]
+ git = '{}'
+ rev = "{}"
- [dependencies.baz]
- path = "../baz"
- "#,
+ [dependencies.baz]
+ path = "../baz"
+ "#,
bar.url(),
rev1
),
.file(
"src/main.rs",
r#"
- extern crate bar;
- extern crate baz;
+ extern crate bar;
+ extern crate baz;
- fn main() {
- assert_eq!(bar::bar(), 1);
- assert_eq!(baz::baz(), 2);
- }
- "#,
+ fn main() {
+ assert_eq!(bar::bar(), 1);
+ assert_eq!(baz::baz(), 2);
+ }
+ "#,
)
.build();
"Cargo.toml",
&format!(
r#"
- [package]
- name = "baz"
- version = "0.0.0"
- authors = []
+ [package]
+ name = "baz"
+ version = "0.0.0"
+ authors = []
- [dependencies.bar]
- git = '{}'
- rev = "{}"
- "#,
+ [dependencies.bar]
+ git = '{}'
+ rev = "{}"
+ "#,
bar.url(),
rev2
),
.file(
"src/lib.rs",
r#"
- extern crate bar;
- pub fn baz() -> i32 { bar::bar() }
- "#,
+ extern crate bar;
+ pub fn baz() -> i32 { bar::bar() }
+ "#,
)
.build();
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.bar]
+ [dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#,
+ version = "0.5.0"
+ git = '{}'
+ "#,
git_project.url()
),
)
p.cargo("build").with_stdout("").run();
// Modify a file manually, shouldn't trigger a recompile
- File::create(&git_project.root().join("src/bar.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() { println!("hello!"); }"#)
- .unwrap();
+ git_project.change_file("src/bar.rs", r#"pub fn bar() { println!("hello!"); }"#);
p.cargo("build").with_stdout("").run();
.file(
"Cargo.toml",
r#"
- [package]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ [package]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
- path = "dep1"
- [dependencies.dep2]
- path = "dep2"
- "#,
+ [dependencies.dep1]
+ path = "dep1"
+ [dependencies.dep2]
+ path = "dep2"
+ "#,
)
.file(
"src/main.rs",
r#"
- #[allow(unused_extern_crates)]
- extern crate dep1;
- #[allow(unused_extern_crates)]
- extern crate dep2;
- fn main() {}
- "#,
+ #[allow(unused_extern_crates)]
+ extern crate dep1;
+ #[allow(unused_extern_crates)]
+ extern crate dep2;
+ fn main() {}
+ "#,
)
.file(
"dep1/Cargo.toml",
&format!(
r#"
- [package]
- name = "dep1"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ [package]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#,
+ [dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#,
git_project.url()
),
)
"dep2/Cargo.toml",
&format!(
r#"
- [package]
- name = "dep2"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ [package]
+ name = "dep2"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#,
+ [dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#,
git_project.url()
),
)
.run();
// Modify a file manually, and commit it
- File::create(&git_project.root().join("src/bar.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() { println!("hello!"); }"#)
- .unwrap();
+ git_project.change_file("src/bar.rs", r#"pub fn bar() { println!("hello!"); }"#);
let repo = git2::Repository::open(&git_project.root()).unwrap();
let old_head = repo.head().unwrap().target().unwrap();
git::add(&repo);
.with_status(101)
.with_stderr(
"\
-[UPDATING] git repository [..]
[ERROR] Unable to update [..]
Caused by:
- revspec '0.1.2' not found; [..]
+ precise value for git is not a git revision: 0.1.2
+
+Caused by:
+ unable to parse OID - contains invalid characters; class=Invalid (3)
",
)
.run();
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- "#,
+ git = '{}'
+ "#,
git_project.url()
),
)
.with_stderr(
"\
[UPDATING] git repository [..]
+[UPDATING] git submodule `file://[..]/dep2`
[COMPILING] dep1 [..]
[COMPILING] foo [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- "#,
+ git = '{}'
+ "#,
git_project.url()
),
)
let expected = format!(
"\
[UPDATING] git repository [..]
-[ERROR] failed to load source for a dependency on `dep1`
+[UPDATING] git submodule `file://[..]/dep2`
+[ERROR] failed to get `dep1` as a dependency of package `foo v0.5.0 [..]`
+
+Caused by:
+ failed to load source for dependency `dep1`
Caused by:
Unable to update {}
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
- git = '{}'
- [dependencies.dep2]
- git = '{}'
- "#,
+ [dependencies.dep1]
+ git = '{}'
+ [dependencies.dep2]
+ git = '{}'
+ "#,
git1.url(),
git2.url()
),
)
.run();
- File::create(&git1.root().join("src/lib.rs"))
- .unwrap()
- .write_all(br#"pub fn foo() {}"#)
- .unwrap();
+ git1.change_file("src/lib.rs", "pub fn foo() {}");
let repo = git2::Repository::open(&git1.root()).unwrap();
git::add(&repo);
let oid = git::commit(&repo);
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.0.0"
- authors = []
+ [project]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
- [dependencies.bar]
- git = '{}'
- "#,
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar.url()
),
)
.file(
"src/main.rs",
r#"
- extern crate bar;
+ extern crate bar;
- fn main() { assert_eq!(bar::bar(), 1) }
- "#,
+ fn main() { assert_eq!(bar::bar(), 1) }
+ "#,
)
.build();
// Update the repo, and simulate someone else updating the lock file and then
// us pulling it down.
- File::create(&bar.root().join("src/lib.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() -> i32 { 1 + 0 }"#)
- .unwrap();
+ bar.change_file("src/lib.rs", "pub fn bar() -> i32 { 1 + 0 }");
let repo = git2::Repository::open(&bar.root()).unwrap();
git::add(&repo);
git::commit(&repo);
let rev = repo.revparse_single("HEAD").unwrap().id();
- File::create(&foo.root().join("Cargo.lock"))
- .unwrap()
- .write_all(
- format!(
- r#"
- [[package]]
- name = "foo"
- version = "0.0.0"
- dependencies = [
- 'bar 0.0.0 (git+{url}#{hash})'
- ]
-
- [[package]]
- name = "bar"
- version = "0.0.0"
- source = 'git+{url}#{hash}'
- "#,
- url = bar.url(),
- hash = rev
- )
- .as_bytes(),
- )
- .unwrap();
+ foo.change_file(
+ "Cargo.lock",
+ &format!(
+ r#"
+ [[package]]
+ name = "foo"
+ version = "0.0.0"
+ dependencies = [
+ 'bar 0.0.0 (git+{url}#{hash})'
+ ]
+
+ [[package]]
+ name = "bar"
+ version = "0.0.0"
+ source = 'git+{url}#{hash}'
+ "#,
+ url = bar.url(),
+ hash = rev
+ ),
+ );
// Now build!
foo.cargo("build")
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- [dependencies.dep1]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ [dependencies.dep1]
+ git = '{}'
+ "#,
git_project.url()
),
)
p.cargo("run")
.with_stderr(
"[UPDATING] git repository `[..]`\n\
+ [UPDATING] git submodule `file://[..]/dep2`\n\
[COMPILING] dep1 v0.5.0 ([..])\n\
[COMPILING] foo v0.5.0 ([..])\n\
[FINISHED] dev [unoptimized + debuginfo] target(s) in \
.with_stdout("project2\n")
.run();
- File::create(&git_project.root().join(".gitmodules"))
- .unwrap()
- .write_all(
- format!(
- "[submodule \"src\"]\n\tpath = src\n\turl={}",
- git_project3.url()
- )
- .as_bytes(),
- )
- .unwrap();
+ git_project.change_file(
+ ".gitmodules",
+ &format!(
+ "[submodule \"src\"]\n\tpath = src\n\turl={}",
+ git_project3.url()
+ ),
+ );
// Sync the submodule and reset it to the new remote.
sub.sync().unwrap();
.remote_set_url("origin", &git_project3.url().to_string())
.unwrap();
let mut origin = subrepo.find_remote("origin").unwrap();
- origin.fetch(&[], None, None).unwrap();
+ origin.fetch(&Vec::<String>::new(), None, None).unwrap();
let id = subrepo.refname_to_id("refs/remotes/origin/master").unwrap();
let obj = subrepo.find_object(id, None).unwrap();
subrepo.reset(&obj, git2::ResetType::Hard, None).unwrap();
.with_stderr("")
.with_stderr(&format!(
"[UPDATING] git repository `{}`\n\
+ [UPDATING] git submodule `file://[..]/dep3`\n\
[UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
",
git_project.url()
.file(
"src/lib.rs",
r#"
- pub fn gimme() -> &'static str { "zoidberg" }
- "#,
+ pub fn gimme() -> &'static str { "zoidberg" }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dev-dependencies.bar]
- version = "0.5.0"
- git = '{}'
- "#,
+ [dev-dependencies.bar]
+ version = "0.5.0"
+ git = '{}'
+ "#,
p2.url()
),
)
.file(
"src/main.rs",
r#"
- fn main() {}
+ fn main() {}
- #[cfg(test)]
- mod tests {
- extern crate bar;
- #[test] fn foo() { bar::gimme(); }
- }
- "#,
+ #[cfg(test)]
+ mod tests {
+ extern crate bar;
+ #[test] fn foo() { bar::gimme(); }
+ }
+ "#,
)
.build();
"\
[COMPILING] [..] v0.5.0 ([..])
[COMPILING] [..] v0.5.0 ([..]
-[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[RUNNING] target/debug/deps/foo-[..][EXE]",
)
.with_stdout_contains("test tests::foo ... ok")
.file(
"Cargo.toml",
r#"
- [package]
- name = "foo"
- version = "0.0.0"
- authors = []
- build = "build.rs"
- "#,
+ [package]
+ name = "foo"
+ version = "0.0.0"
+ authors = []
+ build = "build.rs"
+ "#,
)
.file("build.rs", "fn main() {}")
.file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
// Modify an ignored file and make sure we don't rebuild
println!("second pass");
- File::create(&foo.root().join("src/bar.rs")).unwrap();
+ foo.change_file("src/bar.rs", "");
foo.cargo("build").with_stdout("").run();
}
.file(
"src/lib.rs",
r#"
- pub fn gimme() -> &'static str { "zoidberg" }
- "#,
+ pub fn gimme() -> &'static str { "zoidberg" }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
- [dev-dependencies.bar]
- git = '{}'
- "#,
+ [dev-dependencies.bar]
+ git = '{}'
+ "#,
p2.url()
),
)
"Cargo.toml",
&format!(
r#"
- [project]
- name = "p1"
- version = "0.5.0"
- authors = []
- build = 'build.rs'
- [dependencies.bar]
- git = '{}'
- "#,
+ [project]
+ name = "p1"
+ version = "0.5.0"
+ authors = []
+ build = 'build.rs'
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar.url()
),
)
.run();
// Make a commit to lock p2 to a different rev
- File::create(&bar.root().join("src/lib.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() -> i32 { 2 }"#)
- .unwrap();
+ bar.change_file("src/lib.rs", "pub fn bar() -> i32 { 2 }");
let repo = git2::Repository::open(&bar.root()).unwrap();
git::add(&repo);
git::commit(&repo);
"Cargo.toml",
&format!(
r#"
- [project]
- name = "p2"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#,
+ [project]
+ name = "p2"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar.url()
),
)
.file(
"Cargo.toml",
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.bar]
+ [dependencies.bar]
- version = "0.5.0"
- path = "bar"
+ version = "0.5.0"
+ path = "bar"
- [[bin]]
+ [[bin]]
- name = "foo"
- "#,
+ name = "foo"
+ "#,
)
.file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
.file(
"bar/Cargo.toml",
r#"
- [project]
+ [project]
- name = "bar"
- version = "0.5.0"
- authors = ["wycats@example.com"]
- build = "build.rs"
+ name = "bar"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+ build = "build.rs"
- [lib]
- name = "bar"
- path = "src/bar.rs"
- "#,
+ [lib]
+ name = "bar"
+ path = "src/bar.rs"
+ "#,
)
.file(
"bar/src/bar.rs.in",
r#"
- pub fn gimme() -> i32 { 0 }
- "#,
+ pub fn gimme() -> i32 { 0 }
+ "#,
)
.file(
"bar/build.rs",
r#"
- use std::fs;
- fn main() {
- fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
- }
- "#,
+ use std::fs;
+ fn main() {
+ fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
+ }
+ "#,
)
});
p.process(&p.bin("foo")).with_stdout("0\n").run();
// Touching bar.rs.in should cause the `build` command to run again.
- fs::File::create(&p.root().join("bar/src/bar.rs.in"))
- .unwrap()
- .write_all(b"pub fn gimme() -> i32 { 1 }")
- .unwrap();
+ p.change_file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 1 }");
p.cargo("build").run();
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar.url()
),
)
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar.url()
),
)
"Cargo.toml",
&format!(
r#"
- [package]
- name = "baz"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.bar]
- git = '{}'
- "#,
+ [package]
+ name = "baz"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.bar]
+ git = '{}'
+ "#,
bar2.url()
),
)
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- [dependencies.baz]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ [dependencies.baz]
+ git = '{}'
+ "#,
bar1.url(),
baz.url()
),
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.bar]
- git = '{}'
- [dependencies.a]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.bar]
+ git = '{}'
+ [dependencies.a]
+ git = '{}'
+ "#,
bar.url(),
bar.url()
),
"Cargo.toml",
&format!(
r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.transitive]
- git = '{}'
- "#,
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.transitive]
+ git = '{}'
+ "#,
transitive.url()
),
)
"Cargo.toml",
&format!(
r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = ["wycats@example.com"]
-
- [dependencies.transitive]
- git = '{}'
- "#,
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.transitive]
+ git = '{}'
+ "#,
transitive.url()
),
)
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#,
dep1.url()
),
)
// Update the dependency to point to the second repository, but this
// shouldn't update the transitive dependency which is the same.
- File::create(&p.root().join("Cargo.toml"))
- .unwrap()
- .write_all(
- format!(
- r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#,
- dep2.url()
- )
- .as_bytes(),
- )
- .unwrap();
+ p.change_file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#,
+ dep2.url()
+ ),
+ );
p.cargo("build")
.with_stderr(&format!(
.file(
"Cargo.toml",
r#"
- [package]
- name = "dep"
- version = "0.5.0"
- authors = []
+ [package]
+ name = "dep"
+ version = "0.5.0"
+ authors = []
- [dependencies.a]
- path = "a"
- "#,
+ [dependencies.a]
+ path = "a"
+ "#,
)
.file("src/lib.rs", "")
.file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.dep]
- git = '{}'
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.dep]
+ git = '{}'
+ "#,
dep.url()
),
)
let rev1 = repo.revparse_single("HEAD").unwrap().id();
// Just be sure to change a file
- File::create(&dep.root().join("src/lib.rs"))
- .unwrap()
- .write_all(br#"pub fn bar() -> i32 { 2 }"#)
- .unwrap();
+ dep.change_file("src/lib.rs", "pub fn bar() -> i32 { 2 }");
git::add(&repo);
git::commit(&repo);
p.cargo("update -p dep").run();
- let mut lockfile = String::new();
- File::open(&p.root().join("Cargo.lock"))
- .unwrap()
- .read_to_string(&mut lockfile)
- .unwrap();
+ let lockfile = p.read_lockfile();
assert!(
!lockfile.contains(&rev1.to_string()),
"{} in {}",
.file(
"Cargo.toml",
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- [dependencies.b]
- path = "b"
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ [dependencies.b]
+ path = "b"
+ "#,
)
.file("src/main.rs", "fn main() {}")
.file(
"b/Cargo.toml",
&format!(
r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- git = '{}'
- "#,
- a1.url()
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ git = '{}'
+ "#,
+ a1.url()
),
)
.file("b/src/lib.rs", "pub fn main() {}")
)
.run();
- File::create(&p.root().join("b/Cargo.toml"))
- .unwrap()
- .write_all(
- format!(
- r#"
- [project]
- name = "b"
- version = "0.5.0"
- authors = []
- [dependencies.a]
- git = '{}'
- "#,
- a2.url()
- )
- .as_bytes(),
- )
- .unwrap();
+ p.change_file(
+ "b/Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "b"
+ version = "0.5.0"
+ authors = []
+ [dependencies.a]
+ git = '{}'
+ "#,
+ a2.url()
+ ),
+ );
p.cargo("build")
.with_stderr(
p.file(
"Cargo.toml",
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
- build = "build.rs"
- "#,
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
+ build = "build.rs"
+ "#,
)
.file("build.rs", "fn main() {}")
.file("src/lib.rs", "")
"Cargo.toml",
&format!(
r#"
- [project]
- name = "a"
- version = "0.5.0"
- authors = []
- [dependencies]
- a = {{ git = '{}' }}
- "#,
+ [project]
+ name = "a"
+ version = "0.5.0"
+ authors = []
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
a2.url()
),
)
"Cargo.toml",
&format!(
r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- a = {{ git = '{}' }}
- "#,
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
a1.url()
),
)
.file(
"src/lib.rs",
r#"
- #[macro_use]
- extern crate a;
- "#,
+ #[macro_use]
+ extern crate a;
+ "#,
)
.build();
"Cargo.toml",
&format!(
r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- a = {{ git = '{}' }}
- "#,
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
a.url()
),
)
"Cargo.toml",
&format!(
r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- a = {{ git = '{}' }}
- "#,
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
a.url()
),
)
"Cargo.toml",
&format!(
r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- a = {{ path = 'a' }}
- git = {{ git = '{}' }}
- "#,
+ [dependencies]
+ a = {{ path = 'a' }}
+ git = {{ git = '{}' }}
+ "#,
git.url()
),
)
p.cargo("build").run();
- File::create(p.root().join("a/Cargo.toml"))
- .unwrap()
- .write_all(
- format!(
- r#"
- [package]
- name = "a"
- version = "0.0.1"
- authors = []
+ p.change_file(
+ "a/Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "a"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- git = {{ git = '{}' }}
- "#,
- git.url()
- )
- .as_bytes(),
- )
- .unwrap();
+ [dependencies]
+ git = {{ git = '{}' }}
+ "#,
+ git.url()
+ ),
+ );
p.cargo("build").run();
}
"Cargo.toml",
&format!(
r#"
- [package]
- name = "foo"
- version = "0.0.1"
- authors = []
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
- [dependencies]
- git1 = {{ git = '{0}', rev = 'v0.1.0' }}
- git2 = {{ git = '{0}', rev = 'v0.1.0' }}
- "#,
+ [dependencies]
+ git1 = {{ git = '{0}', rev = 'v0.1.0' }}
+ git2 = {{ git = '{0}', rev = 'v0.1.0' }}
+ "#,
git.url()
),
)
repo.file(
"Cargo.toml",
r#"
- [package]
- name = "foo"
- version = "0.5.0"
- include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
- "#,
+ [package]
+ name = "foo"
+ version = "0.5.0"
+ include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
+ "#,
)
.file(
".gitignore",
r#"
- /target
- Cargo.lock
- ignored.txt
- "#,
+ /target
+ Cargo.lock
+ ignored.txt
+ "#,
)
.file("src/lib.rs", "")
.file("ignored.txt", "")
.with_stdout(
"\
Cargo.toml
+Cargo.toml.orig
ignored.txt
src/lib.rs
",
.file(
"Cargo.toml",
r#"
- [project]
+ [project]
- name = "dep1"
- version = "0.5.0"
- authors = ["carlhuda@example.com"]
- categories = ["algorithms"]
- categories = ["algorithms"]
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ categories = ["algorithms"]
+ categories = ["algorithms"]
- [lib]
+ [lib]
- name = "dep1"
- "#,
+ name = "dep1"
+ "#,
)
.file(
"src/dep1.rs",
r#"
- pub fn hello() -> &'static str {
- "hello world"
- }
- "#,
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#,
)
});
"Cargo.toml",
&format!(
r#"
- [project]
+ [project]
- name = "foo"
- version = "0.5.0"
- authors = ["wycats@example.com"]
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
- [dependencies.dep1]
+ [dependencies.dep1]
- git = '{}'
- "#,
+ git = '{}'
+ "#,
git_project.url()
),
)
.cargo("build")
.with_status(101)
.with_stderr(&format!(
- "[UPDATING] git repository `{}`\n\
- error: failed to load source for a dependency on `dep1`\n\
- \n\
- Caused by:\n \
- Unable to update {}\n\
- \n\
- Caused by:\n \
- failed to parse manifest at `[..]`\n\
- \n\
- Caused by:\n \
- could not parse input as TOML\n\
- \n\
- Caused by:\n \
- duplicate key: `categories` for key `project` at line 10 column 17",
+ "\
+[UPDATING] git repository `{}`
+[ERROR] failed to get `dep1` as a dependency of package `foo v0.5.0 ([..])`
+
+Caused by:
+ failed to load source for dependency `dep1`
+
+Caused by:
+ Unable to update {}
+
+Caused by:
+ failed to parse manifest at `[..]`
+
+Caused by:
+ could not parse input as TOML
+
+Caused by:
+ duplicate key: `categories` for key `project` at line 10 column 21",
path2url(&git_root),
path2url(&git_root),
))
"Cargo.toml",
&format!(
r#"
- [project]
- name = "foo"
- version = "0.5.0"
- authors = []
+ [project]
+ name = "foo"
+ version = "0.5.0"
+ authors = []
- [dependencies]
- dep1 = {{ git = '{}' }}
- "#,
+ [dependencies]
+ dep1 = {{ git = '{}' }}
+ "#,
git_project.url()
),
)
"Cargo.toml",
&format!(
r#"
- [project]
- name = "fo"
- version = "0.5.0"
- authors = []
+ [project]
+ name = "fo"
+ version = "0.5.0"
+ authors = []
- [dependencies]
- dep1 = {{ git = '{}' }}
- "#,
+ [dependencies]
+ dep1 = {{ git = '{}' }}
+ "#,
git_project.url()
),
)
.file("src/main.rs", "fn main() {}")
.build();
- File::create(paths::home().join(".gitconfig"))
- .unwrap()
- .write_all(
- format!(
- r#"
+ fs::write(
+ paths::home().join(".gitconfig"),
+ format!(
+ r#"
[init]
templatedir = {}
"#,
- git_project2
- .url()
- .to_file_path()
- .unwrap()
- .to_str()
- .unwrap()
- .replace("\\", "/")
- )
- .as_bytes(),
- )
- .unwrap();
+ git_project2
+ .url()
+ .to_file_path()
+ .unwrap()
+ .to_str()
+ .unwrap()
+ .replace("\\", "/")
+ ),
+ )
+ .unwrap();
p.cargo("build").run();
}
#[cargo_test]
fn dirty_submodule() {
// `cargo package` warns for dirty file in submodule.
- let git_project = git::new("foo", |project| {
+ let (git_project, repo) = git::new_repo("foo", |project| {
project
.file("Cargo.toml", &basic_manifest("foo", "0.5.0"))
// This is necessary because `git::add` is too eager.
.file(".gitignore", "/target")
- })
- .unwrap();
+ });
let git_project2 = git::new("src", |project| {
project.no_manifest().file("lib.rs", "pub fn f() {}")
- })
- .unwrap();
+ });
- let repo = git2::Repository::open(&git_project.root()).unwrap();
let url = path2url(git_project2.root()).to_string();
git::add_submodule(&repo, &url, Path::new("src"));
git_project.cargo("package --no-verify").run();
// Try with a nested submodule.
- let git_project3 = git::new("bar", |project| project.no_manifest().file("mod.rs", "")).unwrap();
+ let git_project3 = git::new("bar", |project| project.no_manifest().file("mod.rs", ""));
let url = path2url(git_project3.root()).to_string();
git::add_submodule(&sub_repo, &url, Path::new("bar"));
git_project
git::commit(&repo);
git_project.cargo("package --no-verify").run();
}
+
+#[cargo_test]
+fn default_not_master() {
+ let project = project();
+
+ // Create a repository with a `master` branch, but switch the head to a
+ // branch called `main` at the same time.
+ let (git_project, repo) = git::new_repo("dep1", |project| {
+ project
+ .file("Cargo.toml", &basic_lib_manifest("dep1"))
+ .file("src/lib.rs", "pub fn foo() {}")
+ });
+ let head_id = repo.head().unwrap().target().unwrap();
+ let head = repo.find_commit(head_id).unwrap();
+ repo.branch("main", &head, false).unwrap();
+ repo.set_head("refs/heads/main").unwrap();
+
+ // Then create a commit on the new `main` branch so `master` and `main`
+ // differ.
+ git_project.change_file("src/lib.rs", "");
+ git::add(&repo);
+ git::commit(&repo);
+
+ let project = project
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+
+ [dependencies]
+ dep1 = {{ git = '{}' }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file("src/lib.rs", "pub fn foo() { dep1::foo() }")
+ .build();
+
+ project
+ .cargo("build")
+ .with_stderr(
+ "\
+[UPDATING] git repository `[..]`
+warning: fetching `master` branch from `[..]` but the `HEAD` \
+ reference for this repository is not the \
+ `master` branch. This behavior will change \
+ in Cargo in the future and your build may \
+ break, so it's recommended to place \
+ `branch = \"master\"` in Cargo.toml when \
+ depending on this git repository to ensure \
+ that your build will continue to work.
+[COMPILING] dep1 v0.5.0 ([..])
+[COMPILING] foo v0.5.0 ([..])
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn historical_lockfile_works() {
+ let project = project();
+
+ 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 project = project
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+
+ [dependencies]
+ dep1 = {{ git = '{}', branch = 'master' }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ project.cargo("build").run();
+ project.change_file(
+ "Cargo.lock",
+ &format!(
+ r#"# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "dep1"
+version = "0.5.0"
+source = "git+{}#{}"
+
+[[package]]
+name = "foo"
+version = "0.5.0"
+dependencies = [
+ "dep1",
+]
+"#,
+ git_project.url(),
+ head_id
+ ),
+ );
+ project
+ .cargo("build")
+ .with_stderr("[FINISHED] [..]\n")
+ .run();
+}
+
+#[cargo_test]
+fn historical_lockfile_works_with_vendor() {
+ let project = project();
+
+ 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 project = project
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+
+ [dependencies]
+ dep1 = {{ git = '{}', branch = 'master' }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ let output = project.cargo("vendor").exec_with_output().unwrap();
+ project.change_file(".cargo/config", str::from_utf8(&output.stdout).unwrap());
+ project.change_file(
+ "Cargo.lock",
+ &format!(
+ r#"# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "dep1"
+version = "0.5.0"
+source = "git+{}#{}"
+
+[[package]]
+name = "foo"
+version = "0.5.0"
+dependencies = [
+ "dep1",
+]
+"#,
+ git_project.url(),
+ head_id
+ ),
+ );
+ project.cargo("build").run();
+}
+
+#[cargo_test]
+fn two_dep_forms() {
+ let project = project();
+
+ let (git_project, _repo) = git::new_repo("dep1", |project| {
+ project
+ .file("Cargo.toml", &basic_lib_manifest("dep1"))
+ .file("src/lib.rs", "")
+ });
+
+ let project = project
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "foo"
+ version = "0.5.0"
+
+ [dependencies]
+ dep1 = {{ git = '{}', branch = 'master' }}
+ a = {{ path = 'a' }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .file(
+ "a/Cargo.toml",
+ &format!(
+ r#"
+ [project]
+ name = "a"
+ version = "0.5.0"
+
+ [dependencies]
+ dep1 = {{ git = '{}' }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file("a/src/lib.rs", "")
+ .build();
+
+ project
+ .cargo("build")
+ .with_stderr(
+ "\
+[UPDATING] [..]
+warning: two git dependencies found for `[..]` where one uses `branch = \"master\"` \
+and the other doesn't; this will break in a future version of Cargo, so please \
+ensure the dependency forms are consistent
+warning: [..]
+[COMPILING] [..]
+[COMPILING] [..]
+[COMPILING] [..]
+[FINISHED] [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn metadata_master_consistency() {
+ // SourceId consistency in the `cargo metadata` output when `master` is
+ // explicit or implicit, using new or old Cargo.lock.
+ let (git_project, git_repo) = git::new_repo("bar", |project| {
+ project
+ .file("Cargo.toml", &basic_manifest("bar", "1.0.0"))
+ .file("src/lib.rs", "")
+ });
+ let bar_hash = git_repo.head().unwrap().target().unwrap().to_string();
+
+ // Explicit branch="master" with a lock file created before 1.47 (does not contain ?branch=master).
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = {{ git = "{}", branch = "master" }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file(
+ "Cargo.lock",
+ &format!(
+ r#"
+ [[package]]
+ name = "bar"
+ version = "1.0.0"
+ source = "git+{}#{}"
+
+ [[package]]
+ name = "foo"
+ version = "0.1.0"
+ dependencies = [
+ "bar",
+ ]
+ "#,
+ git_project.url(),
+ bar_hash,
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ let metadata = |bar_source| -> String {
+ r#"
+ {
+ "packages": [
+ {
+ "name": "bar",
+ "version": "1.0.0",
+ "id": "bar 1.0.0 (__BAR_SOURCE__#__BAR_HASH__)",
+ "license": null,
+ "license_file": null,
+ "description": null,
+ "source": "__BAR_SOURCE__#__BAR_HASH__",
+ "dependencies": [],
+ "targets": "{...}",
+ "features": {},
+ "manifest_path": "[..]",
+ "metadata": null,
+ "publish": null,
+ "authors": [],
+ "categories": [],
+ "keywords": [],
+ "readme": null,
+ "repository": null,
+ "homepage": null,
+ "documentation": null,
+ "edition": "2015",
+ "links": null
+ },
+ {
+ "name": "foo",
+ "version": "0.1.0",
+ "id": "foo 0.1.0 [..]",
+ "license": null,
+ "license_file": null,
+ "description": null,
+ "source": null,
+ "dependencies": [
+ {
+ "name": "bar",
+ "source": "__BAR_SOURCE__",
+ "req": "*",
+ "kind": null,
+ "rename": null,
+ "optional": false,
+ "uses_default_features": true,
+ "features": [],
+ "target": null,
+ "registry": null
+ }
+ ],
+ "targets": "{...}",
+ "features": {},
+ "manifest_path": "[..]",
+ "metadata": null,
+ "publish": null,
+ "authors": [],
+ "categories": [],
+ "keywords": [],
+ "readme": null,
+ "repository": null,
+ "homepage": null,
+ "documentation": null,
+ "edition": "2015",
+ "links": null
+ }
+ ],
+ "workspace_members": [
+ "foo 0.1.0 [..]"
+ ],
+ "resolve": {
+ "nodes": [
+ {
+ "id": "bar 1.0.0 (__BAR_SOURCE__#__BAR_HASH__)",
+ "dependencies": [],
+ "deps": [],
+ "features": []
+ },
+ {
+ "id": "foo 0.1.0 [..]",
+ "dependencies": [
+ "bar 1.0.0 (__BAR_SOURCE__#__BAR_HASH__)"
+ ],
+ "deps": [
+ {
+ "name": "bar",
+ "pkg": "bar 1.0.0 (__BAR_SOURCE__#__BAR_HASH__)",
+ "dep_kinds": [
+ {
+ "kind": null,
+ "target": null
+ }
+ ]
+ }
+ ],
+ "features": []
+ }
+ ],
+ "root": "foo 0.1.0 [..]"
+ },
+ "target_directory": "[..]",
+ "version": 1,
+ "workspace_root": "[..]",
+ "metadata": null
+ }
+ "#
+ .replace("__BAR_SOURCE__", bar_source)
+ .replace("__BAR_HASH__", &bar_hash)
+ };
+
+ let bar_source = format!("git+{}?branch=master", git_project.url());
+ p.cargo("metadata").with_json(&metadata(&bar_source)).run();
+
+ // Conversely, remove branch="master" from Cargo.toml, but use a new Cargo.lock that has ?branch=master.
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bar = {{ git = "{}" }}
+ "#,
+ git_project.url()
+ ),
+ )
+ .file(
+ "Cargo.lock",
+ &format!(
+ r#"
+ [[package]]
+ name = "bar"
+ version = "1.0.0"
+ source = "git+{}?branch=master#{}"
+
+ [[package]]
+ name = "foo"
+ version = "0.1.0"
+ dependencies = [
+ "bar",
+ ]
+ "#,
+ git_project.url(),
+ bar_hash
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ // No ?branch=master!
+ let bar_source = format!("git+{}", git_project.url());
+ p.cargo("metadata").with_json(&metadata(&bar_source)).run();
+}