3 use std
::fs
::{self, File}
;
4 use std
::io
::prelude
::*;
5 use std
::net
::{TcpListener, TcpStream}
;
7 use std
::sync
::atomic
::{AtomicBool, Ordering}
;
11 use crate::support
::paths
::{self, CargoPathExt}
;
12 use crate::support
::sleep_ms
;
13 use crate::support
::Project
;
14 use crate::support
::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}
;
16 fn disable_git_cli() -> bool
{
17 // mingw git on Windows does not support Windows-style file URIs.
18 // Appveyor in the rust repo has that git up front in the PATH instead
19 // of Git-for-Windows, which causes this to fail.
20 env
::var("CARGO_TEST_DISABLE_GIT_CLI") == Ok("1".to_string())
24 fn cargo_compile_simple_git_dep() {
25 let project
= project();
26 let git_project
= git
::new("dep1", |project
| {
28 .file("Cargo.toml", &basic_lib_manifest("dep1"))
32 pub fn hello() -> &'static str {
48 authors = ["wycats@example.com"]
59 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
63 let git_root
= git_project
.root();
67 .with_stderr(&format
!(
68 "[UPDATING] git repository `{}`\n\
69 [COMPILING] dep1 v0.5.0 ({}#[..])\n\
70 [COMPILING] foo v0.5.0 ([CWD])\n\
71 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
77 assert
!(project
.bin("foo").is_file());
80 .process(&project
.bin("foo"))
81 .with_stdout("hello world\n")
86 fn cargo_compile_git_dep_branch() {
87 let project
= project();
88 let git_project
= git
::new("dep1", |project
| {
90 .file("Cargo.toml", &basic_lib_manifest("dep1"))
94 pub fn hello() -> &'static str {
101 // Make a new branch based on the current HEAD commit
102 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
103 let head
= repo
.head().unwrap().target().unwrap();
104 let head
= repo
.find_commit(head
).unwrap();
105 repo
.branch("branchy", &head
, true).unwrap();
107 let project
= project
116 authors = ["wycats@example.com"]
129 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
133 let git_root
= git_project
.root();
137 .with_stderr(&format
!(
138 "[UPDATING] git repository `{}`\n\
139 [COMPILING] dep1 v0.5.0 ({}?branch=branchy#[..])\n\
140 [COMPILING] foo v0.5.0 ([CWD])\n\
141 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
147 assert
!(project
.bin("foo").is_file());
150 .process(&project
.bin("foo"))
151 .with_stdout("hello world\n")
156 fn cargo_compile_git_dep_tag() {
157 let project
= project();
158 let git_project
= git
::new("dep1", |project
| {
160 .file("Cargo.toml", &basic_lib_manifest("dep1"))
164 pub fn hello() -> &'static str {
171 // Make a tag corresponding to the current HEAD
172 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
173 let head
= repo
.head().unwrap().target().unwrap();
176 &repo
.find_object(head
, None
).unwrap(),
177 &repo
.signature().unwrap(),
183 let project
= project
192 authors = ["wycats@example.com"]
204 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
208 let git_root
= git_project
.root();
212 .with_stderr(&format
!(
213 "[UPDATING] git repository `{}`\n\
214 [COMPILING] dep1 v0.5.0 ({}?tag=v0.1.0#[..])\n\
215 [COMPILING] foo v0.5.0 ([CWD])\n\
216 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
222 assert
!(project
.bin("foo").is_file());
225 .process(&project
.bin("foo"))
226 .with_stdout("hello world\n")
229 project
.cargo("build").run();
233 fn cargo_compile_with_nested_paths() {
234 let git_project
= git
::new("dep1", |project
| {
243 authors = ["carlhuda@example.com"]
260 pub fn hello() -> &'static str {
265 .file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2"))
267 "vendor/dep2/src/dep2.rs",
269 pub fn hello() -> &'static str {
285 authors = ["wycats@example.com"]
301 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
305 p
.cargo("build").run();
307 assert
!(p
.bin("foo").is_file());
309 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
313 fn cargo_compile_with_malformed_nested_paths() {
314 let git_project
= git
::new("dep1", |project
| {
316 .file("Cargo.toml", &basic_lib_manifest("dep1"))
320 pub fn hello() -> &'static str {
325 .file("vendor/dep2/Cargo.toml", "!INVALID!")
337 authors = ["wycats@example.com"]
353 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
357 p
.cargo("build").run();
359 assert
!(p
.bin("foo").is_file());
361 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
365 fn cargo_compile_with_meta_package() {
366 let git_project
= git
::new("meta-dep", |project
| {
368 .file("dep1/Cargo.toml", &basic_lib_manifest("dep1"))
372 pub fn hello() -> &'static str {
377 .file("dep2/Cargo.toml", &basic_lib_manifest("dep2"))
381 pub fn hello() -> &'static str {
397 authors = ["wycats@example.com"]
420 r
#""{} {}", dep1::hello(), dep2::hello()"#,
426 p
.cargo("build").run();
428 assert
!(p
.bin("foo").is_file());
430 p
.process(&p
.bin("foo"))
431 .with_stdout("this is dep1 this is dep2\n")
436 fn cargo_compile_with_short_ssh_git() {
437 let url
= "git@github.com:a/dep";
448 authors = ["wycats@example.com"]
463 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
470 .with_stderr(&format
!(
472 [ERROR] failed to parse manifest at `[..]`
475 invalid url `{}`: relative URL without a base
483 fn two_revs_same_deps() {
484 let bar
= git
::new("meta-dep", |project
| {
486 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
487 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
490 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
491 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
493 // Commit the changes and make sure we trigger a recompile
494 File
::create(&bar
.root().join("src/lib.rs"))
496 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
499 let rev2
= git
::commit(&repo
);
529 assert_eq!(bar::bar(), 1);
530 assert_eq!(baz::baz(), 2);
559 pub fn baz() -> i32 { bar::bar() }
564 foo
.cargo("build -v").run();
565 assert
!(foo
.bin("foo").is_file());
566 foo
.process(&foo
.bin("foo")).run();
571 let git_project
= git
::new("bar", |project
| {
573 .file("Cargo.toml", &basic_lib_manifest("bar"))
574 .file("src/bar.rs", "pub fn bar() {}")
586 authors = ["wycats@example.com"]
596 .file("src/main.rs", &main_file(r
#""{:?}", bar::bar()"#, &["bar"]))
599 // First time around we should compile both foo and bar
601 .with_stderr(&format
!(
602 "[UPDATING] git repository `{}`\n\
603 [COMPILING] bar v0.5.0 ({}#[..])\n\
604 [COMPILING] foo v0.5.0 ([CWD])\n\
605 [FINISHED] dev [unoptimized + debuginfo] target(s) \
612 // Don't recompile the second time
613 p
.cargo("build").with_stdout("").run();
615 // Modify a file manually, shouldn't trigger a recompile
616 File
::create(&git_project
.root().join("src/bar.rs"))
618 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
621 p
.cargo("build").with_stdout("").run();
624 .with_stderr(&format
!(
625 "[UPDATING] git repository `{}`",
630 p
.cargo("build").with_stdout("").run();
632 // Commit the changes and make sure we don't trigger a recompile because the
633 // lock file says not to change
634 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
638 println
!("compile after commit");
639 p
.cargo("build").with_stdout("").run();
640 p
.root().move_into_the_past();
642 // Update the dependency and carry on!
644 .with_stderr(&format
!(
645 "[UPDATING] git repository `{}`\n\
646 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
651 println
!("going for the last compile");
653 .with_stderr(&format
!(
654 "[COMPILING] bar v0.5.0 ({}#[..])\n\
655 [COMPILING] foo v0.5.0 ([CWD])\n\
656 [FINISHED] dev [unoptimized + debuginfo] target(s) \
662 // Make sure clean only cleans one dep
663 p
.cargo("clean -p foo").with_stdout("").run();
666 "[COMPILING] foo v0.5.0 ([CWD])\n\
667 [FINISHED] dev [unoptimized + debuginfo] target(s) \
674 fn update_with_shared_deps() {
675 let git_project
= git
::new("bar", |project
| {
677 .file("Cargo.toml", &basic_lib_manifest("bar"))
678 .file("src/bar.rs", "pub fn bar() {}")
688 authors = ["wycats@example.com"]
699 #[allow(unused_extern_crates)]
701 #[allow(unused_extern_crates)]
713 authors = ["wycats@example.com"]
722 .file("dep1/src/lib.rs", "")
730 authors = ["wycats@example.com"]
739 .file("dep2/src/lib.rs", "")
742 // First time around we should compile both foo and bar
744 .with_stderr(&format
!(
746 [UPDATING] git repository `{git}`
747 [COMPILING] bar v0.5.0 ({git}#[..])
748 [COMPILING] [..] v0.5.0 ([..])
749 [COMPILING] [..] v0.5.0 ([..])
750 [COMPILING] foo v0.5.0 ([CWD])
751 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
752 git
= git_project
.url(),
756 // Modify a file manually, and commit it
757 File
::create(&git_project
.root().join("src/bar.rs"))
759 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
761 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
762 let old_head
= repo
.head().unwrap().target().unwrap();
768 // By default, not transitive updates
769 println
!("dep1 update");
770 p
.cargo("update -p dep1").with_stdout("").run();
772 // Don't do anything bad on a weird --precise argument
773 println
!("bar bad precise update");
774 p
.cargo("update -p bar --precise 0.1.2")
778 [UPDATING] git repository [..]
779 [ERROR] Unable to update [..]
782 revspec '0.1.2' not found; [..]
787 // Specifying a precise rev to the old rev shouldn't actually update
788 // anything because we already have the rev in the db.
789 println
!("bar precise update");
790 p
.cargo("update -p bar --precise")
791 .arg(&old_head
.to_string())
795 // Updating aggressively should, however, update the repo.
796 println
!("dep1 aggressive update");
797 p
.cargo("update -p dep1 --aggressive")
798 .with_stderr(&format
!(
799 "[UPDATING] git repository `{}`\n\
800 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
806 // Make sure we still only compile one version of the git repo
809 .with_stderr(&format
!(
811 [COMPILING] bar v0.5.0 ({git}#[..])
812 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
813 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
814 [COMPILING] foo v0.5.0 ([CWD])
815 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
816 git
= git_project
.url(),
820 // We should be able to update transitive deps
821 p
.cargo("update -p bar")
822 .with_stderr(&format
!(
823 "[UPDATING] git repository `{}`",
830 fn dep_with_submodule() {
831 let project
= project();
832 let git_project
= git
::new("dep1", |project
| {
833 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
835 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}"));
837 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
838 let url
= path2url(git_project2
.root()).to_string();
839 git
::add_submodule(&repo
, &url
, Path
::new("src"));
842 let project
= project
851 authors = ["wycats@example.com"]
862 "extern crate dep1; pub fn foo() { dep1::dep() }",
870 [UPDATING] git repository [..]
871 [COMPILING] dep1 [..]
873 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
879 fn dep_with_bad_submodule() {
880 let project
= project();
881 let git_project
= git
::new("dep1", |project
| {
882 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
884 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}"));
886 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
887 let url
= path2url(git_project2
.root()).to_string();
888 git
::add_submodule(&repo
, &url
, Path
::new("src"));
891 // now amend the first commit on git_project2 to make submodule ref point to not-found
893 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
894 let original_submodule_ref
= repo
.refname_to_id("refs/heads/master").unwrap();
895 let commit
= repo
.find_commit(original_submodule_ref
).unwrap();
898 Some("refs/heads/master"),
902 Some("something something"),
916 authors = ["wycats@example.com"]
927 "extern crate dep1; pub fn foo() { dep1::dep() }",
931 let expected
= format
!(
933 [UPDATING] git repository [..]
934 [ERROR] failed to load source for a dependency on `dep1`
940 failed to update submodule `src`
943 object not found - no match for id [..]
945 path2url(git_project
.root())
949 .with_stderr(expected
)
955 fn two_deps_only_update_one() {
956 let project
= project();
957 let git1
= git
::new("dep1", |project
| {
959 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
960 .file("src/lib.rs", "")
962 let git2
= git
::new("dep2", |project
| {
964 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
965 .file("src/lib.rs", "")
977 authors = ["wycats@example.com"]
988 .file("src/main.rs", "fn main() {}")
991 fn oid_to_short_sha(oid
: git2
::Oid
) -> String
{
992 oid
.to_string()[..8].to_string()
994 fn git_repo_head_sha(p
: &Project
) -> String
{
995 let repo
= git2
::Repository
::open(p
.root()).unwrap();
996 let head
= repo
.head().unwrap().target().unwrap();
997 oid_to_short_sha(head
)
1000 println
!("dep1 head sha: {}", git_repo_head_sha(&git1
));
1001 println
!("dep2 head sha: {}", git_repo_head_sha(&git2
));
1005 "[UPDATING] git repository `[..]`\n\
1006 [UPDATING] git repository `[..]`\n\
1007 [COMPILING] [..] v0.5.0 ([..])\n\
1008 [COMPILING] [..] v0.5.0 ([..])\n\
1009 [COMPILING] foo v0.5.0 ([CWD])\n\
1010 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1014 File
::create(&git1
.root().join("src/lib.rs"))
1016 .write_all(br
#"pub fn foo() {}"#)
1018 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
1020 let oid
= git
::commit(&repo
);
1021 println
!("dep1 head sha: {}", oid_to_short_sha(oid
));
1023 p
.cargo("update -p dep1")
1024 .with_stderr(&format
!(
1025 "[UPDATING] git repository `{}`\n\
1026 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1034 fn stale_cached_version() {
1035 let bar
= git
::new("meta-dep", |project
| {
1037 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
1038 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1041 // Update the git database in the cache with the current state of the git
1064 fn main() { assert_eq!(bar::bar(), 1) }
1069 foo
.cargo("build").run();
1070 foo
.process(&foo
.bin("foo")).run();
1072 // Update the repo, and simulate someone else updating the lock file and then
1073 // us pulling it down.
1074 File
::create(&bar
.root().join("src/lib.rs"))
1076 .write_all(br
#"pub fn bar() -> i32 { 1 + 0 }"#)
1078 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1084 let rev
= repo
.revparse_single("HEAD").unwrap().id();
1086 File
::create(&foo
.root().join("Cargo.lock"))
1095 'bar 0.0.0 (git+{url}#{hash})'
1101 source = 'git+{url}#{hash}'
1112 .with_stderr(&format
!(
1114 [UPDATING] git repository `{bar}`
1115 [COMPILING] bar v0.0.0 ({bar}#[..])
1116 [COMPILING] foo v0.0.0 ([CWD])
1117 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1122 foo
.process(&foo
.bin("foo")).run();
1126 fn dep_with_changed_submodule() {
1127 let project
= project();
1128 let git_project
= git
::new("dep1", |project
| {
1129 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
1132 let git_project2
= git
::new("dep2", |project
| {
1133 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
1136 let git_project3
= git
::new("dep3", |project
| {
1137 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
1140 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
1141 let mut sub
= git
::add_submodule(&repo
, &git_project2
.url().to_string(), Path
::new("src"));
1152 authors = ["wycats@example.com"]
1163 pub fn main() { println!(\"{}\", dep1::dep()) }
1168 println
!("first run");
1171 "[UPDATING] git repository `[..]`\n\
1172 [COMPILING] dep1 v0.5.0 ([..])\n\
1173 [COMPILING] foo v0.5.0 ([..])\n\
1174 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1176 [RUNNING] `target/debug/foo[EXE]`\n",
1178 .with_stdout("project2\n")
1181 File
::create(&git_project
.root().join(".gitmodules"))
1185 "[submodule \"src\"]\n\tpath = src\n\turl={}",
1192 // Sync the submodule and reset it to the new remote.
1193 sub
.sync().unwrap();
1195 let subrepo
= sub
.open().unwrap();
1197 .remote_add_fetch("origin", "refs/heads/*:refs/heads/*")
1200 .remote_set_url("origin", &git_project3
.url().to_string())
1202 let mut origin
= subrepo
.find_remote("origin").unwrap();
1203 origin
.fetch(&[], None
, None
).unwrap();
1204 let id
= subrepo
.refname_to_id("refs/remotes/origin/master").unwrap();
1205 let obj
= subrepo
.find_object(id
, None
).unwrap();
1206 subrepo
.reset(&obj
, git2
::ResetType
::Hard
, None
).unwrap();
1208 sub
.add_to_index(true).unwrap();
1213 // Update the dependency and carry on!
1215 p
.cargo("update -v")
1217 .with_stderr(&format
!(
1218 "[UPDATING] git repository `{}`\n\
1219 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1225 println
!("last run");
1228 "[COMPILING] dep1 v0.5.0 ([..])\n\
1229 [COMPILING] foo v0.5.0 ([..])\n\
1230 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1232 [RUNNING] `target/debug/foo[EXE]`\n",
1234 .with_stdout("project3\n")
1239 fn dev_deps_with_testing() {
1240 let p2
= git
::new("bar", |project
| {
1242 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1246 pub fn gimme() -> &'static str { "zoidberg" }
1260 authors = ["wycats@example.com"]
1262 [dev-dependencies.bar]
1277 #[test] fn foo() { bar::gimme(); }
1283 // Generate a lock file which did not use `bar` to compile, but had to update
1284 // `bar` to generate the lock file
1286 .with_stderr(&format
!(
1288 [UPDATING] git repository `{bar}`
1289 [COMPILING] foo v0.5.0 ([CWD])
1290 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1296 // Make sure we use the previous resolution of `bar` instead of updating it
1301 [COMPILING] [..] v0.5.0 ([..])
1302 [COMPILING] [..] v0.5.0 ([..]
1303 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1304 [RUNNING] target/debug/deps/foo-[..][EXE]",
1306 .with_stdout_contains("test tests::foo ... ok")
1311 fn git_build_cmd_freshness() {
1312 let foo
= git
::new("foo", |project
| {
1324 .file("build.rs", "fn main() {}")
1325 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1326 .file(".gitignore", "src/bar.rs")
1328 foo
.root().move_into_the_past();
1335 [COMPILING] foo v0.0.0 ([CWD])
1336 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1341 // Smoke test to make sure it doesn't compile again
1342 println
!("first pass");
1343 foo
.cargo("build").with_stdout("").run();
1345 // Modify an ignored file and make sure we don't rebuild
1346 println
!("second pass");
1347 File
::create(&foo
.root().join("src/bar.rs")).unwrap();
1348 foo
.cargo("build").with_stdout("").run();
1352 fn git_name_not_always_needed() {
1353 let p2
= git
::new("bar", |project
| {
1355 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1359 pub fn gimme() -> &'static str { "zoidberg" }
1364 let repo
= git2
::Repository
::open(&p2
.root()).unwrap();
1365 let mut cfg
= repo
.config().unwrap();
1366 let _
= cfg
.remove("user.name");
1367 let _
= cfg
.remove("user.email");
1379 [dev-dependencies.bar]
1385 .file("src/main.rs", "fn main() {}")
1388 // Generate a lock file which did not use `bar` to compile, but had to update
1389 // `bar` to generate the lock file
1391 .with_stderr(&format
!(
1393 [UPDATING] git repository `{bar}`
1394 [COMPILING] foo v0.5.0 ([CWD])
1395 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1403 fn git_repo_changing_no_rebuild() {
1404 let bar
= git
::new("bar", |project
| {
1406 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1407 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1410 // Lock p1 to the first rev in the git repo
1428 .file("src/main.rs", "fn main() {}")
1429 .file("build.rs", "fn main() {}")
1431 p1
.root().move_into_the_past();
1433 .with_stderr(&format
!(
1435 [UPDATING] git repository `{bar}`
1438 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1444 // Make a commit to lock p2 to a different rev
1445 File
::create(&bar
.root().join("src/lib.rs"))
1447 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1449 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1453 // Lock p2 to the second rev
1470 .file("src/main.rs", "fn main() {}")
1473 .with_stderr(&format
!(
1475 [UPDATING] git repository `{bar}`
1478 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1484 // And now for the real test! Make sure that p1 doesn't get rebuilt
1485 // even though the git repo has changed.
1486 p1
.cargo("build").with_stdout("").run();
1490 fn git_dep_build_cmd() {
1491 let p
= git
::new("foo", |project
| {
1500 authors = ["wycats@example.com"]
1512 .file("src/foo.rs", &main_file(r
#""{}", bar::gimme()"#, &["bar"]))
1520 authors = ["wycats@example.com"]
1529 "bar/src/bar.rs.in",
1531 pub fn gimme() -> i32 { 0 }
1539 fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
1545 p
.root().join("bar").move_into_the_past();
1547 p
.cargo("build").run();
1549 p
.process(&p
.bin("foo")).with_stdout("0\n").run();
1551 // Touching bar.rs.in should cause the `build` command to run again.
1552 fs
::File
::create(&p
.root().join("bar/src/bar.rs.in"))
1554 .write_all(b
"pub fn gimme() -> i32 { 1 }")
1557 p
.cargo("build").run();
1559 p
.process(&p
.bin("foo")).with_stdout("1\n").run();
1563 fn fetch_downloads() {
1564 let bar
= git
::new("bar", |project
| {
1566 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1567 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1585 .file("src/main.rs", "fn main() {}")
1588 .with_stderr(&format
!(
1589 "[UPDATING] git repository `{url}`",
1594 p
.cargo("fetch").with_stdout("").run();
1598 fn warnings_in_git_dep() {
1599 let bar
= git
::new("bar", |project
| {
1601 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1602 .file("src/lib.rs", "fn unused() {}")
1620 .file("src/main.rs", "fn main() {}")
1624 .with_stderr(&format
!(
1625 "[UPDATING] git repository `{}`\n\
1626 [COMPILING] bar v0.5.0 ({}#[..])\n\
1627 [COMPILING] foo v0.5.0 ([CWD])\n\
1628 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1636 fn update_ambiguous() {
1637 let bar1
= git
::new("bar1", |project
| {
1639 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1640 .file("src/lib.rs", "")
1642 let bar2
= git
::new("bar2", |project
| {
1644 .file("Cargo.toml", &basic_manifest("bar", "0.6.0"))
1645 .file("src/lib.rs", "")
1647 let baz
= git
::new("baz", |project
| {
1656 authors = ["wycats@example.com"]
1664 .file("src/lib.rs", "")
1685 .file("src/main.rs", "fn main() {}")
1688 p
.cargo("generate-lockfile").run();
1689 p
.cargo("update -p bar")
1693 [ERROR] There are multiple `bar` packages in your project, and the specification `bar` \
1695 Please re-run this command with `-p <spec>` where `<spec>` is one of the \
1705 fn update_one_dep_in_repo_with_many_deps() {
1706 let bar
= git
::new("bar", |project
| {
1708 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1709 .file("src/lib.rs", "")
1710 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1711 .file("a/src/lib.rs", "")
1732 .file("src/main.rs", "fn main() {}")
1735 p
.cargo("generate-lockfile").run();
1736 p
.cargo("update -p bar")
1737 .with_stderr(&format
!("[UPDATING] git repository `{}`", bar
.url()))
1742 fn switch_deps_does_not_update_transitive() {
1743 let transitive
= git
::new("transitive", |project
| {
1745 .file("Cargo.toml", &basic_manifest("transitive", "0.5.0"))
1746 .file("src/lib.rs", "")
1748 let dep1
= git
::new("dep1", |project
| {
1757 authors = ["wycats@example.com"]
1759 [dependencies.transitive]
1765 .file("src/lib.rs", "")
1767 let dep2
= git
::new("dep2", |project
| {
1776 authors = ["wycats@example.com"]
1778 [dependencies.transitive]
1784 .file("src/lib.rs", "")
1802 .file("src/main.rs", "fn main() {}")
1806 .with_stderr(&format
!(
1808 [UPDATING] git repository `{}`
1809 [UPDATING] git repository `{}`
1810 [COMPILING] transitive [..]
1811 [COMPILING] dep [..]
1812 [COMPILING] foo [..]
1813 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1820 // Update the dependency to point to the second repository, but this
1821 // shouldn't update the transitive dependency which is the same.
1822 File
::create(&p
.root().join("Cargo.toml"))
1841 .with_stderr(&format
!(
1843 [UPDATING] git repository `{}`
1844 [COMPILING] dep [..]
1845 [COMPILING] foo [..]
1846 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1854 fn update_one_source_updates_all_packages_in_that_git_source() {
1855 let dep
= git
::new("dep", |project
| {
1869 .file("src/lib.rs", "")
1870 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1871 .file("a/src/lib.rs", "")
1889 .file("src/main.rs", "fn main() {}")
1892 p
.cargo("build").run();
1894 let repo
= git2
::Repository
::open(&dep
.root()).unwrap();
1895 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
1897 // Just be sure to change a file
1898 File
::create(&dep
.root().join("src/lib.rs"))
1900 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1905 p
.cargo("update -p dep").run();
1906 let mut lockfile
= String
::new();
1907 File
::open(&p
.root().join("Cargo.lock"))
1909 .read_to_string(&mut lockfile
)
1912 !lockfile
.contains(&rev1
.to_string()),
1920 fn switch_sources() {
1921 let a1
= git
::new("a1", |project
| {
1923 .file("Cargo.toml", &basic_manifest("a", "0.5.0"))
1924 .file("src/lib.rs", "")
1926 let a2
= git
::new("a2", |project
| {
1928 .file("Cargo.toml", &basic_manifest("a", "0.5.1"))
1929 .file("src/lib.rs", "")
1944 .file("src/main.rs", "fn main() {}")
1959 .file("b/src/lib.rs", "pub fn main() {}")
1965 [UPDATING] git repository `file://[..]a1`
1966 [COMPILING] a v0.5.0 ([..]a1#[..]
1967 [COMPILING] b v0.5.0 ([..])
1968 [COMPILING] foo v0.5.0 ([..])
1969 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1974 File
::create(&p
.root().join("b/Cargo.toml"))
1995 [UPDATING] git repository `file://[..]a2`
1996 [COMPILING] a v0.5.1 ([..]a2#[..]
1997 [COMPILING] b v0.5.0 ([..])
1998 [COMPILING] foo v0.5.0 ([..])
1999 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2006 fn dont_require_submodules_are_checked_out() {
2007 let p
= project().build();
2008 let git1
= git
::new("dep1", |p
| {
2019 .file("build.rs", "fn main() {}")
2020 .file("src/lib.rs", "")
2023 let git2
= git
::new("dep2", |p
| p
);
2025 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
2026 let url
= path2url(git2
.root()).to_string();
2027 git
::add_submodule(&repo
, &url
, Path
::new("a/submodule"));
2030 git2
::Repository
::init(&p
.root()).unwrap();
2031 let url
= path2url(git1
.root()).to_string();
2032 let dst
= paths
::home().join("foo");
2033 git2
::Repository
::clone(&url
, &dst
).unwrap();
2035 git1
.cargo("build -v").cwd(&dst
).run();
2039 fn doctest_same_name() {
2040 let a2
= git
::new("a2", |p
| {
2041 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0"))
2042 .file("src/lib.rs", "pub fn a2() {}")
2045 let a1
= git
::new("a1", |p
| {
2055 a = {{ git = '{}' }}
2060 .file("src/lib.rs", "extern crate a; pub fn a1() {}")
2074 a = {{ git = '{}' }}
2088 p
.cargo("test -v").run();
2092 fn lints_are_suppressed() {
2093 let a
= git
::new("a", |p
| {
2094 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2113 a = {{ git = '{}' }}
2118 .file("src/lib.rs", "")
2124 [UPDATING] git repository `[..]`
2125 [COMPILING] a v0.5.0 ([..])
2126 [COMPILING] foo v0.0.1 ([..])
2127 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2134 fn denied_lints_are_allowed() {
2135 let a
= git
::new("a", |p
| {
2136 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2156 a = {{ git = '{}' }}
2161 .file("src/lib.rs", "")
2167 [UPDATING] git repository `[..]`
2168 [COMPILING] a v0.5.0 ([..])
2169 [COMPILING] foo v0.0.1 ([..])
2170 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2177 fn add_a_git_dep() {
2178 let git
= git
::new("git", |p
| {
2179 p
.file("Cargo.toml", &basic_manifest("git", "0.5.0"))
2180 .file("src/lib.rs", "")
2194 a = {{ path = 'a' }}
2195 git = {{ git = '{}' }}
2200 .file("src/lib.rs", "")
2201 .file("a/Cargo.toml", &basic_manifest("a", "0.0.1"))
2202 .file("a/src/lib.rs", "")
2205 p
.cargo("build").run();
2207 File
::create(p
.root().join("a/Cargo.toml"))
2218 git = {{ git = '{}' }}
2226 p
.cargo("build").run();
2230 fn two_at_rev_instead_of_tag() {
2231 let git
= git
::new("git", |p
| {
2232 p
.file("Cargo.toml", &basic_manifest("git1", "0.5.0"))
2233 .file("src/lib.rs", "")
2234 .file("a/Cargo.toml", &basic_manifest("git2", "0.5.0"))
2235 .file("a/src/lib.rs", "")
2238 // Make a tag corresponding to the current HEAD
2239 let repo
= git2
::Repository
::open(&git
.root()).unwrap();
2240 let head
= repo
.head().unwrap().target().unwrap();
2243 &repo
.find_object(head
, None
).unwrap(),
2244 &repo
.signature().unwrap(),
2261 git1 = {{ git = '{0}', rev = 'v0.1.0' }}
2262 git2 = {{ git = '{0}', rev = 'v0.1.0' }}
2267 .file("src/lib.rs", "")
2270 p
.cargo("generate-lockfile").run();
2271 p
.cargo("build -v").run();
2275 fn include_overrides_gitignore() {
2276 // Make sure that `package.include` takes precedence over .gitignore.
2277 let p
= git
::new("foo", |repo
| {
2284 include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
2295 .file("src/lib.rs", "")
2296 .file("ignored.txt", "")
2297 .file("build.rs", "fn main() {}")
2300 p
.cargo("build").run();
2301 p
.change_file("ignored.txt", "Trigger rebuild.");
2305 [COMPILING] foo v0.5.0 ([..])
2306 [RUNNING] `[..]build-script-build[..]`
2307 [RUNNING] `rustc --crate-name foo src/lib.rs [..]`
2308 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2312 p
.cargo("package --list --allow-dirty")
2324 fn invalid_git_dependency_manifest() {
2325 let project
= project();
2326 let git_project
= git
::new("dep1", |project
| {
2335 authors = ["carlhuda@example.com"]
2336 categories = ["algorithms"]
2337 categories = ["algorithms"]
2347 pub fn hello() -> &'static str {
2354 let project
= project
2363 authors = ["wycats@example.com"]
2374 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
2378 let git_root
= git_project
.root();
2383 .with_stderr(&format
!(
2384 "[UPDATING] git repository `{}`\n\
2385 error: failed to load source for a dependency on `dep1`\n\
2388 Unable to update {}\n\
2391 failed to parse manifest at `[..]`\n\
2394 could not parse input as TOML\n\
2397 duplicate key: `categories` for key `project`",
2398 path2url(&git_root
),
2399 path2url(&git_root
),
2405 fn failed_submodule_checkout() {
2406 let project
= project();
2407 let git_project
= git
::new("dep1", |project
| {
2408 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2411 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", ""));
2413 let listener
= TcpListener
::bind("127.0.0.1:0").unwrap();
2414 let addr
= listener
.local_addr().unwrap();
2415 let done
= Arc
::new(AtomicBool
::new(false));
2416 let done2
= done
.clone();
2418 let t
= thread
::spawn(move || {
2419 while !done2
.load(Ordering
::SeqCst
) {
2420 if let Ok((mut socket
, _
)) = listener
.accept() {
2421 drop(socket
.write_all(b
"foo\r\n"));
2426 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
2427 let url
= format
!("https://{}:{}/", addr
.ip(), addr
.port());
2429 let mut s
= repo
.submodule(&url
, Path
::new("bar"), false).unwrap();
2430 let subrepo
= s
.open().unwrap();
2431 let mut cfg
= subrepo
.config().unwrap();
2432 cfg
.set_str("user.email", "foo@bar.com").unwrap();
2433 cfg
.set_str("user.name", "Foo Bar").unwrap();
2434 git
::commit(&subrepo
);
2435 s
.add_finalize().unwrap();
2440 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
2441 let url
= path2url(git_project2
.root()).to_string();
2442 git
::add_submodule(&repo
, &url
, Path
::new("src"));
2446 let project
= project
2457 dep1 = {{ git = '{}' }}
2462 .file("src/lib.rs", "")
2468 .with_stderr_contains(" failed to update submodule `src`")
2469 .with_stderr_contains(" failed to update submodule `bar`")
2474 .with_stderr_contains(" failed to update submodule `src`")
2475 .with_stderr_contains(" failed to update submodule `bar`")
2478 done
.store(true, Ordering
::SeqCst
);
2479 drop(TcpStream
::connect(&addr
));
2485 if disable_git_cli() {
2488 let project
= project();
2489 let git_project
= git
::new("dep1", |project
| {
2491 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2492 .file("src/lib.rs", "")
2495 let project
= project
2506 dep1 = {{ git = '{}' }}
2511 .file("src/lib.rs", "")
2516 git-fetch-with-cli = true
2522 [UPDATING] git repository `[..]`
2523 [RUNNING] `git fetch [..]`
2524 [COMPILING] dep1 [..]
2525 [RUNNING] `rustc [..]`
2526 [COMPILING] foo [..]
2527 [RUNNING] `rustc [..]`
2531 project
.cargo("build -v").with_stderr(stderr
).run();
2535 fn templatedir_doesnt_cause_problems() {
2536 let git_project2
= git
::new("dep2", |project
| {
2538 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
2539 .file("src/lib.rs", "")
2541 let git_project
= git
::new("dep1", |project
| {
2543 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2544 .file("src/lib.rs", "")
2557 dep1 = {{ git = '{}' }}
2562 .file("src/main.rs", "fn main() {}")
2565 File
::create(paths
::home().join(".gitconfig"))
2585 p
.cargo("build").run();
2589 fn git_with_cli_force() {
2590 if disable_git_cli() {
2593 // Supports a force-pushed repo.
2594 let git_project
= git
::new("dep1", |project
| {
2596 .file("Cargo.toml", &basic_lib_manifest("dep1"))
2597 .file("src/lib.rs", r
#"pub fn f() { println!("one"); }"#)
2610 dep1 = {{ git = "{}" }}
2615 .file("src
/main
.rs
", "fn main() { dep1::f(); }
")
2620 git
-fetch
-with
-cli
= true
2624 p.cargo("build
").run();
2625 p.rename_run("foo
", "foo1
").with_stdout("one
").run();
2627 // commit --amend a change that will require a force fetch.
2628 let repo = git2::Repository::open(&git_project.root()).unwrap();
2629 git_project.change_file("src
/lib
.rs
", r#"pub fn f() { println!("two"); }
"#);
2631 let id = repo.refname_to_id("HEAD
").unwrap();
2632 let commit = repo.find_commit(id).unwrap();
2633 let tree_id = t!(t!(repo.index()).write_tree());
2640 Some(&t!(repo.find_tree(tree_id)))
2642 // Perform the fetch.
2643 p.cargo("update
").run();
2644 p.cargo("build
").run();
2645 p.rename_run("foo
", "foo2
").with_stdout("two
").run();
2649 fn git_fetch_cli_env_clean() {
2650 if disable_git_cli() {
2653 // This tests that git-fetch-with-cli works when GIT_DIR environment
2654 // variable is set (for whatever reason).
2655 let git_dep = git::new("dep1
", |project| {
2657 .file("Cargo
.toml
", &basic_manifest("dep1
", "0.5.0"))
2658 .file("src
/lib
.rs
", "")
2661 let git_proj = git::new("foo
", |project| {
2671 dep1
= {{ git = '{}'
}}
2676 .file("src
/lib
.rs
", "pub extern crate dep1
;")
2681 git
-fetch
-with
-cli
= true
2686 // The directory set here isn't too important. Pointing to our own git
2687 // directory causes git to be confused and fail. Can also point to an
2688 // empty directory, or a nonexistent one.
2691 .env("GIT_DIR
", git_proj.root().join(".git
"))