]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/patch.rs
Add RegistryBuilder to help initializing test registries.
[cargo.git] / tests / testsuite / patch.rs
CommitLineData
83571aee
EH
1//! Tests for `[patch]` table source replacement.
2
9115b2c3
AC
3use cargo_test_support::git;
4use cargo_test_support::paths;
340656e2 5use cargo_test_support::registry::{self, Package};
4ae79d2f
EH
6use cargo_test_support::{basic_manifest, project};
7use std::fs;
61a3c68b 8
0e0d9688 9#[cargo_test]
61a3c68b 10fn replace() {
f8c9928c
DW
11 Package::new("bar", "0.1.0").publish();
12 Package::new("baz", "0.1.0")
85984a87
DW
13 .file(
14 "src/lib.rs",
15 "extern crate bar; pub fn baz() { bar::bar(); }",
fecb7246
AC
16 )
17 .dep("bar", "0.1.0")
61a3c68b
AC
18 .publish();
19
f8c9928c 20 let p = project()
1e682848
AC
21 .file(
22 "Cargo.toml",
23 r#"
6f8c7d5a
EH
24 [package]
25 name = "foo"
26 version = "0.0.1"
27 authors = []
61a3c68b 28
6f8c7d5a
EH
29 [dependencies]
30 bar = "0.1.0"
31 baz = "0.1.0"
61a3c68b 32
6f8c7d5a
EH
33 [patch.crates-io]
34 bar = { path = "bar" }
35 "#,
fecb7246
AC
36 )
37 .file(
1e682848
AC
38 "src/lib.rs",
39 "
f8c9928c
DW
40 extern crate bar;
41 extern crate baz;
61a3c68b 42 pub fn bar() {
f8c9928c
DW
43 bar::bar();
44 baz::baz();
61a3c68b 45 }
1e682848 46 ",
fecb7246
AC
47 )
48 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
ca7d9ee2 49 .file("bar/src/lib.rs", "pub fn bar() {}")
d43ee1dd 50 .build();
61a3c68b 51
85984a87
DW
52 p.cargo("build")
53 .with_stderr(
1e682848 54 "\
b020d378 55[UPDATING] `[ROOT][..]` index
e2637b65
AC
56[DOWNLOADING] crates ...
57[DOWNLOADED] baz v0.1.0 ([..])
89f43938 58[COMPILING] bar v0.1.0 ([CWD]/bar)
f8c9928c 59[COMPILING] baz v0.1.0
89f43938 60[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 61[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 62",
fecb7246
AC
63 )
64 .run();
1e682848 65
85984a87 66 p.cargo("build").with_stderr("[FINISHED] [..]").run();
61a3c68b
AC
67}
68
0e0d9688 69#[cargo_test]
61a3c68b
AC
70fn nonexistent() {
71 Package::new("baz", "0.1.0").publish();
72
f8c9928c 73 let p = project()
1e682848
AC
74 .file(
75 "Cargo.toml",
76 r#"
6f8c7d5a
EH
77 [package]
78 name = "foo"
79 version = "0.0.1"
80 authors = []
61a3c68b 81
6f8c7d5a
EH
82 [dependencies]
83 bar = "0.1.0"
61a3c68b 84
6f8c7d5a
EH
85 [patch.crates-io]
86 bar = { path = "bar" }
87 "#,
fecb7246
AC
88 )
89 .file(
85984a87
DW
90 "src/lib.rs",
91 "extern crate bar; pub fn foo() { bar::bar(); }",
fecb7246
AC
92 )
93 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
ca7d9ee2 94 .file("bar/src/lib.rs", "pub fn bar() {}")
d43ee1dd 95 .build();
61a3c68b 96
85984a87
DW
97 p.cargo("build")
98 .with_stderr(
1e682848 99 "\
b020d378 100[UPDATING] `[ROOT][..]` index
89f43938
ZL
101[COMPILING] bar v0.1.0 ([CWD]/bar)
102[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 103[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 104",
fecb7246
AC
105 )
106 .run();
85984a87 107 p.cargo("build").with_stderr("[FINISHED] [..]").run();
61a3c68b
AC
108}
109
0e0d9688 110#[cargo_test]
61a3c68b 111fn patch_git() {
f8c9928c 112 let bar = git::repo(&paths::root().join("override"))
ab19c483 113 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
d43ee1dd
NK
114 .file("src/lib.rs", "")
115 .build();
61a3c68b 116
f8c9928c 117 let p = project()
1e682848
AC
118 .file(
119 "Cargo.toml",
120 &format!(
121 r#"
6f8c7d5a
EH
122 [package]
123 name = "foo"
124 version = "0.0.1"
125 authors = []
61a3c68b 126
6f8c7d5a
EH
127 [dependencies]
128 bar = {{ git = '{}' }}
61a3c68b 129
6f8c7d5a
EH
130 [patch.'{0}']
131 bar = {{ path = "bar" }}
132 "#,
f8c9928c 133 bar.url()
1e682848 134 ),
fecb7246
AC
135 )
136 .file(
85984a87
DW
137 "src/lib.rs",
138 "extern crate bar; pub fn foo() { bar::bar(); }",
fecb7246
AC
139 )
140 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
ca7d9ee2 141 .file("bar/src/lib.rs", "pub fn bar() {}")
d43ee1dd 142 .build();
61a3c68b 143
85984a87
DW
144 p.cargo("build")
145 .with_stderr(
1e682848 146 "\
730d07c1 147[UPDATING] git repository `file://[..]`
89f43938
ZL
148[COMPILING] bar v0.1.0 ([CWD]/bar)
149[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 150[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 151",
fecb7246
AC
152 )
153 .run();
85984a87 154 p.cargo("build").with_stderr("[FINISHED] [..]").run();
61a3c68b
AC
155}
156
0e0d9688 157#[cargo_test]
61a3c68b 158fn patch_to_git() {
f8c9928c 159 let bar = git::repo(&paths::root().join("override"))
ab19c483 160 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 161 .file("src/lib.rs", "pub fn bar() {}")
d43ee1dd 162 .build();
61a3c68b 163
f8c9928c 164 Package::new("bar", "0.1.0").publish();
61a3c68b 165
f8c9928c 166 let p = project()
1e682848
AC
167 .file(
168 "Cargo.toml",
169 &format!(
170 r#"
6f8c7d5a
EH
171 [package]
172 name = "foo"
173 version = "0.0.1"
174 authors = []
61a3c68b 175
6f8c7d5a
EH
176 [dependencies]
177 bar = "0.1"
61a3c68b 178
6f8c7d5a
EH
179 [patch.crates-io]
180 bar = {{ git = '{}' }}
181 "#,
f8c9928c 182 bar.url()
1e682848 183 ),
fecb7246
AC
184 )
185 .file(
85984a87
DW
186 "src/lib.rs",
187 "extern crate bar; pub fn foo() { bar::bar(); }",
fecb7246
AC
188 )
189 .build();
61a3c68b 190
85984a87
DW
191 p.cargo("build")
192 .with_stderr(
1e682848 193 "\
730d07c1 194[UPDATING] git repository `file://[..]`
b020d378 195[UPDATING] `[ROOT][..]` index
730d07c1 196[COMPILING] bar v0.1.0 (file://[..])
89f43938 197[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 198[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 199",
fecb7246
AC
200 )
201 .run();
85984a87 202 p.cargo("build").with_stderr("[FINISHED] [..]").run();
61a3c68b
AC
203}
204
0e0d9688 205#[cargo_test]
61a3c68b 206fn unused() {
f8c9928c 207 Package::new("bar", "0.1.0").publish();
61a3c68b 208
f8c9928c 209 let p = project()
1e682848
AC
210 .file(
211 "Cargo.toml",
212 r#"
6f8c7d5a
EH
213 [package]
214 name = "foo"
215 version = "0.0.1"
216 authors = []
61a3c68b 217
6f8c7d5a
EH
218 [dependencies]
219 bar = "0.1.0"
61a3c68b 220
6f8c7d5a
EH
221 [patch.crates-io]
222 bar = { path = "bar" }
223 "#,
fecb7246
AC
224 )
225 .file("src/lib.rs", "")
ab19c483 226 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
ca7d9ee2 227 .file("bar/src/lib.rs", "not rust code")
d43ee1dd 228 .build();
61a3c68b 229
85984a87
DW
230 p.cargo("build")
231 .with_stderr(
1e682848 232 "\
b020d378 233[UPDATING] `[ROOT][..]` index
e35ecbe7
EH
234[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
235[..]
236[..]
237[..]
238[..]
e2637b65
AC
239[DOWNLOADING] crates ...
240[DOWNLOADED] bar v0.1.0 [..]
f8c9928c 241[COMPILING] bar v0.1.0
89f43938 242[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 243[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 244",
fecb7246
AC
245 )
246 .run();
e35ecbe7
EH
247 p.cargo("build")
248 .with_stderr(
249 "\
250[WARNING] Patch `bar v0.2.0 ([CWD]/bar)` was not used in the crate graph.
251[..]
252[..]
253[..]
254[..]
255[FINISHED] [..]
256",
257 )
258 .run();
61a3c68b
AC
259
260 // unused patch should be in the lock file
4ae79d2f 261 let lock = p.read_lockfile();
61a3c68b
AC
262 let toml: toml::Value = toml::from_str(&lock).unwrap();
263 assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
f8c9928c 264 assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
1e682848
AC
265 assert_eq!(
266 toml["patch"]["unused"][0]["version"].as_str(),
267 Some("0.2.0")
268 );
61a3c68b
AC
269}
270
0e0d9688 271#[cargo_test]
61a3c68b 272fn unused_git() {
f8c9928c 273 Package::new("bar", "0.1.0").publish();
61a3c68b
AC
274
275 let foo = git::repo(&paths::root().join("override"))
ab19c483 276 .file("Cargo.toml", &basic_manifest("bar", "0.2.0"))
d43ee1dd
NK
277 .file("src/lib.rs", "")
278 .build();
61a3c68b 279
f8c9928c 280 let p = project()
1e682848
AC
281 .file(
282 "Cargo.toml",
283 &format!(
284 r#"
6f8c7d5a
EH
285 [package]
286 name = "foo"
287 version = "0.0.1"
288 authors = []
61a3c68b 289
6f8c7d5a
EH
290 [dependencies]
291 bar = "0.1"
61a3c68b 292
6f8c7d5a
EH
293 [patch.crates-io]
294 bar = {{ git = '{}' }}
295 "#,
1e682848
AC
296 foo.url()
297 ),
fecb7246
AC
298 )
299 .file("src/lib.rs", "")
d43ee1dd 300 .build();
61a3c68b 301
85984a87
DW
302 p.cargo("build")
303 .with_stderr(
1e682848 304 "\
730d07c1 305[UPDATING] git repository `file://[..]`
b020d378 306[UPDATING] `[ROOT][..]` index
e35ecbe7
EH
307[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
308[..]
309[..]
310[..]
311[..]
e2637b65
AC
312[DOWNLOADING] crates ...
313[DOWNLOADED] bar v0.1.0 [..]
f8c9928c 314[COMPILING] bar v0.1.0
89f43938 315[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 316[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 317",
fecb7246
AC
318 )
319 .run();
e35ecbe7
EH
320 p.cargo("build")
321 .with_stderr(
322 "\
323[WARNING] Patch `bar v0.2.0 ([..])` was not used in the crate graph.
324[..]
325[..]
326[..]
327[..]
328[FINISHED] [..]
329",
330 )
331 .run();
61a3c68b
AC
332}
333
0e0d9688 334#[cargo_test]
61a3c68b 335fn add_patch() {
f8c9928c 336 Package::new("bar", "0.1.0").publish();
61a3c68b 337
f8c9928c 338 let p = project()
1e682848
AC
339 .file(
340 "Cargo.toml",
341 r#"
6f8c7d5a
EH
342 [package]
343 name = "foo"
344 version = "0.0.1"
345 authors = []
61a3c68b 346
6f8c7d5a
EH
347 [dependencies]
348 bar = "0.1.0"
349 "#,
fecb7246
AC
350 )
351 .file("src/lib.rs", "")
ab19c483 352 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 353 .file("bar/src/lib.rs", r#""#)
d43ee1dd 354 .build();
61a3c68b 355
85984a87
DW
356 p.cargo("build")
357 .with_stderr(
1e682848 358 "\
b020d378 359[UPDATING] `[ROOT][..]` index
e2637b65
AC
360[DOWNLOADING] crates ...
361[DOWNLOADED] bar v0.1.0 [..]
f8c9928c 362[COMPILING] bar v0.1.0
89f43938 363[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 364[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 365",
fecb7246
AC
366 )
367 .run();
85984a87 368 p.cargo("build").with_stderr("[FINISHED] [..]").run();
1e682848 369
4ae79d2f
EH
370 p.change_file(
371 "Cargo.toml",
372 r#"
61a3c68b 373 [package]
f8c9928c 374 name = "foo"
61a3c68b
AC
375 version = "0.0.1"
376 authors = []
377
378 [dependencies]
f8c9928c 379 bar = "0.1.0"
61a3c68b
AC
380
381 [patch.crates-io]
f8c9928c 382 bar = { path = 'bar' }
4ae79d2f
EH
383 "#,
384 );
61a3c68b 385
85984a87
DW
386 p.cargo("build")
387 .with_stderr(
1e682848 388 "\
89f43938
ZL
389[COMPILING] bar v0.1.0 ([CWD]/bar)
390[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 391[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 392",
fecb7246
AC
393 )
394 .run();
85984a87 395 p.cargo("build").with_stderr("[FINISHED] [..]").run();
61a3c68b
AC
396}
397
0e0d9688 398#[cargo_test]
61a3c68b 399fn add_ignored_patch() {
f8c9928c 400 Package::new("bar", "0.1.0").publish();
61a3c68b 401
f8c9928c 402 let p = project()
1e682848
AC
403 .file(
404 "Cargo.toml",
405 r#"
6f8c7d5a
EH
406 [package]
407 name = "foo"
408 version = "0.0.1"
409 authors = []
61a3c68b 410
6f8c7d5a
EH
411 [dependencies]
412 bar = "0.1.0"
413 "#,
fecb7246
AC
414 )
415 .file("src/lib.rs", "")
ab19c483 416 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
f8c9928c 417 .file("bar/src/lib.rs", r#""#)
d43ee1dd 418 .build();
61a3c68b 419
85984a87
DW
420 p.cargo("build")
421 .with_stderr(
1e682848 422 "\
b020d378 423[UPDATING] `[ROOT][..]` index
e2637b65
AC
424[DOWNLOADING] crates ...
425[DOWNLOADED] bar v0.1.0 [..]
f8c9928c 426[COMPILING] bar v0.1.0
89f43938 427[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 428[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 429",
fecb7246
AC
430 )
431 .run();
85984a87 432 p.cargo("build").with_stderr("[FINISHED] [..]").run();
1e682848 433
4ae79d2f
EH
434 p.change_file(
435 "Cargo.toml",
436 r#"
61a3c68b 437 [package]
f8c9928c 438 name = "foo"
61a3c68b
AC
439 version = "0.0.1"
440 authors = []
441
442 [dependencies]
f8c9928c 443 bar = "0.1.0"
61a3c68b
AC
444
445 [patch.crates-io]
f8c9928c 446 bar = { path = 'bar' }
4ae79d2f
EH
447 "#,
448 );
61a3c68b 449
85984a87 450 p.cargo("build")
e35ecbe7
EH
451 .with_stderr(
452 "\
453[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
454[..]
455[..]
456[..]
457[..]
458[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
459 )
460 .run();
461 p.cargo("build")
462 .with_stderr(
463 "\
464[WARNING] Patch `bar v0.1.1 ([CWD]/bar)` was not used in the crate graph.
465[..]
466[..]
467[..]
468[..]
469[FINISHED] [..]",
470 )
471 .run();
472
473 p.cargo("update").run();
474 p.cargo("build")
475 .with_stderr(
476 "\
477[COMPILING] bar v0.1.1 ([CWD]/bar)
478[COMPILING] foo v0.0.1 ([CWD])
479[FINISHED] dev [..]
480",
481 )
85984a87 482 .run();
61a3c68b
AC
483}
484
0e0d9688 485#[cargo_test]
7d112803
EH
486fn no_warn_ws_patch() {
487 Package::new("c", "0.1.0").publish();
488
489 // Don't issue an unused patch warning when the patch isn't used when
490 // partially building a workspace.
491 let p = project()
492 .file(
493 "Cargo.toml",
494 r#"
6f8c7d5a
EH
495 [workspace]
496 members = ["a", "b", "c"]
7d112803 497
6f8c7d5a
EH
498 [patch.crates-io]
499 c = { path = "c" }
500 "#,
7d112803
EH
501 )
502 .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
503 .file("a/src/lib.rs", "")
504 .file(
505 "b/Cargo.toml",
506 r#"
6f8c7d5a
EH
507 [package]
508 name = "b"
509 version = "0.1.0"
510 [dependencies]
511 c = "0.1.0"
512 "#,
7d112803
EH
513 )
514 .file("b/src/lib.rs", "")
515 .file("c/Cargo.toml", &basic_manifest("c", "0.1.0"))
516 .file("c/src/lib.rs", "")
517 .build();
518
519 p.cargo("build -p a")
520 .with_stderr(
521 "\
522[UPDATING] [..]
523[COMPILING] a [..]
524[FINISHED] [..]",
525 )
526 .run();
527}
528
0e0d9688 529#[cargo_test]
61a3c68b 530fn new_minor() {
f8c9928c 531 Package::new("bar", "0.1.0").publish();
61a3c68b 532
f8c9928c 533 let p = project()
1e682848
AC
534 .file(
535 "Cargo.toml",
536 r#"
6f8c7d5a
EH
537 [package]
538 name = "foo"
539 version = "0.0.1"
540 authors = []
61a3c68b 541
6f8c7d5a
EH
542 [dependencies]
543 bar = "0.1.0"
61a3c68b 544
6f8c7d5a
EH
545 [patch.crates-io]
546 bar = { path = 'bar' }
547 "#,
fecb7246
AC
548 )
549 .file("src/lib.rs", "")
ab19c483 550 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
f8c9928c 551 .file("bar/src/lib.rs", r#""#)
d43ee1dd 552 .build();
61a3c68b 553
85984a87
DW
554 p.cargo("build")
555 .with_stderr(
1e682848 556 "\
b020d378 557[UPDATING] `[ROOT][..]` index
f8c9928c 558[COMPILING] bar v0.1.1 [..]
89f43938 559[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 560[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 561",
fecb7246
AC
562 )
563 .run();
61a3c68b
AC
564}
565
0e0d9688 566#[cargo_test]
61a3c68b 567fn transitive_new_minor() {
f8c9928c 568 Package::new("baz", "0.1.0").publish();
61a3c68b 569
f8c9928c 570 let p = project()
1e682848
AC
571 .file(
572 "Cargo.toml",
573 r#"
6f8c7d5a
EH
574 [package]
575 name = "foo"
576 version = "0.0.1"
577 authors = []
61a3c68b 578
6f8c7d5a
EH
579 [dependencies]
580 bar = { path = 'bar' }
61a3c68b 581
6f8c7d5a
EH
582 [patch.crates-io]
583 baz = { path = 'baz' }
584 "#,
fecb7246
AC
585 )
586 .file("src/lib.rs", "")
1e682848 587 .file(
f8c9928c 588 "bar/Cargo.toml",
1e682848 589 r#"
6f8c7d5a
EH
590 [package]
591 name = "bar"
592 version = "0.1.0"
593 authors = []
61a3c68b 594
6f8c7d5a
EH
595 [dependencies]
596 baz = '0.1.0'
597 "#,
fecb7246
AC
598 )
599 .file("bar/src/lib.rs", r#""#)
ab19c483 600 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.1"))
f8c9928c 601 .file("baz/src/lib.rs", r#""#)
d43ee1dd 602 .build();
61a3c68b 603
85984a87
DW
604 p.cargo("build")
605 .with_stderr(
1e682848 606 "\
b020d378 607[UPDATING] `[ROOT][..]` index
f8c9928c
DW
608[COMPILING] baz v0.1.1 [..]
609[COMPILING] bar v0.1.0 [..]
89f43938 610[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 611[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 612",
fecb7246
AC
613 )
614 .run();
61a3c68b
AC
615}
616
0e0d9688 617#[cargo_test]
61a3c68b 618fn new_major() {
f8c9928c 619 Package::new("bar", "0.1.0").publish();
61a3c68b 620
f8c9928c 621 let p = project()
1e682848
AC
622 .file(
623 "Cargo.toml",
624 r#"
6f8c7d5a
EH
625 [package]
626 name = "foo"
627 version = "0.0.1"
628 authors = []
61a3c68b 629
6f8c7d5a
EH
630 [dependencies]
631 bar = "0.2.0"
61a3c68b 632
6f8c7d5a
EH
633 [patch.crates-io]
634 bar = { path = 'bar' }
635 "#,
fecb7246
AC
636 )
637 .file("src/lib.rs", "")
ab19c483 638 .file("bar/Cargo.toml", &basic_manifest("bar", "0.2.0"))
f8c9928c 639 .file("bar/src/lib.rs", r#""#)
d43ee1dd 640 .build();
61a3c68b 641
85984a87
DW
642 p.cargo("build")
643 .with_stderr(
1e682848 644 "\
b020d378 645[UPDATING] `[ROOT][..]` index
f8c9928c 646[COMPILING] bar v0.2.0 [..]
89f43938 647[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 648[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 649",
fecb7246
AC
650 )
651 .run();
61a3c68b 652
f8c9928c 653 Package::new("bar", "0.2.0").publish();
85984a87
DW
654 p.cargo("update").run();
655 p.cargo("build")
656 .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
657 .run();
61a3c68b 658
4ae79d2f
EH
659 p.change_file(
660 "Cargo.toml",
661 r#"
61a3c68b 662 [package]
f8c9928c 663 name = "foo"
61a3c68b
AC
664 version = "0.0.1"
665 authors = []
666
667 [dependencies]
f8c9928c 668 bar = "0.2.0"
4ae79d2f
EH
669 "#,
670 );
85984a87
DW
671 p.cargo("build")
672 .with_stderr(
1e682848 673 "\
b020d378 674[UPDATING] `[ROOT][..]` index
e2637b65
AC
675[DOWNLOADING] crates ...
676[DOWNLOADED] bar v0.2.0 [..]
f8c9928c 677[COMPILING] bar v0.2.0
89f43938 678[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 679[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 680",
fecb7246
AC
681 )
682 .run();
61a3c68b
AC
683}
684
0e0d9688 685#[cargo_test]
61a3c68b 686fn transitive_new_major() {
f8c9928c 687 Package::new("baz", "0.1.0").publish();
61a3c68b 688
f8c9928c 689 let p = project()
1e682848
AC
690 .file(
691 "Cargo.toml",
692 r#"
6f8c7d5a
EH
693 [package]
694 name = "foo"
695 version = "0.0.1"
696 authors = []
61a3c68b 697
6f8c7d5a
EH
698 [dependencies]
699 bar = { path = 'bar' }
61a3c68b 700
6f8c7d5a
EH
701 [patch.crates-io]
702 baz = { path = 'baz' }
703 "#,
fecb7246
AC
704 )
705 .file("src/lib.rs", "")
1e682848 706 .file(
f8c9928c 707 "bar/Cargo.toml",
1e682848 708 r#"
6f8c7d5a
EH
709 [package]
710 name = "bar"
711 version = "0.1.0"
712 authors = []
61a3c68b 713
6f8c7d5a
EH
714 [dependencies]
715 baz = '0.2.0'
716 "#,
fecb7246
AC
717 )
718 .file("bar/src/lib.rs", r#""#)
ab19c483 719 .file("baz/Cargo.toml", &basic_manifest("baz", "0.2.0"))
f8c9928c 720 .file("baz/src/lib.rs", r#""#)
d43ee1dd 721 .build();
61a3c68b 722
85984a87
DW
723 p.cargo("build")
724 .with_stderr(
1e682848 725 "\
b020d378 726[UPDATING] `[ROOT][..]` index
f8c9928c
DW
727[COMPILING] baz v0.2.0 [..]
728[COMPILING] bar v0.1.0 [..]
89f43938 729[COMPILING] foo v0.0.1 ([CWD])
61a3c68b 730[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4d094c08
DPB
731",
732 )
733 .run();
734}
735
736#[cargo_test]
737fn shared_by_transitive() {
738 Package::new("baz", "0.1.1").publish();
739
740 let baz = git::repo(&paths::root().join("override"))
741 .file("Cargo.toml", &basic_manifest("baz", "0.1.2"))
742 .file("src/lib.rs", "")
743 .build();
744
745 let p = project()
746 .file(
747 "Cargo.toml",
748 &format!(
749 r#"
750 [package]
751 name = "foo"
752 version = " 0.1.0"
753
754 [dependencies]
755 bar = {{ path = "bar" }}
756 baz = "0.1"
757
758 [patch.crates-io]
759 baz = {{ git = "{}", version = "0.1" }}
760 "#,
761 baz.url(),
762 ),
763 )
764 .file("src/lib.rs", "")
765 .file(
766 "bar/Cargo.toml",
767 r#"
768 [package]
769 name = "bar"
770 version = "0.1.0"
771
772 [dependencies]
773 baz = "0.1.1"
774 "#,
775 )
776 .file("bar/src/lib.rs", "")
777 .build();
778
779 p.cargo("build")
780 .with_stderr(
781 "\
782[UPDATING] git repository `file://[..]`
783[UPDATING] `[ROOT][..]` index
784[COMPILING] baz v0.1.2 [..]
785[COMPILING] bar v0.1.0 [..]
786[COMPILING] foo v0.1.0 ([CWD])
787[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 788",
fecb7246
AC
789 )
790 .run();
61a3c68b
AC
791}
792
0e0d9688 793#[cargo_test]
61a3c68b
AC
794fn remove_patch() {
795 Package::new("foo", "0.1.0").publish();
796 Package::new("bar", "0.1.0").publish();
797
f8c9928c 798 let p = project()
1e682848
AC
799 .file(
800 "Cargo.toml",
801 r#"
6f8c7d5a
EH
802 [package]
803 name = "foo"
804 version = "0.0.1"
805 authors = []
61a3c68b 806
6f8c7d5a
EH
807 [dependencies]
808 bar = "0.1"
61a3c68b 809
6f8c7d5a
EH
810 [patch.crates-io]
811 foo = { path = 'foo' }
812 bar = { path = 'bar' }
813 "#,
fecb7246
AC
814 )
815 .file("src/lib.rs", "")
ab19c483 816 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 817 .file("bar/src/lib.rs", r#""#)
ab19c483 818 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
f8c9928c 819 .file("foo/src/lib.rs", r#""#)
d43ee1dd 820 .build();
61a3c68b 821
f8c9928c 822 // Generate a lock file where `foo` is unused
85984a87 823 p.cargo("build").run();
4ae79d2f 824 let lock_file1 = p.read_lockfile();
61a3c68b 825
f8c9928c 826 // Remove `foo` and generate a new lock file form the old one
4ae79d2f
EH
827 p.change_file(
828 "Cargo.toml",
829 r#"
830 [package]
831 name = "foo"
832 version = "0.0.1"
833 authors = []
834
835 [dependencies]
836 bar = "0.1"
837
838 [patch.crates-io]
839 bar = { path = 'bar' }
840 "#,
841 );
85984a87 842 p.cargo("build").run();
4ae79d2f 843 let lock_file2 = p.read_lockfile();
61a3c68b
AC
844
845 // Remove the lock file and build from scratch
846 fs::remove_file(p.root().join("Cargo.lock")).unwrap();
85984a87 847 p.cargo("build").run();
4ae79d2f 848 let lock_file3 = p.read_lockfile();
61a3c68b 849
f8c9928c 850 assert!(lock_file1.contains("foo"));
61a3c68b 851 assert_eq!(lock_file2, lock_file3);
0247dc42 852 assert_ne!(lock_file1, lock_file2);
61a3c68b
AC
853}
854
0e0d9688 855#[cargo_test]
61a3c68b 856fn non_crates_io() {
f8c9928c 857 Package::new("bar", "0.1.0").publish();
61a3c68b 858
f8c9928c 859 let p = project()
1e682848
AC
860 .file(
861 "Cargo.toml",
862 r#"
6f8c7d5a
EH
863 [package]
864 name = "foo"
865 version = "0.0.1"
866 authors = []
61a3c68b 867
6f8c7d5a
EH
868 [patch.some-other-source]
869 bar = { path = 'bar' }
870 "#,
fecb7246
AC
871 )
872 .file("src/lib.rs", "")
ab19c483 873 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 874 .file("bar/src/lib.rs", r#""#)
d43ee1dd 875 .build();
61a3c68b 876
85984a87
DW
877 p.cargo("build")
878 .with_status(101)
879 .with_stderr(
1e682848 880 "\
61a3c68b
AC
881error: failed to parse manifest at `[..]`
882
7eaa1cf7
EH
883Caused by:
884 [patch] entry `some-other-source` should be a URL or registry name
885
61a3c68b
AC
886Caused by:
887 invalid url `some-other-source`: relative URL without a base
1e682848 888",
fecb7246
AC
889 )
890 .run();
61a3c68b
AC
891}
892
0e0d9688 893#[cargo_test]
61a3c68b 894fn replace_with_crates_io() {
f8c9928c 895 Package::new("bar", "0.1.0").publish();
61a3c68b 896
f8c9928c 897 let p = project()
1e682848
AC
898 .file(
899 "Cargo.toml",
900 r#"
6f8c7d5a
EH
901 [package]
902 name = "foo"
903 version = "0.0.1"
904 authors = []
61a3c68b 905
6f8c7d5a
EH
906 [patch.crates-io]
907 bar = "0.1"
908 "#,
fecb7246
AC
909 )
910 .file("src/lib.rs", "")
ab19c483 911 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 912 .file("bar/src/lib.rs", r#""#)
d43ee1dd 913 .build();
61a3c68b 914
85984a87
DW
915 p.cargo("build")
916 .with_status(101)
917 .with_stderr(
1e682848 918 "\
61a3c68b
AC
919[UPDATING] [..]
920error: failed to resolve patches for `[..]`
921
922Caused by:
f8c9928c 923 patch for `bar` in `[..]` points to the same source, but patches must point \
61a3c68b 924 to different sources
1e682848 925",
fecb7246
AC
926 )
927 .run();
61a3c68b 928}
e4bf48e9 929
0e0d9688 930#[cargo_test]
e4bf48e9 931fn patch_in_virtual() {
f8c9928c 932 Package::new("bar", "0.1.0").publish();
e4bf48e9 933
f8c9928c 934 let p = project()
1e682848
AC
935 .file(
936 "Cargo.toml",
937 r#"
6f8c7d5a
EH
938 [workspace]
939 members = ["foo"]
e4bf48e9 940
6f8c7d5a
EH
941 [patch.crates-io]
942 bar = { path = "bar" }
943 "#,
fecb7246
AC
944 )
945 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f8c9928c 946 .file("bar/src/lib.rs", r#""#)
1e682848 947 .file(
f8c9928c 948 "foo/Cargo.toml",
1e682848 949 r#"
6f8c7d5a
EH
950 [package]
951 name = "foo"
952 version = "0.1.0"
953 authors = []
e4bf48e9 954
6f8c7d5a
EH
955 [dependencies]
956 bar = "0.1"
957 "#,
fecb7246
AC
958 )
959 .file("foo/src/lib.rs", r#""#)
d43ee1dd 960 .build();
e4bf48e9 961
85984a87
DW
962 p.cargo("build").run();
963 p.cargo("build").with_stderr("[FINISHED] [..]").run();
e4bf48e9 964}
eebddd37 965
0e0d9688 966#[cargo_test]
eebddd37 967fn patch_depends_on_another_patch() {
f8c9928c 968 Package::new("bar", "0.1.0")
eebddd37
AC
969 .file("src/lib.rs", "broken code")
970 .publish();
971
f8c9928c
DW
972 Package::new("baz", "0.1.0")
973 .dep("bar", "0.1")
eebddd37
AC
974 .file("src/lib.rs", "broken code")
975 .publish();
976
f8c9928c 977 let p = project()
1e682848
AC
978 .file(
979 "Cargo.toml",
980 r#"
6f8c7d5a
EH
981 [package]
982 name = "foo"
983 authors = []
984 version = "0.1.0"
eebddd37 985
6f8c7d5a
EH
986 [dependencies]
987 bar = "0.1"
988 baz = "0.1"
eebddd37 989
6f8c7d5a
EH
990 [patch.crates-io]
991 bar = { path = "bar" }
992 baz = { path = "baz" }
993 "#,
fecb7246
AC
994 )
995 .file("src/lib.rs", "")
ab19c483 996 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
f8c9928c 997 .file("bar/src/lib.rs", r#""#)
1e682848 998 .file(
f8c9928c 999 "baz/Cargo.toml",
1e682848 1000 r#"
6f8c7d5a
EH
1001 [package]
1002 name = "baz"
1003 version = "0.1.1"
1004 authors = []
eebddd37 1005
6f8c7d5a
EH
1006 [dependencies]
1007 bar = "0.1"
1008 "#,
fecb7246
AC
1009 )
1010 .file("baz/src/lib.rs", r#""#)
eebddd37
AC
1011 .build();
1012
85984a87 1013 p.cargo("build").run();
eebddd37
AC
1014
1015 // Nothing should be rebuilt, no registry should be updated.
85984a87 1016 p.cargo("build").with_stderr("[FINISHED] [..]").run();
eebddd37 1017}
658343aa 1018
0e0d9688 1019#[cargo_test]
658343aa 1020fn replace_prerelease() {
f8c9928c 1021 Package::new("baz", "1.1.0-pre.1").publish();
7fe2fbc8 1022 let p = project()
658343aa
AK
1023 .file(
1024 "Cargo.toml",
1025 r#"
6f8c7d5a
EH
1026 [workspace]
1027 members = ["bar"]
658343aa 1028
6f8c7d5a
EH
1029 [patch.crates-io]
1030 baz = { path = "./baz" }
1031 "#,
fecb7246
AC
1032 )
1033 .file(
f8c9928c 1034 "bar/Cargo.toml",
658343aa 1035 r#"
6f8c7d5a
EH
1036 [project]
1037 name = "bar"
1038 version = "0.5.0"
1039 authors = []
658343aa 1040
6f8c7d5a
EH
1041 [dependencies]
1042 baz = "1.1.0-pre.1"
1043 "#,
fecb7246
AC
1044 )
1045 .file(
85984a87
DW
1046 "bar/src/main.rs",
1047 "extern crate baz; fn main() { baz::baz() }",
fecb7246
AC
1048 )
1049 .file(
f8c9928c 1050 "baz/Cargo.toml",
658343aa 1051 r#"
6f8c7d5a
EH
1052 [project]
1053 name = "baz"
1054 version = "1.1.0-pre.1"
1055 authors = []
1056 [workspace]
1057 "#,
fecb7246
AC
1058 )
1059 .file("baz/src/lib.rs", "pub fn baz() {}")
658343aa
AK
1060 .build();
1061
85984a87 1062 p.cargo("build").run();
658343aa 1063}
83bb30ce
AC
1064
1065#[cargo_test]
1066fn patch_older() {
1067 Package::new("baz", "1.0.2").publish();
1068
1069 let p = project()
1070 .file(
1071 "Cargo.toml",
1072 r#"
1073 [package]
1074 name = "foo"
1075 version = "0.1.0"
1076
1077 [dependencies]
1078 bar = { path = 'bar' }
1079 baz = "=1.0.1"
1080
1081 [patch.crates-io]
1082 baz = { path = "./baz" }
1083 "#,
1084 )
1085 .file("src/lib.rs", "")
1086 .file(
1087 "bar/Cargo.toml",
1088 r#"
1089 [project]
1090 name = "bar"
1091 version = "0.5.0"
1092 authors = []
1093
1094 [dependencies]
1095 baz = "1.0.0"
1096 "#,
1097 )
1098 .file("bar/src/lib.rs", "")
1099 .file(
1100 "baz/Cargo.toml",
1101 r#"
1102 [project]
1103 name = "baz"
1104 version = "1.0.1"
1105 authors = []
1106 "#,
1107 )
1108 .file("baz/src/lib.rs", "")
1109 .build();
1110
1111 p.cargo("build")
1112 .with_stderr(
1113 "\
1114[UPDATING] [..]
1115[COMPILING] baz v1.0.1 [..]
1116[COMPILING] bar v0.5.0 [..]
1117[COMPILING] foo v0.1.0 [..]
1118[FINISHED] [..]
1119",
1120 )
1121 .run();
1122}
0bd1d34c
AC
1123
1124#[cargo_test]
1125fn cycle() {
1126 Package::new("a", "1.0.0").publish();
1127 Package::new("b", "1.0.0").publish();
1128 let p = project()
1129 .file(
1130 "Cargo.toml",
1131 r#"
1132 [workspace]
1133 members = ["a", "b"]
1134
1135 [patch.crates-io]
1136 a = {path="a"}
1137 b = {path="b"}
1138 "#,
1139 )
1140 .file(
1141 "a/Cargo.toml",
1142 r#"
1143 [package]
1144 name = "a"
1145 version = "1.0.0"
1146
1147 [dependencies]
1148 b = "1.0"
1149 "#,
1150 )
1151 .file("a/src/lib.rs", "")
1152 .file(
1153 "b/Cargo.toml",
1154 r#"
1155 [package]
1156 name = "b"
1157 version = "1.0.0"
1158
1159 [dependencies]
1160 a = "1.0"
1161 "#,
1162 )
1163 .file("b/src/lib.rs", "")
1164 .build();
1165
1166 p.cargo("check")
1167 .with_status(101)
1168 .with_stderr(
1169 "\
1170[UPDATING] [..]
1171error: cyclic package dependency: [..]
1172package `[..]`
1173 ... which is depended on by `[..]`
a92fd48f 1174 ... which is depended on by `[..]`
0bd1d34c
AC
1175",
1176 )
1177 .run();
1178}
2a391a77
AC
1179
1180#[cargo_test]
1181fn multipatch() {
1182 Package::new("a", "1.0.0").publish();
1183 Package::new("a", "2.0.0").publish();
1184 let p = project()
1185 .file(
1186 "Cargo.toml",
1187 r#"
1188 [package]
1189 name = "foo"
1190 version = "0.0.1"
1191
1192 [dependencies]
1193 a1 = { version = "1", package = "a" }
1194 a2 = { version = "2", package = "a" }
1195
1196 [patch.crates-io]
1197 b1 = { path = "a1", package = "a" }
1198 b2 = { path = "a2", package = "a" }
1199 "#,
1200 )
1201 .file("src/lib.rs", "pub fn foo() { a1::f1(); a2::f2(); }")
1202 .file(
1203 "a1/Cargo.toml",
1204 r#"
1205 [package]
1206 name = "a"
1207 version = "1.0.0"
1208 "#,
1209 )
1210 .file("a1/src/lib.rs", "pub fn f1() {}")
1211 .file(
1212 "a2/Cargo.toml",
1213 r#"
1214 [package]
1215 name = "a"
1216 version = "2.0.0"
1217 "#,
1218 )
1219 .file("a2/src/lib.rs", "pub fn f2() {}")
1220 .build();
1221
1222 p.cargo("build").run();
1223}
803bf329
AC
1224
1225#[cargo_test]
1226fn patch_same_version() {
1227 let bar = git::repo(&paths::root().join("override"))
1228 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
1229 .file("src/lib.rs", "")
1230 .build();
1231
9115b2c3 1232 cargo_test_support::registry::init();
803bf329
AC
1233
1234 let p = project()
1235 .file(
1236 "Cargo.toml",
1237 &format!(
1238 r#"
6f8c7d5a
EH
1239 [package]
1240 name = "foo"
1241 version = "0.0.1"
1242 [dependencies]
1243 bar = "0.1"
1244 [patch.crates-io]
1245 bar = {{ path = "bar" }}
1246 bar2 = {{ git = '{}', package = 'bar' }}
1247 "#,
803bf329
AC
1248 bar.url(),
1249 ),
1250 )
1251 .file("src/lib.rs", "")
1252 .file(
1253 "bar/Cargo.toml",
1254 r#"
1255 [package]
1256 name = "bar"
1257 version = "0.1.0"
1258 "#,
1259 )
1260 .file("bar/src/lib.rs", "")
1261 .build();
1262
1263 p.cargo("build")
1264 .with_status(101)
1265 .with_stderr(
1266 "\
1267[UPDATING] [..]
1268error: cannot have two `[patch]` entries which both resolve to `bar v0.1.0`
1269",
1270 )
1271 .run();
1272}
1273
1274#[cargo_test]
1275fn two_semver_compatible() {
1276 let bar = git::repo(&paths::root().join("override"))
1277 .file("Cargo.toml", &basic_manifest("bar", "0.1.1"))
1278 .file("src/lib.rs", "")
1279 .build();
1280
9115b2c3 1281 cargo_test_support::registry::init();
803bf329
AC
1282
1283 let p = project()
1284 .file(
1285 "Cargo.toml",
1286 &format!(
1287 r#"
6f8c7d5a
EH
1288 [package]
1289 name = "foo"
1290 version = "0.0.1"
1291 [dependencies]
1292 bar = "0.1"
1293 [patch.crates-io]
1294 bar = {{ path = "bar" }}
1295 bar2 = {{ git = '{}', package = 'bar' }}
1296 "#,
803bf329
AC
1297 bar.url(),
1298 ),
1299 )
1300 .file("src/lib.rs", "pub fn foo() { bar::foo() }")
1301 .file(
1302 "bar/Cargo.toml",
1303 r#"
1304 [package]
1305 name = "bar"
1306 version = "0.1.2"
1307 "#,
1308 )
1309 .file("bar/src/lib.rs", "pub fn foo() {}")
1310 .build();
1311
1312 // assert the build succeeds and doesn't panic anywhere, and then afterwards
1313 // assert that the build succeeds again without updating anything or
1314 // building anything else.
1315 p.cargo("build").run();
1316 p.cargo("build")
1317 .with_stderr(
1318 "\
1319warning: Patch `bar v0.1.1 [..]` was not used in the crate graph.
1320Check that [..]
1321with the [..]
1322what is [..]
1323version. [..]
1324[FINISHED] [..]",
1325 )
1326 .run();
1327}
1328
1329#[cargo_test]
1330fn multipatch_select_big() {
1331 let bar = git::repo(&paths::root().join("override"))
1332 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
1333 .file("src/lib.rs", "")
1334 .build();
1335
9115b2c3 1336 cargo_test_support::registry::init();
803bf329
AC
1337
1338 let p = project()
1339 .file(
1340 "Cargo.toml",
1341 &format!(
1342 r#"
6f8c7d5a
EH
1343 [package]
1344 name = "foo"
1345 version = "0.0.1"
1346 [dependencies]
1347 bar = "*"
1348 [patch.crates-io]
1349 bar = {{ path = "bar" }}
1350 bar2 = {{ git = '{}', package = 'bar' }}
1351 "#,
803bf329
AC
1352 bar.url(),
1353 ),
1354 )
1355 .file("src/lib.rs", "pub fn foo() { bar::foo() }")
1356 .file(
1357 "bar/Cargo.toml",
1358 r#"
1359 [package]
1360 name = "bar"
1361 version = "0.2.0"
1362 "#,
1363 )
1364 .file("bar/src/lib.rs", "pub fn foo() {}")
1365 .build();
1366
1367 // assert the build succeeds, which is only possible if 0.2.0 is selected
1368 // since 0.1.0 is missing the function we need. Afterwards assert that the
1369 // build succeeds again without updating anything or building anything else.
1370 p.cargo("build").run();
1371 p.cargo("build")
1372 .with_stderr(
1373 "\
1374warning: Patch `bar v0.1.0 [..]` was not used in the crate graph.
1375Check that [..]
1376with the [..]
1377what is [..]
1378version. [..]
1379[FINISHED] [..]",
1380 )
1381 .run();
1382}
e5454122
AC
1383
1384#[cargo_test]
1385fn canonicalize_a_bunch() {
1386 let base = git::repo(&paths::root().join("base"))
1387 .file("Cargo.toml", &basic_manifest("base", "0.1.0"))
1388 .file("src/lib.rs", "")
1389 .build();
1390
1391 let intermediate = git::repo(&paths::root().join("intermediate"))
1392 .file(
1393 "Cargo.toml",
1394 &format!(
1395 r#"
1396 [package]
1397 name = "intermediate"
1398 version = "0.1.0"
1399
1400 [dependencies]
1401 # Note the lack of trailing slash
1402 base = {{ git = '{}' }}
1403 "#,
1404 base.url(),
1405 ),
1406 )
1407 .file("src/lib.rs", "pub fn f() { base::f() }")
1408 .build();
1409
1410 let newbase = git::repo(&paths::root().join("newbase"))
1411 .file("Cargo.toml", &basic_manifest("base", "0.1.0"))
1412 .file("src/lib.rs", "pub fn f() {}")
1413 .build();
1414
1415 let p = project()
1416 .file(
1417 "Cargo.toml",
1418 &format!(
1419 r#"
1420 [package]
1421 name = "foo"
1422 version = "0.0.1"
1423
1424 [dependencies]
1425 # Note the trailing slashes
1426 base = {{ git = '{base}/' }}
1427 intermediate = {{ git = '{intermediate}/' }}
1428
1429 [patch.'{base}'] # Note the lack of trailing slash
1430 base = {{ git = '{newbase}' }}
1431 "#,
1432 base = base.url(),
1433 intermediate = intermediate.url(),
1434 newbase = newbase.url(),
1435 ),
1436 )
1437 .file("src/lib.rs", "pub fn a() { base::f(); intermediate::f() }")
1438 .build();
1439
1440 // Once to make sure it actually works
1441 p.cargo("build").run();
1442
1443 // Then a few more times for good measure to ensure no weird warnings about
1444 // `[patch]` are printed.
1445 p.cargo("build").with_stderr("[FINISHED] [..]").run();
1446 p.cargo("build").with_stderr("[FINISHED] [..]").run();
1447}
501e5804
EH
1448
1449#[cargo_test]
1450fn update_unused_new_version() {
1451 // If there is an unused patch entry, and then you update the patch,
1452 // make sure `cargo update` will be able to fix the lock file.
1453 Package::new("bar", "0.1.5").publish();
1454
1455 // Start with a lock file to 0.1.5, and an "unused" patch because the
1456 // version is too old.
1457 let p = project()
1458 .file(
1459 "Cargo.toml",
1460 r#"
1461 [package]
1462 name = "foo"
1463 version = "0.0.1"
1464
1465 [dependencies]
1466 bar = "0.1.5"
1467
1468 [patch.crates-io]
1469 bar = { path = "../bar" }
1470 "#,
1471 )
1472 .file("src/lib.rs", "")
1473 .build();
1474
1475 // Patch is too old.
1476 let bar = project()
1477 .at("bar")
1478 .file("Cargo.toml", &basic_manifest("bar", "0.1.4"))
1479 .file("src/lib.rs", "")
1480 .build();
1481
1482 p.cargo("build")
1483 .with_stderr_contains("[WARNING] Patch `bar v0.1.4 [..] was not used in the crate graph.")
1484 .run();
1485 // unused patch should be in the lock file
1486 let lock = p.read_lockfile();
1487 let toml: toml::Value = toml::from_str(&lock).unwrap();
1488 assert_eq!(toml["patch"]["unused"].as_array().unwrap().len(), 1);
1489 assert_eq!(toml["patch"]["unused"][0]["name"].as_str(), Some("bar"));
1490 assert_eq!(
1491 toml["patch"]["unused"][0]["version"].as_str(),
1492 Some("0.1.4")
1493 );
1494
1495 // Oh, OK, let's update to the latest version.
1496 bar.change_file("Cargo.toml", &basic_manifest("bar", "0.1.6"));
1497
1498 // Create a backup so we can test it with different options.
1499 fs::copy(p.root().join("Cargo.lock"), p.root().join("Cargo.lock.bak")).unwrap();
1500
afa3aced 1501 // Try to build again, this should automatically update Cargo.lock.
b78cb373 1502 p.cargo("build")
b78cb373
EH
1503 .with_stderr(
1504 "\
afa3aced
EH
1505[UPDATING] `[..]/registry` index
1506[COMPILING] bar v0.1.6 ([..]/bar)
1507[COMPILING] foo v0.0.1 ([..]/foo)
1508[FINISHED] [..]
b78cb373
EH
1509",
1510 )
1511 .run();
afa3aced
EH
1512 // This should not update any registry.
1513 p.cargo("build").with_stderr("[FINISHED] [..]").run();
1514 assert!(!p.read_lockfile().contains("unused"));
b78cb373 1515
afa3aced
EH
1516 // Restore the lock file, and see if `update` will work, too.
1517 fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
1518
1519 // Try `update -p`.
501e5804
EH
1520 p.cargo("update -p bar")
1521 .with_stderr(
1522 "\
1523[UPDATING] `[..]/registry` index
1524[ADDING] bar v0.1.6 ([..]/bar)
1525[REMOVING] bar v0.1.5
1526",
1527 )
1528 .run();
1529
1530 // Try with bare `cargo update`.
1531 fs::copy(p.root().join("Cargo.lock.bak"), p.root().join("Cargo.lock")).unwrap();
1532 p.cargo("update")
1533 .with_stderr(
1534 "\
1535[UPDATING] `[..]/registry` index
1536[ADDING] bar v0.1.6 ([..]/bar)
1537[REMOVING] bar v0.1.5
1538",
1539 )
1540 .run();
1541}
b78cb373
EH
1542
1543#[cargo_test]
1544fn too_many_matches() {
1545 // The patch locations has multiple versions that match.
340656e2 1546 registry::alt_init();
b78cb373
EH
1547 Package::new("bar", "0.1.0").publish();
1548 Package::new("bar", "0.1.0").alternative(true).publish();
1549 Package::new("bar", "0.1.1").alternative(true).publish();
1550
1551 let p = project()
1552 .file(
1553 "Cargo.toml",
1554 r#"
1555 [package]
1556 name = "foo"
1557 version = "0.1.0"
1558
1559 [dependencies]
1560 bar = "0.1"
1561
1562 [patch.crates-io]
1563 bar = { version = "0.1", registry = "alternative" }
1564 "#,
1565 )
1566 .file("src/lib.rs", "")
1567 .build();
1568
afa3aced 1569 // Picks 0.1.1, the most recent version.
b78cb373 1570 p.cargo("check")
4f2bae93 1571 .with_status(101)
afa3aced
EH
1572 .with_stderr(
1573 "\
1574[UPDATING] `[..]/alternative-registry` index
4f2bae93
EH
1575[ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
1576
1577Caused by:
1578 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
1579
1580Caused by:
1581 patch for `bar` in `registry `[..]/alternative-registry`` resolved to more than one candidate
6514c289
AC
1582 Found versions: 0.1.0, 0.1.1
1583 Update the patch definition to select only one package.
1584 For example, add an `=` version requirement to the patch definition, such as `version = \"=0.1.1\"`.
afa3aced
EH
1585",
1586 )
b78cb373
EH
1587 .run();
1588}
1589
1590#[cargo_test]
1591fn no_matches() {
1592 // A patch to a location that does not contain the named package.
1593 let p = project()
1594 .file(
1595 "Cargo.toml",
1596 r#"
6f8c7d5a
EH
1597 [package]
1598 name = "foo"
1599 version = "0.1.0"
b78cb373 1600
6f8c7d5a
EH
1601 [dependencies]
1602 bar = "0.1"
b78cb373 1603
6f8c7d5a
EH
1604 [patch.crates-io]
1605 bar = { path = "bar" }
1606 "#,
b78cb373
EH
1607 )
1608 .file("src/lib.rs", "")
1609 .file("bar/Cargo.toml", &basic_manifest("abc", "0.1.0"))
1610 .file("bar/src/lib.rs", "")
1611 .build();
1612
1613 p.cargo("check")
1614 .with_status(101)
1615 .with_stderr(
1616 "\
1617error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
1618
1619Caused by:
4f2bae93 1620 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
afa3aced
EH
1621
1622Caused by:
5dde9cc9 1623 The patch location `[..]/foo/bar` does not appear to contain any packages matching the name `bar`.
b78cb373
EH
1624",
1625 )
1626 .run();
1627}
1628
1629#[cargo_test]
1630fn mismatched_version() {
1631 // A patch to a location that has an old version.
1632 let p = project()
1633 .file(
1634 "Cargo.toml",
1635 r#"
6f8c7d5a
EH
1636 [package]
1637 name = "foo"
1638 version = "0.1.0"
b78cb373 1639
6f8c7d5a
EH
1640 [dependencies]
1641 bar = "0.1.1"
b78cb373 1642
6f8c7d5a
EH
1643 [patch.crates-io]
1644 bar = { path = "bar", version = "0.1.1" }
1645 "#,
b78cb373
EH
1646 )
1647 .file("src/lib.rs", "")
1648 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1649 .file("bar/src/lib.rs", "")
1650 .build();
1651
1652 p.cargo("check")
1653 .with_status(101)
1654 .with_stderr(
1655 "\
1656[ERROR] failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
1657
1658Caused by:
4f2bae93 1659 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
afa3aced
EH
1660
1661Caused by:
5dde9cc9 1662 The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, \
6514c289
AC
1663 but the patch definition requires `^0.1.1`.
1664 Check that the version in the patch location is what you expect, \
1665 and update the patch definition to match.
b78cb373
EH
1666",
1667 )
1668 .run();
1669}
afa3aced
EH
1670
1671#[cargo_test]
1672fn patch_walks_backwards() {
1673 // Starting with a locked patch, change the patch so it points to an older version.
1674 Package::new("bar", "0.1.0").publish();
1675
1676 let p = project()
1677 .file(
1678 "Cargo.toml",
1679 r#"
1680 [package]
1681 name = "foo"
1682 version = "0.1.0"
1683
1684 [dependencies]
1685 bar = "0.1"
1686
1687 [patch.crates-io]
1688 bar = {path="bar"}
1689 "#,
1690 )
1691 .file("src/lib.rs", "")
1692 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
1693 .file("bar/src/lib.rs", "")
1694 .build();
1695
1696 p.cargo("check")
1697 .with_stderr(
1698 "\
1699[UPDATING] `[..]/registry` index
1700[CHECKING] bar v0.1.1 ([..]/foo/bar)
1701[CHECKING] foo v0.1.0 ([..]/foo)
1702[FINISHED] [..]
1703",
1704 )
1705 .run();
1706
1707 // Somehow the user changes the version backwards.
1708 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"));
1709
1710 p.cargo("check")
1711 .with_stderr(
1712 "\
1713[UPDATING] `[..]/registry` index
1714[CHECKING] bar v0.1.0 ([..]/foo/bar)
1715[CHECKING] foo v0.1.0 ([..]/foo)
1716[FINISHED] [..]
1717",
1718 )
1719 .run();
1720}
1721
1722#[cargo_test]
1723fn patch_walks_backwards_restricted() {
1724 // This is the same as `patch_walks_backwards`, but the patch contains a
1725 // `version` qualifier. This is unusual, just checking a strange edge case.
1726 Package::new("bar", "0.1.0").publish();
1727
1728 let p = project()
1729 .file(
1730 "Cargo.toml",
1731 r#"
1732 [package]
1733 name = "foo"
1734 version = "0.1.0"
1735
1736 [dependencies]
1737 bar = "0.1"
1738
1739 [patch.crates-io]
1740 bar = {path="bar", version="0.1.1"}
1741 "#,
1742 )
1743 .file("src/lib.rs", "")
1744 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"))
1745 .file("bar/src/lib.rs", "")
1746 .build();
1747
1748 p.cargo("check")
1749 .with_stderr(
1750 "\
1751[UPDATING] `[..]/registry` index
1752[CHECKING] bar v0.1.1 ([..]/foo/bar)
1753[CHECKING] foo v0.1.0 ([..]/foo)
1754[FINISHED] [..]
1755",
1756 )
1757 .run();
1758
1759 // Somehow the user changes the version backwards.
1760 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"));
1761
1762 p.cargo("check")
1763 .with_status(101)
1764 .with_stderr(
1765 "\
1766error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`
1767
1768Caused by:
4f2bae93 1769 patch for `bar` in `https://github.com/rust-lang/crates.io-index` failed to resolve
afa3aced
EH
1770
1771Caused by:
5dde9cc9 1772 The patch location `[..]/foo/bar` contains a `bar` package with version `0.1.0`, but the patch definition requires `^0.1.1`.
6514c289 1773 Check that the version in the patch location is what you expect, and update the patch definition to match.
afa3aced
EH
1774",
1775 )
1776 .run();
1777}
1778
1779#[cargo_test]
1780fn patched_dep_new_version() {
1781 // What happens when a patch is locked, and then one of the patched
1782 // dependencies needs to be updated. In this case, the baz requirement
1783 // gets updated from 0.1.0 to 0.1.1.
1784 Package::new("bar", "0.1.0").dep("baz", "0.1.0").publish();
1785 Package::new("baz", "0.1.0").publish();
1786
1787 let p = project()
1788 .file(
1789 "Cargo.toml",
1790 r#"
1791 [package]
1792 name = "foo"
1793 version = "0.1.0"
1794
1795 [dependencies]
1796 bar = "0.1"
1797
1798 [patch.crates-io]
1799 bar = {path="bar"}
1800 "#,
1801 )
1802 .file("src/lib.rs", "")
1803 .file(
1804 "bar/Cargo.toml",
1805 r#"
1806 [package]
1807 name = "bar"
1808 version = "0.1.0"
1809
1810 [dependencies]
1811 baz = "0.1"
1812 "#,
1813 )
1814 .file("bar/src/lib.rs", "")
1815 .build();
1816
1817 // Lock everything.
1818 p.cargo("check")
1819 .with_stderr(
1820 "\
1821[UPDATING] `[..]/registry` index
1822[DOWNLOADING] crates ...
1823[DOWNLOADED] baz v0.1.0 [..]
1824[CHECKING] baz v0.1.0
1825[CHECKING] bar v0.1.0 ([..]/foo/bar)
1826[CHECKING] foo v0.1.0 ([..]/foo)
1827[FINISHED] [..]
1828",
1829 )
1830 .run();
1831
1832 Package::new("baz", "0.1.1").publish();
1833
1834 // Just the presence of the new version should not have changed anything.
1835 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1836
1837 // Modify the patch so it requires the new version.
1838 p.change_file(
1839 "bar/Cargo.toml",
1840 r#"
1841 [package]
1842 name = "bar"
1843 version = "0.1.0"
1844
1845 [dependencies]
1846 baz = "0.1.1"
1847 "#,
1848 );
1849
1850 // Should unlock and update cleanly.
1851 p.cargo("check")
1852 .with_stderr(
1853 "\
1854[UPDATING] `[..]/registry` index
1855[DOWNLOADING] crates ...
1856[DOWNLOADED] baz v0.1.1 (registry `[..]/registry`)
1857[CHECKING] baz v0.1.1
1858[CHECKING] bar v0.1.0 ([..]/foo/bar)
1859[CHECKING] foo v0.1.0 ([..]/foo)
1860[FINISHED] [..]
1861",
1862 )
1863 .run();
1864}
1865
1866#[cargo_test]
1867fn patch_update_doesnt_update_other_sources() {
1868 // Very extreme edge case, make sure a patch update doesn't update other
1869 // sources.
340656e2 1870 registry::alt_init();
afa3aced
EH
1871 Package::new("bar", "0.1.0").publish();
1872 Package::new("bar", "0.1.0").alternative(true).publish();
1873
1874 let p = project()
1875 .file(
1876 "Cargo.toml",
1877 r#"
1878 [package]
1879 name = "foo"
1880 version = "0.1.0"
1881
1882 [dependencies]
1883 bar = "0.1"
1884 bar_alt = { version = "0.1", registry = "alternative", package = "bar" }
1885
1886 [patch.crates-io]
1887 bar = { path = "bar" }
1888 "#,
1889 )
1890 .file("src/lib.rs", "")
1891 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1892 .file("bar/src/lib.rs", "")
1893 .build();
1894
1895 p.cargo("check")
1896 .with_stderr_unordered(
1897 "\
1898[UPDATING] `[..]/registry` index
1899[UPDATING] `[..]/alternative-registry` index
1900[DOWNLOADING] crates ...
1901[DOWNLOADED] bar v0.1.0 (registry `[..]/alternative-registry`)
1902[CHECKING] bar v0.1.0 (registry `[..]/alternative-registry`)
1903[CHECKING] bar v0.1.0 ([..]/foo/bar)
1904[CHECKING] foo v0.1.0 ([..]/foo)
1905[FINISHED] [..]
1906",
1907 )
1908 .run();
1909
1910 // Publish new versions in both sources.
1911 Package::new("bar", "0.1.1").publish();
1912 Package::new("bar", "0.1.1").alternative(true).publish();
1913
1914 // Since it is locked, nothing should change.
1915 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1916
1917 // Require new version on crates.io.
1918 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1"));
1919
1920 // This should not update bar_alt.
1921 p.cargo("check")
1922 .with_stderr(
1923 "\
1924[UPDATING] `[..]/registry` index
1925[CHECKING] bar v0.1.1 ([..]/foo/bar)
1926[CHECKING] foo v0.1.0 ([..]/foo)
1927[FINISHED] [..]
1928",
1929 )
1930 .run();
1931}
1932
1933#[cargo_test]
1934fn can_update_with_alt_reg() {
1935 // A patch to an alt reg can update.
340656e2 1936 registry::alt_init();
afa3aced
EH
1937 Package::new("bar", "0.1.0").publish();
1938 Package::new("bar", "0.1.0").alternative(true).publish();
1939 Package::new("bar", "0.1.1").alternative(true).publish();
1940
1941 let p = project()
1942 .file(
1943 "Cargo.toml",
1944 r#"
1945 [package]
1946 name = "foo"
1947 version = "0.1.0"
1948
1949 [dependencies]
1950 bar = "0.1"
1951
1952 [patch.crates-io]
4f2bae93 1953 bar = { version = "=0.1.1", registry = "alternative" }
afa3aced
EH
1954 "#,
1955 )
1956 .file("src/lib.rs", "")
1957 .build();
1958
1959 p.cargo("check")
1960 .with_stderr(
1961 "\
1962[UPDATING] `[..]/alternative-registry` index
1963[UPDATING] `[..]/registry` index
1964[DOWNLOADING] crates ...
1965[DOWNLOADED] bar v0.1.1 (registry `[..]/alternative-registry`)
1966[CHECKING] bar v0.1.1 (registry `[..]/alternative-registry`)
1967[CHECKING] foo v0.1.0 ([..]/foo)
1968[FINISHED] [..]
1969",
1970 )
1971 .run();
1972
1973 Package::new("bar", "0.1.2").alternative(true).publish();
1974
1975 // Should remain locked.
1976 p.cargo("check").with_stderr("[FINISHED] [..]").run();
1977
4f2bae93 1978 // This does nothing, due to `=` requirement.
afa3aced
EH
1979 p.cargo("update -p bar")
1980 .with_stderr(
1981 "\
1982[UPDATING] `[..]/alternative-registry` index
1983[UPDATING] `[..]/registry` index
4f2bae93
EH
1984",
1985 )
1986 .run();
1987
1988 // Bump to 0.1.2.
1989 p.change_file(
1990 "Cargo.toml",
1991 r#"
1992 [package]
1993 name = "foo"
1994 version = "0.1.0"
1995
1996 [dependencies]
1997 bar = "0.1"
1998
1999 [patch.crates-io]
2000 bar = { version = "=0.1.2", registry = "alternative" }
2001 "#,
2002 );
2003
2004 p.cargo("check")
2005 .with_stderr(
2006 "\
2007[UPDATING] `[..]/alternative-registry` index
2008[UPDATING] `[..]/registry` index
2009[DOWNLOADING] crates ...
2010[DOWNLOADED] bar v0.1.2 (registry `[..]/alternative-registry`)
2011[CHECKING] bar v0.1.2 (registry `[..]/alternative-registry`)
2012[CHECKING] foo v0.1.0 ([..]/foo)
2013[FINISHED] [..]
afa3aced
EH
2014",
2015 )
2016 .run();
2017}