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