]> git.proxmox.com Git - rustc.git/blob - src/tools/cargo/tests/testsuite/patch.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / src / tools / cargo / tests / testsuite / patch.rs
1 //! Tests for `[patch]` table source replacement.
2
3 use cargo_test_support::git;
4 use cargo_test_support::paths;
5 use cargo_test_support::registry::{self, Package};
6 use cargo_test_support::{basic_manifest, project};
7 use std::fs;
8
9 #[cargo_test]
10 fn replace() {
11 Package::new("bar", "0.1.0").publish();
12 Package::new("baz", "0.1.0")
13 .file(
14 "src/lib.rs",
15 "extern crate bar; pub fn baz() { bar::bar(); }",
16 )
17 .dep("bar", "0.1.0")
18 .publish();
19
20 let p = project()
21 .file(
22 "Cargo.toml",
23 r#"
24 [package]
25 name = "foo"
26 version = "0.0.1"
27 authors = []
28
29 [dependencies]
30 bar = "0.1.0"
31 baz = "0.1.0"
32
33 [patch.crates-io]
34 bar = { path = "bar" }
35 "#,
36 )
37 .file(
38 "src/lib.rs",
39 "
40 extern crate bar;
41 extern crate baz;
42 pub fn bar() {
43 bar::bar();
44 baz::baz();
45 }
46 ",
47 )
48 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
49 .file("bar/src/lib.rs", "pub fn bar() {}")
50 .build();
51
52 p.cargo("check")
53 .with_stderr(
54 "\
55 [UPDATING] `dummy-registry` index
56 [DOWNLOADING] crates ...
57 [DOWNLOADED] baz v0.1.0 ([..])
58 [CHECKING] bar v0.1.0 ([CWD]/bar)
59 [CHECKING] baz v0.1.0
60 [CHECKING] foo v0.0.1 ([CWD])
61 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
62 ",
63 )
64 .run();
65
66 p.cargo("check").with_stderr("[FINISHED] [..]").run();
67 }
68
69 #[cargo_test]
70 fn from_config() {
71 Package::new("bar", "0.1.0").publish();
72
73 let p = project()
74 .file(
75 "Cargo.toml",
76 r#"
77 [package]
78 name = "foo"
79 version = "0.0.1"
80 authors = []
81
82 [dependencies]
83 bar = "0.1.0"
84 "#,
85 )
86 .file(
87 ".cargo/config.toml",
88 r#"
89 [patch.crates-io]
90 bar = { path = 'bar' }
91 "#,
92 )
93 .file("src/lib.rs", "")
94 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
95 .file("bar/src/lib.rs", r#""#)
96 .build();
97
98 p.cargo("check")
99 .with_stderr(
100 "\
101 [UPDATING] `dummy-registry` index
102 [CHECKING] bar v0.1.1 ([..])
103 [CHECKING] foo v0.0.1 ([CWD])
104 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
105 ",
106 )
107 .run();
108 }
109
110 #[cargo_test]
111 fn from_config_relative() {
112 Package::new("bar", "0.1.0").publish();
113
114 let p = project()
115 .file(
116 "Cargo.toml",
117 r#"
118 [package]
119 name = "foo"
120 version = "0.0.1"
121 authors = []
122
123 [dependencies]
124 bar = "0.1.0"
125 "#,
126 )
127 .file(
128 "../.cargo/config.toml",
129 r#"
130 [patch.crates-io]
131 bar = { path = 'foo/bar' }
132 "#,
133 )
134 .file("src/lib.rs", "")
135 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
136 .file("bar/src/lib.rs", r#""#)
137 .build();
138
139 p.cargo("check")
140 .with_stderr(
141 "\
142 [UPDATING] `dummy-registry` index
143 [CHECKING] bar v0.1.1 ([..])
144 [CHECKING] foo v0.0.1 ([CWD])
145 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
146 ",
147 )
148 .run();
149 }
150
151 #[cargo_test]
152 fn from_config_precedence() {
153 Package::new("bar", "0.1.0").publish();
154
155 let p = project()
156 .file(
157 "Cargo.toml",
158 r#"
159 [package]
160 name = "foo"
161 version = "0.0.1"
162 authors = []
163
164 [dependencies]
165 bar = "0.1.0"
166
167 [patch.crates-io]
168 bar = { path = 'no-such-path' }
169 "#,
170 )
171 .file(
172 ".cargo/config.toml",
173 r#"
174 [patch.crates-io]
175 bar = { path = 'bar' }
176 "#,
177 )
178 .file("src/lib.rs", "")
179 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
180 .file("bar/src/lib.rs", r#""#)
181 .build();
182
183 p.cargo("check")
184 .with_stderr(
185 "\
186 [UPDATING] `dummy-registry` index
187 [CHECKING] bar v0.1.1 ([..])
188 [CHECKING] foo v0.0.1 ([CWD])
189 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
190 ",
191 )
192 .run();
193 }
194
195 #[cargo_test]
196 fn nonexistent() {
197 Package::new("baz", "0.1.0").publish();
198
199 let p = project()
200 .file(
201 "Cargo.toml",
202 r#"
203 [package]
204 name = "foo"
205 version = "0.0.1"
206 authors = []
207
208 [dependencies]
209 bar = "0.1.0"
210
211 [patch.crates-io]
212 bar = { path = "bar" }
213 "#,
214 )
215 .file(
216 "src/lib.rs",
217 "extern crate bar; pub fn foo() { bar::bar(); }",
218 )
219 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
220 .file("bar/src/lib.rs", "pub fn bar() {}")
221 .build();
222
223 p.cargo("check")
224 .with_stderr(
225 "\
226 [UPDATING] `dummy-registry` index
227 [CHECKING] bar v0.1.0 ([CWD]/bar)
228 [CHECKING] foo v0.0.1 ([CWD])
229 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
230 ",
231 )
232 .run();
233 p.cargo("check").with_stderr("[FINISHED] [..]").run();
234 }
235
236 #[cargo_test]
237 fn patch_git() {
238 let bar = git::repo(&paths::root().join("override"))
239 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
240 .file("src/lib.rs", "")
241 .build();
242
243 let p = project()
244 .file(
245 "Cargo.toml",
246 &format!(
247 r#"
248 [package]
249 name = "foo"
250 version = "0.0.1"
251 authors = []
252
253 [dependencies]
254 bar = {{ git = '{}' }}
255
256 [patch.'{0}']
257 bar = {{ path = "bar" }}
258 "#,
259 bar.url()
260 ),
261 )
262 .file(
263 "src/lib.rs",
264 "extern crate bar; pub fn foo() { bar::bar(); }",
265 )
266 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
267 .file("bar/src/lib.rs", "pub fn bar() {}")
268 .build();
269
270 p.cargo("check")
271 .with_stderr(
272 "\
273 [UPDATING] git repository `file://[..]`
274 [CHECKING] bar v0.1.0 ([CWD]/bar)
275 [CHECKING] foo v0.0.1 ([CWD])
276 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
277 ",
278 )
279 .run();
280 p.cargo("check").with_stderr("[FINISHED] [..]").run();
281 }
282
283 #[cargo_test]
284 fn patch_to_git() {
285 let bar = git::repo(&paths::root().join("override"))
286 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
287 .file("src/lib.rs", "pub fn bar() {}")
288 .build();
289
290 Package::new("bar", "0.1.0").publish();
291
292 let p = project()
293 .file(
294 "Cargo.toml",
295 &format!(
296 r#"
297 [package]
298 name = "foo"
299 version = "0.0.1"
300 authors = []
301
302 [dependencies]
303 bar = "0.1"
304
305 [patch.crates-io]
306 bar = {{ git = '{}' }}
307 "#,
308 bar.url()
309 ),
310 )
311 .file(
312 "src/lib.rs",
313 "extern crate bar; pub fn foo() { bar::bar(); }",
314 )
315 .build();
316
317 p.cargo("check")
318 .with_stderr(
319 "\
320 [UPDATING] git repository `file://[..]`
321 [UPDATING] `dummy-registry` index
322 [CHECKING] bar v0.1.0 (file://[..])
323 [CHECKING] foo v0.0.1 ([CWD])
324 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
325 ",
326 )
327 .run();
328 p.cargo("check").with_stderr("[FINISHED] [..]").run();
329 }
330
331 #[cargo_test]
332 fn unused() {
333 Package::new("bar", "0.1.0").publish();
334
335 let p = project()
336 .file(
337 "Cargo.toml",
338 r#"
339 [package]
340 name = "foo"
341 version = "0.0.1"
342 authors = []
343
344 [dependencies]
345 bar = "0.1.0"
346
347 [patch.crates-io]
348 bar = { path = "bar" }
349 "#,
350 )
351 .file("src/lib.rs", "")
352 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
353 .file("bar/src/lib.rs", "not rust code")
354 .build();
355
356 p.cargo("check")
357 .with_stderr(
358 "\
359 [UPDATING] `dummy-registry` index
360 [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
361 Check that [..]
362 with the [..]
363 what is [..]
364 version. [..]
365 [DOWNLOADING] crates ...
366 [DOWNLOADED] bar v0.1.0 [..]
367 [CHECKING] bar v0.1.0
368 [CHECKING] foo v0.0.1 ([CWD])
369 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
370 ",
371 )
372 .run();
373 p.cargo("check")
374 .with_stderr(
375 "\
376 [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
377 Check that [..]
378 with the [..]
379 what is [..]
380 version. [..]
381 [FINISHED] [..]
382 ",
383 )
384 .run();
385
386 // unused patch should be in the lock file
387 let lock = p.read_lockfile();
388 let toml: toml::Table = toml::from_str(&lock).unwrap();
389 assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
390 assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
391 assert_eq!(
392 toml["patch"]["unused"][0]["version"].as_str(),
393 Some("0.2.0")
394 );
395 }
396
397 #[cargo_test]
398 fn unused_with_mismatch_source_being_patched() {
399 registry::alt_init();
400 Package::new("bar", "0.1.0").publish();
401
402 let p = project()
403 .file(
404 "Cargo.toml",
405 r#"
406 [package]
407 name = "foo"
408 version = "0.0.1"
409 authors = []
410
411 [dependencies]
412 bar = "0.1.0"
413
414 [patch.alternative]
415 bar = { path = "bar" }
416
417 [patch.crates-io]
418 bar = { path = "baz" }
419 "#,
420 )
421 .file("src/lib.rs", "")
422 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
423 .file("bar/src/lib.rs", "not rust code")
424 .file("baz/Cargo.toml", &basic_manifest("bar", "0.3.0"))
425 .file("baz/src/lib.rs", "not rust code")
426 .build();
427
428 p.cargo("check")
429 .with_stderr(
430 "\
431 [UPDATING] `dummy-registry` index
432 [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
433 Perhaps you misspelled the source URL being patched.
434 Possible URLs for `[patch.<URL>]`:
435 crates-io
436 [WARNING] Patch `bar v0.3.0 ([CWD]/baz)` was not used in the crate graph.
437 Check that [..]
438 with the [..]
439 what is [..]
440 version. [..]
441 [DOWNLOADING] crates ...
442 [DOWNLOADED] bar v0.1.0 [..]
443 [CHECKING] bar v0.1.0
444 [CHECKING] foo v0.0.1 ([CWD])
445 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
446 ",
447 )
448 .run();
449 }
450
451 #[cargo_test]
452 fn prefer_patch_version() {
453 Package::new("bar", "0.1.2").publish();
454
455 let p = project()
456 .file(
457 "Cargo.toml",
458 r#"
459 [package]
460 name = "foo"
461 version = "0.0.1"
462 authors = []
463
464 [dependencies]
465 bar = "0.1.0"
466
467 [patch.crates-io]
468 bar = { path = "bar" }
469 "#,
470 )
471 .file("src/lib.rs", "")
472 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
473 .file("bar/src/lib.rs", "")
474 .build();
475
476 p.cargo("check")
477 .with_stderr(
478 "\
479 [UPDATING] `dummy-registry` index
480 [CHECKING] bar v0.1.1 ([CWD]/bar)
481 [CHECKING] foo v0.0.1 ([CWD])
482 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
483 ",
484 )
485 .run();
486 p.cargo("check")
487 .with_stderr(
488 "\
489 [FINISHED] [..]
490 ",
491 )
492 .run();
493
494 // there should be no patch.unused in the toml file
495 let lock = p.read_lockfile();
496 let toml: toml::Table = toml::from_str(&lock).unwrap();
497 assert!(toml.get("patch").is_none());
498 }
499
500 #[cargo_test]
501 fn unused_from_config() {
502 Package::new("bar", "0.1.0").publish();
503
504 let p = project()
505 .file(
506 "Cargo.toml",
507 r#"
508 [package]
509 name = "foo"
510 version = "0.0.1"
511 authors = []
512
513 [dependencies]
514 bar = "0.1.0"
515 "#,
516 )
517 .file(
518 ".cargo/config.toml",
519 r#"
520 [patch.crates-io]
521 bar = { path = "bar" }
522 "#,
523 )
524 .file("src/lib.rs", "")
525 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
526 .file("bar/src/lib.rs", "not rust code")
527 .build();
528
529 p.cargo("check")
530 .with_stderr(
531 "\
532 [UPDATING] `dummy-registry` index
533 [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
534 Check that [..]
535 with the [..]
536 what is [..]
537 version. [..]
538 [DOWNLOADING] crates ...
539 [DOWNLOADED] bar v0.1.0 [..]
540 [CHECKING] bar v0.1.0
541 [CHECKING] foo v0.0.1 ([CWD])
542 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
543 ",
544 )
545 .run();
546 p.cargo("check")
547 .with_stderr(
548 "\
549 [WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
550 Check that [..]
551 with the [..]
552 what is [..]
553 version. [..]
554 [FINISHED] [..]
555 ",
556 )
557 .run();
558
559 // unused patch should be in the lock file
560 let lock = p.read_lockfile();
561 let toml: toml::Table = toml::from_str(&lock).unwrap();
562 assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
563 assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
564 assert_eq!(
565 toml["patch"]["unused"][0]["version"].as_str(),
566 Some("0.2.0")
567 );
568 }
569
570 #[cargo_test]
571 fn unused_git() {
572 Package::new("bar", "0.1.0").publish();
573
574 let foo = git::repo(&paths::root().join("override"))
575 .file("Cargo.toml", &basic_manifest("bar", "0.2.0"))
576 .file("src/lib.rs", "")
577 .build();
578
579 let p = project()
580 .file(
581 "Cargo.toml",
582 &format!(
583 r#"
584 [package]
585 name = "foo"
586 version = "0.0.1"
587 authors = []
588
589 [dependencies]
590 bar = "0.1"
591
592 [patch.crates-io]
593 bar = {{ git = '{}' }}
594 "#,
595 foo.url()
596 ),
597 )
598 .file("src/lib.rs", "")
599 .build();
600
601 p.cargo("check")
602 .with_stderr(
603 "\
604 [UPDATING] git repository `file://[..]`
605 [UPDATING] `dummy-registry` index
606 [WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
607 Check that [..]
608 with the [..]
609 what is [..]
610 version. [..]
611 [DOWNLOADING] crates ...
612 [DOWNLOADED] bar v0.1.0 [..]
613 [CHECKING] bar v0.1.0
614 [CHECKING] foo v0.0.1 ([CWD])
615 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
616 ",
617 )
618 .run();
619 p.cargo("check")
620 .with_stderr(
621 "\
622 [WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
623 Check that [..]
624 with the [..]
625 what is [..]
626 version. [..]
627 [FINISHED] [..]
628 ",
629 )
630 .run();
631 }
632
633 #[cargo_test]
634 fn add_patch() {
635 Package::new("bar", "0.1.0").publish();
636
637 let p = project()
638 .file(
639 "Cargo.toml",
640 r#"
641 [package]
642 name = "foo"
643 version = "0.0.1"
644 authors = []
645
646 [dependencies]
647 bar = "0.1.0"
648 "#,
649 )
650 .file("src/lib.rs", "")
651 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
652 .file("bar/src/lib.rs", r#""#)
653 .build();
654
655 p.cargo("check")
656 .with_stderr(
657 "\
658 [UPDATING] `dummy-registry` index
659 [DOWNLOADING] crates ...
660 [DOWNLOADED] bar v0.1.0 [..]
661 [CHECKING] bar v0.1.0
662 [CHECKING] foo v0.0.1 ([CWD])
663 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
664 ",
665 )
666 .run();
667 p.cargo("check").with_stderr("[FINISHED] [..]").run();
668
669 p.change_file(
670 "Cargo.toml",
671 r#"
672 [package]
673 name = "foo"
674 version = "0.0.1"
675 authors = []
676
677 [dependencies]
678 bar = "0.1.0"
679
680 [patch.crates-io]
681 bar = { path = 'bar' }
682 "#,
683 );
684
685 p.cargo("check")
686 .with_stderr(
687 "\
688 [CHECKING] bar v0.1.0 ([CWD]/bar)
689 [CHECKING] foo v0.0.1 ([CWD])
690 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
691 ",
692 )
693 .run();
694 p.cargo("check").with_stderr("[FINISHED] [..]").run();
695 }
696
697 #[cargo_test]
698 fn add_patch_from_config() {
699 Package::new("bar", "0.1.0").publish();
700
701 let p = project()
702 .file(
703 "Cargo.toml",
704 r#"
705 [package]
706 name = "foo"
707 version = "0.0.1"
708 authors = []
709
710 [dependencies]
711 bar = "0.1.0"
712 "#,
713 )
714 .file("src/lib.rs", "")
715 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
716 .file("bar/src/lib.rs", r#""#)
717 .build();
718
719 p.cargo("check")
720 .with_stderr(
721 "\
722 [UPDATING] `dummy-registry` index
723 [DOWNLOADING] crates ...
724 [DOWNLOADED] bar v0.1.0 [..]
725 [CHECKING] bar v0.1.0
726 [CHECKING] foo v0.0.1 ([CWD])
727 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
728 ",
729 )
730 .run();
731 p.cargo("check").with_stderr("[FINISHED] [..]").run();
732
733 p.change_file(
734 ".cargo/config.toml",
735 r#"
736 [patch.crates-io]
737 bar = { path = 'bar' }
738 "#,
739 );
740
741 p.cargo("check")
742 .with_stderr(
743 "\
744 [CHECKING] bar v0.1.0 ([CWD]/bar)
745 [CHECKING] foo v0.0.1 ([CWD])
746 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
747 ",
748 )
749 .run();
750 p.cargo("check").with_stderr("[FINISHED] [..]").run();
751 }
752
753 #[cargo_test]
754 fn add_ignored_patch() {
755 Package::new("bar", "0.1.0").publish();
756
757 let p = project()
758 .file(
759 "Cargo.toml",
760 r#"
761 [package]
762 name = "foo"
763 version = "0.0.1"
764 authors = []
765
766 [dependencies]
767 bar = "0.1.0"
768 "#,
769 )
770 .file("src/lib.rs", "")
771 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
772 .file("bar/src/lib.rs", r#""#)
773 .build();
774
775 p.cargo("check")
776 .with_stderr(
777 "\
778 [UPDATING] `dummy-registry` index
779 [DOWNLOADING] crates ...
780 [DOWNLOADED] bar v0.1.0 [..]
781 [CHECKING] bar v0.1.0
782 [CHECKING] foo v0.0.1 ([CWD])
783 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
784 ",
785 )
786 .run();
787 p.cargo("check").with_stderr("[FINISHED] [..]").run();
788
789 p.change_file(
790 "Cargo.toml",
791 r#"
792 [package]
793 name = "foo"
794 version = "0.0.1"
795 authors = []
796
797 [dependencies]
798 bar = "0.1.0"
799
800 [patch.crates-io]
801 bar = { path = 'bar' }
802 "#,
803 );
804
805 p.cargo("check")
806 .with_stderr(
807 "\
808 [WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
809 Check that [..]
810 with the [..]
811 what is [..]
812 version. [..]
813 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
814 )
815 .run();
816 p.cargo("check")
817 .with_stderr(
818 "\
819 [WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
820 Check that [..]
821 with the [..]
822 what is [..]
823 version. [..]
824 [FINISHED] [..]",
825 )
826 .run();
827
828 p.cargo("update").run();
829 p.cargo("check")
830 .with_stderr(
831 "\
832 [CHECKING] bar v0.1.1 ([CWD]/bar)
833 [CHECKING] foo v0.0.1 ([CWD])
834 [FINISHED] dev [..]
835 ",
836 )
837 .run();
838 }
839
840 #[cargo_test]
841 fn add_patch_with_features() {
842 Package::new("bar", "0.1.0").publish();
843
844 let p = project()
845 .file(
846 "Cargo.toml",
847 r#"
848 [package]
849 name = "foo"
850 version = "0.0.1"
851 authors = []
852
853 [dependencies]
854 bar = "0.1.0"
855
856 [patch.crates-io]
857 bar = { path = 'bar', features = ["some_feature"] }
858 "#,
859 )
860 .file("src/lib.rs", "")
861 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
862 .file("bar/src/lib.rs", r#""#)
863 .build();
864
865 p.cargo("check")
866 .with_stderr(
867 "\
868 [WARNING] patch for `bar` uses the features mechanism. \
869 default-features and features will not take effect because the patch dependency does not support this mechanism
870 [UPDATING] `dummy-registry` index
871 [CHECKING] bar v0.1.0 ([CWD]/bar)
872 [CHECKING] foo v0.0.1 ([CWD])
873 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
874 ",
875 )
876 .run();
877 p.cargo("check")
878 .with_stderr(
879 "\
880 [WARNING] patch for `bar` uses the features mechanism. \
881 default-features and features will not take effect because the patch dependency does not support this mechanism
882 [FINISHED] [..]
883 ",
884 )
885 .run();
886 }
887
888 #[cargo_test]
889 fn add_patch_with_setting_default_features() {
890 Package::new("bar", "0.1.0").publish();
891
892 let p = project()
893 .file(
894 "Cargo.toml",
895 r#"
896 [package]
897 name = "foo"
898 version = "0.0.1"
899 authors = []
900
901 [dependencies]
902 bar = "0.1.0"
903
904 [patch.crates-io]
905 bar = { path = 'bar', default-features = false, features = ["none_default_feature"] }
906 "#,
907 )
908 .file("src/lib.rs", "")
909 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
910 .file("bar/src/lib.rs", r#""#)
911 .build();
912
913 p.cargo("check")
914 .with_stderr(
915 "\
916 [WARNING] patch for `bar` uses the features mechanism. \
917 default-features and features will not take effect because the patch dependency does not support this mechanism
918 [UPDATING] `dummy-registry` index
919 [CHECKING] bar v0.1.0 ([CWD]/bar)
920 [CHECKING] foo v0.0.1 ([CWD])
921 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
922 ",
923 )
924 .run();
925 p.cargo("check")
926 .with_stderr(
927 "\
928 [WARNING] patch for `bar` uses the features mechanism. \
929 default-features and features will not take effect because the patch dependency does not support this mechanism
930 [FINISHED] [..]
931 ",
932 )
933 .run();
934 }
935
936 #[cargo_test]
937 fn no_warn_ws_patch() {
938 Package::new("c", "0.1.0").publish();
939
940 // Don't issue an unused patch warning when the patch isn't used when
941 // partially building a workspace.
942 let p = project()
943 .file(
944 "Cargo.toml",
945 r#"
946 [workspace]
947 members = ["a", "b", "c"]
948
949 [patch.crates-io]
950 c = { path = "c" }
951 "#,
952 )
953 .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
954 .file("a/src/lib.rs", "")
955 .file(
956 "b/Cargo.toml",
957 r#"
958 [package]
959 name = "b"
960 version = "0.1.0"
961 [dependencies]
962 c = "0.1.0"
963 "#,
964 )
965 .file("b/src/lib.rs", "")
966 .file("c/Cargo.toml", &basic_manifest("c", "0.1.0"))
967 .file("c/src/lib.rs", "")
968 .build();
969
970 p.cargo("check -p a")
971 .with_stderr(
972 "\
973 [UPDATING] [..]
974 [CHECKING] a [..]
975 [FINISHED] [..]",
976 )
977 .run();
978 }
979
980 #[cargo_test]
981 fn new_minor() {
982 Package::new("bar", "0.1.0").publish();
983
984 let p = project()
985 .file(
986 "Cargo.toml",
987 r#"
988 [package]
989 name = "foo"
990 version = "0.0.1"
991 authors = []
992
993 [dependencies]
994 bar = "0.1.0"
995
996 [patch.crates-io]
997 bar = { path = 'bar' }
998 "#,
999 )
1000 .file("src/lib.rs", "")
1001 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
1002 .file("bar/src/lib.rs", r#""#)
1003 .build();
1004
1005 p.cargo("check")
1006 .with_stderr(
1007 "\
1008 [UPDATING] `dummy-registry` index
1009 [CHECKING] bar v0.1.1 [..]
1010 [CHECKING] foo v0.0.1 ([CWD])
1011 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1012 ",
1013 )
1014 .run();
1015 }
1016
1017 #[cargo_test]
1018 fn transitive_new_minor() {
1019 Package::new("baz", "0.1.0").publish();
1020
1021 let p = project()
1022 .file(
1023 "Cargo.toml",
1024 r#"
1025 [package]
1026 name = "foo"
1027 version = "0.0.1"
1028 authors = []
1029
1030 [dependencies]
1031 bar = { path = 'bar' }
1032
1033 [patch.crates-io]
1034 baz = { path = 'baz' }
1035 "#,
1036 )
1037 .file("src/lib.rs", "")
1038 .file(
1039 "bar/Cargo.toml",
1040 r#"
1041 [package]
1042 name = "bar"
1043 version = "0.1.0"
1044 authors = []
1045
1046 [dependencies]
1047 baz = '0.1.0'
1048 "#,
1049 )
1050 .file("bar/src/lib.rs", r#""#)
1051 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.1"))
1052 .file("baz/src/lib.rs", r#""#)
1053 .build();
1054
1055 p.cargo("check")
1056 .with_stderr(
1057 "\
1058 [UPDATING] `dummy-registry` index
1059 [CHECKING] baz v0.1.1 [..]
1060 [CHECKING] bar v0.1.0 [..]
1061 [CHECKING] foo v0.0.1 ([CWD])
1062 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1063 ",
1064 )
1065 .run();
1066 }
1067
1068 #[cargo_test]
1069 fn new_major() {
1070 Package::new("bar", "0.1.0").publish();
1071
1072 let p = project()
1073 .file(
1074 "Cargo.toml",
1075 r#"
1076 [package]
1077 name = "foo"
1078 version = "0.0.1"
1079 authors = []
1080
1081 [dependencies]
1082 bar = "0.2.0"
1083
1084 [patch.crates-io]
1085 bar = { path = 'bar' }
1086 "#,
1087 )
1088 .file("src/lib.rs", "")
1089 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
1090 .file("bar/src/lib.rs", r#""#)
1091 .build();
1092
1093 p.cargo("check")
1094 .with_stderr(
1095 "\
1096 [UPDATING] `dummy-registry` index
1097 [CHECKING] bar v0.2.0 [..]
1098 [CHECKING] foo v0.0.1 ([CWD])
1099 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1100 ",
1101 )
1102 .run();
1103
1104 Package::new("bar", "0.2.0").publish();
1105 p.cargo("update").run();
1106 p.cargo("check")
1107 .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1108 .run();
1109
1110 p.change_file(
1111 "Cargo.toml",
1112 r#"
1113 [package]
1114 name = "foo"
1115 version = "0.0.1"
1116 authors = []
1117
1118 [dependencies]
1119 bar = "0.2.0"
1120 "#,
1121 );
1122 p.cargo("check")
1123 .with_stderr(
1124 "\
1125 [UPDATING] `dummy-registry` index
1126 [DOWNLOADING] crates ...
1127 [DOWNLOADED] bar v0.2.0 [..]
1128 [CHECKING] bar v0.2.0
1129 [CHECKING] foo v0.0.1 ([CWD])
1130 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1131 ",
1132 )
1133 .run();
1134 }
1135
1136 #[cargo_test]
1137 fn transitive_new_major() {
1138 Package::new("baz", "0.1.0").publish();
1139
1140 let p = project()
1141 .file(
1142 "Cargo.toml",
1143 r#"
1144 [package]
1145 name = "foo"
1146 version = "0.0.1"
1147 authors = []
1148
1149 [dependencies]
1150 bar = { path = 'bar' }
1151
1152 [patch.crates-io]
1153 baz = { path = 'baz' }
1154 "#,
1155 )
1156 .file("src/lib.rs", "")
1157 .file(
1158 "bar/Cargo.toml",
1159 r#"
1160 [package]
1161 name = "bar"
1162 version = "0.1.0"
1163 authors = []
1164
1165 [dependencies]
1166 baz = '0.2.0'
1167 "#,
1168 )
1169 .file("bar/src/lib.rs", r#""#)
1170 .file("baz/Cargo.toml", &basic_manifest("baz", "0.2.0"))
1171 .file("baz/src/lib.rs", r#""#)
1172 .build();
1173
1174 p.cargo("check")
1175 .with_stderr(
1176 "\
1177 [UPDATING] `dummy-registry` index
1178 [CHECKING] baz v0.2.0 [..]
1179 [CHECKING] bar v0.1.0 [..]
1180 [CHECKING] foo v0.0.1 ([CWD])
1181 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1182 ",
1183 )
1184 .run();
1185 }
1186
1187 #[cargo_test]
1188 fn shared_by_transitive() {
1189 Package::new("baz", "0.1.1").publish();
1190
1191 let baz = git::repo(&paths::root().join("override"))
1192 .file("Cargo.toml", &basic_manifest("baz", "0.1.2"))
1193 .file("src/lib.rs", "")
1194 .build();
1195
1196 let p = project()
1197 .file(
1198 "Cargo.toml",
1199 &format!(
1200 r#"
1201 [package]
1202 name = "foo"
1203 version = " 0.1.0"
1204
1205 [dependencies]
1206 bar = {{ path = "bar" }}
1207 baz = "0.1"
1208
1209 [patch.crates-io]
1210 baz = {{ git = "{}", version = "0.1" }}
1211 "#,
1212 baz.url(),
1213 ),
1214 )
1215 .file("src/lib.rs", "")
1216 .file(
1217 "bar/Cargo.toml",
1218 r#"
1219 [package]
1220 name = "bar"
1221 version = "0.1.0"
1222
1223 [dependencies]
1224 baz = "0.1.1"
1225 "#,
1226 )
1227 .file("bar/src/lib.rs", "")
1228 .build();
1229
1230 p.cargo("check")
1231 .with_stderr(
1232 "\
1233 [UPDATING] git repository `file://[..]`
1234 [UPDATING] `dummy-registry` index
1235 [CHECKING] baz v0.1.2 [..]
1236 [CHECKING] bar v0.1.0 [..]
1237 [CHECKING] foo v0.1.0 ([CWD])
1238 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1239 ",
1240 )
1241 .run();
1242 }
1243
1244 #[cargo_test]
1245 fn remove_patch() {
1246 Package::new("foo", "0.1.0").publish();
1247 Package::new("bar", "0.1.0").publish();
1248
1249 let p = project()
1250 .file(
1251 "Cargo.toml",
1252 r#"
1253 [package]
1254 name = "foo"
1255 version = "0.0.1"
1256 authors = []
1257
1258 [dependencies]
1259 bar = "0.1"
1260
1261 [patch.crates-io]
1262 foo = { path = 'foo' }
1263 bar = { path = 'bar' }
1264 "#,
1265 )
1266 .file("src/lib.rs", "")
1267 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1268 .file("bar/src/lib.rs", r#""#)
1269 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
1270 .file("foo/src/lib.rs", r#""#)
1271 .build();
1272
1273 // Generate a lock file where `foo` is unused
1274 p.cargo("check").run();
1275 let lock_file1 = p.read_lockfile();
1276
1277 // Remove `foo` and generate a new lock file form the old one
1278 p.change_file(
1279 "Cargo.toml",
1280 r#"
1281 [package]
1282 name = "foo"
1283 version = "0.0.1"
1284 authors = []
1285
1286 [dependencies]
1287 bar = "0.1"
1288
1289 [patch.crates-io]
1290 bar = { path = 'bar' }
1291 "#,
1292 );
1293 p.cargo("check").run();
1294 let lock_file2 = p.read_lockfile();
1295
1296 // Remove the lock file and build from scratch
1297 fs::remove_file(p.root().join("Cargo.lock")).unwrap();
1298 p.cargo("check").run();
1299 let lock_file3 = p.read_lockfile();
1300
1301 assert!(lock_file1.contains("foo"));
1302 assert_eq!(lock_file2, lock_file3);
1303 assert_ne!(lock_file1, lock_file2);
1304 }
1305
1306 #[cargo_test]
1307 fn non_crates_io() {
1308 Package::new("bar", "0.1.0").publish();
1309
1310 let p = project()
1311 .file(
1312 "Cargo.toml",
1313 r#"
1314 [package]
1315 name = "foo"
1316 version = "0.0.1"
1317 authors = []
1318
1319 [patch.some-other-source]
1320 bar = { path = 'bar' }
1321 "#,
1322 )
1323 .file("src/lib.rs", "")
1324 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1325 .file("bar/src/lib.rs", r#""#)
1326 .build();
1327
1328 p.cargo("check")
1329 .with_status(101)
1330 .with_stderr(
1331 "\
1332 error: failed to parse manifest at `[..]`
1333
1334 Caused by:
1335 [patch] entry `some-other-source` should be a URL or registry name
1336
1337 Caused by:
1338 invalid url `some-other-source`: relative URL without a base
1339 ",
1340 )
1341 .run();
1342 }
1343
1344 #[cargo_test]
1345 fn replace_with_crates_io() {
1346 Package::new("bar", "0.1.0").publish();
1347
1348 let p = project()
1349 .file(
1350 "Cargo.toml",
1351 r#"
1352 [package]
1353 name = "foo"
1354 version = "0.0.1"
1355 authors = []
1356
1357 [patch.crates-io]
1358 bar = "0.1"
1359 "#,
1360 )
1361 .file("src/lib.rs", "")
1362 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1363 .file("bar/src/lib.rs", r#""#)
1364 .build();
1365
1366 p.cargo("check")
1367 .with_status(101)
1368 .with_stderr(
1369 "\
1370 [UPDATING] [..]
1371 error: failed to resolve patches for `[..]`
1372
1373 Caused by:
1374 patch for `bar` in `[..]` points to the same source, but patches must point \
1375 to different sources
1376 ",
1377 )
1378 .run();
1379 }
1380
1381 #[cargo_test]
1382 fn patch_in_virtual() {
1383 Package::new("bar", "0.1.0").publish();
1384
1385 let p = project()
1386 .file(
1387 "Cargo.toml",
1388 r#"
1389 [workspace]
1390 members = ["foo"]
1391
1392 [patch.crates-io]
1393 bar = { path = "bar" }
1394 "#,
1395 )
1396 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1397 .file("bar/src/lib.rs", r#""#)
1398 .file(
1399 "foo/Cargo.toml",
1400 r#"
1401 [package]
1402 name = "foo"
1403 version = "0.1.0"
1404 authors = []
1405
1406 [dependencies]
1407 bar = "0.1"
1408 "#,
1409 )
1410 .file("foo/src/lib.rs", r#""#)
1411 .build();
1412
1413 p.cargo("check").run();
1414 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1415 }
1416
1417 #[cargo_test]
1418 fn patch_depends_on_another_patch() {
1419 Package::new("bar", "0.1.0")
1420 .file("src/lib.rs", "broken code")
1421 .publish();
1422
1423 Package::new("baz", "0.1.0")
1424 .dep("bar", "0.1")
1425 .file("src/lib.rs", "broken code")
1426 .publish();
1427
1428 let p = project()
1429 .file(
1430 "Cargo.toml",
1431 r#"
1432 [package]
1433 name = "foo"
1434 authors = []
1435 version = "0.1.0"
1436
1437 [dependencies]
1438 bar = "0.1"
1439 baz = "0.1"
1440
1441 [patch.crates-io]
1442 bar = { path = "bar" }
1443 baz = { path = "baz" }
1444 "#,
1445 )
1446 .file("src/lib.rs", "")
1447 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
1448 .file("bar/src/lib.rs", r#""#)
1449 .file(
1450 "baz/Cargo.toml",
1451 r#"
1452 [package]
1453 name = "baz"
1454 version = "0.1.1"
1455 authors = []
1456
1457 [dependencies]
1458 bar = "0.1"
1459 "#,
1460 )
1461 .file("baz/src/lib.rs", r#""#)
1462 .build();
1463
1464 p.cargo("check").run();
1465
1466 // Nothing should be rebuilt, no registry should be updated.
1467 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1468 }
1469
1470 #[cargo_test]
1471 fn replace_prerelease() {
1472 Package::new("baz", "1.1.0-pre.1").publish();
1473 let p = project()
1474 .file(
1475 "Cargo.toml",
1476 r#"
1477 [workspace]
1478 members = ["bar"]
1479
1480 [patch.crates-io]
1481 baz = { path = "./baz" }
1482 "#,
1483 )
1484 .file(
1485 "bar/Cargo.toml",
1486 r#"
1487 [package]
1488 name = "bar"
1489 version = "0.5.0"
1490 authors = []
1491
1492 [dependencies]
1493 baz = "1.1.0-pre.1"
1494 "#,
1495 )
1496 .file(
1497 "bar/src/main.rs",
1498 "extern crate baz; fn main() { baz::baz() }",
1499 )
1500 .file(
1501 "baz/Cargo.toml",
1502 r#"
1503 [package]
1504 name = "baz"
1505 version = "1.1.0-pre.1"
1506 authors = []
1507 [workspace]
1508 "#,
1509 )
1510 .file("baz/src/lib.rs", "pub fn baz() {}")
1511 .build();
1512
1513 p.cargo("check").run();
1514 }
1515
1516 #[cargo_test]
1517 fn patch_older() {
1518 Package::new("baz", "1.0.2").publish();
1519
1520 let p = project()
1521 .file(
1522 "Cargo.toml",
1523 r#"
1524 [package]
1525 name = "foo"
1526 version = "0.1.0"
1527
1528 [dependencies]
1529 bar = { path = 'bar' }
1530 baz = "=1.0.1"
1531
1532 [patch.crates-io]
1533 baz = { path = "./baz" }
1534 "#,
1535 )
1536 .file("src/lib.rs", "")
1537 .file(
1538 "bar/Cargo.toml",
1539 r#"
1540 [package]
1541 name = "bar"
1542 version = "0.5.0"
1543 authors = []
1544
1545 [dependencies]
1546 baz = "1.0.0"
1547 "#,
1548 )
1549 .file("bar/src/lib.rs", "")
1550 .file(
1551 "baz/Cargo.toml",
1552 r#"
1553 [package]
1554 name = "baz"
1555 version = "1.0.1"
1556 authors = []
1557 "#,
1558 )
1559 .file("baz/src/lib.rs", "")
1560 .build();
1561
1562 p.cargo("check")
1563 .with_stderr(
1564 "\
1565 [UPDATING] [..]
1566 [CHECKING] baz v1.0.1 [..]
1567 [CHECKING] bar v0.5.0 [..]
1568 [CHECKING] foo v0.1.0 [..]
1569 [FINISHED] [..]
1570 ",
1571 )
1572 .run();
1573 }
1574
1575 #[cargo_test]
1576 fn cycle() {
1577 Package::new("a", "1.0.0").publish();
1578 Package::new("b", "1.0.0").publish();
1579 let p = project()
1580 .file(
1581 "Cargo.toml",
1582 r#"
1583 [workspace]
1584 members = ["a", "b"]
1585
1586 [patch.crates-io]
1587 a = {path="a"}
1588 b = {path="b"}
1589 "#,
1590 )
1591 .file(
1592 "a/Cargo.toml",
1593 r#"
1594 [package]
1595 name = "a"
1596 version = "1.0.0"
1597
1598 [dependencies]
1599 b = "1.0"
1600 "#,
1601 )
1602 .file("a/src/lib.rs", "")
1603 .file(
1604 "b/Cargo.toml",
1605 r#"
1606 [package]
1607 name = "b"
1608 version = "1.0.0"
1609
1610 [dependencies]
1611 a = "1.0"
1612 "#,
1613 )
1614 .file("b/src/lib.rs", "")
1615 .build();
1616
1617 p.cargo("check")
1618 .with_status(101)
1619 .with_stderr(
1620 "\
1621 [UPDATING] [..]
1622 [ERROR] cyclic package dependency: [..]
1623 package `[..]`
1624 ... which satisfies dependency `[..]` of package `[..]`
1625 ... which satisfies dependency `[..]` of package `[..]`
1626 ",
1627 )
1628 .run();
1629 }
1630
1631 #[cargo_test]
1632 fn multipatch() {
1633 Package::new("a", "1.0.0").publish();
1634 Package::new("a", "2.0.0").publish();
1635 let p = project()
1636 .file(
1637 "Cargo.toml",
1638 r#"
1639 [package]
1640 name = "foo"
1641 version = "0.0.1"
1642
1643 [dependencies]
1644 a1 = { version = "1", package = "a" }
1645 a2 = { version = "2", package = "a" }
1646
1647 [patch.crates-io]
1648 b1 = { path = "a1", package = "a" }
1649 b2 = { path = "a2", package = "a" }
1650 "#,
1651 )
1652 .file("src/lib.rs", "pub fn foo() { a1::f1(); a2::f2(); }")
1653 .file(
1654 "a1/Cargo.toml",
1655 r#"
1656 [package]
1657 name = "a"
1658 version = "1.0.0"
1659 "#,
1660 )
1661 .file("a1/src/lib.rs", "pub fn f1() {}")
1662 .file(
1663 "a2/Cargo.toml",
1664 r#"
1665 [package]
1666 name = "a"
1667 version = "2.0.0"
1668 "#,
1669 )
1670 .file("a2/src/lib.rs", "pub fn f2() {}")
1671 .build();
1672
1673 p.cargo("check").run();
1674 }
1675
1676 #[cargo_test]
1677 fn patch_same_version() {
1678 let bar = git::repo(&paths::root().join("override"))
1679 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
1680 .file("src/lib.rs", "")
1681 .build();
1682
1683 cargo_test_support::registry::init();
1684
1685 let p = project()
1686 .file(
1687 "Cargo.toml",
1688 &format!(
1689 r#"
1690 [package]
1691 name = "foo"
1692 version = "0.0.1"
1693 [dependencies]
1694 bar = "0.1"
1695 [patch.crates-io]
1696 bar = {{ path = "bar" }}
1697 bar2 = {{ git = '{}', package = 'bar' }}
1698 "#,
1699 bar.url(),
1700 ),
1701 )
1702 .file("src/lib.rs", "")
1703 .file(
1704 "bar/Cargo.toml",
1705 r#"
1706 [package]
1707 name = "bar"
1708 version = "0.1.0"
1709 "#,
1710 )
1711 .file("bar/src/lib.rs", "")
1712 .build();
1713
1714 p.cargo("check")
1715 .with_status(101)
1716 .with_stderr(
1717 "\
1718 [UPDATING] [..]
1719 error: cannot have two `[patch]` entries which both resolve to `bar v0.1.0`
1720 ",
1721 )
1722 .run();
1723 }
1724
1725 #[cargo_test]
1726 fn two_semver_compatible() {
1727 let bar = git::repo(&paths::root().join("override"))
1728 .file("Cargo.toml", &basic_manifest("bar", "0.1.1"))
1729 .file("src/lib.rs", "")
1730 .build();
1731
1732 cargo_test_support::registry::init();
1733
1734 let p = project()
1735 .file(
1736 "Cargo.toml",
1737 &format!(
1738 r#"
1739 [package]
1740 name = "foo"
1741 version = "0.0.1"
1742 [dependencies]
1743 bar = "0.1"
1744 [patch.crates-io]
1745 bar = {{ path = "bar" }}
1746 bar2 = {{ git = '{}', package = 'bar' }}
1747 "#,
1748 bar.url(),
1749 ),
1750 )
1751 .file("src/lib.rs", "pub fn foo() { bar::foo() }")
1752 .file(
1753 "bar/Cargo.toml",
1754 r#"
1755 [package]
1756 name = "bar"
1757 version = "0.1.2"
1758 "#,
1759 )
1760 .file("bar/src/lib.rs", "pub fn foo() {}")
1761 .build();
1762
1763 // assert the build succeeds and doesn't panic anywhere, and then afterwards
1764 // assert that the build succeeds again without updating anything or
1765 // building anything else.
1766 p.cargo("check").run();
1767 p.cargo("check")
1768 .with_stderr(
1769 "\
1770 warning: Patch `bar v0.1.1 [..]` was not used in the crate graph.
1771 Perhaps you misspelled the source URL being patched.
1772 Possible URLs for `[patch.<URL>]`:
1773 [CWD]/bar
1774 [FINISHED] [..]",
1775 )
1776 .run();
1777 }
1778
1779 #[cargo_test]
1780 fn multipatch_select_big() {
1781 let bar = git::repo(&paths::root().join("override"))
1782 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
1783 .file("src/lib.rs", "")
1784 .build();
1785
1786 cargo_test_support::registry::init();
1787
1788 let p = project()
1789 .file(
1790 "Cargo.toml",
1791 &format!(
1792 r#"
1793 [package]
1794 name = "foo"
1795 version = "0.0.1"
1796 [dependencies]
1797 bar = "*"
1798 [patch.crates-io]
1799 bar = {{ path = "bar" }}
1800 bar2 = {{ git = '{}', package = 'bar' }}
1801 "#,
1802 bar.url(),
1803 ),
1804 )
1805 .file("src/lib.rs", "pub fn foo() { bar::foo() }")
1806 .file(
1807 "bar/Cargo.toml",
1808 r#"
1809 [package]
1810 name = "bar"
1811 version = "0.2.0"
1812 "#,
1813 )
1814 .file("bar/src/lib.rs", "pub fn foo() {}")
1815 .build();
1816
1817 // assert the build succeeds, which is only possible if 0.2.0 is selected
1818 // since 0.1.0 is missing the function we need. Afterwards assert that the
1819 // build succeeds again without updating anything or building anything else.
1820 p.cargo("check").run();
1821 p.cargo("check")
1822 .with_stderr(
1823 "\
1824 warning: Patch `bar v0.1.0 [..]` was not used in the crate graph.
1825 Perhaps you misspelled the source URL being patched.
1826 Possible URLs for `[patch.<URL>]`:
1827 [CWD]/bar
1828 [FINISHED] [..]",
1829 )
1830 .run();
1831 }
1832
1833 #[cargo_test]
1834 fn canonicalize_a_bunch() {
1835 let base = git::repo(&paths::root().join("base"))
1836 .file("Cargo.toml", &basic_manifest("base", "0.1.0"))
1837 .file("src/lib.rs", "")
1838 .build();
1839
1840 let intermediate = git::repo(&paths::root().join("intermediate"))
1841 .file(
1842 "Cargo.toml",
1843 &format!(
1844 r#"
1845 [package]
1846 name = "intermediate"
1847 version = "0.1.0"
1848
1849 [dependencies]
1850 # Note the lack of trailing slash
1851 base = {{ git = '{}' }}
1852 "#,
1853 base.url(),
1854 ),
1855 )
1856 .file("src/lib.rs", "pub fn f() { base::f() }")
1857 .build();
1858
1859 let newbase = git::repo(&paths::root().join("newbase"))
1860 .file("Cargo.toml", &basic_manifest("base", "0.1.0"))
1861 .file("src/lib.rs", "pub fn f() {}")
1862 .build();
1863
1864 let p = project()
1865 .file(
1866 "Cargo.toml",
1867 &format!(
1868 r#"
1869 [package]
1870 name = "foo"
1871 version = "0.0.1"
1872
1873 [dependencies]
1874 # Note the trailing slashes
1875 base = {{ git = '{base}/' }}
1876 intermediate = {{ git = '{intermediate}/' }}
1877
1878 [patch.'{base}'] # Note the lack of trailing slash
1879 base = {{ git = '{newbase}' }}
1880 "#,
1881 base = base.url(),
1882 intermediate = intermediate.url(),
1883 newbase = newbase.url(),
1884 ),
1885 )
1886 .file("src/lib.rs", "pub fn a() { base::f(); intermediate::f() }")
1887 .build();
1888
1889 // Once to make sure it actually works
1890 p.cargo("check").run();
1891
1892 // Then a few more times for good measure to ensure no weird warnings about
1893 // `[patch]` are printed.
1894 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1895 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1896 }
1897
1898 #[cargo_test]
1899 fn update_unused_new_version() {
1900 // If there is an unused patch entry, and then you update the patch,
1901 // make sure `cargo update` will be able to fix the lock file.
1902 Package::new("bar", "0.1.5").publish();
1903
1904 // Start with a lock file to 0.1.5, and an "unused" patch because the
1905 // version is too old.
1906 let p = project()
1907 .file(
1908 "Cargo.toml",
1909 r#"
1910 [package]
1911 name = "foo"
1912 version = "0.0.1"
1913
1914 [dependencies]
1915 bar = "0.1.5"
1916
1917 [patch.crates-io]
1918 bar = { path = "../bar" }
1919 "#,
1920 )
1921 .file("src/lib.rs", "")
1922 .build();
1923
1924 // Patch is too old.
1925 let bar = project()
1926 .at("bar")
1927 .file("Cargo.toml", &basic_manifest("bar", "0.1.4"))
1928 .file("src/lib.rs", "")
1929 .build();
1930
1931 p.cargo("check")
1932 .with_stderr_contains("[WARNING] Patch `bar v0.1.4 [..] was not used in the crate graph.")
1933 .run();
1934 // unused patch should be in the lock file
1935 let lock = p.read_lockfile();
1936 let toml: toml::Table = toml::from_str(&lock).unwrap();
1937 assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
1938 assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
1939 assert_eq!(
1940 toml["patch"]["unused"][0]["version"].as_str(),
1941 Some("0.1.4")
1942 );
1943
1944 // Oh, OK, let's update to the latest version.
1945 bar.change_file("Cargo.toml", &basic_manifest("bar", "0.1.6"));
1946
1947 // Create a backup so we can test it with different options.
1948 fs::copy(p.root().join("Cargo.lock"), p.root().join("Cargo.lock.bak")).unwrap();
1949
1950 // Try to build again, this should automatically update Cargo.lock.
1951 p.cargo("check")
1952 .with_stderr(
1953 "\
1954 [UPDATING] `dummy-registry` index
1955 [CHECKING] bar v0.1.6 ([..]/bar)
1956 [CHECKING] foo v0.0.1 ([..]/foo)
1957 [FINISHED] [..]
1958 ",
1959 )
1960 .run();
1961 // This should not update any registry.
1962 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1963 assert!(!p.read_lockfile().contains("unused"));
1964
1965 // Restore the lock file, and see if `update` will work, too.
1966 fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
1967
1968 // Try `update -p`.
1969 p.cargo("update -p bar")
1970 .with_stderr(
1971 "\
1972 [UPDATING] `dummy-registry` index
1973 [ADDING] bar v0.1.6 ([..]/bar)
1974 [REMOVING] bar v0.1.5
1975 ",
1976 )
1977 .run();
1978
1979 // Try with bare `cargo update`.
1980 fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
1981 p.cargo("update")
1982 .with_stderr(
1983 "\
1984 [UPDATING] `dummy-registry` index
1985 [ADDING] bar v0.1.6 ([..]/bar)
1986 [REMOVING] bar v0.1.5
1987 ",
1988 )
1989 .run();
1990 }
1991
1992 #[cargo_test]
1993 fn too_many_matches() {
1994 // The patch locations has multiple versions that match.
1995 registry::alt_init();
1996 Package::new("bar", "0.1.0").publish();
1997 Package::new("bar", "0.1.0").alternative(true).publish();
1998 Package::new("bar", "0.1.1").alternative(true).publish();
1999
2000 let p = project()
2001 .file(
2002 "Cargo.toml",
2003 r#"
2004 [package]
2005 name = "foo"
2006 version = "0.1.0"
2007
2008 [dependencies]
2009 bar = "0.1"
2010
2011 [patch.crates-io]
2012 bar = { version = "0.1", registry = "alternative" }
2013 "#,
2014 )
2015 .file("src/lib.rs", "")
2016 .build();
2017
2018 // Picks 0.1.1, the most recent version.
2019 p.cargo("check")
2020 .with_status(101)
2021 .with_stderr(
2022 "\
2023 [UPDATING] `alternative` index
2024 [ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
2025
2026 Caused by:
2027 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
2028
2029 Caused by:
2030 patch for `bar` in `registry `alternative`` resolved to more than one candidate
2031 Found versions: 0.1.0, 0.1.1
2032 Update the patch definition to select only one package.
2033 For example, add an `=` version requirement to the patch definition, such as `version = \"=0.1.1\"`.
2034 ",
2035 )
2036 .run();
2037 }
2038
2039 #[cargo_test]
2040 fn no_matches() {
2041 // A patch to a location that does not contain the named package.
2042 let p = project()
2043 .file(
2044 "Cargo.toml",
2045 r#"
2046 [package]
2047 name = "foo"
2048 version = "0.1.0"
2049
2050 [dependencies]
2051 bar = "0.1"
2052
2053 [patch.crates-io]
2054 bar = { path = "bar" }
2055 "#,
2056 )
2057 .file("src/lib.rs", "")
2058 .file("bar/Cargo.toml", &basic_manifest("abc", "0.1.0"))
2059 .file("bar/src/lib.rs", "")
2060 .build();
2061
2062 p.cargo("check")
2063 .with_status(101)
2064 .with_stderr(
2065 "\
2066 error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
2067
2068 Caused by:
2069 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
2070
2071 Caused by:
2072 The patch location `[..]/foo/bar` does not appear to contain any packages matching the name `bar`.
2073 ",
2074 )
2075 .run();
2076 }
2077
2078 #[cargo_test]
2079 fn mismatched_version() {
2080 // A patch to a location that has an old version.
2081 let p = project()
2082 .file(
2083 "Cargo.toml",
2084 r#"
2085 [package]
2086 name = "foo"
2087 version = "0.1.0"
2088
2089 [dependencies]
2090 bar = "0.1.1"
2091
2092 [patch.crates-io]
2093 bar = { path = "bar", version = "0.1.1" }
2094 "#,
2095 )
2096 .file("src/lib.rs", "")
2097 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
2098 .file("bar/src/lib.rs", "")
2099 .build();
2100
2101 p.cargo("check")
2102 .with_status(101)
2103 .with_stderr(
2104 "\
2105 [ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
2106
2107 Caused by:
2108 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
2109
2110 Caused by:
2111 The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, \
2112 but the patch definition requires `^0.1.1`.
2113 Check that the version in the patch location is what you expect, \
2114 and update the patch definition to match.
2115 ",
2116 )
2117 .run();
2118 }
2119
2120 #[cargo_test]
2121 fn patch_walks_backwards() {
2122 // Starting with a locked patch, change the patch so it points to an older version.
2123 Package::new("bar", "0.1.0").publish();
2124
2125 let p = project()
2126 .file(
2127 "Cargo.toml",
2128 r#"
2129 [package]
2130 name = "foo"
2131 version = "0.1.0"
2132
2133 [dependencies]
2134 bar = "0.1"
2135
2136 [patch.crates-io]
2137 bar = {path="bar"}
2138 "#,
2139 )
2140 .file("src/lib.rs", "")
2141 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
2142 .file("bar/src/lib.rs", "")
2143 .build();
2144
2145 p.cargo("check")
2146 .with_stderr(
2147 "\
2148 [UPDATING] `dummy-registry` index
2149 [CHECKING] bar v0.1.1 ([..]/foo/bar)
2150 [CHECKING] foo v0.1.0 ([..]/foo)
2151 [FINISHED] [..]
2152 ",
2153 )
2154 .run();
2155
2156 // Somehow the user changes the version backwards.
2157 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"));
2158
2159 p.cargo("check")
2160 .with_stderr(
2161 "\
2162 [UPDATING] `dummy-registry` index
2163 [CHECKING] bar v0.1.0 ([..]/foo/bar)
2164 [CHECKING] foo v0.1.0 ([..]/foo)
2165 [FINISHED] [..]
2166 ",
2167 )
2168 .run();
2169 }
2170
2171 #[cargo_test]
2172 fn patch_walks_backwards_restricted() {
2173 // This is the same as `patch_walks_backwards`, but the patch contains a
2174 // `version` qualifier. This is unusual, just checking a strange edge case.
2175 Package::new("bar", "0.1.0").publish();
2176
2177 let p = project()
2178 .file(
2179 "Cargo.toml",
2180 r#"
2181 [package]
2182 name = "foo"
2183 version = "0.1.0"
2184
2185 [dependencies]
2186 bar = "0.1"
2187
2188 [patch.crates-io]
2189 bar = {path="bar", version="0.1.1"}
2190 "#,
2191 )
2192 .file("src/lib.rs", "")
2193 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
2194 .file("bar/src/lib.rs", "")
2195 .build();
2196
2197 p.cargo("check")
2198 .with_stderr(
2199 "\
2200 [UPDATING] `dummy-registry` index
2201 [CHECKING] bar v0.1.1 ([..]/foo/bar)
2202 [CHECKING] foo v0.1.0 ([..]/foo)
2203 [FINISHED] [..]
2204 ",
2205 )
2206 .run();
2207
2208 // Somehow the user changes the version backwards.
2209 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"));
2210
2211 p.cargo("check")
2212 .with_status(101)
2213 .with_stderr(
2214 "\
2215 error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
2216
2217 Caused by:
2218 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
2219
2220 Caused by:
2221 The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, but the patch definition requires `^0.1.1`.
2222 Check that the version in the patch location is what you expect, and update the patch definition to match.
2223 ",
2224 )
2225 .run();
2226 }
2227
2228 #[cargo_test]
2229 fn patched_dep_new_version() {
2230 // What happens when a patch is locked, and then one of the patched
2231 // dependencies needs to be updated. In this case, the baz requirement
2232 // gets updated from 0.1.0 to 0.1.1.
2233 Package::new("bar", "0.1.0").dep("baz", "0.1.0").publish();
2234 Package::new("baz", "0.1.0").publish();
2235
2236 let p = project()
2237 .file(
2238 "Cargo.toml",
2239 r#"
2240 [package]
2241 name = "foo"
2242 version = "0.1.0"
2243
2244 [dependencies]
2245 bar = "0.1"
2246
2247 [patch.crates-io]
2248 bar = {path="bar"}
2249 "#,
2250 )
2251 .file("src/lib.rs", "")
2252 .file(
2253 "bar/Cargo.toml",
2254 r#"
2255 [package]
2256 name = "bar"
2257 version = "0.1.0"
2258
2259 [dependencies]
2260 baz = "0.1"
2261 "#,
2262 )
2263 .file("bar/src/lib.rs", "")
2264 .build();
2265
2266 // Lock everything.
2267 p.cargo("check")
2268 .with_stderr(
2269 "\
2270 [UPDATING] `dummy-registry` index
2271 [DOWNLOADING] crates ...
2272 [DOWNLOADED] baz v0.1.0 [..]
2273 [CHECKING] baz v0.1.0
2274 [CHECKING] bar v0.1.0 ([..]/foo/bar)
2275 [CHECKING] foo v0.1.0 ([..]/foo)
2276 [FINISHED] [..]
2277 ",
2278 )
2279 .run();
2280
2281 Package::new("baz", "0.1.1").publish();
2282
2283 // Just the presence of the new version should not have changed anything.
2284 p.cargo("check").with_stderr("[FINISHED] [..]").run();
2285
2286 // Modify the patch so it requires the new version.
2287 p.change_file(
2288 "bar/Cargo.toml",
2289 r#"
2290 [package]
2291 name = "bar"
2292 version = "0.1.0"
2293
2294 [dependencies]
2295 baz = "0.1.1"
2296 "#,
2297 );
2298
2299 // Should unlock and update cleanly.
2300 p.cargo("check")
2301 .with_stderr(
2302 "\
2303 [UPDATING] `dummy-registry` index
2304 [DOWNLOADING] crates ...
2305 [DOWNLOADED] baz v0.1.1 (registry `dummy-registry`)
2306 [CHECKING] baz v0.1.1
2307 [CHECKING] bar v0.1.0 ([..]/foo/bar)
2308 [CHECKING] foo v0.1.0 ([..]/foo)
2309 [FINISHED] [..]
2310 ",
2311 )
2312 .run();
2313 }
2314
2315 #[cargo_test]
2316 fn patch_update_doesnt_update_other_sources() {
2317 // Very extreme edge case, make sure a patch update doesn't update other
2318 // sources.
2319 registry::alt_init();
2320 Package::new("bar", "0.1.0").publish();
2321 Package::new("bar", "0.1.0").alternative(true).publish();
2322
2323 let p = project()
2324 .file(
2325 "Cargo.toml",
2326 r#"
2327 [package]
2328 name = "foo"
2329 version = "0.1.0"
2330
2331 [dependencies]
2332 bar = "0.1"
2333 bar_alt = { version = "0.1", registry = "alternative", package = "bar" }
2334
2335 [patch.crates-io]
2336 bar = { path = "bar" }
2337 "#,
2338 )
2339 .file("src/lib.rs", "")
2340 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
2341 .file("bar/src/lib.rs", "")
2342 .build();
2343
2344 p.cargo("check")
2345 .with_stderr_unordered(
2346 "\
2347 [UPDATING] `dummy-registry` index
2348 [UPDATING] `alternative` index
2349 [DOWNLOADING] crates ...
2350 [DOWNLOADED] bar v0.1.0 (registry `alternative`)
2351 [CHECKING] bar v0.1.0 (registry `alternative`)
2352 [CHECKING] bar v0.1.0 ([..]/foo/bar)
2353 [CHECKING] foo v0.1.0 ([..]/foo)
2354 [FINISHED] [..]
2355 ",
2356 )
2357 .run();
2358
2359 // Publish new versions in both sources.
2360 Package::new("bar", "0.1.1").publish();
2361 Package::new("bar", "0.1.1").alternative(true).publish();
2362
2363 // Since it is locked, nothing should change.
2364 p.cargo("check").with_stderr("[FINISHED] [..]").run();
2365
2366 // Require new version on crates.io.
2367 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"));
2368
2369 // This should not update bar_alt.
2370 p.cargo("check")
2371 .with_stderr(
2372 "\
2373 [UPDATING] `dummy-registry` index
2374 [CHECKING] bar v0.1.1 ([..]/foo/bar)
2375 [CHECKING] foo v0.1.0 ([..]/foo)
2376 [FINISHED] [..]
2377 ",
2378 )
2379 .run();
2380 }
2381
2382 #[cargo_test]
2383 fn can_update_with_alt_reg() {
2384 // A patch to an alt reg can update.
2385 registry::alt_init();
2386 Package::new("bar", "0.1.0").publish();
2387 Package::new("bar", "0.1.0").alternative(true).publish();
2388 Package::new("bar", "0.1.1").alternative(true).publish();
2389
2390 let p = project()
2391 .file(
2392 "Cargo.toml",
2393 r#"
2394 [package]
2395 name = "foo"
2396 version = "0.1.0"
2397
2398 [dependencies]
2399 bar = "0.1"
2400
2401 [patch.crates-io]
2402 bar = { version = "=0.1.1", registry = "alternative" }
2403 "#,
2404 )
2405 .file("src/lib.rs", "")
2406 .build();
2407
2408 p.cargo("check")
2409 .with_stderr(
2410 "\
2411 [UPDATING] `alternative` index
2412 [UPDATING] `dummy-registry` index
2413 [DOWNLOADING] crates ...
2414 [DOWNLOADED] bar v0.1.1 (registry `alternative`)
2415 [CHECKING] bar v0.1.1 (registry `alternative`)
2416 [CHECKING] foo v0.1.0 ([..]/foo)
2417 [FINISHED] [..]
2418 ",
2419 )
2420 .run();
2421
2422 Package::new("bar", "0.1.2").alternative(true).publish();
2423
2424 // Should remain locked.
2425 p.cargo("check").with_stderr("[FINISHED] [..]").run();
2426
2427 // This does nothing, due to `=` requirement.
2428 p.cargo("update -p bar")
2429 .with_stderr(
2430 "\
2431 [UPDATING] `alternative` index
2432 [UPDATING] `dummy-registry` index
2433 ",
2434 )
2435 .run();
2436
2437 // Bump to 0.1.2.
2438 p.change_file(
2439 "Cargo.toml",
2440 r#"
2441 [package]
2442 name = "foo"
2443 version = "0.1.0"
2444
2445 [dependencies]
2446 bar = "0.1"
2447
2448 [patch.crates-io]
2449 bar = { version = "=0.1.2", registry = "alternative" }
2450 "#,
2451 );
2452
2453 p.cargo("check")
2454 .with_stderr(
2455 "\
2456 [UPDATING] `alternative` index
2457 [UPDATING] `dummy-registry` index
2458 [DOWNLOADING] crates ...
2459 [DOWNLOADED] bar v0.1.2 (registry `alternative`)
2460 [CHECKING] bar v0.1.2 (registry `alternative`)
2461 [CHECKING] foo v0.1.0 ([..]/foo)
2462 [FINISHED] [..]
2463 ",
2464 )
2465 .run();
2466 }
2467
2468 #[cargo_test]
2469 fn old_git_patch() {
2470 // Example where an old lockfile with an explicit branch="master" in Cargo.toml.
2471 Package::new("bar", "1.0.0").publish();
2472 let (bar, bar_repo) = git::new_repo("bar", |p| {
2473 p.file("Cargo.toml", &basic_manifest("bar", "1.0.0"))
2474 .file("src/lib.rs", "")
2475 });
2476
2477 let bar_oid = bar_repo.head().unwrap().target().unwrap();
2478
2479 let p = project()
2480 .file(
2481 "Cargo.toml",
2482 &format!(
2483 r#"
2484 [package]
2485 name = "foo"
2486 version = "0.1.0"
2487
2488 [dependencies]
2489 bar = "1.0"
2490
2491 [patch.crates-io]
2492 bar = {{ git = "{}", branch = "master" }}
2493 "#,
2494 bar.url()
2495 ),
2496 )
2497 .file(
2498 "Cargo.lock",
2499 &format!(
2500 r#"
2501 # This file is automatically @generated by Cargo.
2502 # It is not intended for manual editing.
2503 [[package]]
2504 name = "bar"
2505 version = "1.0.0"
2506 source = "git+{}#{}"
2507
2508 [[package]]
2509 name = "foo"
2510 version = "0.1.0"
2511 dependencies = [
2512 "bar",
2513 ]
2514 "#,
2515 bar.url(),
2516 bar_oid
2517 ),
2518 )
2519 .file("src/lib.rs", "")
2520 .build();
2521
2522 bar.change_file("Cargo.toml", &basic_manifest("bar", "2.0.0"));
2523 git::add(&bar_repo);
2524 git::commit(&bar_repo);
2525
2526 // This *should* keep the old lock.
2527 p.cargo("tree")
2528 // .env("CARGO_LOG", "trace")
2529 .with_stderr(
2530 "\
2531 [UPDATING] [..]
2532 ",
2533 )
2534 // .with_status(1)
2535 .with_stdout(format!(
2536 "\
2537 foo v0.1.0 [..]
2538 └── bar v1.0.0 (file:///[..]branch=master#{})
2539 ",
2540 &bar_oid.to_string()[..8]
2541 ))
2542 .run();
2543 }
2544
2545 // From https://github.com/rust-lang/cargo/issues/7463
2546 #[cargo_test]
2547 fn patch_eq_conflict_panic() {
2548 Package::new("bar", "0.1.0").publish();
2549 Package::new("bar", "0.1.1").publish();
2550 let p = project()
2551 .file(
2552 "Cargo.toml",
2553 r#"
2554 [package]
2555 name = "foo"
2556 version = "0.1.0"
2557
2558 [dependencies]
2559 bar = "=0.1.0"
2560
2561 [dev-dependencies]
2562 bar = "=0.1.1"
2563
2564 [patch.crates-io]
2565 bar = {path="bar"}
2566 "#,
2567 )
2568 .file("src/lib.rs", "")
2569 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
2570 .file("bar/src/lib.rs", "")
2571 .build();
2572
2573 p.cargo("generate-lockfile")
2574 .with_status(101)
2575 .with_stderr(
2576 r#"[UPDATING] `dummy-registry` index
2577 [ERROR] failed to select a version for `bar`.
2578 ... required by package `foo v0.1.0 ([..])`
2579 versions that meet the requirements `=0.1.1` are: 0.1.1
2580
2581 all possible versions conflict with previously selected packages.
2582
2583 previously selected package `bar v0.1.0`
2584 ... which satisfies dependency `bar = "=0.1.0"` of package `foo v0.1.0 ([..])`
2585
2586 failed to select a version for `bar` which could resolve this conflict
2587 "#,
2588 )
2589 .run();
2590 }
2591
2592 // From https://github.com/rust-lang/cargo/issues/11336
2593 #[cargo_test]
2594 fn mismatched_version2() {
2595 Package::new("qux", "0.1.0-beta.1").publish();
2596 Package::new("qux", "0.1.0-beta.2").publish();
2597 Package::new("bar", "0.1.0")
2598 .dep("qux", "=0.1.0-beta.1")
2599 .publish();
2600 let p = project()
2601 .file(
2602 "Cargo.toml",
2603 r#"
2604 [package]
2605 name = "foo"
2606 version = "0.1.0"
2607
2608 [dependencies]
2609 bar = "0.1.0"
2610 qux = "0.1.0-beta.2"
2611
2612 [patch.crates-io]
2613 qux = { path = "qux" }
2614 "#,
2615 )
2616 .file("src/lib.rs", "")
2617 .file(
2618 "qux/Cargo.toml",
2619 r#"
2620 [package]
2621 name = "qux"
2622 version = "0.1.0-beta.1"
2623 "#,
2624 )
2625 .file("qux/src/lib.rs", "")
2626 .build();
2627
2628 p.cargo("generate-lockfile")
2629 .with_status(101)
2630 .with_stderr(
2631 r#"[UPDATING] `dummy-registry` index
2632 [ERROR] failed to select a version for `qux`.
2633 ... required by package `bar v0.1.0`
2634 ... which satisfies dependency `bar = "^0.1.0"` of package `foo v0.1.0 ([..])`
2635 versions that meet the requirements `=0.1.0-beta.1` are: 0.1.0-beta.1
2636
2637 all possible versions conflict with previously selected packages.
2638
2639 previously selected package `qux v0.1.0-beta.2`
2640 ... which satisfies dependency `qux = "^0.1.0-beta.2"` of package `foo v0.1.0 ([..])`
2641
2642 failed to select a version for `qux` which could resolve this conflict"#,
2643 )
2644 .run();
2645 }