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 {
49 authors = ["wycats@example.com"]
60 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
64 let git_root
= git_project
.root();
68 .with_stderr(&format
!(
69 "[UPDATING] git repository `{}`\n\
70 [COMPILING] dep1 v0.5.0 ({}#[..])\n\
71 [COMPILING] foo v0.5.0 ([CWD])\n\
72 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
78 assert
!(project
.bin("foo").is_file());
81 .process(&project
.bin("foo"))
82 .with_stdout("hello world\n")
87 fn cargo_compile_git_dep_branch() {
88 let project
= project();
89 let git_project
= git
::new("dep1", |project
| {
91 .file("Cargo.toml", &basic_lib_manifest("dep1"))
95 pub fn hello() -> &'static str {
103 // Make a new branch based on the current HEAD commit
104 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
105 let head
= repo
.head().unwrap().target().unwrap();
106 let head
= repo
.find_commit(head
).unwrap();
107 repo
.branch("branchy", &head
, true).unwrap();
109 let project
= project
118 authors = ["wycats@example.com"]
131 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
135 let git_root
= git_project
.root();
139 .with_stderr(&format
!(
140 "[UPDATING] git repository `{}`\n\
141 [COMPILING] dep1 v0.5.0 ({}?branch=branchy#[..])\n\
142 [COMPILING] foo v0.5.0 ([CWD])\n\
143 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
149 assert
!(project
.bin("foo").is_file());
152 .process(&project
.bin("foo"))
153 .with_stdout("hello world\n")
158 fn cargo_compile_git_dep_tag() {
159 let project
= project();
160 let git_project
= git
::new("dep1", |project
| {
162 .file("Cargo.toml", &basic_lib_manifest("dep1"))
166 pub fn hello() -> &'static str {
174 // Make a tag corresponding to the current HEAD
175 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
176 let head
= repo
.head().unwrap().target().unwrap();
179 &repo
.find_object(head
, None
).unwrap(),
180 &repo
.signature().unwrap(),
186 let project
= project
195 authors = ["wycats@example.com"]
207 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
211 let git_root
= git_project
.root();
215 .with_stderr(&format
!(
216 "[UPDATING] git repository `{}`\n\
217 [COMPILING] dep1 v0.5.0 ({}?tag=v0.1.0#[..])\n\
218 [COMPILING] foo v0.5.0 ([CWD])\n\
219 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
225 assert
!(project
.bin("foo").is_file());
228 .process(&project
.bin("foo"))
229 .with_stdout("hello world\n")
232 project
.cargo("build").run();
236 fn cargo_compile_with_nested_paths() {
237 let git_project
= git
::new("dep1", |project
| {
246 authors = ["carlhuda@example.com"]
263 pub fn hello() -> &'static str {
268 .file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2"))
270 "vendor/dep2/src/dep2.rs",
272 pub fn hello() -> &'static str {
289 authors = ["wycats@example.com"]
305 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
309 p
.cargo("build").run();
311 assert
!(p
.bin("foo").is_file());
313 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
317 fn cargo_compile_with_malformed_nested_paths() {
318 let git_project
= git
::new("dep1", |project
| {
320 .file("Cargo.toml", &basic_lib_manifest("dep1"))
324 pub fn hello() -> &'static str {
329 .file("vendor/dep2/Cargo.toml", "!INVALID!")
342 authors = ["wycats@example.com"]
358 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
362 p
.cargo("build").run();
364 assert
!(p
.bin("foo").is_file());
366 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
370 fn cargo_compile_with_meta_package() {
371 let git_project
= git
::new("meta-dep", |project
| {
373 .file("dep1/Cargo.toml", &basic_lib_manifest("dep1"))
377 pub fn hello() -> &'static str {
382 .file("dep2/Cargo.toml", &basic_lib_manifest("dep2"))
386 pub fn hello() -> &'static str {
403 authors = ["wycats@example.com"]
426 r
#""{} {}", dep1::hello(), dep2::hello()"#,
432 p
.cargo("build").run();
434 assert
!(p
.bin("foo").is_file());
436 p
.process(&p
.bin("foo"))
437 .with_stdout("this is dep1 this is dep2\n")
442 fn cargo_compile_with_short_ssh_git() {
443 let url
= "git@github.com:a/dep";
454 authors = ["wycats@example.com"]
469 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
476 .with_stderr(&format
!(
478 [ERROR] failed to parse manifest at `[..]`
481 invalid url `{}`: relative URL without a base
489 fn two_revs_same_deps() {
490 let bar
= git
::new("meta-dep", |project
| {
492 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
493 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
497 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
498 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
500 // Commit the changes and make sure we trigger a recompile
501 File
::create(&bar
.root().join("src/lib.rs"))
503 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
506 let rev2
= git
::commit(&repo
);
536 assert_eq!(bar::bar(), 1);
537 assert_eq!(baz::baz(), 2);
566 pub fn baz() -> i32 { bar::bar() }
571 foo
.cargo("build -v").run();
572 assert
!(foo
.bin("foo").is_file());
573 foo
.process(&foo
.bin("foo")).run();
578 let git_project
= git
::new("bar", |project
| {
580 .file("Cargo.toml", &basic_lib_manifest("bar"))
581 .file("src/bar.rs", "pub fn bar() {}")
594 authors = ["wycats@example.com"]
604 .file("src/main.rs", &main_file(r
#""{:?}", bar::bar()"#, &["bar"]))
607 // First time around we should compile both foo and bar
609 .with_stderr(&format
!(
610 "[UPDATING] git repository `{}`\n\
611 [COMPILING] bar v0.5.0 ({}#[..])\n\
612 [COMPILING] foo v0.5.0 ([CWD])\n\
613 [FINISHED] dev [unoptimized + debuginfo] target(s) \
620 // Don't recompile the second time
621 p
.cargo("build").with_stdout("").run();
623 // Modify a file manually, shouldn't trigger a recompile
624 File
::create(&git_project
.root().join("src/bar.rs"))
626 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
629 p
.cargo("build").with_stdout("").run();
632 .with_stderr(&format
!(
633 "[UPDATING] git repository `{}`",
638 p
.cargo("build").with_stdout("").run();
640 // Commit the changes and make sure we don't trigger a recompile because the
641 // lock file says not to change
642 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
646 println
!("compile after commit");
647 p
.cargo("build").with_stdout("").run();
648 p
.root().move_into_the_past();
650 // Update the dependency and carry on!
652 .with_stderr(&format
!(
653 "[UPDATING] git repository `{}`\n\
654 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
659 println
!("going for the last compile");
661 .with_stderr(&format
!(
662 "[COMPILING] bar v0.5.0 ({}#[..])\n\
663 [COMPILING] foo v0.5.0 ([CWD])\n\
664 [FINISHED] dev [unoptimized + debuginfo] target(s) \
670 // Make sure clean only cleans one dep
671 p
.cargo("clean -p foo").with_stdout("").run();
674 "[COMPILING] foo v0.5.0 ([CWD])\n\
675 [FINISHED] dev [unoptimized + debuginfo] target(s) \
682 fn update_with_shared_deps() {
683 let git_project
= git
::new("bar", |project
| {
685 .file("Cargo.toml", &basic_lib_manifest("bar"))
686 .file("src/bar.rs", "pub fn bar() {}")
697 authors = ["wycats@example.com"]
708 #[allow(unused_extern_crates)]
710 #[allow(unused_extern_crates)]
722 authors = ["wycats@example.com"]
731 .file("dep1/src/lib.rs", "")
739 authors = ["wycats@example.com"]
748 .file("dep2/src/lib.rs", "")
751 // First time around we should compile both foo and bar
753 .with_stderr(&format
!(
755 [UPDATING] git repository `{git}`
756 [COMPILING] bar v0.5.0 ({git}#[..])
757 [COMPILING] [..] v0.5.0 ([..])
758 [COMPILING] [..] v0.5.0 ([..])
759 [COMPILING] foo v0.5.0 ([CWD])
760 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
761 git
= git_project
.url(),
765 // Modify a file manually, and commit it
766 File
::create(&git_project
.root().join("src/bar.rs"))
768 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
770 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
771 let old_head
= repo
.head().unwrap().target().unwrap();
777 // By default, not transitive updates
778 println
!("dep1 update");
779 p
.cargo("update -p dep1").with_stdout("").run();
781 // Don't do anything bad on a weird --precise argument
782 println
!("bar bad precise update");
783 p
.cargo("update -p bar --precise 0.1.2")
787 [UPDATING] git repository [..]
788 [ERROR] Unable to update [..]
791 revspec '0.1.2' not found; [..]
796 // Specifying a precise rev to the old rev shouldn't actually update
797 // anything because we already have the rev in the db.
798 println
!("bar precise update");
799 p
.cargo("update -p bar --precise")
800 .arg(&old_head
.to_string())
804 // Updating aggressively should, however, update the repo.
805 println
!("dep1 aggressive update");
806 p
.cargo("update -p dep1 --aggressive")
807 .with_stderr(&format
!(
808 "[UPDATING] git repository `{}`\n\
809 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
815 // Make sure we still only compile one version of the git repo
818 .with_stderr(&format
!(
820 [COMPILING] bar v0.5.0 ({git}#[..])
821 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
822 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
823 [COMPILING] foo v0.5.0 ([CWD])
824 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
825 git
= git_project
.url(),
829 // We should be able to update transitive deps
830 p
.cargo("update -p bar")
831 .with_stderr(&format
!(
832 "[UPDATING] git repository `{}`",
839 fn dep_with_submodule() {
840 let project
= project();
841 let git_project
= git
::new("dep1", |project
| {
842 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
846 git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}")).unwrap();
848 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
849 let url
= path2url(git_project2
.root()).to_string();
850 git
::add_submodule(&repo
, &url
, Path
::new("src"));
853 let project
= project
862 authors = ["wycats@example.com"]
873 "extern crate dep1; pub fn foo() { dep1::dep() }",
881 [UPDATING] git repository [..]
882 [COMPILING] dep1 [..]
884 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
890 fn dep_with_bad_submodule() {
891 let project
= project();
892 let git_project
= git
::new("dep1", |project
| {
893 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
897 git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}")).unwrap();
899 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
900 let url
= path2url(git_project2
.root()).to_string();
901 git
::add_submodule(&repo
, &url
, Path
::new("src"));
904 // now amend the first commit on git_project2 to make submodule ref point to not-found
906 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
907 let original_submodule_ref
= repo
.refname_to_id("refs/heads/master").unwrap();
908 let commit
= repo
.find_commit(original_submodule_ref
).unwrap();
911 Some("refs/heads/master"),
915 Some("something something"),
929 authors = ["wycats@example.com"]
940 "extern crate dep1; pub fn foo() { dep1::dep() }",
944 let expected
= format
!(
946 [UPDATING] git repository [..]
947 [ERROR] failed to load source for a dependency on `dep1`
953 failed to update submodule `src`
956 object not found - no match for id [..]
958 path2url(git_project
.root())
962 .with_stderr(expected
)
968 fn two_deps_only_update_one() {
969 let project
= project();
970 let git1
= git
::new("dep1", |project
| {
972 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
973 .file("src/lib.rs", "")
976 let git2
= git
::new("dep2", |project
| {
978 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
979 .file("src/lib.rs", "")
992 authors = ["wycats@example.com"]
1003 .file("src/main.rs", "fn main() {}")
1006 fn oid_to_short_sha(oid
: git2
::Oid
) -> String
{
1007 oid
.to_string()[..8].to_string()
1009 fn git_repo_head_sha(p
: &Project
) -> String
{
1010 let repo
= git2
::Repository
::open(p
.root()).unwrap();
1011 let head
= repo
.head().unwrap().target().unwrap();
1012 oid_to_short_sha(head
)
1015 println
!("dep1 head sha: {}", git_repo_head_sha(&git1
));
1016 println
!("dep2 head sha: {}", git_repo_head_sha(&git2
));
1020 "[UPDATING] git repository `[..]`\n\
1021 [UPDATING] git repository `[..]`\n\
1022 [COMPILING] [..] v0.5.0 ([..])\n\
1023 [COMPILING] [..] v0.5.0 ([..])\n\
1024 [COMPILING] foo v0.5.0 ([CWD])\n\
1025 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1029 File
::create(&git1
.root().join("src/lib.rs"))
1031 .write_all(br
#"pub fn foo() {}"#)
1033 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
1035 let oid
= git
::commit(&repo
);
1036 println
!("dep1 head sha: {}", oid_to_short_sha(oid
));
1038 p
.cargo("update -p dep1")
1039 .with_stderr(&format
!(
1040 "[UPDATING] git repository `{}`\n\
1041 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1049 fn stale_cached_version() {
1050 let bar
= git
::new("meta-dep", |project
| {
1052 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
1053 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1057 // Update the git database in the cache with the current state of the git
1080 fn main() { assert_eq!(bar::bar(), 1) }
1085 foo
.cargo("build").run();
1086 foo
.process(&foo
.bin("foo")).run();
1088 // Update the repo, and simulate someone else updating the lock file and then
1089 // us pulling it down.
1090 File
::create(&bar
.root().join("src/lib.rs"))
1092 .write_all(br
#"pub fn bar() -> i32 { 1 + 0 }"#)
1094 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1100 let rev
= repo
.revparse_single("HEAD").unwrap().id();
1102 File
::create(&foo
.root().join("Cargo.lock"))
1111 'bar 0.0.0 (git+{url}#{hash})'
1117 source = 'git+{url}#{hash}'
1128 .with_stderr(&format
!(
1130 [UPDATING] git repository `{bar}`
1131 [COMPILING] bar v0.0.0 ({bar}#[..])
1132 [COMPILING] foo v0.0.0 ([CWD])
1133 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1138 foo
.process(&foo
.bin("foo")).run();
1142 fn dep_with_changed_submodule() {
1143 let project
= project();
1144 let git_project
= git
::new("dep1", |project
| {
1145 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
1149 let git_project2
= git
::new("dep2", |project
| {
1150 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
1154 let git_project3
= git
::new("dep3", |project
| {
1155 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
1159 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
1160 let mut sub
= git
::add_submodule(&repo
, &git_project2
.url().to_string(), Path
::new("src"));
1171 authors = ["wycats@example.com"]
1182 pub fn main() { println!(\"{}\", dep1::dep()) }
1187 println
!("first run");
1190 "[UPDATING] git repository `[..]`\n\
1191 [COMPILING] dep1 v0.5.0 ([..])\n\
1192 [COMPILING] foo v0.5.0 ([..])\n\
1193 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1195 [RUNNING] `target/debug/foo[EXE]`\n",
1197 .with_stdout("project2\n")
1200 File
::create(&git_project
.root().join(".gitmodules"))
1204 "[submodule \"src\"]\n\tpath = src\n\turl={}",
1211 // Sync the submodule and reset it to the new remote.
1212 sub
.sync().unwrap();
1214 let subrepo
= sub
.open().unwrap();
1216 .remote_add_fetch("origin", "refs/heads/*:refs/heads/*")
1219 .remote_set_url("origin", &git_project3
.url().to_string())
1221 let mut origin
= subrepo
.find_remote("origin").unwrap();
1222 origin
.fetch(&[], None
, None
).unwrap();
1223 let id
= subrepo
.refname_to_id("refs/remotes/origin/master").unwrap();
1224 let obj
= subrepo
.find_object(id
, None
).unwrap();
1225 subrepo
.reset(&obj
, git2
::ResetType
::Hard
, None
).unwrap();
1227 sub
.add_to_index(true).unwrap();
1232 // Update the dependency and carry on!
1234 p
.cargo("update -v")
1236 .with_stderr(&format
!(
1237 "[UPDATING] git repository `{}`\n\
1238 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1244 println
!("last run");
1247 "[COMPILING] dep1 v0.5.0 ([..])\n\
1248 [COMPILING] foo v0.5.0 ([..])\n\
1249 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1251 [RUNNING] `target/debug/foo[EXE]`\n",
1253 .with_stdout("project3\n")
1258 fn dev_deps_with_testing() {
1259 let p2
= git
::new("bar", |project
| {
1261 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1265 pub fn gimme() -> &'static str { "zoidberg" }
1280 authors = ["wycats@example.com"]
1282 [dev-dependencies.bar]
1297 #[test] fn foo() { bar::gimme(); }
1303 // Generate a lock file which did not use `bar` to compile, but had to update
1304 // `bar` to generate the lock file
1306 .with_stderr(&format
!(
1308 [UPDATING] git repository `{bar}`
1309 [COMPILING] foo v0.5.0 ([CWD])
1310 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1316 // Make sure we use the previous resolution of `bar` instead of updating it
1321 [COMPILING] [..] v0.5.0 ([..])
1322 [COMPILING] [..] v0.5.0 ([..]
1323 [FINISHED] test [unoptimized + debuginfo] target(s) in [..]
1324 [RUNNING] target/debug/deps/foo-[..][EXE]",
1326 .with_stdout_contains("test tests::foo ... ok")
1331 fn git_build_cmd_freshness() {
1332 let foo
= git
::new("foo", |project
| {
1344 .file("build.rs", "fn main() {}")
1345 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1346 .file(".gitignore", "src/bar.rs")
1349 foo
.root().move_into_the_past();
1356 [COMPILING] foo v0.0.0 ([CWD])
1357 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1362 // Smoke test to make sure it doesn't compile again
1363 println
!("first pass");
1364 foo
.cargo("build").with_stdout("").run();
1366 // Modify an ignored file and make sure we don't rebuild
1367 println
!("second pass");
1368 File
::create(&foo
.root().join("src/bar.rs")).unwrap();
1369 foo
.cargo("build").with_stdout("").run();
1373 fn git_name_not_always_needed() {
1374 let p2
= git
::new("bar", |project
| {
1376 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1380 pub fn gimme() -> &'static str { "zoidberg" }
1386 let repo
= git2
::Repository
::open(&p2
.root()).unwrap();
1387 let mut cfg
= repo
.config().unwrap();
1388 let _
= cfg
.remove("user.name");
1389 let _
= cfg
.remove("user.email");
1401 [dev-dependencies.bar]
1407 .file("src/main.rs", "fn main() {}")
1410 // Generate a lock file which did not use `bar` to compile, but had to update
1411 // `bar` to generate the lock file
1413 .with_stderr(&format
!(
1415 [UPDATING] git repository `{bar}`
1416 [COMPILING] foo v0.5.0 ([CWD])
1417 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1425 fn git_repo_changing_no_rebuild() {
1426 let bar
= git
::new("bar", |project
| {
1428 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1429 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1433 // Lock p1 to the first rev in the git repo
1451 .file("src/main.rs", "fn main() {}")
1452 .file("build.rs", "fn main() {}")
1454 p1
.root().move_into_the_past();
1456 .with_stderr(&format
!(
1458 [UPDATING] git repository `{bar}`
1461 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1467 // Make a commit to lock p2 to a different rev
1468 File
::create(&bar
.root().join("src/lib.rs"))
1470 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1472 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1476 // Lock p2 to the second rev
1493 .file("src/main.rs", "fn main() {}")
1496 .with_stderr(&format
!(
1498 [UPDATING] git repository `{bar}`
1501 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1507 // And now for the real test! Make sure that p1 doesn't get rebuilt
1508 // even though the git repo has changed.
1509 p1
.cargo("build").with_stdout("").run();
1513 fn git_dep_build_cmd() {
1514 let p
= git
::new("foo", |project
| {
1523 authors = ["wycats@example.com"]
1535 .file("src/foo.rs", &main_file(r
#""{}", bar::gimme()"#, &["bar"]))
1543 authors = ["wycats@example.com"]
1552 "bar/src/bar.rs.in",
1554 pub fn gimme() -> i32 { 0 }
1562 fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
1569 p
.root().join("bar").move_into_the_past();
1571 p
.cargo("build").run();
1573 p
.process(&p
.bin("foo")).with_stdout("0\n").run();
1575 // Touching bar.rs.in should cause the `build` command to run again.
1576 fs
::File
::create(&p
.root().join("bar/src/bar.rs.in"))
1578 .write_all(b
"pub fn gimme() -> i32 { 1 }")
1581 p
.cargo("build").run();
1583 p
.process(&p
.bin("foo")).with_stdout("1\n").run();
1587 fn fetch_downloads() {
1588 let bar
= git
::new("bar", |project
| {
1590 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1591 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1610 .file("src/main.rs", "fn main() {}")
1613 .with_stderr(&format
!(
1614 "[UPDATING] git repository `{url}`",
1619 p
.cargo("fetch").with_stdout("").run();
1623 fn warnings_in_git_dep() {
1624 let bar
= git
::new("bar", |project
| {
1626 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1627 .file("src/lib.rs", "fn unused() {}")
1646 .file("src/main.rs", "fn main() {}")
1650 .with_stderr(&format
!(
1651 "[UPDATING] git repository `{}`\n\
1652 [COMPILING] bar v0.5.0 ({}#[..])\n\
1653 [COMPILING] foo v0.5.0 ([CWD])\n\
1654 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1662 fn update_ambiguous() {
1663 let bar1
= git
::new("bar1", |project
| {
1665 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1666 .file("src/lib.rs", "")
1669 let bar2
= git
::new("bar2", |project
| {
1671 .file("Cargo.toml", &basic_manifest("bar", "0.6.0"))
1672 .file("src/lib.rs", "")
1675 let baz
= git
::new("baz", |project
| {
1684 authors = ["wycats@example.com"]
1692 .file("src/lib.rs", "")
1714 .file("src/main.rs", "fn main() {}")
1717 p
.cargo("generate-lockfile").run();
1718 p
.cargo("update -p bar")
1722 [ERROR] There are multiple `bar` packages in your project, and the specification `bar` \
1724 Please re-run this command with `-p <spec>` where `<spec>` is one of the \
1734 fn update_one_dep_in_repo_with_many_deps() {
1735 let bar
= git
::new("bar", |project
| {
1737 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1738 .file("src/lib.rs", "")
1739 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1740 .file("a/src/lib.rs", "")
1762 .file("src/main.rs", "fn main() {}")
1765 p
.cargo("generate-lockfile").run();
1766 p
.cargo("update -p bar")
1767 .with_stderr(&format
!("[UPDATING] git repository `{}`", bar
.url()))
1772 fn switch_deps_does_not_update_transitive() {
1773 let transitive
= git
::new("transitive", |project
| {
1775 .file("Cargo.toml", &basic_manifest("transitive", "0.5.0"))
1776 .file("src/lib.rs", "")
1779 let dep1
= git
::new("dep1", |project
| {
1788 authors = ["wycats@example.com"]
1790 [dependencies.transitive]
1796 .file("src/lib.rs", "")
1799 let dep2
= git
::new("dep2", |project
| {
1808 authors = ["wycats@example.com"]
1810 [dependencies.transitive]
1816 .file("src/lib.rs", "")
1835 .file("src/main.rs", "fn main() {}")
1839 .with_stderr(&format
!(
1841 [UPDATING] git repository `{}`
1842 [UPDATING] git repository `{}`
1843 [COMPILING] transitive [..]
1844 [COMPILING] dep [..]
1845 [COMPILING] foo [..]
1846 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1853 // Update the dependency to point to the second repository, but this
1854 // shouldn't update the transitive dependency which is the same.
1855 File
::create(&p
.root().join("Cargo.toml"))
1874 .with_stderr(&format
!(
1876 [UPDATING] git repository `{}`
1877 [COMPILING] dep [..]
1878 [COMPILING] foo [..]
1879 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1887 fn update_one_source_updates_all_packages_in_that_git_source() {
1888 let dep
= git
::new("dep", |project
| {
1902 .file("src/lib.rs", "")
1903 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1904 .file("a/src/lib.rs", "")
1923 .file("src/main.rs", "fn main() {}")
1926 p
.cargo("build").run();
1928 let repo
= git2
::Repository
::open(&dep
.root()).unwrap();
1929 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
1931 // Just be sure to change a file
1932 File
::create(&dep
.root().join("src/lib.rs"))
1934 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1939 p
.cargo("update -p dep").run();
1940 let mut lockfile
= String
::new();
1941 File
::open(&p
.root().join("Cargo.lock"))
1943 .read_to_string(&mut lockfile
)
1946 !lockfile
.contains(&rev1
.to_string()),
1954 fn switch_sources() {
1955 let a1
= git
::new("a1", |project
| {
1957 .file("Cargo.toml", &basic_manifest("a", "0.5.0"))
1958 .file("src/lib.rs", "")
1961 let a2
= git
::new("a2", |project
| {
1963 .file("Cargo.toml", &basic_manifest("a", "0.5.1"))
1964 .file("src/lib.rs", "")
1980 .file("src/main.rs", "fn main() {}")
1995 .file("b/src/lib.rs", "pub fn main() {}")
2001 [UPDATING] git repository `file://[..]a1`
2002 [COMPILING] a v0.5.0 ([..]a1#[..]
2003 [COMPILING] b v0.5.0 ([..])
2004 [COMPILING] foo v0.5.0 ([..])
2005 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2010 File
::create(&p
.root().join("b/Cargo.toml"))
2031 [UPDATING] git repository `file://[..]a2`
2032 [COMPILING] a v0.5.1 ([..]a2#[..]
2033 [COMPILING] b v0.5.0 ([..])
2034 [COMPILING] foo v0.5.0 ([..])
2035 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2042 fn dont_require_submodules_are_checked_out() {
2043 let p
= project().build();
2044 let git1
= git
::new("dep1", |p
| {
2055 .file("build.rs", "fn main() {}")
2056 .file("src/lib.rs", "")
2060 let git2
= git
::new("dep2", |p
| p
).unwrap();
2062 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
2063 let url
= path2url(git2
.root()).to_string();
2064 git
::add_submodule(&repo
, &url
, Path
::new("a/submodule"));
2067 git2
::Repository
::init(&p
.root()).unwrap();
2068 let url
= path2url(git1
.root()).to_string();
2069 let dst
= paths
::home().join("foo");
2070 git2
::Repository
::clone(&url
, &dst
).unwrap();
2072 git1
.cargo("build -v").cwd(&dst
).run();
2076 fn doctest_same_name() {
2077 let a2
= git
::new("a2", |p
| {
2078 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0"))
2079 .file("src/lib.rs", "pub fn a2() {}")
2083 let a1
= git
::new("a1", |p
| {
2093 a = {{ git = '{}' }}
2098 .file("src/lib.rs", "extern crate a; pub fn a1() {}")
2113 a = {{ git = '{}' }}
2127 p
.cargo("test -v").run();
2131 fn lints_are_suppressed() {
2132 let a
= git
::new("a", |p
| {
2133 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2153 a = {{ git = '{}' }}
2158 .file("src/lib.rs", "")
2164 [UPDATING] git repository `[..]`
2165 [COMPILING] a v0.5.0 ([..])
2166 [COMPILING] foo v0.0.1 ([..])
2167 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2174 fn denied_lints_are_allowed() {
2175 let a
= git
::new("a", |p
| {
2176 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2197 a = {{ git = '{}' }}
2202 .file("src/lib.rs", "")
2208 [UPDATING] git repository `[..]`
2209 [COMPILING] a v0.5.0 ([..])
2210 [COMPILING] foo v0.0.1 ([..])
2211 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2218 fn add_a_git_dep() {
2219 let git
= git
::new("git", |p
| {
2220 p
.file("Cargo.toml", &basic_manifest("git", "0.5.0"))
2221 .file("src/lib.rs", "")
2236 a = {{ path = 'a' }}
2237 git = {{ git = '{}' }}
2242 .file("src/lib.rs", "")
2243 .file("a/Cargo.toml", &basic_manifest("a", "0.0.1"))
2244 .file("a/src/lib.rs", "")
2247 p
.cargo("build").run();
2249 File
::create(p
.root().join("a/Cargo.toml"))
2260 git = {{ git = '{}' }}
2268 p
.cargo("build").run();
2272 fn two_at_rev_instead_of_tag() {
2273 let git
= git
::new("git", |p
| {
2274 p
.file("Cargo.toml", &basic_manifest("git1", "0.5.0"))
2275 .file("src/lib.rs", "")
2276 .file("a/Cargo.toml", &basic_manifest("git2", "0.5.0"))
2277 .file("a/src/lib.rs", "")
2281 // Make a tag corresponding to the current HEAD
2282 let repo
= git2
::Repository
::open(&git
.root()).unwrap();
2283 let head
= repo
.head().unwrap().target().unwrap();
2286 &repo
.find_object(head
, None
).unwrap(),
2287 &repo
.signature().unwrap(),
2304 git1 = {{ git = '{0}', rev = 'v0.1.0' }}
2305 git2 = {{ git = '{0}', rev = 'v0.1.0' }}
2310 .file("src/lib.rs", "")
2313 p
.cargo("generate-lockfile").run();
2314 p
.cargo("build -v").run();
2318 fn include_overrides_gitignore() {
2319 // Make sure that `package.include` takes precedence over .gitignore.
2320 let p
= git
::new("foo", |repo
| {
2327 include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
2338 .file("src/lib.rs", "")
2339 .file("ignored.txt", "")
2340 .file("build.rs", "fn main() {}")
2344 p
.cargo("build").run();
2345 p
.change_file("ignored.txt", "Trigger rebuild.");
2349 [COMPILING] foo v0.5.0 ([..])
2350 [RUNNING] `[..]build-script-build[..]`
2351 [RUNNING] `rustc --crate-name foo src/lib.rs [..]`
2352 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2356 p
.cargo("package --list --allow-dirty")
2368 fn invalid_git_dependency_manifest() {
2369 let project
= project();
2370 let git_project
= git
::new("dep1", |project
| {
2379 authors = ["carlhuda@example.com"]
2380 categories = ["algorithms"]
2381 categories = ["algorithms"]
2391 pub fn hello() -> &'static str {
2399 let project
= project
2408 authors = ["wycats@example.com"]
2419 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
2423 let git_root
= git_project
.root();
2428 .with_stderr(&format
!(
2429 "[UPDATING] git repository `{}`\n\
2430 error: failed to load source for a dependency on `dep1`\n\
2433 Unable to update {}\n\
2436 failed to parse manifest at `[..]`\n\
2439 could not parse input as TOML\n\
2442 duplicate key: `categories` for key `project`",
2443 path2url(&git_root
),
2444 path2url(&git_root
),
2450 fn failed_submodule_checkout() {
2451 let project
= project();
2452 let git_project
= git
::new("dep1", |project
| {
2453 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2457 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", "")).unwrap();
2459 let listener
= TcpListener
::bind("127.0.0.1:0").unwrap();
2460 let addr
= listener
.local_addr().unwrap();
2461 let done
= Arc
::new(AtomicBool
::new(false));
2462 let done2
= done
.clone();
2464 let t
= thread
::spawn(move || {
2465 while !done2
.load(Ordering
::SeqCst
) {
2466 if let Ok((mut socket
, _
)) = listener
.accept() {
2467 drop(socket
.write_all(b
"foo\r\n"));
2472 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
2473 let url
= format
!("https://{}:{}/", addr
.ip(), addr
.port());
2475 let mut s
= repo
.submodule(&url
, Path
::new("bar"), false).unwrap();
2476 let subrepo
= s
.open().unwrap();
2477 let mut cfg
= subrepo
.config().unwrap();
2478 cfg
.set_str("user.email", "foo@bar.com").unwrap();
2479 cfg
.set_str("user.name", "Foo Bar").unwrap();
2480 git
::commit(&subrepo
);
2481 s
.add_finalize().unwrap();
2486 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
2487 let url
= path2url(git_project2
.root()).to_string();
2488 git
::add_submodule(&repo
, &url
, Path
::new("src"));
2492 let project
= project
2503 dep1 = {{ git = '{}' }}
2508 .file("src/lib.rs", "")
2514 .with_stderr_contains(" failed to update submodule `src`")
2515 .with_stderr_contains(" failed to update submodule `bar`")
2520 .with_stderr_contains(" failed to update submodule `src`")
2521 .with_stderr_contains(" failed to update submodule `bar`")
2524 done
.store(true, Ordering
::SeqCst
);
2525 drop(TcpStream
::connect(&addr
));
2531 if disable_git_cli() {
2534 let project
= project();
2535 let git_project
= git
::new("dep1", |project
| {
2537 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2538 .file("src/lib.rs", "")
2542 let project
= project
2553 dep1 = {{ git = '{}' }}
2558 .file("src/lib.rs", "")
2563 git-fetch-with-cli = true
2569 [UPDATING] git repository `[..]`
2570 [RUNNING] `git fetch [..]`
2571 [COMPILING] dep1 [..]
2572 [RUNNING] `rustc [..]`
2573 [COMPILING] foo [..]
2574 [RUNNING] `rustc [..]`
2578 project
.cargo("build -v").with_stderr(stderr
).run();
2582 fn templatedir_doesnt_cause_problems() {
2583 let git_project2
= git
::new("dep2", |project
| {
2585 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
2586 .file("src/lib.rs", "")
2589 let git_project
= git
::new("dep1", |project
| {
2591 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2592 .file("src/lib.rs", "")
2606 dep1 = {{ git = '{}' }}
2611 .file("src/main.rs", "fn main() {}")
2614 File
::create(paths
::home().join(".gitconfig"))
2634 p
.cargo("build").run();
2638 fn git_with_cli_force() {
2639 if disable_git_cli() {
2642 // Supports a force-pushed repo.
2643 let git_project
= git
::new("dep1", |project
| {
2645 .file("Cargo.toml", &basic_lib_manifest("dep1"))
2646 .file("src/lib.rs", r
#"pub fn f() { println!("one"); }"#)
2660 dep1 = {{ git = "{}" }}
2665 .file("src
/main
.rs
", "fn main() { dep1::f(); }
")
2670 git
-fetch
-with
-cli
= true
2674 p.cargo("build
").run();
2675 p.rename_run("foo
", "foo1
").with_stdout("one
").run();
2677 // commit --amend a change that will require a force fetch.
2678 let repo = git2::Repository::open(&git_project.root()).unwrap();
2679 git_project.change_file("src
/lib
.rs
", r#"pub fn f() { println!("two"); }
"#);
2681 let id = repo.refname_to_id("HEAD
").unwrap();
2682 let commit = repo.find_commit(id).unwrap();
2683 let tree_id = t!(t!(repo.index()).write_tree());
2690 Some(&t!(repo.find_tree(tree_id)))
2692 // Perform the fetch.
2693 p.cargo("update
").run();
2694 p.cargo("build
").run();
2695 p.rename_run("foo
", "foo2
").with_stdout("two
").run();
2699 fn git_fetch_cli_env_clean() {
2700 if disable_git_cli() {
2703 // This tests that git-fetch-with-cli works when GIT_DIR environment
2704 // variable is set (for whatever reason).
2705 let git_dep = git::new("dep1
", |project| {
2707 .file("Cargo
.toml
", &basic_manifest("dep1
", "0.5.0"))
2708 .file("src
/lib
.rs
", "")
2712 let git_proj = git::new("foo
", |project| {
2722 dep1
= {{ git = '{}'
}}
2727 .file("src
/lib
.rs
", "pub extern crate dep1
;")
2732 git
-fetch
-with
-cli
= true
2738 // The directory set here isn't too important. Pointing to our own git
2739 // directory causes git to be confused and fail. Can also point to an
2740 // empty directory, or a nonexistent one.
2743 .env("GIT_DIR
", git_proj.root().join(".git
"))