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