1 //! Tests for git support.
5 use std
::fs
::{self, File}
;
6 use std
::io
::prelude
::*;
7 use std
::net
::{TcpListener, TcpStream}
;
9 use std
::sync
::atomic
::{AtomicBool, Ordering}
;
13 use cargo_test_support
::paths
::{self, CargoPathExt}
;
14 use cargo_test_support
::{basic_lib_manifest, basic_manifest, git, main_file, path2url, project}
;
15 use cargo_test_support
::{sleep_ms, t, Project}
;
17 fn disable_git_cli() -> bool
{
18 // mingw git on Windows does not support Windows-style file URIs.
19 // Appveyor in the rust repo has that git up front in the PATH instead
20 // of Git-for-Windows, which causes this to fail.
21 env
::var("CARGO_TEST_DISABLE_GIT_CLI") == Ok("1".to_string())
25 fn cargo_compile_simple_git_dep() {
26 let project
= project();
27 let git_project
= git
::new("dep1", |project
| {
29 .file("Cargo.toml", &basic_lib_manifest("dep1"))
33 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 {
102 // Make a new branch based on the current HEAD commit
103 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
104 let head
= repo
.head().unwrap().target().unwrap();
105 let head
= repo
.find_commit(head
).unwrap();
106 repo
.branch("branchy", &head
, true).unwrap();
108 let project
= project
117 authors = ["wycats@example.com"]
130 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
134 let git_root
= git_project
.root();
138 .with_stderr(&format
!(
139 "[UPDATING] git repository `{}`\n\
140 [COMPILING] dep1 v0.5.0 ({}?branch=branchy#[..])\n\
141 [COMPILING] foo v0.5.0 ([CWD])\n\
142 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
148 assert
!(project
.bin("foo").is_file());
151 .process(&project
.bin("foo"))
152 .with_stdout("hello world\n")
157 fn cargo_compile_git_dep_tag() {
158 let project
= project();
159 let git_project
= git
::new("dep1", |project
| {
161 .file("Cargo.toml", &basic_lib_manifest("dep1"))
165 pub fn hello() -> &'static str {
172 // Make a tag corresponding to the current HEAD
173 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
174 let head
= repo
.head().unwrap().target().unwrap();
177 &repo
.find_object(head
, None
).unwrap(),
178 &repo
.signature().unwrap(),
184 let project
= project
193 authors = ["wycats@example.com"]
205 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
209 let git_root
= git_project
.root();
213 .with_stderr(&format
!(
214 "[UPDATING] git repository `{}`\n\
215 [COMPILING] dep1 v0.5.0 ({}?tag=v0.1.0#[..])\n\
216 [COMPILING] foo v0.5.0 ([CWD])\n\
217 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
223 assert
!(project
.bin("foo").is_file());
226 .process(&project
.bin("foo"))
227 .with_stdout("hello world\n")
230 project
.cargo("build").run();
234 fn cargo_compile_with_nested_paths() {
235 let git_project
= git
::new("dep1", |project
| {
244 authors = ["carlhuda@example.com"]
261 pub fn hello() -> &'static str {
266 .file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2"))
268 "vendor/dep2/src/dep2.rs",
270 pub fn hello() -> &'static str {
286 authors = ["wycats@example.com"]
302 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
306 p
.cargo("build").run();
308 assert
!(p
.bin("foo").is_file());
310 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
314 fn cargo_compile_with_malformed_nested_paths() {
315 let git_project
= git
::new("dep1", |project
| {
317 .file("Cargo.toml", &basic_lib_manifest("dep1"))
321 pub fn hello() -> &'static str {
326 .file("vendor/dep2/Cargo.toml", "!INVALID!")
338 authors = ["wycats@example.com"]
354 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
358 p
.cargo("build").run();
360 assert
!(p
.bin("foo").is_file());
362 p
.process(&p
.bin("foo")).with_stdout("hello world\n").run();
366 fn cargo_compile_with_meta_package() {
367 let git_project
= git
::new("meta-dep", |project
| {
369 .file("dep1/Cargo.toml", &basic_lib_manifest("dep1"))
373 pub fn hello() -> &'static str {
378 .file("dep2/Cargo.toml", &basic_lib_manifest("dep2"))
382 pub fn hello() -> &'static str {
398 authors = ["wycats@example.com"]
421 r
#""{} {}", dep1::hello(), dep2::hello()"#,
427 p
.cargo("build").run();
429 assert
!(p
.bin("foo").is_file());
431 p
.process(&p
.bin("foo"))
432 .with_stdout("this is dep1 this is dep2\n")
437 fn cargo_compile_with_short_ssh_git() {
438 let url
= "git@github.com:a/dep";
449 authors = ["wycats@example.com"]
464 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
471 .with_stderr(&format
!(
473 [ERROR] failed to parse manifest at `[..]`
476 invalid url `{}`: relative URL without a base
484 fn two_revs_same_deps() {
485 let bar
= git
::new("meta-dep", |project
| {
487 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
488 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
491 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
492 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
494 // Commit the changes and make sure we trigger a recompile
495 File
::create(&bar
.root().join("src/lib.rs"))
497 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
500 let rev2
= git
::commit(&repo
);
530 assert_eq!(bar::bar(), 1);
531 assert_eq!(baz::baz(), 2);
560 pub fn baz() -> i32 { bar::bar() }
565 foo
.cargo("build -v").run();
566 assert
!(foo
.bin("foo").is_file());
567 foo
.process(&foo
.bin("foo")).run();
572 let git_project
= git
::new("bar", |project
| {
574 .file("Cargo.toml", &basic_lib_manifest("bar"))
575 .file("src/bar.rs", "pub fn bar() {}")
587 authors = ["wycats@example.com"]
597 .file("src/main.rs", &main_file(r
#""{:?}", bar::bar()"#, &["bar"]))
600 // First time around we should compile both foo and bar
602 .with_stderr(&format
!(
603 "[UPDATING] git repository `{}`\n\
604 [COMPILING] bar v0.5.0 ({}#[..])\n\
605 [COMPILING] foo v0.5.0 ([CWD])\n\
606 [FINISHED] dev [unoptimized + debuginfo] target(s) \
613 // Don't recompile the second time
614 p
.cargo("build").with_stdout("").run();
616 // Modify a file manually, shouldn't trigger a recompile
617 File
::create(&git_project
.root().join("src/bar.rs"))
619 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
622 p
.cargo("build").with_stdout("").run();
625 .with_stderr(&format
!(
626 "[UPDATING] git repository `{}`",
631 p
.cargo("build").with_stdout("").run();
633 // Commit the changes and make sure we don't trigger a recompile because the
634 // lock file says not to change
635 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
639 println
!("compile after commit");
640 p
.cargo("build").with_stdout("").run();
641 p
.root().move_into_the_past();
643 // Update the dependency and carry on!
645 .with_stderr(&format
!(
646 "[UPDATING] git repository `{}`\n\
647 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
652 println
!("going for the last compile");
654 .with_stderr(&format
!(
655 "[COMPILING] bar v0.5.0 ({}#[..])\n\
656 [COMPILING] foo v0.5.0 ([CWD])\n\
657 [FINISHED] dev [unoptimized + debuginfo] target(s) \
663 // Make sure clean only cleans one dep
664 p
.cargo("clean -p foo").with_stdout("").run();
667 "[COMPILING] foo v0.5.0 ([CWD])\n\
668 [FINISHED] dev [unoptimized + debuginfo] target(s) \
675 fn update_with_shared_deps() {
676 let git_project
= git
::new("bar", |project
| {
678 .file("Cargo.toml", &basic_lib_manifest("bar"))
679 .file("src/bar.rs", "pub fn bar() {}")
689 authors = ["wycats@example.com"]
700 #[allow(unused_extern_crates)]
702 #[allow(unused_extern_crates)]
714 authors = ["wycats@example.com"]
723 .file("dep1/src/lib.rs", "")
731 authors = ["wycats@example.com"]
740 .file("dep2/src/lib.rs", "")
743 // First time around we should compile both foo and bar
745 .with_stderr(&format
!(
747 [UPDATING] git repository `{git}`
748 [COMPILING] bar v0.5.0 ({git}#[..])
749 [COMPILING] [..] v0.5.0 ([..])
750 [COMPILING] [..] v0.5.0 ([..])
751 [COMPILING] foo v0.5.0 ([CWD])
752 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
753 git
= git_project
.url(),
757 // Modify a file manually, and commit it
758 File
::create(&git_project
.root().join("src/bar.rs"))
760 .write_all(br
#"pub fn bar() { println!("hello!"); }"#)
762 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
763 let old_head
= repo
.head().unwrap().target().unwrap();
769 // By default, not transitive updates
770 println
!("dep1 update");
771 p
.cargo("update -p dep1").with_stdout("").run();
773 // Don't do anything bad on a weird --precise argument
774 println
!("bar bad precise update");
775 p
.cargo("update -p bar --precise 0.1.2")
779 [UPDATING] git repository [..]
780 [ERROR] Unable to update [..]
783 revspec '0.1.2' not found; [..]
788 // Specifying a precise rev to the old rev shouldn't actually update
789 // anything because we already have the rev in the db.
790 println
!("bar precise update");
791 p
.cargo("update -p bar --precise")
792 .arg(&old_head
.to_string())
796 // Updating aggressively should, however, update the repo.
797 println
!("dep1 aggressive update");
798 p
.cargo("update -p dep1 --aggressive")
799 .with_stderr(&format
!(
800 "[UPDATING] git repository `{}`\n\
801 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
807 // Make sure we still only compile one version of the git repo
810 .with_stderr(&format
!(
812 [COMPILING] bar v0.5.0 ({git}#[..])
813 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
814 [COMPILING] [..] v0.5.0 ([CWD][..]dep[..])
815 [COMPILING] foo v0.5.0 ([CWD])
816 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
817 git
= git_project
.url(),
821 // We should be able to update transitive deps
822 p
.cargo("update -p bar")
823 .with_stderr(&format
!(
824 "[UPDATING] git repository `{}`",
831 fn dep_with_submodule() {
832 let project
= project();
833 let git_project
= git
::new("dep1", |project
| {
834 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
836 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}"));
838 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
839 let url
= path2url(git_project2
.root()).to_string();
840 git
::add_submodule(&repo
, &url
, Path
::new("src"));
843 let project
= project
852 authors = ["wycats@example.com"]
863 "extern crate dep1; pub fn foo() { dep1::dep() }",
871 [UPDATING] git repository [..]
872 [COMPILING] dep1 [..]
874 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
880 fn dep_with_bad_submodule() {
881 let project
= project();
882 let git_project
= git
::new("dep1", |project
| {
883 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
885 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", "pub fn dep() {}"));
887 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
888 let url
= path2url(git_project2
.root()).to_string();
889 git
::add_submodule(&repo
, &url
, Path
::new("src"));
892 // now amend the first commit on git_project2 to make submodule ref point to not-found
894 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
895 let original_submodule_ref
= repo
.refname_to_id("refs/heads/master").unwrap();
896 let commit
= repo
.find_commit(original_submodule_ref
).unwrap();
899 Some("refs/heads/master"),
903 Some("something something"),
917 authors = ["wycats@example.com"]
928 "extern crate dep1; pub fn foo() { dep1::dep() }",
932 let expected
= format
!(
934 [UPDATING] git repository [..]
935 [ERROR] failed to load source for a dependency on `dep1`
941 failed to update submodule `src`
944 object not found - no match for id [..]
946 path2url(git_project
.root())
950 .with_stderr(expected
)
956 fn two_deps_only_update_one() {
957 let project
= project();
958 let git1
= git
::new("dep1", |project
| {
960 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
961 .file("src/lib.rs", "")
963 let git2
= git
::new("dep2", |project
| {
965 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
966 .file("src/lib.rs", "")
978 authors = ["wycats@example.com"]
989 .file("src/main.rs", "fn main() {}")
992 fn oid_to_short_sha(oid
: git2
::Oid
) -> String
{
993 oid
.to_string()[..8].to_string()
995 fn git_repo_head_sha(p
: &Project
) -> String
{
996 let repo
= git2
::Repository
::open(p
.root()).unwrap();
997 let head
= repo
.head().unwrap().target().unwrap();
998 oid_to_short_sha(head
)
1001 println
!("dep1 head sha: {}", git_repo_head_sha(&git1
));
1002 println
!("dep2 head sha: {}", git_repo_head_sha(&git2
));
1006 "[UPDATING] git repository `[..]`\n\
1007 [UPDATING] git repository `[..]`\n\
1008 [COMPILING] [..] v0.5.0 ([..])\n\
1009 [COMPILING] [..] v0.5.0 ([..])\n\
1010 [COMPILING] foo v0.5.0 ([CWD])\n\
1011 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1015 File
::create(&git1
.root().join("src/lib.rs"))
1017 .write_all(br
#"pub fn foo() {}"#)
1019 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
1021 let oid
= git
::commit(&repo
);
1022 println
!("dep1 head sha: {}", oid_to_short_sha(oid
));
1024 p
.cargo("update -p dep1")
1025 .with_stderr(&format
!(
1026 "[UPDATING] git repository `{}`\n\
1027 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1035 fn stale_cached_version() {
1036 let bar
= git
::new("meta-dep", |project
| {
1038 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
1039 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1042 // Update the git database in the cache with the current state of the git
1065 fn main() { assert_eq!(bar::bar(), 1) }
1070 foo
.cargo("build").run();
1071 foo
.process(&foo
.bin("foo")).run();
1073 // Update the repo, and simulate someone else updating the lock file and then
1074 // us pulling it down.
1075 File
::create(&bar
.root().join("src/lib.rs"))
1077 .write_all(br
#"pub fn bar() -> i32 { 1 + 0 }"#)
1079 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1085 let rev
= repo
.revparse_single("HEAD").unwrap().id();
1087 File
::create(&foo
.root().join("Cargo.lock"))
1096 'bar 0.0.0 (git+{url}#{hash})'
1102 source = 'git+{url}#{hash}'
1113 .with_stderr(&format
!(
1115 [UPDATING] git repository `{bar}`
1116 [COMPILING] bar v0.0.0 ({bar}#[..])
1117 [COMPILING] foo v0.0.0 ([CWD])
1118 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1123 foo
.process(&foo
.bin("foo")).run();
1127 fn dep_with_changed_submodule() {
1128 let project
= project();
1129 let git_project
= git
::new("dep1", |project
| {
1130 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
1133 let git_project2
= git
::new("dep2", |project
| {
1134 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
1137 let git_project3
= git
::new("dep3", |project
| {
1138 project
.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
1141 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
1142 let mut sub
= git
::add_submodule(&repo
, &git_project2
.url().to_string(), Path
::new("src"));
1153 authors = ["wycats@example.com"]
1164 pub fn main() { println!(\"{}\", dep1::dep()) }
1169 println
!("first run");
1172 "[UPDATING] git repository `[..]`\n\
1173 [COMPILING] dep1 v0.5.0 ([..])\n\
1174 [COMPILING] foo v0.5.0 ([..])\n\
1175 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1177 [RUNNING] `target/debug/foo[EXE]`\n",
1179 .with_stdout("project2\n")
1182 File
::create(&git_project
.root().join(".gitmodules"))
1186 "[submodule \"src\"]\n\tpath = src\n\turl={}",
1193 // Sync the submodule and reset it to the new remote.
1194 sub
.sync().unwrap();
1196 let subrepo
= sub
.open().unwrap();
1198 .remote_add_fetch("origin", "refs/heads/*:refs/heads/*")
1201 .remote_set_url("origin", &git_project3
.url().to_string())
1203 let mut origin
= subrepo
.find_remote("origin").unwrap();
1204 origin
.fetch(&[], None
, None
).unwrap();
1205 let id
= subrepo
.refname_to_id("refs/remotes/origin/master").unwrap();
1206 let obj
= subrepo
.find_object(id
, None
).unwrap();
1207 subrepo
.reset(&obj
, git2
::ResetType
::Hard
, None
).unwrap();
1209 sub
.add_to_index(true).unwrap();
1214 // Update the dependency and carry on!
1216 p
.cargo("update -v")
1218 .with_stderr(&format
!(
1219 "[UPDATING] git repository `{}`\n\
1220 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1226 println
!("last run");
1229 "[COMPILING] dep1 v0.5.0 ([..])\n\
1230 [COMPILING] foo v0.5.0 ([..])\n\
1231 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1233 [RUNNING] `target/debug/foo[EXE]`\n",
1235 .with_stdout("project3\n")
1240 fn dev_deps_with_testing() {
1241 let p2
= git
::new("bar", |project
| {
1243 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1247 pub fn gimme() -> &'static str { "zoidberg" }
1261 authors = ["wycats@example.com"]
1263 [dev-dependencies.bar]
1278 #[test] fn foo() { bar::gimme(); }
1284 // Generate a lock file which did not use `bar` to compile, but had to update
1285 // `bar` to generate the lock file
1287 .with_stderr(&format
!(
1289 [UPDATING] git repository `{bar}`
1290 [COMPILING] foo v0.5.0 ([CWD])
1291 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1297 // Make sure we use the previous resolution of `bar` instead of updating it
1302 [COMPILING] [..] v0.5.0 ([..])
1303 [COMPILING] [..] v0.5.0 ([..]
1304 [FINISHED] test [unoptimized + debuginfo] target(s) in [..]
1305 [RUNNING] target/debug/deps/foo-[..][EXE]",
1307 .with_stdout_contains("test tests::foo ... ok")
1312 fn git_build_cmd_freshness() {
1313 let foo
= git
::new("foo", |project
| {
1325 .file("build.rs", "fn main() {}")
1326 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1327 .file(".gitignore", "src/bar.rs")
1329 foo
.root().move_into_the_past();
1336 [COMPILING] foo v0.0.0 ([CWD])
1337 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1342 // Smoke test to make sure it doesn't compile again
1343 println
!("first pass");
1344 foo
.cargo("build").with_stdout("").run();
1346 // Modify an ignored file and make sure we don't rebuild
1347 println
!("second pass");
1348 File
::create(&foo
.root().join("src/bar.rs")).unwrap();
1349 foo
.cargo("build").with_stdout("").run();
1353 fn git_name_not_always_needed() {
1354 let p2
= git
::new("bar", |project
| {
1356 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1360 pub fn gimme() -> &'static str { "zoidberg" }
1365 let repo
= git2
::Repository
::open(&p2
.root()).unwrap();
1366 let mut cfg
= repo
.config().unwrap();
1367 let _
= cfg
.remove("user.name");
1368 let _
= cfg
.remove("user.email");
1380 [dev-dependencies.bar]
1386 .file("src/main.rs", "fn main() {}")
1389 // Generate a lock file which did not use `bar` to compile, but had to update
1390 // `bar` to generate the lock file
1392 .with_stderr(&format
!(
1394 [UPDATING] git repository `{bar}`
1395 [COMPILING] foo v0.5.0 ([CWD])
1396 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1404 fn git_repo_changing_no_rebuild() {
1405 let bar
= git
::new("bar", |project
| {
1407 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1408 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1411 // Lock p1 to the first rev in the git repo
1429 .file("src/main.rs", "fn main() {}")
1430 .file("build.rs", "fn main() {}")
1432 p1
.root().move_into_the_past();
1434 .with_stderr(&format
!(
1436 [UPDATING] git repository `{bar}`
1439 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1445 // Make a commit to lock p2 to a different rev
1446 File
::create(&bar
.root().join("src/lib.rs"))
1448 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1450 let repo
= git2
::Repository
::open(&bar
.root()).unwrap();
1454 // Lock p2 to the second rev
1471 .file("src/main.rs", "fn main() {}")
1474 .with_stderr(&format
!(
1476 [UPDATING] git repository `{bar}`
1479 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1485 // And now for the real test! Make sure that p1 doesn't get rebuilt
1486 // even though the git repo has changed.
1487 p1
.cargo("build").with_stdout("").run();
1491 fn git_dep_build_cmd() {
1492 let p
= git
::new("foo", |project
| {
1501 authors = ["wycats@example.com"]
1513 .file("src/foo.rs", &main_file(r
#""{}", bar::gimme()"#, &["bar"]))
1521 authors = ["wycats@example.com"]
1530 "bar/src/bar.rs.in",
1532 pub fn gimme() -> i32 { 0 }
1540 fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
1546 p
.root().join("bar").move_into_the_past();
1548 p
.cargo("build").run();
1550 p
.process(&p
.bin("foo")).with_stdout("0\n").run();
1552 // Touching bar.rs.in should cause the `build` command to run again.
1553 fs
::File
::create(&p
.root().join("bar/src/bar.rs.in"))
1555 .write_all(b
"pub fn gimme() -> i32 { 1 }")
1558 p
.cargo("build").run();
1560 p
.process(&p
.bin("foo")).with_stdout("1\n").run();
1564 fn fetch_downloads() {
1565 let bar
= git
::new("bar", |project
| {
1567 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1568 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1586 .file("src/main.rs", "fn main() {}")
1589 .with_stderr(&format
!(
1590 "[UPDATING] git repository `{url}`",
1595 p
.cargo("fetch").with_stdout("").run();
1599 fn warnings_in_git_dep() {
1600 let bar
= git
::new("bar", |project
| {
1602 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1603 .file("src/lib.rs", "fn unused() {}")
1621 .file("src/main.rs", "fn main() {}")
1625 .with_stderr(&format
!(
1626 "[UPDATING] git repository `{}`\n\
1627 [COMPILING] bar v0.5.0 ({}#[..])\n\
1628 [COMPILING] foo v0.5.0 ([CWD])\n\
1629 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
1637 fn update_ambiguous() {
1638 let bar1
= git
::new("bar1", |project
| {
1640 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1641 .file("src/lib.rs", "")
1643 let bar2
= git
::new("bar2", |project
| {
1645 .file("Cargo.toml", &basic_manifest("bar", "0.6.0"))
1646 .file("src/lib.rs", "")
1648 let baz
= git
::new("baz", |project
| {
1657 authors = ["wycats@example.com"]
1665 .file("src/lib.rs", "")
1686 .file("src/main.rs", "fn main() {}")
1689 p
.cargo("generate-lockfile").run();
1690 p
.cargo("update -p bar")
1694 [ERROR] There are multiple `bar` packages in your project, and the specification `bar` \
1696 Please re-run this command with `-p <spec>` where `<spec>` is one of the \
1706 fn update_one_dep_in_repo_with_many_deps() {
1707 let bar
= git
::new("bar", |project
| {
1709 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1710 .file("src/lib.rs", "")
1711 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1712 .file("a/src/lib.rs", "")
1733 .file("src/main.rs", "fn main() {}")
1736 p
.cargo("generate-lockfile").run();
1737 p
.cargo("update -p bar")
1738 .with_stderr(&format
!("[UPDATING] git repository `{}`", bar
.url()))
1743 fn switch_deps_does_not_update_transitive() {
1744 let transitive
= git
::new("transitive", |project
| {
1746 .file("Cargo.toml", &basic_manifest("transitive", "0.5.0"))
1747 .file("src/lib.rs", "")
1749 let dep1
= git
::new("dep1", |project
| {
1758 authors = ["wycats@example.com"]
1760 [dependencies.transitive]
1766 .file("src/lib.rs", "")
1768 let dep2
= git
::new("dep2", |project
| {
1777 authors = ["wycats@example.com"]
1779 [dependencies.transitive]
1785 .file("src/lib.rs", "")
1803 .file("src/main.rs", "fn main() {}")
1807 .with_stderr(&format
!(
1809 [UPDATING] git repository `{}`
1810 [UPDATING] git repository `{}`
1811 [COMPILING] transitive [..]
1812 [COMPILING] dep [..]
1813 [COMPILING] foo [..]
1814 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1821 // Update the dependency to point to the second repository, but this
1822 // shouldn't update the transitive dependency which is the same.
1823 File
::create(&p
.root().join("Cargo.toml"))
1842 .with_stderr(&format
!(
1844 [UPDATING] git repository `{}`
1845 [COMPILING] dep [..]
1846 [COMPILING] foo [..]
1847 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1855 fn update_one_source_updates_all_packages_in_that_git_source() {
1856 let dep
= git
::new("dep", |project
| {
1870 .file("src/lib.rs", "")
1871 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1872 .file("a/src/lib.rs", "")
1890 .file("src/main.rs", "fn main() {}")
1893 p
.cargo("build").run();
1895 let repo
= git2
::Repository
::open(&dep
.root()).unwrap();
1896 let rev1
= repo
.revparse_single("HEAD").unwrap().id();
1898 // Just be sure to change a file
1899 File
::create(&dep
.root().join("src/lib.rs"))
1901 .write_all(br
#"pub fn bar() -> i32 { 2 }"#)
1906 p
.cargo("update -p dep").run();
1907 let mut lockfile
= String
::new();
1908 File
::open(&p
.root().join("Cargo.lock"))
1910 .read_to_string(&mut lockfile
)
1913 !lockfile
.contains(&rev1
.to_string()),
1921 fn switch_sources() {
1922 let a1
= git
::new("a1", |project
| {
1924 .file("Cargo.toml", &basic_manifest("a", "0.5.0"))
1925 .file("src/lib.rs", "")
1927 let a2
= git
::new("a2", |project
| {
1929 .file("Cargo.toml", &basic_manifest("a", "0.5.1"))
1930 .file("src/lib.rs", "")
1945 .file("src/main.rs", "fn main() {}")
1960 .file("b/src/lib.rs", "pub fn main() {}")
1966 [UPDATING] git repository `file://[..]a1`
1967 [COMPILING] a v0.5.0 ([..]a1#[..]
1968 [COMPILING] b v0.5.0 ([..])
1969 [COMPILING] foo v0.5.0 ([..])
1970 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1975 File
::create(&p
.root().join("b/Cargo.toml"))
1996 [UPDATING] git repository `file://[..]a2`
1997 [COMPILING] a v0.5.1 ([..]a2#[..]
1998 [COMPILING] b v0.5.0 ([..])
1999 [COMPILING] foo v0.5.0 ([..])
2000 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2007 fn dont_require_submodules_are_checked_out() {
2008 let p
= project().build();
2009 let git1
= git
::new("dep1", |p
| {
2020 .file("build.rs", "fn main() {}")
2021 .file("src/lib.rs", "")
2024 let git2
= git
::new("dep2", |p
| p
);
2026 let repo
= git2
::Repository
::open(&git1
.root()).unwrap();
2027 let url
= path2url(git2
.root()).to_string();
2028 git
::add_submodule(&repo
, &url
, Path
::new("a/submodule"));
2031 git2
::Repository
::init(&p
.root()).unwrap();
2032 let url
= path2url(git1
.root()).to_string();
2033 let dst
= paths
::home().join("foo");
2034 git2
::Repository
::clone(&url
, &dst
).unwrap();
2036 git1
.cargo("build -v").cwd(&dst
).run();
2040 fn doctest_same_name() {
2041 let a2
= git
::new("a2", |p
| {
2042 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0"))
2043 .file("src/lib.rs", "pub fn a2() {}")
2046 let a1
= git
::new("a1", |p
| {
2056 a = {{ git = '{}' }}
2061 .file("src/lib.rs", "extern crate a; pub fn a1() {}")
2075 a = {{ git = '{}' }}
2089 p
.cargo("test -v").run();
2093 fn lints_are_suppressed() {
2094 let a
= git
::new("a", |p
| {
2095 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2114 a = {{ git = '{}' }}
2119 .file("src/lib.rs", "")
2125 [UPDATING] git repository `[..]`
2126 [COMPILING] a v0.5.0 ([..])
2127 [COMPILING] foo v0.0.1 ([..])
2128 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2135 fn denied_lints_are_allowed() {
2136 let a
= git
::new("a", |p
| {
2137 p
.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2157 a = {{ git = '{}' }}
2162 .file("src/lib.rs", "")
2168 [UPDATING] git repository `[..]`
2169 [COMPILING] a v0.5.0 ([..])
2170 [COMPILING] foo v0.0.1 ([..])
2171 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2178 fn add_a_git_dep() {
2179 let git
= git
::new("git", |p
| {
2180 p
.file("Cargo.toml", &basic_manifest("git", "0.5.0"))
2181 .file("src/lib.rs", "")
2195 a = {{ path = 'a' }}
2196 git = {{ git = '{}' }}
2201 .file("src/lib.rs", "")
2202 .file("a/Cargo.toml", &basic_manifest("a", "0.0.1"))
2203 .file("a/src/lib.rs", "")
2206 p
.cargo("build").run();
2208 File
::create(p
.root().join("a/Cargo.toml"))
2219 git = {{ git = '{}' }}
2227 p
.cargo("build").run();
2231 fn two_at_rev_instead_of_tag() {
2232 let git
= git
::new("git", |p
| {
2233 p
.file("Cargo.toml", &basic_manifest("git1", "0.5.0"))
2234 .file("src/lib.rs", "")
2235 .file("a/Cargo.toml", &basic_manifest("git2", "0.5.0"))
2236 .file("a/src/lib.rs", "")
2239 // Make a tag corresponding to the current HEAD
2240 let repo
= git2
::Repository
::open(&git
.root()).unwrap();
2241 let head
= repo
.head().unwrap().target().unwrap();
2244 &repo
.find_object(head
, None
).unwrap(),
2245 &repo
.signature().unwrap(),
2262 git1 = {{ git = '{0}', rev = 'v0.1.0' }}
2263 git2 = {{ git = '{0}', rev = 'v0.1.0' }}
2268 .file("src/lib.rs", "")
2271 p
.cargo("generate-lockfile").run();
2272 p
.cargo("build -v").run();
2276 fn include_overrides_gitignore() {
2277 // Make sure that `package.include` takes precedence over .gitignore.
2278 let p
= git
::new("foo", |repo
| {
2285 include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
2296 .file("src/lib.rs", "")
2297 .file("ignored.txt", "")
2298 .file("build.rs", "fn main() {}")
2301 p
.cargo("build").run();
2302 p
.change_file("ignored.txt", "Trigger rebuild.");
2306 [COMPILING] foo v0.5.0 ([..])
2307 [RUNNING] `[..]build-script-build[..]`
2308 [RUNNING] `rustc --crate-name foo src/lib.rs [..]`
2309 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2313 p
.cargo("package --list --allow-dirty")
2325 fn invalid_git_dependency_manifest() {
2326 let project
= project();
2327 let git_project
= git
::new("dep1", |project
| {
2336 authors = ["carlhuda@example.com"]
2337 categories = ["algorithms"]
2338 categories = ["algorithms"]
2348 pub fn hello() -> &'static str {
2355 let project
= project
2364 authors = ["wycats@example.com"]
2375 &main_file(r
#""{}", dep1::hello()"#, &["dep1"]),
2379 let git_root
= git_project
.root();
2384 .with_stderr(&format
!(
2385 "[UPDATING] git repository `{}`\n\
2386 error: failed to load source for a dependency on `dep1`\n\
2389 Unable to update {}\n\
2392 failed to parse manifest at `[..]`\n\
2395 could not parse input as TOML\n\
2398 duplicate key: `categories` for key `project` at line 10 column 17",
2399 path2url(&git_root
),
2400 path2url(&git_root
),
2406 fn failed_submodule_checkout() {
2407 let project
= project();
2408 let git_project
= git
::new("dep1", |project
| {
2409 project
.file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2412 let git_project2
= git
::new("dep2", |project
| project
.file("lib.rs", ""));
2414 let listener
= TcpListener
::bind("127.0.0.1:0").unwrap();
2415 let addr
= listener
.local_addr().unwrap();
2416 let done
= Arc
::new(AtomicBool
::new(false));
2417 let done2
= done
.clone();
2419 let t
= thread
::spawn(move || {
2420 while !done2
.load(Ordering
::SeqCst
) {
2421 if let Ok((mut socket
, _
)) = listener
.accept() {
2422 drop(socket
.write_all(b
"foo\r\n"));
2427 let repo
= git2
::Repository
::open(&git_project2
.root()).unwrap();
2428 let url
= format
!("https://{}:{}/", addr
.ip(), addr
.port());
2430 let mut s
= repo
.submodule(&url
, Path
::new("bar"), false).unwrap();
2431 let subrepo
= s
.open().unwrap();
2432 let mut cfg
= subrepo
.config().unwrap();
2433 cfg
.set_str("user.email", "foo@bar.com").unwrap();
2434 cfg
.set_str("user.name", "Foo Bar").unwrap();
2435 git
::commit(&subrepo
);
2436 s
.add_finalize().unwrap();
2441 let repo
= git2
::Repository
::open(&git_project
.root()).unwrap();
2442 let url
= path2url(git_project2
.root()).to_string();
2443 git
::add_submodule(&repo
, &url
, Path
::new("src"));
2447 let project
= project
2458 dep1 = {{ git = '{}' }}
2463 .file("src/lib.rs", "")
2469 .with_stderr_contains(" failed to update submodule `src`")
2470 .with_stderr_contains(" failed to update submodule `bar`")
2475 .with_stderr_contains(" failed to update submodule `src`")
2476 .with_stderr_contains(" failed to update submodule `bar`")
2479 done
.store(true, Ordering
::SeqCst
);
2480 drop(TcpStream
::connect(&addr
));
2486 if disable_git_cli() {
2489 let project
= project();
2490 let git_project
= git
::new("dep1", |project
| {
2492 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2493 .file("src/lib.rs", "")
2496 let project
= project
2507 dep1 = {{ git = '{}' }}
2512 .file("src/lib.rs", "")
2517 git-fetch-with-cli = true
2523 [UPDATING] git repository `[..]`
2524 [RUNNING] `git fetch [..]`
2525 [COMPILING] dep1 [..]
2526 [RUNNING] `rustc [..]`
2527 [COMPILING] foo [..]
2528 [RUNNING] `rustc [..]`
2532 project
.cargo("build -v").with_stderr(stderr
).run();
2536 fn templatedir_doesnt_cause_problems() {
2537 let git_project2
= git
::new("dep2", |project
| {
2539 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
2540 .file("src/lib.rs", "")
2542 let git_project
= git
::new("dep1", |project
| {
2544 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2545 .file("src/lib.rs", "")
2558 dep1 = {{ git = '{}' }}
2563 .file("src/main.rs", "fn main() {}")
2566 File
::create(paths
::home().join(".gitconfig"))
2586 p
.cargo("build").run();
2590 fn git_with_cli_force() {
2591 if disable_git_cli() {
2594 // Supports a force-pushed repo.
2595 let git_project
= git
::new("dep1", |project
| {
2597 .file("Cargo.toml", &basic_lib_manifest("dep1"))
2598 .file("src/lib.rs", r
#"pub fn f() { println!("one"); }"#)
2611 dep1 = {{ git = "{}" }}
2616 .file("src
/main
.rs
", "fn main() { dep1::f(); }
")
2621 git
-fetch
-with
-cli
= true
2625 p.cargo("build
").run();
2626 p.rename_run("foo
", "foo1
").with_stdout("one
").run();
2628 // commit --amend a change that will require a force fetch.
2629 let repo = git2::Repository::open(&git_project.root()).unwrap();
2630 git_project.change_file("src
/lib
.rs
", r#"pub fn f() { println!("two"); }
"#);
2632 let id = repo.refname_to_id("HEAD
").unwrap();
2633 let commit = repo.find_commit(id).unwrap();
2634 let tree_id = t!(t!(repo.index()).write_tree());
2641 Some(&t!(repo.find_tree(tree_id)))
2643 // Perform the fetch.
2644 p.cargo("update
").run();
2645 p.cargo("build
").run();
2646 p.rename_run("foo
", "foo2
").with_stdout("two
").run();
2650 fn git_fetch_cli_env_clean() {
2651 if disable_git_cli() {
2654 // This tests that git-fetch-with-cli works when GIT_DIR environment
2655 // variable is set (for whatever reason).
2656 let git_dep = git::new("dep1
", |project| {
2658 .file("Cargo
.toml
", &basic_manifest("dep1
", "0.5.0"))
2659 .file("src
/lib
.rs
", "")
2662 let git_proj = git::new("foo
", |project| {
2672 dep1
= {{ git = '{}'
}}
2677 .file("src
/lib
.rs
", "pub extern crate dep1
;")
2682 git
-fetch
-with
-cli
= true
2687 // The directory set here isn't too important. Pointing to our own git
2688 // directory causes git to be confused and fail. Can also point to an
2689 // empty directory, or a nonexistent one.
2692 .env("GIT_DIR
", git_proj.root().join(".git
"))
2697 fn dirty_submodule() {
2698 // `cargo package` warns for dirty file in submodule.
2699 let (git_project, repo) = git::new_repo("foo
", |project| {
2701 .file("Cargo
.toml
", &basic_manifest("foo
", "0.5.0"))
2702 // This is necessary because `git::add` is too eager.
2703 .file(".gitignore
", "/target
")
2705 let git_project2 = git::new("src
", |project| {
2706 project.no_manifest().file("lib
.rs
", "pub fn f() {}
")
2709 let url = path2url(git_project2.root()).to_string();
2710 git::add_submodule(&repo, &url, Path::new("src
"));
2712 // Submodule added, but not committed.
2714 .cargo("package
--no
-verify
")
2718 [WARNING
] manifest has no
[..]
2720 [ERROR
] 1 files
in the working directory contain changes that were not yet committed into git
:
2724 to proceed despite
[..]
2730 git_project.cargo("package
--no
-verify
").run();
2732 // Modify file, check for warning.
2733 git_project.change_file("src
/lib
.rs
", "");
2735 .cargo("package
--no
-verify
")
2739 [WARNING
] manifest has no
[..]
2741 [ERROR
] 1 files
in the working directory contain changes that were not yet committed into git
:
2745 to proceed despite
[..]
2749 // Commit the change.
2750 let sub_repo = git2::Repository::open(git_project.root().join("src
")).unwrap();
2751 git::add(&sub_repo);
2752 git::commit(&sub_repo);
2755 git_project.cargo("package
--no
-verify
").run();
2757 // Try with a nested submodule.
2758 let git_project3 = git::new("bar
", |project| project.no_manifest().file("mod.rs
", ""));
2759 let url = path2url(git_project3.root()).to_string();
2760 git::add_submodule(&sub_repo, &url, Path::new("bar
"));
2762 .cargo("package
--no
-verify
")
2766 [WARNING
] manifest has no
[..]
2768 [ERROR
] 1 files
in the working directory contain changes that were not yet committed into git
:
2772 to proceed despite
[..]
2777 // Commit the submodule addition.
2778 git::commit(&sub_repo);
2781 git_project.cargo("package
--no
-verify
").run();
2782 // Modify within nested submodule.
2783 git_project.change_file("src
/bar
/mod.rs
", "//test");
2785 .cargo("package --no-verify")
2789 [WARNING] manifest has no [..]
2791 [ERROR] 1 files in the working directory contain changes that were not yet committed into git:
2795 to proceed despite [..]
2799 // And commit the change.
2800 let sub_sub_repo
= git2
::Repository
::open(git_project
.root().join("src/bar")).unwrap();
2801 git
::add(&sub_sub_repo
);
2802 git
::commit(&sub_sub_repo
);
2803 git
::add(&sub_repo
);
2804 git
::commit(&sub_repo
);
2807 git_project
.cargo("package --no-verify").run();