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