]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/git.rs
Merge remote-tracking branch 'origin/master' into custom-profile-pr-rfc
[cargo.git] / tests / testsuite / git.rs
1 use git2;
2 use std::env;
3 use std::fs::{self, File};
4 use std::io::prelude::*;
5 use std::net::{TcpListener, TcpStream};
6 use std::path::Path;
7 use std::sync::atomic::{AtomicBool, Ordering};
8 use std::sync::Arc;
9 use std::thread;
10
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};
15
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())
21 }
22
23 #[cargo_test]
24 fn cargo_compile_simple_git_dep() {
25 let project = project();
26 let git_project = git::new("dep1", |project| {
27 project
28 .file("Cargo.toml", &basic_lib_manifest("dep1"))
29 .file(
30 "src/dep1.rs",
31 r#"
32 pub fn hello() -> &'static str {
33 "hello world"
34 }
35 "#,
36 )
37 })
38 .unwrap();
39
40 let project = project
41 .file(
42 "Cargo.toml",
43 &format!(
44 r#"
45 [project]
46
47 name = "foo"
48 version = "0.5.0"
49 authors = ["wycats@example.com"]
50
51 [dependencies.dep1]
52
53 git = '{}'
54 "#,
55 git_project.url()
56 ),
57 )
58 .file(
59 "src/main.rs",
60 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
61 )
62 .build();
63
64 let git_root = git_project.root();
65
66 project
67 .cargo("build")
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",
73 path2url(&git_root),
74 path2url(&git_root),
75 ))
76 .run();
77
78 assert!(project.bin("foo").is_file());
79
80 project
81 .process(&project.bin("foo"))
82 .with_stdout("hello world\n")
83 .run();
84 }
85
86 #[cargo_test]
87 fn cargo_compile_git_dep_branch() {
88 let project = project();
89 let git_project = git::new("dep1", |project| {
90 project
91 .file("Cargo.toml", &basic_lib_manifest("dep1"))
92 .file(
93 "src/dep1.rs",
94 r#"
95 pub fn hello() -> &'static str {
96 "hello world"
97 }
98 "#,
99 )
100 })
101 .unwrap();
102
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();
108
109 let project = project
110 .file(
111 "Cargo.toml",
112 &format!(
113 r#"
114 [project]
115
116 name = "foo"
117 version = "0.5.0"
118 authors = ["wycats@example.com"]
119
120 [dependencies.dep1]
121
122 git = '{}'
123 branch = "branchy"
124
125 "#,
126 git_project.url()
127 ),
128 )
129 .file(
130 "src/main.rs",
131 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
132 )
133 .build();
134
135 let git_root = git_project.root();
136
137 project
138 .cargo("build")
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",
144 path2url(&git_root),
145 path2url(&git_root),
146 ))
147 .run();
148
149 assert!(project.bin("foo").is_file());
150
151 project
152 .process(&project.bin("foo"))
153 .with_stdout("hello world\n")
154 .run();
155 }
156
157 #[cargo_test]
158 fn cargo_compile_git_dep_tag() {
159 let project = project();
160 let git_project = git::new("dep1", |project| {
161 project
162 .file("Cargo.toml", &basic_lib_manifest("dep1"))
163 .file(
164 "src/dep1.rs",
165 r#"
166 pub fn hello() -> &'static str {
167 "hello world"
168 }
169 "#,
170 )
171 })
172 .unwrap();
173
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();
177 repo.tag(
178 "v0.1.0",
179 &repo.find_object(head, None).unwrap(),
180 &repo.signature().unwrap(),
181 "make a new tag",
182 false,
183 )
184 .unwrap();
185
186 let project = project
187 .file(
188 "Cargo.toml",
189 &format!(
190 r#"
191 [project]
192
193 name = "foo"
194 version = "0.5.0"
195 authors = ["wycats@example.com"]
196
197 [dependencies.dep1]
198
199 git = '{}'
200 tag = "v0.1.0"
201 "#,
202 git_project.url()
203 ),
204 )
205 .file(
206 "src/main.rs",
207 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
208 )
209 .build();
210
211 let git_root = git_project.root();
212
213 project
214 .cargo("build")
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",
220 path2url(&git_root),
221 path2url(&git_root),
222 ))
223 .run();
224
225 assert!(project.bin("foo").is_file());
226
227 project
228 .process(&project.bin("foo"))
229 .with_stdout("hello world\n")
230 .run();
231
232 project.cargo("build").run();
233 }
234
235 #[cargo_test]
236 fn cargo_compile_with_nested_paths() {
237 let git_project = git::new("dep1", |project| {
238 project
239 .file(
240 "Cargo.toml",
241 r#"
242 [project]
243
244 name = "dep1"
245 version = "0.5.0"
246 authors = ["carlhuda@example.com"]
247
248 [dependencies.dep2]
249
250 version = "0.5.0"
251 path = "vendor/dep2"
252
253 [lib]
254
255 name = "dep1"
256 "#,
257 )
258 .file(
259 "src/dep1.rs",
260 r#"
261 extern crate dep2;
262
263 pub fn hello() -> &'static str {
264 dep2::hello()
265 }
266 "#,
267 )
268 .file("vendor/dep2/Cargo.toml", &basic_lib_manifest("dep2"))
269 .file(
270 "vendor/dep2/src/dep2.rs",
271 r#"
272 pub fn hello() -> &'static str {
273 "hello world"
274 }
275 "#,
276 )
277 })
278 .unwrap();
279
280 let p = project()
281 .file(
282 "Cargo.toml",
283 &format!(
284 r#"
285 [project]
286
287 name = "foo"
288 version = "0.5.0"
289 authors = ["wycats@example.com"]
290
291 [dependencies.dep1]
292
293 version = "0.5.0"
294 git = '{}'
295
296 [[bin]]
297
298 name = "foo"
299 "#,
300 git_project.url()
301 ),
302 )
303 .file(
304 "src/foo.rs",
305 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
306 )
307 .build();
308
309 p.cargo("build").run();
310
311 assert!(p.bin("foo").is_file());
312
313 p.process(&p.bin("foo")).with_stdout("hello world\n").run();
314 }
315
316 #[cargo_test]
317 fn cargo_compile_with_malformed_nested_paths() {
318 let git_project = git::new("dep1", |project| {
319 project
320 .file("Cargo.toml", &basic_lib_manifest("dep1"))
321 .file(
322 "src/dep1.rs",
323 r#"
324 pub fn hello() -> &'static str {
325 "hello world"
326 }
327 "#,
328 )
329 .file("vendor/dep2/Cargo.toml", "!INVALID!")
330 })
331 .unwrap();
332
333 let p = project()
334 .file(
335 "Cargo.toml",
336 &format!(
337 r#"
338 [project]
339
340 name = "foo"
341 version = "0.5.0"
342 authors = ["wycats@example.com"]
343
344 [dependencies.dep1]
345
346 version = "0.5.0"
347 git = '{}'
348
349 [[bin]]
350
351 name = "foo"
352 "#,
353 git_project.url()
354 ),
355 )
356 .file(
357 "src/foo.rs",
358 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
359 )
360 .build();
361
362 p.cargo("build").run();
363
364 assert!(p.bin("foo").is_file());
365
366 p.process(&p.bin("foo")).with_stdout("hello world\n").run();
367 }
368
369 #[cargo_test]
370 fn cargo_compile_with_meta_package() {
371 let git_project = git::new("meta-dep", |project| {
372 project
373 .file("dep1/Cargo.toml", &basic_lib_manifest("dep1"))
374 .file(
375 "dep1/src/dep1.rs",
376 r#"
377 pub fn hello() -> &'static str {
378 "this is dep1"
379 }
380 "#,
381 )
382 .file("dep2/Cargo.toml", &basic_lib_manifest("dep2"))
383 .file(
384 "dep2/src/dep2.rs",
385 r#"
386 pub fn hello() -> &'static str {
387 "this is dep2"
388 }
389 "#,
390 )
391 })
392 .unwrap();
393
394 let p = project()
395 .file(
396 "Cargo.toml",
397 &format!(
398 r#"
399 [project]
400
401 name = "foo"
402 version = "0.5.0"
403 authors = ["wycats@example.com"]
404
405 [dependencies.dep1]
406
407 version = "0.5.0"
408 git = '{}'
409
410 [dependencies.dep2]
411
412 version = "0.5.0"
413 git = '{}'
414
415 [[bin]]
416
417 name = "foo"
418 "#,
419 git_project.url(),
420 git_project.url()
421 ),
422 )
423 .file(
424 "src/foo.rs",
425 &main_file(
426 r#""{} {}", dep1::hello(), dep2::hello()"#,
427 &["dep1", "dep2"],
428 ),
429 )
430 .build();
431
432 p.cargo("build").run();
433
434 assert!(p.bin("foo").is_file());
435
436 p.process(&p.bin("foo"))
437 .with_stdout("this is dep1 this is dep2\n")
438 .run();
439 }
440
441 #[cargo_test]
442 fn cargo_compile_with_short_ssh_git() {
443 let url = "git@github.com:a/dep";
444
445 let p = project()
446 .file(
447 "Cargo.toml",
448 &format!(
449 r#"
450 [project]
451
452 name = "foo"
453 version = "0.5.0"
454 authors = ["wycats@example.com"]
455
456 [dependencies.dep]
457
458 git = "{}"
459
460 [[bin]]
461
462 name = "foo"
463 "#,
464 url
465 ),
466 )
467 .file(
468 "src/foo.rs",
469 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
470 )
471 .build();
472
473 p.cargo("build")
474 .with_status(101)
475 .with_stdout("")
476 .with_stderr(&format!(
477 "\
478 [ERROR] failed to parse manifest at `[..]`
479
480 Caused by:
481 invalid url `{}`: relative URL without a base
482 ",
483 url
484 ))
485 .run();
486 }
487
488 #[cargo_test]
489 fn two_revs_same_deps() {
490 let bar = git::new("meta-dep", |project| {
491 project
492 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
493 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
494 })
495 .unwrap();
496
497 let repo = git2::Repository::open(&bar.root()).unwrap();
498 let rev1 = repo.revparse_single("HEAD").unwrap().id();
499
500 // Commit the changes and make sure we trigger a recompile
501 File::create(&bar.root().join("src/lib.rs"))
502 .unwrap()
503 .write_all(br#"pub fn bar() -> i32 { 2 }"#)
504 .unwrap();
505 git::add(&repo);
506 let rev2 = git::commit(&repo);
507
508 let foo = project()
509 .file(
510 "Cargo.toml",
511 &format!(
512 r#"
513 [project]
514 name = "foo"
515 version = "0.0.0"
516 authors = []
517
518 [dependencies.bar]
519 git = '{}'
520 rev = "{}"
521
522 [dependencies.baz]
523 path = "../baz"
524 "#,
525 bar.url(),
526 rev1
527 ),
528 )
529 .file(
530 "src/main.rs",
531 r#"
532 extern crate bar;
533 extern crate baz;
534
535 fn main() {
536 assert_eq!(bar::bar(), 1);
537 assert_eq!(baz::baz(), 2);
538 }
539 "#,
540 )
541 .build();
542
543 let _baz = project()
544 .at("baz")
545 .file(
546 "Cargo.toml",
547 &format!(
548 r#"
549 [package]
550 name = "baz"
551 version = "0.0.0"
552 authors = []
553
554 [dependencies.bar]
555 git = '{}'
556 rev = "{}"
557 "#,
558 bar.url(),
559 rev2
560 ),
561 )
562 .file(
563 "src/lib.rs",
564 r#"
565 extern crate bar;
566 pub fn baz() -> i32 { bar::bar() }
567 "#,
568 )
569 .build();
570
571 foo.cargo("build -v").run();
572 assert!(foo.bin("foo").is_file());
573 foo.process(&foo.bin("foo")).run();
574 }
575
576 #[cargo_test]
577 fn recompilation() {
578 let git_project = git::new("bar", |project| {
579 project
580 .file("Cargo.toml", &basic_lib_manifest("bar"))
581 .file("src/bar.rs", "pub fn bar() {}")
582 })
583 .unwrap();
584
585 let p = project()
586 .file(
587 "Cargo.toml",
588 &format!(
589 r#"
590 [project]
591
592 name = "foo"
593 version = "0.5.0"
594 authors = ["wycats@example.com"]
595
596 [dependencies.bar]
597
598 version = "0.5.0"
599 git = '{}'
600 "#,
601 git_project.url()
602 ),
603 )
604 .file("src/main.rs", &main_file(r#""{:?}", bar::bar()"#, &["bar"]))
605 .build();
606
607 // First time around we should compile both foo and bar
608 p.cargo("build")
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) \
614 in [..]\n",
615 git_project.url(),
616 git_project.url(),
617 ))
618 .run();
619
620 // Don't recompile the second time
621 p.cargo("build").with_stdout("").run();
622
623 // Modify a file manually, shouldn't trigger a recompile
624 File::create(&git_project.root().join("src/bar.rs"))
625 .unwrap()
626 .write_all(br#"pub fn bar() { println!("hello!"); }"#)
627 .unwrap();
628
629 p.cargo("build").with_stdout("").run();
630
631 p.cargo("update")
632 .with_stderr(&format!(
633 "[UPDATING] git repository `{}`",
634 git_project.url()
635 ))
636 .run();
637
638 p.cargo("build").with_stdout("").run();
639
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();
643 git::add(&repo);
644 git::commit(&repo);
645
646 println!("compile after commit");
647 p.cargo("build").with_stdout("").run();
648 p.root().move_into_the_past();
649
650 // Update the dependency and carry on!
651 p.cargo("update")
652 .with_stderr(&format!(
653 "[UPDATING] git repository `{}`\n\
654 [UPDATING] bar v0.5.0 ([..]) -> #[..]\n\
655 ",
656 git_project.url()
657 ))
658 .run();
659 println!("going for the last compile");
660 p.cargo("build")
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) \
665 in [..]\n",
666 git_project.url(),
667 ))
668 .run();
669
670 // Make sure clean only cleans one dep
671 p.cargo("clean -p foo").with_stdout("").run();
672 p.cargo("build")
673 .with_stderr(
674 "[COMPILING] foo v0.5.0 ([CWD])\n\
675 [FINISHED] dev [unoptimized + debuginfo] target(s) \
676 in [..]",
677 )
678 .run();
679 }
680
681 #[cargo_test]
682 fn update_with_shared_deps() {
683 let git_project = git::new("bar", |project| {
684 project
685 .file("Cargo.toml", &basic_lib_manifest("bar"))
686 .file("src/bar.rs", "pub fn bar() {}")
687 })
688 .unwrap();
689
690 let p = project()
691 .file(
692 "Cargo.toml",
693 r#"
694 [package]
695 name = "foo"
696 version = "0.5.0"
697 authors = ["wycats@example.com"]
698
699 [dependencies.dep1]
700 path = "dep1"
701 [dependencies.dep2]
702 path = "dep2"
703 "#,
704 )
705 .file(
706 "src/main.rs",
707 r#"
708 #[allow(unused_extern_crates)]
709 extern crate dep1;
710 #[allow(unused_extern_crates)]
711 extern crate dep2;
712 fn main() {}
713 "#,
714 )
715 .file(
716 "dep1/Cargo.toml",
717 &format!(
718 r#"
719 [package]
720 name = "dep1"
721 version = "0.5.0"
722 authors = ["wycats@example.com"]
723
724 [dependencies.bar]
725 version = "0.5.0"
726 git = '{}'
727 "#,
728 git_project.url()
729 ),
730 )
731 .file("dep1/src/lib.rs", "")
732 .file(
733 "dep2/Cargo.toml",
734 &format!(
735 r#"
736 [package]
737 name = "dep2"
738 version = "0.5.0"
739 authors = ["wycats@example.com"]
740
741 [dependencies.bar]
742 version = "0.5.0"
743 git = '{}'
744 "#,
745 git_project.url()
746 ),
747 )
748 .file("dep2/src/lib.rs", "")
749 .build();
750
751 // First time around we should compile both foo and bar
752 p.cargo("build")
753 .with_stderr(&format!(
754 "\
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(),
762 ))
763 .run();
764
765 // Modify a file manually, and commit it
766 File::create(&git_project.root().join("src/bar.rs"))
767 .unwrap()
768 .write_all(br#"pub fn bar() { println!("hello!"); }"#)
769 .unwrap();
770 let repo = git2::Repository::open(&git_project.root()).unwrap();
771 let old_head = repo.head().unwrap().target().unwrap();
772 git::add(&repo);
773 git::commit(&repo);
774
775 sleep_ms(1000);
776
777 // By default, not transitive updates
778 println!("dep1 update");
779 p.cargo("update -p dep1").with_stdout("").run();
780
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")
784 .with_status(101)
785 .with_stderr(
786 "\
787 [UPDATING] git repository [..]
788 [ERROR] Unable to update [..]
789
790 Caused by:
791 revspec '0.1.2' not found; [..]
792 ",
793 )
794 .run();
795
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())
801 .with_stdout("")
802 .run();
803
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\
810 ",
811 git_project.url()
812 ))
813 .run();
814
815 // Make sure we still only compile one version of the git repo
816 println!("build");
817 p.cargo("build")
818 .with_stderr(&format!(
819 "\
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(),
826 ))
827 .run();
828
829 // We should be able to update transitive deps
830 p.cargo("update -p bar")
831 .with_stderr(&format!(
832 "[UPDATING] git repository `{}`",
833 git_project.url()
834 ))
835 .run();
836 }
837
838 #[cargo_test]
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"))
843 })
844 .unwrap();
845 let git_project2 =
846 git::new("dep2", |project| project.file("lib.rs", "pub fn dep() {}")).unwrap();
847
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"));
851 git::commit(&repo);
852
853 let project = project
854 .file(
855 "Cargo.toml",
856 &format!(
857 r#"
858 [project]
859
860 name = "foo"
861 version = "0.5.0"
862 authors = ["wycats@example.com"]
863
864 [dependencies.dep1]
865
866 git = '{}'
867 "#,
868 git_project.url()
869 ),
870 )
871 .file(
872 "src/lib.rs",
873 "extern crate dep1; pub fn foo() { dep1::dep() }",
874 )
875 .build();
876
877 project
878 .cargo("build")
879 .with_stderr(
880 "\
881 [UPDATING] git repository [..]
882 [COMPILING] dep1 [..]
883 [COMPILING] foo [..]
884 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
885 )
886 .run();
887 }
888
889 #[cargo_test]
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"))
894 })
895 .unwrap();
896 let git_project2 =
897 git::new("dep2", |project| project.file("lib.rs", "pub fn dep() {}")).unwrap();
898
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"));
902 git::commit(&repo);
903
904 // now amend the first commit on git_project2 to make submodule ref point to not-found
905 // commit
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();
909 commit
910 .amend(
911 Some("refs/heads/master"),
912 None,
913 None,
914 None,
915 Some("something something"),
916 None,
917 )
918 .unwrap();
919
920 let p = project
921 .file(
922 "Cargo.toml",
923 &format!(
924 r#"
925 [project]
926
927 name = "foo"
928 version = "0.5.0"
929 authors = ["wycats@example.com"]
930
931 [dependencies.dep1]
932
933 git = '{}'
934 "#,
935 git_project.url()
936 ),
937 )
938 .file(
939 "src/lib.rs",
940 "extern crate dep1; pub fn foo() { dep1::dep() }",
941 )
942 .build();
943
944 let expected = format!(
945 "\
946 [UPDATING] git repository [..]
947 [ERROR] failed to load source for a dependency on `dep1`
948
949 Caused by:
950 Unable to update {}
951
952 Caused by:
953 failed to update submodule `src`
954
955 Caused by:
956 object not found - no match for id [..]
957 ",
958 path2url(git_project.root())
959 );
960
961 p.cargo("build")
962 .with_stderr(expected)
963 .with_status(101)
964 .run();
965 }
966
967 #[cargo_test]
968 fn two_deps_only_update_one() {
969 let project = project();
970 let git1 = git::new("dep1", |project| {
971 project
972 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
973 .file("src/lib.rs", "")
974 })
975 .unwrap();
976 let git2 = git::new("dep2", |project| {
977 project
978 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
979 .file("src/lib.rs", "")
980 })
981 .unwrap();
982
983 let p = project
984 .file(
985 "Cargo.toml",
986 &format!(
987 r#"
988 [project]
989
990 name = "foo"
991 version = "0.5.0"
992 authors = ["wycats@example.com"]
993
994 [dependencies.dep1]
995 git = '{}'
996 [dependencies.dep2]
997 git = '{}'
998 "#,
999 git1.url(),
1000 git2.url()
1001 ),
1002 )
1003 .file("src/main.rs", "fn main() {}")
1004 .build();
1005
1006 fn oid_to_short_sha(oid: git2::Oid) -> String {
1007 oid.to_string()[..8].to_string()
1008 }
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)
1013 }
1014
1015 println!("dep1 head sha: {}", git_repo_head_sha(&git1));
1016 println!("dep2 head sha: {}", git_repo_head_sha(&git2));
1017
1018 p.cargo("build")
1019 .with_stderr(
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",
1026 )
1027 .run();
1028
1029 File::create(&git1.root().join("src/lib.rs"))
1030 .unwrap()
1031 .write_all(br#"pub fn foo() {}"#)
1032 .unwrap();
1033 let repo = git2::Repository::open(&git1.root()).unwrap();
1034 git::add(&repo);
1035 let oid = git::commit(&repo);
1036 println!("dep1 head sha: {}", oid_to_short_sha(oid));
1037
1038 p.cargo("update -p dep1")
1039 .with_stderr(&format!(
1040 "[UPDATING] git repository `{}`\n\
1041 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1042 ",
1043 git1.url()
1044 ))
1045 .run();
1046 }
1047
1048 #[cargo_test]
1049 fn stale_cached_version() {
1050 let bar = git::new("meta-dep", |project| {
1051 project
1052 .file("Cargo.toml", &basic_manifest("bar", "0.0.0"))
1053 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1054 })
1055 .unwrap();
1056
1057 // Update the git database in the cache with the current state of the git
1058 // repo
1059 let foo = project()
1060 .file(
1061 "Cargo.toml",
1062 &format!(
1063 r#"
1064 [project]
1065 name = "foo"
1066 version = "0.0.0"
1067 authors = []
1068
1069 [dependencies.bar]
1070 git = '{}'
1071 "#,
1072 bar.url()
1073 ),
1074 )
1075 .file(
1076 "src/main.rs",
1077 r#"
1078 extern crate bar;
1079
1080 fn main() { assert_eq!(bar::bar(), 1) }
1081 "#,
1082 )
1083 .build();
1084
1085 foo.cargo("build").run();
1086 foo.process(&foo.bin("foo")).run();
1087
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"))
1091 .unwrap()
1092 .write_all(br#"pub fn bar() -> i32 { 1 + 0 }"#)
1093 .unwrap();
1094 let repo = git2::Repository::open(&bar.root()).unwrap();
1095 git::add(&repo);
1096 git::commit(&repo);
1097
1098 sleep_ms(1000);
1099
1100 let rev = repo.revparse_single("HEAD").unwrap().id();
1101
1102 File::create(&foo.root().join("Cargo.lock"))
1103 .unwrap()
1104 .write_all(
1105 format!(
1106 r#"
1107 [[package]]
1108 name = "foo"
1109 version = "0.0.0"
1110 dependencies = [
1111 'bar 0.0.0 (git+{url}#{hash})'
1112 ]
1113
1114 [[package]]
1115 name = "bar"
1116 version = "0.0.0"
1117 source = 'git+{url}#{hash}'
1118 "#,
1119 url = bar.url(),
1120 hash = rev
1121 )
1122 .as_bytes(),
1123 )
1124 .unwrap();
1125
1126 // Now build!
1127 foo.cargo("build")
1128 .with_stderr(&format!(
1129 "\
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 [..]
1134 ",
1135 bar = bar.url(),
1136 ))
1137 .run();
1138 foo.process(&foo.bin("foo")).run();
1139 }
1140
1141 #[cargo_test]
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"))
1146 })
1147 .unwrap();
1148
1149 let git_project2 = git::new("dep2", |project| {
1150 project.file("lib.rs", "pub fn dep() -> &'static str { \"project2\" }")
1151 })
1152 .unwrap();
1153
1154 let git_project3 = git::new("dep3", |project| {
1155 project.file("lib.rs", "pub fn dep() -> &'static str { \"project3\" }")
1156 })
1157 .unwrap();
1158
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"));
1161 git::commit(&repo);
1162
1163 let p = project
1164 .file(
1165 "Cargo.toml",
1166 &format!(
1167 r#"
1168 [project]
1169 name = "foo"
1170 version = "0.5.0"
1171 authors = ["wycats@example.com"]
1172 [dependencies.dep1]
1173 git = '{}'
1174 "#,
1175 git_project.url()
1176 ),
1177 )
1178 .file(
1179 "src/main.rs",
1180 "
1181 extern crate dep1;
1182 pub fn main() { println!(\"{}\", dep1::dep()) }
1183 ",
1184 )
1185 .build();
1186
1187 println!("first run");
1188 p.cargo("run")
1189 .with_stderr(
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 \
1194 [..]\n\
1195 [RUNNING] `target/debug/foo[EXE]`\n",
1196 )
1197 .with_stdout("project2\n")
1198 .run();
1199
1200 File::create(&git_project.root().join(".gitmodules"))
1201 .unwrap()
1202 .write_all(
1203 format!(
1204 "[submodule \"src\"]\n\tpath = src\n\turl={}",
1205 git_project3.url()
1206 )
1207 .as_bytes(),
1208 )
1209 .unwrap();
1210
1211 // Sync the submodule and reset it to the new remote.
1212 sub.sync().unwrap();
1213 {
1214 let subrepo = sub.open().unwrap();
1215 subrepo
1216 .remote_add_fetch("origin", "refs/heads/*:refs/heads/*")
1217 .unwrap();
1218 subrepo
1219 .remote_set_url("origin", &git_project3.url().to_string())
1220 .unwrap();
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();
1226 }
1227 sub.add_to_index(true).unwrap();
1228 git::add(&repo);
1229 git::commit(&repo);
1230
1231 sleep_ms(1000);
1232 // Update the dependency and carry on!
1233 println!("update");
1234 p.cargo("update -v")
1235 .with_stderr("")
1236 .with_stderr(&format!(
1237 "[UPDATING] git repository `{}`\n\
1238 [UPDATING] dep1 v0.5.0 ([..]) -> #[..]\n\
1239 ",
1240 git_project.url()
1241 ))
1242 .run();
1243
1244 println!("last run");
1245 p.cargo("run")
1246 .with_stderr(
1247 "[COMPILING] dep1 v0.5.0 ([..])\n\
1248 [COMPILING] foo v0.5.0 ([..])\n\
1249 [FINISHED] dev [unoptimized + debuginfo] target(s) in \
1250 [..]\n\
1251 [RUNNING] `target/debug/foo[EXE]`\n",
1252 )
1253 .with_stdout("project3\n")
1254 .run();
1255 }
1256
1257 #[cargo_test]
1258 fn dev_deps_with_testing() {
1259 let p2 = git::new("bar", |project| {
1260 project
1261 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1262 .file(
1263 "src/lib.rs",
1264 r#"
1265 pub fn gimme() -> &'static str { "zoidberg" }
1266 "#,
1267 )
1268 })
1269 .unwrap();
1270
1271 let p = project()
1272 .file(
1273 "Cargo.toml",
1274 &format!(
1275 r#"
1276 [project]
1277
1278 name = "foo"
1279 version = "0.5.0"
1280 authors = ["wycats@example.com"]
1281
1282 [dev-dependencies.bar]
1283 version = "0.5.0"
1284 git = '{}'
1285 "#,
1286 p2.url()
1287 ),
1288 )
1289 .file(
1290 "src/main.rs",
1291 r#"
1292 fn main() {}
1293
1294 #[cfg(test)]
1295 mod tests {
1296 extern crate bar;
1297 #[test] fn foo() { bar::gimme(); }
1298 }
1299 "#,
1300 )
1301 .build();
1302
1303 // Generate a lock file which did not use `bar` to compile, but had to update
1304 // `bar` to generate the lock file
1305 p.cargo("build")
1306 .with_stderr(&format!(
1307 "\
1308 [UPDATING] git repository `{bar}`
1309 [COMPILING] foo v0.5.0 ([CWD])
1310 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1311 ",
1312 bar = p2.url()
1313 ))
1314 .run();
1315
1316 // Make sure we use the previous resolution of `bar` instead of updating it
1317 // a second time.
1318 p.cargo("test")
1319 .with_stderr(
1320 "\
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]",
1325 )
1326 .with_stdout_contains("test tests::foo ... ok")
1327 .run();
1328 }
1329
1330 #[cargo_test]
1331 fn git_build_cmd_freshness() {
1332 let foo = git::new("foo", |project| {
1333 project
1334 .file(
1335 "Cargo.toml",
1336 r#"
1337 [package]
1338 name = "foo"
1339 version = "0.0.0"
1340 authors = []
1341 build = "build.rs"
1342 "#,
1343 )
1344 .file("build.rs", "fn main() {}")
1345 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1346 .file(".gitignore", "src/bar.rs")
1347 })
1348 .unwrap();
1349 foo.root().move_into_the_past();
1350
1351 sleep_ms(1000);
1352
1353 foo.cargo("build")
1354 .with_stderr(
1355 "\
1356 [COMPILING] foo v0.0.0 ([CWD])
1357 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1358 ",
1359 )
1360 .run();
1361
1362 // Smoke test to make sure it doesn't compile again
1363 println!("first pass");
1364 foo.cargo("build").with_stdout("").run();
1365
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();
1370 }
1371
1372 #[cargo_test]
1373 fn git_name_not_always_needed() {
1374 let p2 = git::new("bar", |project| {
1375 project
1376 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1377 .file(
1378 "src/lib.rs",
1379 r#"
1380 pub fn gimme() -> &'static str { "zoidberg" }
1381 "#,
1382 )
1383 })
1384 .unwrap();
1385
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");
1390
1391 let p = project()
1392 .file(
1393 "Cargo.toml",
1394 &format!(
1395 r#"
1396 [project]
1397 name = "foo"
1398 version = "0.5.0"
1399 authors = []
1400
1401 [dev-dependencies.bar]
1402 git = '{}'
1403 "#,
1404 p2.url()
1405 ),
1406 )
1407 .file("src/main.rs", "fn main() {}")
1408 .build();
1409
1410 // Generate a lock file which did not use `bar` to compile, but had to update
1411 // `bar` to generate the lock file
1412 p.cargo("build")
1413 .with_stderr(&format!(
1414 "\
1415 [UPDATING] git repository `{bar}`
1416 [COMPILING] foo v0.5.0 ([CWD])
1417 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1418 ",
1419 bar = p2.url()
1420 ))
1421 .run();
1422 }
1423
1424 #[cargo_test]
1425 fn git_repo_changing_no_rebuild() {
1426 let bar = git::new("bar", |project| {
1427 project
1428 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1429 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1430 })
1431 .unwrap();
1432
1433 // Lock p1 to the first rev in the git repo
1434 let p1 = project()
1435 .at("p1")
1436 .file(
1437 "Cargo.toml",
1438 &format!(
1439 r#"
1440 [project]
1441 name = "p1"
1442 version = "0.5.0"
1443 authors = []
1444 build = 'build.rs'
1445 [dependencies.bar]
1446 git = '{}'
1447 "#,
1448 bar.url()
1449 ),
1450 )
1451 .file("src/main.rs", "fn main() {}")
1452 .file("build.rs", "fn main() {}")
1453 .build();
1454 p1.root().move_into_the_past();
1455 p1.cargo("build")
1456 .with_stderr(&format!(
1457 "\
1458 [UPDATING] git repository `{bar}`
1459 [COMPILING] [..]
1460 [COMPILING] [..]
1461 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1462 ",
1463 bar = bar.url()
1464 ))
1465 .run();
1466
1467 // Make a commit to lock p2 to a different rev
1468 File::create(&bar.root().join("src/lib.rs"))
1469 .unwrap()
1470 .write_all(br#"pub fn bar() -> i32 { 2 }"#)
1471 .unwrap();
1472 let repo = git2::Repository::open(&bar.root()).unwrap();
1473 git::add(&repo);
1474 git::commit(&repo);
1475
1476 // Lock p2 to the second rev
1477 let p2 = project()
1478 .at("p2")
1479 .file(
1480 "Cargo.toml",
1481 &format!(
1482 r#"
1483 [project]
1484 name = "p2"
1485 version = "0.5.0"
1486 authors = []
1487 [dependencies.bar]
1488 git = '{}'
1489 "#,
1490 bar.url()
1491 ),
1492 )
1493 .file("src/main.rs", "fn main() {}")
1494 .build();
1495 p2.cargo("build")
1496 .with_stderr(&format!(
1497 "\
1498 [UPDATING] git repository `{bar}`
1499 [COMPILING] [..]
1500 [COMPILING] [..]
1501 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1502 ",
1503 bar = bar.url()
1504 ))
1505 .run();
1506
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();
1510 }
1511
1512 #[cargo_test]
1513 fn git_dep_build_cmd() {
1514 let p = git::new("foo", |project| {
1515 project
1516 .file(
1517 "Cargo.toml",
1518 r#"
1519 [project]
1520
1521 name = "foo"
1522 version = "0.5.0"
1523 authors = ["wycats@example.com"]
1524
1525 [dependencies.bar]
1526
1527 version = "0.5.0"
1528 path = "bar"
1529
1530 [[bin]]
1531
1532 name = "foo"
1533 "#,
1534 )
1535 .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
1536 .file(
1537 "bar/Cargo.toml",
1538 r#"
1539 [project]
1540
1541 name = "bar"
1542 version = "0.5.0"
1543 authors = ["wycats@example.com"]
1544 build = "build.rs"
1545
1546 [lib]
1547 name = "bar"
1548 path = "src/bar.rs"
1549 "#,
1550 )
1551 .file(
1552 "bar/src/bar.rs.in",
1553 r#"
1554 pub fn gimme() -> i32 { 0 }
1555 "#,
1556 )
1557 .file(
1558 "bar/build.rs",
1559 r#"
1560 use std::fs;
1561 fn main() {
1562 fs::copy("src/bar.rs.in", "src/bar.rs").unwrap();
1563 }
1564 "#,
1565 )
1566 })
1567 .unwrap();
1568
1569 p.root().join("bar").move_into_the_past();
1570
1571 p.cargo("build").run();
1572
1573 p.process(&p.bin("foo")).with_stdout("0\n").run();
1574
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"))
1577 .unwrap()
1578 .write_all(b"pub fn gimme() -> i32 { 1 }")
1579 .unwrap();
1580
1581 p.cargo("build").run();
1582
1583 p.process(&p.bin("foo")).with_stdout("1\n").run();
1584 }
1585
1586 #[cargo_test]
1587 fn fetch_downloads() {
1588 let bar = git::new("bar", |project| {
1589 project
1590 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1591 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
1592 })
1593 .unwrap();
1594
1595 let p = project()
1596 .file(
1597 "Cargo.toml",
1598 &format!(
1599 r#"
1600 [project]
1601 name = "foo"
1602 version = "0.5.0"
1603 authors = []
1604 [dependencies.bar]
1605 git = '{}'
1606 "#,
1607 bar.url()
1608 ),
1609 )
1610 .file("src/main.rs", "fn main() {}")
1611 .build();
1612 p.cargo("fetch")
1613 .with_stderr(&format!(
1614 "[UPDATING] git repository `{url}`",
1615 url = bar.url()
1616 ))
1617 .run();
1618
1619 p.cargo("fetch").with_stdout("").run();
1620 }
1621
1622 #[cargo_test]
1623 fn warnings_in_git_dep() {
1624 let bar = git::new("bar", |project| {
1625 project
1626 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1627 .file("src/lib.rs", "fn unused() {}")
1628 })
1629 .unwrap();
1630
1631 let p = project()
1632 .file(
1633 "Cargo.toml",
1634 &format!(
1635 r#"
1636 [project]
1637 name = "foo"
1638 version = "0.5.0"
1639 authors = []
1640 [dependencies.bar]
1641 git = '{}'
1642 "#,
1643 bar.url()
1644 ),
1645 )
1646 .file("src/main.rs", "fn main() {}")
1647 .build();
1648
1649 p.cargo("build")
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",
1655 bar.url(),
1656 bar.url(),
1657 ))
1658 .run();
1659 }
1660
1661 #[cargo_test]
1662 fn update_ambiguous() {
1663 let bar1 = git::new("bar1", |project| {
1664 project
1665 .file("Cargo.toml", &basic_manifest("bar", "0.5.0"))
1666 .file("src/lib.rs", "")
1667 })
1668 .unwrap();
1669 let bar2 = git::new("bar2", |project| {
1670 project
1671 .file("Cargo.toml", &basic_manifest("bar", "0.6.0"))
1672 .file("src/lib.rs", "")
1673 })
1674 .unwrap();
1675 let baz = git::new("baz", |project| {
1676 project
1677 .file(
1678 "Cargo.toml",
1679 &format!(
1680 r#"
1681 [package]
1682 name = "baz"
1683 version = "0.5.0"
1684 authors = ["wycats@example.com"]
1685
1686 [dependencies.bar]
1687 git = '{}'
1688 "#,
1689 bar2.url()
1690 ),
1691 )
1692 .file("src/lib.rs", "")
1693 })
1694 .unwrap();
1695
1696 let p = project()
1697 .file(
1698 "Cargo.toml",
1699 &format!(
1700 r#"
1701 [project]
1702 name = "foo"
1703 version = "0.5.0"
1704 authors = []
1705 [dependencies.bar]
1706 git = '{}'
1707 [dependencies.baz]
1708 git = '{}'
1709 "#,
1710 bar1.url(),
1711 baz.url()
1712 ),
1713 )
1714 .file("src/main.rs", "fn main() {}")
1715 .build();
1716
1717 p.cargo("generate-lockfile").run();
1718 p.cargo("update -p bar")
1719 .with_status(101)
1720 .with_stderr(
1721 "\
1722 [ERROR] There are multiple `bar` packages in your project, and the specification `bar` \
1723 is ambiguous.
1724 Please re-run this command with `-p <spec>` where `<spec>` is one of the \
1725 following:
1726 bar:0.[..].0
1727 bar:0.[..].0
1728 ",
1729 )
1730 .run();
1731 }
1732
1733 #[cargo_test]
1734 fn update_one_dep_in_repo_with_many_deps() {
1735 let bar = git::new("bar", |project| {
1736 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", "")
1741 })
1742 .unwrap();
1743
1744 let p = project()
1745 .file(
1746 "Cargo.toml",
1747 &format!(
1748 r#"
1749 [project]
1750 name = "foo"
1751 version = "0.5.0"
1752 authors = []
1753 [dependencies.bar]
1754 git = '{}'
1755 [dependencies.a]
1756 git = '{}'
1757 "#,
1758 bar.url(),
1759 bar.url()
1760 ),
1761 )
1762 .file("src/main.rs", "fn main() {}")
1763 .build();
1764
1765 p.cargo("generate-lockfile").run();
1766 p.cargo("update -p bar")
1767 .with_stderr(&format!("[UPDATING] git repository `{}`", bar.url()))
1768 .run();
1769 }
1770
1771 #[cargo_test]
1772 fn switch_deps_does_not_update_transitive() {
1773 let transitive = git::new("transitive", |project| {
1774 project
1775 .file("Cargo.toml", &basic_manifest("transitive", "0.5.0"))
1776 .file("src/lib.rs", "")
1777 })
1778 .unwrap();
1779 let dep1 = git::new("dep1", |project| {
1780 project
1781 .file(
1782 "Cargo.toml",
1783 &format!(
1784 r#"
1785 [package]
1786 name = "dep"
1787 version = "0.5.0"
1788 authors = ["wycats@example.com"]
1789
1790 [dependencies.transitive]
1791 git = '{}'
1792 "#,
1793 transitive.url()
1794 ),
1795 )
1796 .file("src/lib.rs", "")
1797 })
1798 .unwrap();
1799 let dep2 = git::new("dep2", |project| {
1800 project
1801 .file(
1802 "Cargo.toml",
1803 &format!(
1804 r#"
1805 [package]
1806 name = "dep"
1807 version = "0.5.0"
1808 authors = ["wycats@example.com"]
1809
1810 [dependencies.transitive]
1811 git = '{}'
1812 "#,
1813 transitive.url()
1814 ),
1815 )
1816 .file("src/lib.rs", "")
1817 })
1818 .unwrap();
1819
1820 let p = project()
1821 .file(
1822 "Cargo.toml",
1823 &format!(
1824 r#"
1825 [project]
1826 name = "foo"
1827 version = "0.5.0"
1828 authors = []
1829 [dependencies.dep]
1830 git = '{}'
1831 "#,
1832 dep1.url()
1833 ),
1834 )
1835 .file("src/main.rs", "fn main() {}")
1836 .build();
1837
1838 p.cargo("build")
1839 .with_stderr(&format!(
1840 "\
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 [..]
1847 ",
1848 dep1.url(),
1849 transitive.url()
1850 ))
1851 .run();
1852
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"))
1856 .unwrap()
1857 .write_all(
1858 format!(
1859 r#"
1860 [project]
1861 name = "foo"
1862 version = "0.5.0"
1863 authors = []
1864 [dependencies.dep]
1865 git = '{}'
1866 "#,
1867 dep2.url()
1868 )
1869 .as_bytes(),
1870 )
1871 .unwrap();
1872
1873 p.cargo("build")
1874 .with_stderr(&format!(
1875 "\
1876 [UPDATING] git repository `{}`
1877 [COMPILING] dep [..]
1878 [COMPILING] foo [..]
1879 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1880 ",
1881 dep2.url()
1882 ))
1883 .run();
1884 }
1885
1886 #[cargo_test]
1887 fn update_one_source_updates_all_packages_in_that_git_source() {
1888 let dep = git::new("dep", |project| {
1889 project
1890 .file(
1891 "Cargo.toml",
1892 r#"
1893 [package]
1894 name = "dep"
1895 version = "0.5.0"
1896 authors = []
1897
1898 [dependencies.a]
1899 path = "a"
1900 "#,
1901 )
1902 .file("src/lib.rs", "")
1903 .file("a/Cargo.toml", &basic_manifest("a", "0.5.0"))
1904 .file("a/src/lib.rs", "")
1905 })
1906 .unwrap();
1907
1908 let p = project()
1909 .file(
1910 "Cargo.toml",
1911 &format!(
1912 r#"
1913 [project]
1914 name = "foo"
1915 version = "0.5.0"
1916 authors = []
1917 [dependencies.dep]
1918 git = '{}'
1919 "#,
1920 dep.url()
1921 ),
1922 )
1923 .file("src/main.rs", "fn main() {}")
1924 .build();
1925
1926 p.cargo("build").run();
1927
1928 let repo = git2::Repository::open(&dep.root()).unwrap();
1929 let rev1 = repo.revparse_single("HEAD").unwrap().id();
1930
1931 // Just be sure to change a file
1932 File::create(&dep.root().join("src/lib.rs"))
1933 .unwrap()
1934 .write_all(br#"pub fn bar() -> i32 { 2 }"#)
1935 .unwrap();
1936 git::add(&repo);
1937 git::commit(&repo);
1938
1939 p.cargo("update -p dep").run();
1940 let mut lockfile = String::new();
1941 File::open(&p.root().join("Cargo.lock"))
1942 .unwrap()
1943 .read_to_string(&mut lockfile)
1944 .unwrap();
1945 assert!(
1946 !lockfile.contains(&rev1.to_string()),
1947 "{} in {}",
1948 rev1,
1949 lockfile
1950 );
1951 }
1952
1953 #[cargo_test]
1954 fn switch_sources() {
1955 let a1 = git::new("a1", |project| {
1956 project
1957 .file("Cargo.toml", &basic_manifest("a", "0.5.0"))
1958 .file("src/lib.rs", "")
1959 })
1960 .unwrap();
1961 let a2 = git::new("a2", |project| {
1962 project
1963 .file("Cargo.toml", &basic_manifest("a", "0.5.1"))
1964 .file("src/lib.rs", "")
1965 })
1966 .unwrap();
1967
1968 let p = project()
1969 .file(
1970 "Cargo.toml",
1971 r#"
1972 [project]
1973 name = "foo"
1974 version = "0.5.0"
1975 authors = []
1976 [dependencies.b]
1977 path = "b"
1978 "#,
1979 )
1980 .file("src/main.rs", "fn main() {}")
1981 .file(
1982 "b/Cargo.toml",
1983 &format!(
1984 r#"
1985 [project]
1986 name = "b"
1987 version = "0.5.0"
1988 authors = []
1989 [dependencies.a]
1990 git = '{}'
1991 "#,
1992 a1.url()
1993 ),
1994 )
1995 .file("b/src/lib.rs", "pub fn main() {}")
1996 .build();
1997
1998 p.cargo("build")
1999 .with_stderr(
2000 "\
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 [..]
2006 ",
2007 )
2008 .run();
2009
2010 File::create(&p.root().join("b/Cargo.toml"))
2011 .unwrap()
2012 .write_all(
2013 format!(
2014 r#"
2015 [project]
2016 name = "b"
2017 version = "0.5.0"
2018 authors = []
2019 [dependencies.a]
2020 git = '{}'
2021 "#,
2022 a2.url()
2023 )
2024 .as_bytes(),
2025 )
2026 .unwrap();
2027
2028 p.cargo("build")
2029 .with_stderr(
2030 "\
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 [..]
2036 ",
2037 )
2038 .run();
2039 }
2040
2041 #[cargo_test]
2042 fn dont_require_submodules_are_checked_out() {
2043 let p = project().build();
2044 let git1 = git::new("dep1", |p| {
2045 p.file(
2046 "Cargo.toml",
2047 r#"
2048 [project]
2049 name = "foo"
2050 version = "0.5.0"
2051 authors = []
2052 build = "build.rs"
2053 "#,
2054 )
2055 .file("build.rs", "fn main() {}")
2056 .file("src/lib.rs", "")
2057 .file("a/foo", "")
2058 })
2059 .unwrap();
2060 let git2 = git::new("dep2", |p| p).unwrap();
2061
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"));
2065 git::commit(&repo);
2066
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();
2071
2072 git1.cargo("build -v").cwd(&dst).run();
2073 }
2074
2075 #[cargo_test]
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() {}")
2080 })
2081 .unwrap();
2082
2083 let a1 = git::new("a1", |p| {
2084 p.file(
2085 "Cargo.toml",
2086 &format!(
2087 r#"
2088 [project]
2089 name = "a"
2090 version = "0.5.0"
2091 authors = []
2092 [dependencies]
2093 a = {{ git = '{}' }}
2094 "#,
2095 a2.url()
2096 ),
2097 )
2098 .file("src/lib.rs", "extern crate a; pub fn a1() {}")
2099 })
2100 .unwrap();
2101
2102 let p = project()
2103 .file(
2104 "Cargo.toml",
2105 &format!(
2106 r#"
2107 [package]
2108 name = "foo"
2109 version = "0.0.1"
2110 authors = []
2111
2112 [dependencies]
2113 a = {{ git = '{}' }}
2114 "#,
2115 a1.url()
2116 ),
2117 )
2118 .file(
2119 "src/lib.rs",
2120 r#"
2121 #[macro_use]
2122 extern crate a;
2123 "#,
2124 )
2125 .build();
2126
2127 p.cargo("test -v").run();
2128 }
2129
2130 #[cargo_test]
2131 fn lints_are_suppressed() {
2132 let a = git::new("a", |p| {
2133 p.file("Cargo.toml", &basic_manifest("a", "0.5.0")).file(
2134 "src/lib.rs",
2135 "
2136 use std::option;
2137 ",
2138 )
2139 })
2140 .unwrap();
2141
2142 let p = project()
2143 .file(
2144 "Cargo.toml",
2145 &format!(
2146 r#"
2147 [package]
2148 name = "foo"
2149 version = "0.0.1"
2150 authors = []
2151
2152 [dependencies]
2153 a = {{ git = '{}' }}
2154 "#,
2155 a.url()
2156 ),
2157 )
2158 .file("src/lib.rs", "")
2159 .build();
2160
2161 p.cargo("build")
2162 .with_stderr(
2163 "\
2164 [UPDATING] git repository `[..]`
2165 [COMPILING] a v0.5.0 ([..])
2166 [COMPILING] foo v0.0.1 ([..])
2167 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2168 ",
2169 )
2170 .run();
2171 }
2172
2173 #[cargo_test]
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(
2177 "src/lib.rs",
2178 "
2179 #![deny(warnings)]
2180 use std::option;
2181 ",
2182 )
2183 })
2184 .unwrap();
2185
2186 let p = project()
2187 .file(
2188 "Cargo.toml",
2189 &format!(
2190 r#"
2191 [package]
2192 name = "foo"
2193 version = "0.0.1"
2194 authors = []
2195
2196 [dependencies]
2197 a = {{ git = '{}' }}
2198 "#,
2199 a.url()
2200 ),
2201 )
2202 .file("src/lib.rs", "")
2203 .build();
2204
2205 p.cargo("build")
2206 .with_stderr(
2207 "\
2208 [UPDATING] git repository `[..]`
2209 [COMPILING] a v0.5.0 ([..])
2210 [COMPILING] foo v0.0.1 ([..])
2211 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2212 ",
2213 )
2214 .run();
2215 }
2216
2217 #[cargo_test]
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", "")
2222 })
2223 .unwrap();
2224
2225 let p = project()
2226 .file(
2227 "Cargo.toml",
2228 &format!(
2229 r#"
2230 [package]
2231 name = "foo"
2232 version = "0.0.1"
2233 authors = []
2234
2235 [dependencies]
2236 a = {{ path = 'a' }}
2237 git = {{ git = '{}' }}
2238 "#,
2239 git.url()
2240 ),
2241 )
2242 .file("src/lib.rs", "")
2243 .file("a/Cargo.toml", &basic_manifest("a", "0.0.1"))
2244 .file("a/src/lib.rs", "")
2245 .build();
2246
2247 p.cargo("build").run();
2248
2249 File::create(p.root().join("a/Cargo.toml"))
2250 .unwrap()
2251 .write_all(
2252 format!(
2253 r#"
2254 [package]
2255 name = "a"
2256 version = "0.0.1"
2257 authors = []
2258
2259 [dependencies]
2260 git = {{ git = '{}' }}
2261 "#,
2262 git.url()
2263 )
2264 .as_bytes(),
2265 )
2266 .unwrap();
2267
2268 p.cargo("build").run();
2269 }
2270
2271 #[cargo_test]
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", "")
2278 })
2279 .unwrap();
2280
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();
2284 repo.tag(
2285 "v0.1.0",
2286 &repo.find_object(head, None).unwrap(),
2287 &repo.signature().unwrap(),
2288 "make a new tag",
2289 false,
2290 )
2291 .unwrap();
2292
2293 let p = project()
2294 .file(
2295 "Cargo.toml",
2296 &format!(
2297 r#"
2298 [package]
2299 name = "foo"
2300 version = "0.0.1"
2301 authors = []
2302
2303 [dependencies]
2304 git1 = {{ git = '{0}', rev = 'v0.1.0' }}
2305 git2 = {{ git = '{0}', rev = 'v0.1.0' }}
2306 "#,
2307 git.url()
2308 ),
2309 )
2310 .file("src/lib.rs", "")
2311 .build();
2312
2313 p.cargo("generate-lockfile").run();
2314 p.cargo("build -v").run();
2315 }
2316
2317 #[cargo_test]
2318 fn include_overrides_gitignore() {
2319 // Make sure that `package.include` takes precedence over .gitignore.
2320 let p = git::new("foo", |repo| {
2321 repo.file(
2322 "Cargo.toml",
2323 r#"
2324 [package]
2325 name = "foo"
2326 version = "0.5.0"
2327 include = ["src/lib.rs", "ignored.txt", "Cargo.toml"]
2328 "#,
2329 )
2330 .file(
2331 ".gitignore",
2332 r#"
2333 /target
2334 Cargo.lock
2335 ignored.txt
2336 "#,
2337 )
2338 .file("src/lib.rs", "")
2339 .file("ignored.txt", "")
2340 .file("build.rs", "fn main() {}")
2341 })
2342 .unwrap();
2343
2344 p.cargo("build").run();
2345 p.change_file("ignored.txt", "Trigger rebuild.");
2346 p.cargo("build -v")
2347 .with_stderr(
2348 "\
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 [..]
2353 ",
2354 )
2355 .run();
2356 p.cargo("package --list --allow-dirty")
2357 .with_stdout(
2358 "\
2359 Cargo.toml
2360 ignored.txt
2361 src/lib.rs
2362 ",
2363 )
2364 .run();
2365 }
2366
2367 #[cargo_test]
2368 fn invalid_git_dependency_manifest() {
2369 let project = project();
2370 let git_project = git::new("dep1", |project| {
2371 project
2372 .file(
2373 "Cargo.toml",
2374 r#"
2375 [project]
2376
2377 name = "dep1"
2378 version = "0.5.0"
2379 authors = ["carlhuda@example.com"]
2380 categories = ["algorithms"]
2381 categories = ["algorithms"]
2382
2383 [lib]
2384
2385 name = "dep1"
2386 "#,
2387 )
2388 .file(
2389 "src/dep1.rs",
2390 r#"
2391 pub fn hello() -> &'static str {
2392 "hello world"
2393 }
2394 "#,
2395 )
2396 })
2397 .unwrap();
2398
2399 let project = project
2400 .file(
2401 "Cargo.toml",
2402 &format!(
2403 r#"
2404 [project]
2405
2406 name = "foo"
2407 version = "0.5.0"
2408 authors = ["wycats@example.com"]
2409
2410 [dependencies.dep1]
2411
2412 git = '{}'
2413 "#,
2414 git_project.url()
2415 ),
2416 )
2417 .file(
2418 "src/main.rs",
2419 &main_file(r#""{}", dep1::hello()"#, &["dep1"]),
2420 )
2421 .build();
2422
2423 let git_root = git_project.root();
2424
2425 project
2426 .cargo("build")
2427 .with_status(101)
2428 .with_stderr(&format!(
2429 "[UPDATING] git repository `{}`\n\
2430 error: failed to load source for a dependency on `dep1`\n\
2431 \n\
2432 Caused by:\n \
2433 Unable to update {}\n\
2434 \n\
2435 Caused by:\n \
2436 failed to parse manifest at `[..]`\n\
2437 \n\
2438 Caused by:\n \
2439 could not parse input as TOML\n\
2440 \n\
2441 Caused by:\n \
2442 duplicate key: `categories` for key `project`",
2443 path2url(&git_root),
2444 path2url(&git_root),
2445 ))
2446 .run();
2447 }
2448
2449 #[cargo_test]
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"))
2454 })
2455 .unwrap();
2456
2457 let git_project2 = git::new("dep2", |project| project.file("lib.rs", "")).unwrap();
2458
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();
2463
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"));
2468 }
2469 }
2470 });
2471
2472 let repo = git2::Repository::open(&git_project2.root()).unwrap();
2473 let url = format!("https://{}:{}/", addr.ip(), addr.port());
2474 {
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();
2482 }
2483 git::commit(&repo);
2484 drop((repo, url));
2485
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"));
2489 git::commit(&repo);
2490 drop(repo);
2491
2492 let project = project
2493 .file(
2494 "Cargo.toml",
2495 &format!(
2496 r#"
2497 [project]
2498 name = "foo"
2499 version = "0.5.0"
2500 authors = []
2501
2502 [dependencies]
2503 dep1 = {{ git = '{}' }}
2504 "#,
2505 git_project.url()
2506 ),
2507 )
2508 .file("src/lib.rs", "")
2509 .build();
2510
2511 project
2512 .cargo("build")
2513 .with_status(101)
2514 .with_stderr_contains(" failed to update submodule `src`")
2515 .with_stderr_contains(" failed to update submodule `bar`")
2516 .run();
2517 project
2518 .cargo("build")
2519 .with_status(101)
2520 .with_stderr_contains(" failed to update submodule `src`")
2521 .with_stderr_contains(" failed to update submodule `bar`")
2522 .run();
2523
2524 done.store(true, Ordering::SeqCst);
2525 drop(TcpStream::connect(&addr));
2526 t.join().unwrap();
2527 }
2528
2529 #[cargo_test]
2530 fn use_the_cli() {
2531 if disable_git_cli() {
2532 return;
2533 }
2534 let project = project();
2535 let git_project = git::new("dep1", |project| {
2536 project
2537 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2538 .file("src/lib.rs", "")
2539 })
2540 .unwrap();
2541
2542 let project = project
2543 .file(
2544 "Cargo.toml",
2545 &format!(
2546 r#"
2547 [project]
2548 name = "foo"
2549 version = "0.5.0"
2550 authors = []
2551
2552 [dependencies]
2553 dep1 = {{ git = '{}' }}
2554 "#,
2555 git_project.url()
2556 ),
2557 )
2558 .file("src/lib.rs", "")
2559 .file(
2560 ".cargo/config",
2561 "
2562 [net]
2563 git-fetch-with-cli = true
2564 ",
2565 )
2566 .build();
2567
2568 let stderr = "\
2569 [UPDATING] git repository `[..]`
2570 [RUNNING] `git fetch [..]`
2571 [COMPILING] dep1 [..]
2572 [RUNNING] `rustc [..]`
2573 [COMPILING] foo [..]
2574 [RUNNING] `rustc [..]`
2575 [FINISHED] [..]
2576 ";
2577
2578 project.cargo("build -v").with_stderr(stderr).run();
2579 }
2580
2581 #[cargo_test]
2582 fn templatedir_doesnt_cause_problems() {
2583 let git_project2 = git::new("dep2", |project| {
2584 project
2585 .file("Cargo.toml", &basic_manifest("dep2", "0.5.0"))
2586 .file("src/lib.rs", "")
2587 })
2588 .unwrap();
2589 let git_project = git::new("dep1", |project| {
2590 project
2591 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2592 .file("src/lib.rs", "")
2593 })
2594 .unwrap();
2595 let p = project()
2596 .file(
2597 "Cargo.toml",
2598 &format!(
2599 r#"
2600 [project]
2601 name = "fo"
2602 version = "0.5.0"
2603 authors = []
2604
2605 [dependencies]
2606 dep1 = {{ git = '{}' }}
2607 "#,
2608 git_project.url()
2609 ),
2610 )
2611 .file("src/main.rs", "fn main() {}")
2612 .build();
2613
2614 File::create(paths::home().join(".gitconfig"))
2615 .unwrap()
2616 .write_all(
2617 format!(
2618 r#"
2619 [init]
2620 templatedir = {}
2621 "#,
2622 git_project2
2623 .url()
2624 .to_file_path()
2625 .unwrap()
2626 .to_str()
2627 .unwrap()
2628 .replace("\\", "/")
2629 )
2630 .as_bytes(),
2631 )
2632 .unwrap();
2633
2634 p.cargo("build").run();
2635 }
2636
2637 #[cargo_test]
2638 fn git_with_cli_force() {
2639 if disable_git_cli() {
2640 return;
2641 }
2642 // Supports a force-pushed repo.
2643 let git_project = git::new("dep1", |project| {
2644 project
2645 .file("Cargo.toml", &basic_lib_manifest("dep1"))
2646 .file("src/lib.rs", r#"pub fn f() { println!("one"); }"#)
2647 })
2648 .unwrap();
2649 let p = project()
2650 .file(
2651 "Cargo.toml",
2652 &format!(
2653 r#"
2654 [project]
2655 name = "foo"
2656 version = "0.0.1"
2657 edition = "2018"
2658
2659 [dependencies]
2660 dep1 = {{ git = "{}" }}
2661 "#,
2662 git_project.url()
2663 ),
2664 )
2665 .file("src/main.rs", "fn main() { dep1::f(); }")
2666 .file(
2667 ".cargo/config",
2668 "
2669 [net]
2670 git-fetch-with-cli = true
2671 ",
2672 )
2673 .build();
2674 p.cargo("build").run();
2675 p.rename_run("foo", "foo1").with_stdout("one").run();
2676
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"); }"#);
2680 git::add(&repo);
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());
2684 t!(commit.amend(
2685 Some("HEAD"),
2686 None,
2687 None,
2688 None,
2689 None,
2690 Some(&t!(repo.find_tree(tree_id)))
2691 ));
2692 // Perform the fetch.
2693 p.cargo("update").run();
2694 p.cargo("build").run();
2695 p.rename_run("foo", "foo2").with_stdout("two").run();
2696 }
2697
2698 #[cargo_test]
2699 fn git_fetch_cli_env_clean() {
2700 if disable_git_cli() {
2701 return;
2702 }
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| {
2706 project
2707 .file("Cargo.toml", &basic_manifest("dep1", "0.5.0"))
2708 .file("src/lib.rs", "")
2709 })
2710 .unwrap();
2711
2712 let git_proj = git::new("foo", |project| {
2713 project
2714 .file(
2715 "Cargo.toml",
2716 &format!(
2717 r#"
2718 [package]
2719 name = "foo"
2720 version = "0.1.0"
2721 [dependencies]
2722 dep1 = {{ git = '{}' }}
2723 "#,
2724 git_dep.url()
2725 ),
2726 )
2727 .file("src/lib.rs", "pub extern crate dep1;")
2728 .file(
2729 ".cargo/config",
2730 "
2731 [net]
2732 git-fetch-with-cli = true
2733 ",
2734 )
2735 })
2736 .unwrap();
2737
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.
2741 git_proj
2742 .cargo("fetch")
2743 .env("GIT_DIR", git_proj.root().join(".git"))
2744 .run();
2745 }