]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/vendor.rs
Add RegistryBuilder to help initializing test registries.
[cargo.git] / tests / testsuite / vendor.rs
CommitLineData
83571aee 1//! Tests for the `cargo vendor` command.
723748fa
EH
2//!
3//! Note that every test here uses `--respect-source-config` so that the
4//! "fake" crates.io is used. Otherwise `vendor` would download the crates.io
5//! index from the network.
83571aee 6
4a1e7107
AB
7use std::fs;
8
9115b2c3 9use cargo_test_support::git;
340656e2 10use cargo_test_support::registry::{self, Package};
4a1e7107 11use cargo_test_support::{basic_lib_manifest, paths, project, Project};
3842d8e6 12
0e0d9688 13#[cargo_test]
3842d8e6
AC
14fn vendor_simple() {
15 let p = project()
16 .file(
17 "Cargo.toml",
18 r#"
19 [package]
20 name = "foo"
21 version = "0.1.0"
22
23 [dependencies]
24 log = "0.3.5"
25 "#,
26 )
27 .file("src/lib.rs", "")
28 .build();
29
30 Package::new("log", "0.3.5").publish();
31
32 p.cargo("vendor --respect-source-config").run();
33 let lock = p.read_file("vendor/log/Cargo.toml");
34 assert!(lock.contains("version = \"0.3.5\""));
35
36 add_vendor_config(&p);
37 p.cargo("build").run();
38}
39
40fn add_vendor_config(p: &Project) {
41 p.change_file(
42 ".cargo/config",
43 r#"
44 [source.crates-io]
45 replace-with = 'vendor'
46
47 [source.vendor]
48 directory = 'vendor'
49 "#,
50 );
51}
52
0e0d9688 53#[cargo_test]
3842d8e6
AC
54fn two_versions() {
55 let p = project()
56 .file(
57 "Cargo.toml",
58 r#"
59 [package]
60 name = "foo"
61 version = "0.1.0"
62
63 [dependencies]
64 bitflags = "0.8.0"
65 bar = { path = "bar" }
66 "#,
67 )
68 .file("src/lib.rs", "")
69 .file(
70 "bar/Cargo.toml",
71 r#"
72 [package]
73 name = "bar"
74 version = "0.1.0"
75
76 [dependencies]
77 bitflags = "0.7.0"
78 "#,
79 )
80 .file("bar/src/lib.rs", "")
81 .build();
82
83 Package::new("bitflags", "0.7.0").publish();
84 Package::new("bitflags", "0.8.0").publish();
85
86 p.cargo("vendor --respect-source-config").run();
87
88 let lock = p.read_file("vendor/bitflags/Cargo.toml");
89 assert!(lock.contains("version = \"0.8.0\""));
90 let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
3235a3de
JF
91 assert!(lock.contains("version = \"0.7.0\""));
92
93 add_vendor_config(&p);
94 p.cargo("build").run();
95}
96
97#[cargo_test]
98fn two_explicit_versions() {
99 let p = project()
100 .file(
101 "Cargo.toml",
102 r#"
103 [package]
104 name = "foo"
105 version = "0.1.0"
106
107 [dependencies]
108 bitflags = "0.8.0"
109 bar = { path = "bar" }
110 "#,
111 )
112 .file("src/lib.rs", "")
113 .file(
114 "bar/Cargo.toml",
115 r#"
116 [package]
117 name = "bar"
118 version = "0.1.0"
119
120 [dependencies]
121 bitflags = "0.7.0"
122 "#,
123 )
124 .file("bar/src/lib.rs", "")
125 .build();
126
127 Package::new("bitflags", "0.7.0").publish();
128 Package::new("bitflags", "0.8.0").publish();
129
fd807955 130 p.cargo("vendor --respect-source-config --versioned-dirs")
3235a3de
JF
131 .run();
132
133 let lock = p.read_file("vendor/bitflags-0.8.0/Cargo.toml");
134 assert!(lock.contains("version = \"0.8.0\""));
135 let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
3842d8e6
AC
136 assert!(lock.contains("version = \"0.7.0\""));
137
138 add_vendor_config(&p);
139 p.cargo("build").run();
140}
141
0e0d9688 142#[cargo_test]
3842d8e6
AC
143fn help() {
144 let p = project().build();
145 p.cargo("vendor -h").run();
146}
147
0e0d9688 148#[cargo_test]
3842d8e6
AC
149fn update_versions() {
150 let p = project()
151 .file(
152 "Cargo.toml",
153 r#"
154 [package]
155 name = "foo"
156 version = "0.1.0"
157
158 [dependencies]
159 bitflags = "0.7.0"
160 "#,
161 )
162 .file("src/lib.rs", "")
163 .build();
164
165 Package::new("bitflags", "0.7.0").publish();
166 Package::new("bitflags", "0.8.0").publish();
167
168 p.cargo("vendor --respect-source-config").run();
169
170 let lock = p.read_file("vendor/bitflags/Cargo.toml");
171 assert!(lock.contains("version = \"0.7.0\""));
172
173 p.change_file(
174 "Cargo.toml",
175 r#"
176 [package]
177 name = "foo"
178 version = "0.1.0"
179
180 [dependencies]
181 bitflags = "0.8.0"
182 "#,
183 );
184 p.cargo("vendor --respect-source-config").run();
185
186 let lock = p.read_file("vendor/bitflags/Cargo.toml");
187 assert!(lock.contains("version = \"0.8.0\""));
188}
189
0e0d9688 190#[cargo_test]
3842d8e6
AC
191fn two_lockfiles() {
192 let p = project()
193 .no_manifest()
194 .file(
195 "foo/Cargo.toml",
196 r#"
197 [package]
198 name = "foo"
199 version = "0.1.0"
200
201 [dependencies]
202 bitflags = "=0.7.0"
203 "#,
204 )
205 .file("foo/src/lib.rs", "")
206 .file(
207 "bar/Cargo.toml",
208 r#"
209 [package]
210 name = "bar"
211 version = "0.1.0"
212
213 [dependencies]
214 bitflags = "=0.8.0"
215 "#,
216 )
217 .file("bar/src/lib.rs", "")
218 .build();
219
220 Package::new("bitflags", "0.7.0").publish();
221 Package::new("bitflags", "0.8.0").publish();
222
223 p.cargo("vendor --respect-source-config -s bar/Cargo.toml --manifest-path foo/Cargo.toml")
224 .run();
225
226 let lock = p.read_file("vendor/bitflags/Cargo.toml");
227 assert!(lock.contains("version = \"0.8.0\""));
228 let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
229 assert!(lock.contains("version = \"0.7.0\""));
230
231 add_vendor_config(&p);
232 p.cargo("build").cwd("foo").run();
233 p.cargo("build").cwd("bar").run();
234}
235
0e0d9688 236#[cargo_test]
3842d8e6
AC
237fn delete_old_crates() {
238 let p = project()
239 .file(
240 "Cargo.toml",
241 r#"
242 [package]
243 name = "foo"
244 version = "0.1.0"
245
246 [dependencies]
247 bitflags = "=0.7.0"
248 "#,
249 )
250 .file("src/lib.rs", "")
251 .build();
252
253 Package::new("bitflags", "0.7.0").publish();
254 Package::new("log", "0.3.5").publish();
255
256 p.cargo("vendor --respect-source-config").run();
257 p.read_file("vendor/bitflags/Cargo.toml");
258
259 p.change_file(
260 "Cargo.toml",
261 r#"
262 [package]
263 name = "foo"
264 version = "0.1.0"
265
266 [dependencies]
267 log = "=0.3.5"
268 "#,
269 );
270
271 p.cargo("vendor --respect-source-config").run();
272 let lock = p.read_file("vendor/log/Cargo.toml");
273 assert!(lock.contains("version = \"0.3.5\""));
274 assert!(!p.root().join("vendor/bitflags/Cargo.toml").exists());
275}
276
0e0d9688 277#[cargo_test]
3842d8e6
AC
278fn ignore_files() {
279 let p = project()
280 .file(
281 "Cargo.toml",
282 r#"
283 [package]
284 name = "foo"
285 version = "0.1.0"
286
287 [dependencies]
288 url = "1.4.1"
289 "#,
290 )
291 .file("src/lib.rs", "")
292 .build();
293
294 Package::new("url", "1.4.1")
295 .file("src/lib.rs", "")
296 .file("foo.orig", "")
297 .file(".gitignore", "")
298 .file(".gitattributes", "")
299 .file("foo.rej", "")
300 .publish();
301
302 p.cargo("vendor --respect-source-config").run();
303 let csum = p.read_file("vendor/url/.cargo-checksum.json");
304 assert!(!csum.contains("foo.orig"));
305 assert!(!csum.contains(".gitignore"));
306 assert!(!csum.contains(".gitattributes"));
307 assert!(!csum.contains(".cargo-ok"));
308 assert!(!csum.contains("foo.rej"));
309}
310
0e0d9688 311#[cargo_test]
3842d8e6
AC
312fn included_files_only() {
313 let git = git::new("a", |p| {
314 p.file("Cargo.toml", &basic_lib_manifest("a"))
315 .file("src/lib.rs", "")
316 .file(".gitignore", "a")
317 .file("a/b.md", "")
3c20a243 318 });
3842d8e6
AC
319
320 let p = project()
321 .file(
322 "Cargo.toml",
323 &format!(
324 r#"
325 [package]
326 name = "foo"
327 version = "0.1.0"
328
329 [dependencies]
330 a = {{ git = '{}' }}
331 "#,
332 git.url()
333 ),
334 )
335 .file("src/lib.rs", "")
336 .build();
337
338 p.cargo("vendor --respect-source-config").run();
339 let csum = p.read_file("vendor/a/.cargo-checksum.json");
340 assert!(!csum.contains("a/b.md"));
341}
342
0e0d9688 343#[cargo_test]
3842d8e6
AC
344fn dependent_crates_in_crates() {
345 let git = git::new("a", |p| {
346 p.file(
347 "Cargo.toml",
348 r#"
349 [package]
350 name = "a"
351 version = "0.1.0"
352
353 [dependencies]
354 b = { path = 'b' }
355 "#,
356 )
357 .file("src/lib.rs", "")
358 .file("b/Cargo.toml", &basic_lib_manifest("b"))
359 .file("b/src/lib.rs", "")
3c20a243 360 });
3842d8e6
AC
361 let p = project()
362 .file(
363 "Cargo.toml",
364 &format!(
365 r#"
366 [package]
367 name = "foo"
368 version = "0.1.0"
369
370 [dependencies]
371 a = {{ git = '{}' }}
372 "#,
373 git.url()
374 ),
375 )
376 .file("src/lib.rs", "")
377 .build();
378
379 p.cargo("vendor --respect-source-config").run();
380 p.read_file("vendor/a/.cargo-checksum.json");
381 p.read_file("vendor/b/.cargo-checksum.json");
382}
383
0e0d9688 384#[cargo_test]
3842d8e6
AC
385fn vendoring_git_crates() {
386 let git = git::new("git", |p| {
387 p.file("Cargo.toml", &basic_lib_manifest("serde_derive"))
388 .file("src/lib.rs", "")
389 .file("src/wut.rs", "")
3c20a243 390 });
3842d8e6
AC
391
392 let p = project()
393 .file(
394 "Cargo.toml",
395 &format!(
396 r#"
397 [package]
398 name = "foo"
399 version = "0.1.0"
400
401 [dependencies.serde]
402 version = "0.5.0"
403
404 [dependencies.serde_derive]
405 version = "0.5.0"
406
407 [patch.crates-io]
408 serde_derive = {{ git = '{}' }}
409 "#,
410 git.url()
411 ),
412 )
413 .file("src/lib.rs", "")
414 .build();
415 Package::new("serde", "0.5.0")
416 .dep("serde_derive", "0.5")
417 .publish();
418 Package::new("serde_derive", "0.5.0").publish();
419
420 p.cargo("vendor --respect-source-config").run();
421 p.read_file("vendor/serde_derive/src/wut.rs");
422
423 add_vendor_config(&p);
424 p.cargo("build").run();
425}
426
0e0d9688 427#[cargo_test]
3842d8e6
AC
428fn git_simple() {
429 let git = git::new("git", |p| {
430 p.file("Cargo.toml", &basic_lib_manifest("a"))
431 .file("src/lib.rs", "")
3c20a243 432 });
3842d8e6
AC
433
434 let p = project()
435 .file(
436 "Cargo.toml",
437 &format!(
438 r#"
439 [package]
440 name = "foo"
441 version = "0.1.0"
442
443 [dependencies]
444 a = {{ git = '{}' }}
445 "#,
446 git.url()
447 ),
448 )
449 .file("src/lib.rs", "")
450 .build();
451
452 p.cargo("vendor --respect-source-config").run();
453 let csum = p.read_file("vendor/a/.cargo-checksum.json");
454 assert!(csum.contains("\"package\":null"));
455}
456
0e0d9688 457#[cargo_test]
3842d8e6
AC
458fn git_duplicate() {
459 let git = git::new("a", |p| {
460 p.file(
461 "Cargo.toml",
462 r#"
463 [package]
464 name = "a"
465 version = "0.1.0"
466
467 [dependencies]
468 b = { path = 'b' }
469 "#,
470 )
471 .file("src/lib.rs", "")
472 .file("b/Cargo.toml", &basic_lib_manifest("b"))
473 .file("b/src/lib.rs", "")
3c20a243 474 });
3842d8e6
AC
475
476 let p = project()
477 .file(
478 "Cargo.toml",
479 &format!(
480 r#"
481 [package]
482 name = "foo"
483 version = "0.1.0"
484
485 [dependencies]
486 a = {{ git = '{}' }}
487 b = '0.5.0'
488
489 "#,
490 git.url()
491 ),
492 )
493 .file("src/lib.rs", "")
494 .build();
495 Package::new("b", "0.5.0").publish();
496
497 p.cargo("vendor --respect-source-config")
498 .with_stderr(
499 "\
500[UPDATING] [..]
501[UPDATING] [..]
502[DOWNLOADING] [..]
503[DOWNLOADED] [..]
504error: failed to sync
505
506Caused by:
507 found duplicate version of package `b v0.5.0` vendored from two sources:
508
6514c289
AC
509 <tab>source 1: [..]
510 <tab>source 2: [..]
3842d8e6
AC
511",
512 )
513 .with_status(101)
514 .run();
515}
516
0e0d9688 517#[cargo_test]
3842d8e6
AC
518fn depend_on_vendor_dir_not_deleted() {
519 let p = project()
520 .file(
521 "Cargo.toml",
522 r#"
523 [package]
524 name = "foo"
525 version = "0.1.0"
526
527 [dependencies]
528 libc = "0.2.30"
529 "#,
530 )
531 .file("src/lib.rs", "")
532 .build();
533
534 Package::new("libc", "0.2.30").publish();
535
536 p.cargo("vendor --respect-source-config").run();
537 assert!(p.root().join("vendor/libc").is_dir());
538
539 p.change_file(
540 "Cargo.toml",
541 r#"
542 [package]
543 name = "foo"
544 version = "0.1.0"
545
546 [dependencies]
547 libc = "0.2.30"
548
549 [patch.crates-io]
550 libc = { path = 'vendor/libc' }
551 "#,
552 );
553
554 p.cargo("vendor --respect-source-config").run();
555 assert!(p.root().join("vendor/libc").is_dir());
556}
492abb35
EH
557
558#[cargo_test]
559fn ignore_hidden() {
560 // Don't delete files starting with `.`
561 Package::new("bar", "0.1.0").publish();
562 let p = project()
563 .file(
564 "Cargo.toml",
565 r#"
566 [package]
567 name = "foo"
568 version = "1.0.0"
569 [dependencies]
570 bar = "0.1.0"
571 "#,
572 )
573 .file("src/lib.rs", "")
574 .build();
575 p.cargo("vendor --respect-source-config").run();
576 // Add a `.git` directory.
577 let repo = git::init(&p.root().join("vendor"));
578 git::add(&repo);
579 git::commit(&repo);
580 assert!(p.root().join("vendor/.git").exists());
581 // Vendor again, shouldn't change anything.
582 p.cargo("vendor --respect-source-config").run();
583 // .git should not be removed.
584 assert!(p.root().join("vendor/.git").exists());
585 // And just for good measure, make sure no files changed.
586 let mut opts = git2::StatusOptions::new();
587 assert!(repo
588 .statuses(Some(&mut opts))
589 .unwrap()
590 .iter()
591 .all(|status| status.status() == git2::Status::CURRENT));
592}
723748fa
EH
593
594#[cargo_test]
595fn config_instructions_works() {
596 // Check that the config instructions work for all dependency kinds.
340656e2 597 registry::alt_init();
723748fa
EH
598 Package::new("dep", "0.1.0").publish();
599 Package::new("altdep", "0.1.0").alternative(true).publish();
600 let git_project = git::new("gitdep", |project| {
601 project
602 .file("Cargo.toml", &basic_lib_manifest("gitdep"))
603 .file("src/lib.rs", "")
604 });
605 let p = project()
606 .file(
607 "Cargo.toml",
608 &format!(
609 r#"
610 [package]
611 name = "foo"
612 version = "0.1.0"
613
614 [dependencies]
615 dep = "0.1"
616 altdep = {{version="0.1", registry="alternative"}}
617 gitdep = {{git='{}'}}
618 "#,
619 git_project.url()
620 ),
621 )
622 .file("src/lib.rs", "")
623 .build();
624 let output = p
625 .cargo("vendor --respect-source-config")
626 .exec_with_output()
627 .unwrap();
628 let output = String::from_utf8(output.stdout).unwrap();
629 p.change_file(".cargo/config", &output);
630
631 p.cargo("check -v")
632 .with_stderr_contains("[..]foo/vendor/dep/src/lib.rs[..]")
633 .with_stderr_contains("[..]foo/vendor/altdep/src/lib.rs[..]")
634 .with_stderr_contains("[..]foo/vendor/gitdep/src/lib.rs[..]")
635 .run();
636}
4a1e7107
AB
637
638#[cargo_test]
639fn git_crlf_preservation() {
640 // Check that newlines don't get changed when you vendor
641 // (will only fail if your system is setup with core.autocrlf=true on windows)
642 let input = "hello \nthere\nmy newline\nfriends";
643 let git_project = git::new("git", |p| {
644 p.file("Cargo.toml", &basic_lib_manifest("a"))
645 .file("src/lib.rs", input)
646 });
647
648 let p = project()
649 .file(
650 "Cargo.toml",
651 &format!(
652 r#"
653 [package]
654 name = "foo"
655 version = "0.1.0"
656
657 [dependencies]
658 a = {{ git = '{}' }}
659 "#,
660 git_project.url()
661 ),
662 )
663 .file("src/lib.rs", "")
664 .build();
665
666 fs::write(
667 paths::home().join(".gitconfig"),
668 r#"
669 [core]
670 autocrlf = true
671 "#,
672 )
673 .unwrap();
674
675 p.cargo("vendor --respect-source-config").run();
676 let output = p.read_file("vendor/a/src/lib.rs");
677 assert_eq!(input, output);
678}