]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/directory.rs
Auto merge of #8094 - Freax13:fix-target, r=ehuss
[cargo.git] / tests / testsuite / directory.rs
1 //! Tests for directory sources.
2
3 use std::collections::HashMap;
4 use std::fs;
5 use std::str;
6
7 use serde::Serialize;
8
9 use cargo_test_support::cargo_process;
10 use cargo_test_support::git;
11 use cargo_test_support::paths;
12 use cargo_test_support::registry::{cksum, Package};
13 use cargo_test_support::{basic_manifest, project, t, ProjectBuilder};
14
15 fn setup() {
16 let root = paths::root();
17 t!(fs::create_dir(&root.join(".cargo")));
18 t!(fs::write(
19 root.join(".cargo/config"),
20 r#"
21 [source.crates-io]
22 replace-with = 'my-awesome-local-registry'
23
24 [source.my-awesome-local-registry]
25 directory = 'index'
26 "#
27 ));
28 }
29
30 struct VendorPackage {
31 p: Option<ProjectBuilder>,
32 cksum: Checksum,
33 }
34
35 #[derive(Serialize)]
36 struct Checksum {
37 package: Option<String>,
38 files: HashMap<String, String>,
39 }
40
41 impl VendorPackage {
42 fn new(name: &str) -> VendorPackage {
43 VendorPackage {
44 p: Some(project().at(&format!("index/{}", name))),
45 cksum: Checksum {
46 package: Some(String::new()),
47 files: HashMap::new(),
48 },
49 }
50 }
51
52 fn file(&mut self, name: &str, contents: &str) -> &mut VendorPackage {
53 self.p = Some(self.p.take().unwrap().file(name, contents));
54 self.cksum
55 .files
56 .insert(name.to_string(), cksum(contents.as_bytes()));
57 self
58 }
59
60 fn disable_checksum(&mut self) -> &mut VendorPackage {
61 self.cksum.package = None;
62 self
63 }
64
65 fn no_manifest(mut self) -> Self {
66 self.p = self.p.map(|pb| pb.no_manifest());
67 self
68 }
69
70 fn build(&mut self) {
71 let p = self.p.take().unwrap();
72 let json = serde_json::to_string(&self.cksum).unwrap();
73 let p = p.file(".cargo-checksum.json", &json);
74 let _ = p.build();
75 }
76 }
77
78 #[cargo_test]
79 fn simple() {
80 setup();
81
82 VendorPackage::new("bar")
83 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
84 .file("src/lib.rs", "pub fn bar() {}")
85 .build();
86
87 let p = project()
88 .file(
89 "Cargo.toml",
90 r#"
91 [package]
92 name = "foo"
93 version = "0.1.0"
94 authors = []
95
96 [dependencies]
97 bar = "0.1.0"
98 "#,
99 )
100 .file(
101 "src/lib.rs",
102 "extern crate bar; pub fn foo() { bar::bar(); }",
103 )
104 .build();
105
106 p.cargo("build")
107 .with_stderr(
108 "\
109 [COMPILING] bar v0.1.0
110 [COMPILING] foo v0.1.0 ([CWD])
111 [FINISHED] [..]
112 ",
113 )
114 .run();
115 }
116
117 #[cargo_test]
118 fn simple_install() {
119 setup();
120
121 VendorPackage::new("foo")
122 .file("src/lib.rs", "pub fn foo() {}")
123 .build();
124
125 VendorPackage::new("bar")
126 .file(
127 "Cargo.toml",
128 r#"
129 [package]
130 name = "bar"
131 version = "0.1.0"
132 authors = []
133
134 [dependencies]
135 foo = "0.0.1"
136 "#,
137 )
138 .file(
139 "src/main.rs",
140 "extern crate foo; pub fn main() { foo::foo(); }",
141 )
142 .build();
143
144 cargo_process("install bar")
145 .with_stderr(
146 "\
147 [INSTALLING] bar v0.1.0
148 [COMPILING] foo v0.0.1
149 [COMPILING] bar v0.1.0
150 [FINISHED] release [optimized] target(s) in [..]s
151 [INSTALLING] [..]bar[..]
152 [INSTALLED] package `bar v0.1.0` (executable `bar[EXE]`)
153 [WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
154 ",
155 )
156 .run();
157 }
158
159 #[cargo_test]
160 fn simple_install_fail() {
161 setup();
162
163 VendorPackage::new("foo")
164 .file("src/lib.rs", "pub fn foo() {}")
165 .build();
166
167 VendorPackage::new("bar")
168 .file(
169 "Cargo.toml",
170 r#"
171 [package]
172 name = "bar"
173 version = "0.1.0"
174 authors = []
175
176 [dependencies]
177 foo = "0.1.0"
178 baz = "9.8.7"
179 "#,
180 )
181 .file(
182 "src/main.rs",
183 "extern crate foo; pub fn main() { foo::foo(); }",
184 )
185 .build();
186
187 cargo_process("install bar")
188 .with_status(101)
189 .with_stderr(
190 " Installing bar v0.1.0
191 error: failed to compile `bar v0.1.0`, intermediate artifacts can be found at `[..]`
192
193 Caused by:
194 no matching package named `baz` found
195 location searched: registry `https://github.com/rust-lang/crates.io-index`
196 perhaps you meant: bar or foo
197 required by package `bar v0.1.0`
198 ",
199 )
200 .run();
201 }
202
203 #[cargo_test]
204 fn install_without_feature_dep() {
205 setup();
206
207 VendorPackage::new("foo")
208 .file("src/lib.rs", "pub fn foo() {}")
209 .build();
210
211 VendorPackage::new("bar")
212 .file(
213 "Cargo.toml",
214 r#"
215 [package]
216 name = "bar"
217 version = "0.1.0"
218 authors = []
219
220 [dependencies]
221 foo = "0.0.1"
222 baz = { version = "9.8.7", optional = true }
223
224 [features]
225 wantbaz = ["baz"]
226 "#,
227 )
228 .file(
229 "src/main.rs",
230 "extern crate foo; pub fn main() { foo::foo(); }",
231 )
232 .build();
233
234 cargo_process("install bar")
235 .with_stderr(
236 "\
237 [INSTALLING] bar v0.1.0
238 [COMPILING] foo v0.0.1
239 [COMPILING] bar v0.1.0
240 [FINISHED] release [optimized] target(s) in [..]s
241 [INSTALLING] [..]bar[..]
242 [INSTALLED] package `bar v0.1.0` (executable `bar[EXE]`)
243 [WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
244 ",
245 )
246 .run();
247 }
248
249 #[cargo_test]
250 fn not_there() {
251 setup();
252
253 let _ = project().at("index").build();
254
255 let p = project()
256 .file(
257 "Cargo.toml",
258 r#"
259 [package]
260 name = "foo"
261 version = "0.1.0"
262 authors = []
263
264 [dependencies]
265 bar = "0.1.0"
266 "#,
267 )
268 .file(
269 "src/lib.rs",
270 "extern crate bar; pub fn foo() { bar::bar(); }",
271 )
272 .build();
273
274 p.cargo("build")
275 .with_status(101)
276 .with_stderr(
277 "\
278 error: no matching package named `bar` found
279 location searched: [..]
280 required by package `foo v0.1.0 ([..])`
281 ",
282 )
283 .run();
284 }
285
286 #[cargo_test]
287 fn multiple() {
288 setup();
289
290 VendorPackage::new("bar-0.1.0")
291 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
292 .file("src/lib.rs", "pub fn bar() {}")
293 .file(".cargo-checksum", "")
294 .build();
295
296 VendorPackage::new("bar-0.2.0")
297 .file("Cargo.toml", &basic_manifest("bar", "0.2.0"))
298 .file("src/lib.rs", "pub fn bar() {}")
299 .file(".cargo-checksum", "")
300 .build();
301
302 let p = project()
303 .file(
304 "Cargo.toml",
305 r#"
306 [package]
307 name = "foo"
308 version = "0.1.0"
309 authors = []
310
311 [dependencies]
312 bar = "0.1.0"
313 "#,
314 )
315 .file(
316 "src/lib.rs",
317 "extern crate bar; pub fn foo() { bar::bar(); }",
318 )
319 .build();
320
321 p.cargo("build")
322 .with_stderr(
323 "\
324 [COMPILING] bar v0.1.0
325 [COMPILING] foo v0.1.0 ([CWD])
326 [FINISHED] [..]
327 ",
328 )
329 .run();
330 }
331
332 #[cargo_test]
333 fn crates_io_then_directory() {
334 let p = project()
335 .file(
336 "Cargo.toml",
337 r#"
338 [package]
339 name = "foo"
340 version = "0.1.0"
341 authors = []
342
343 [dependencies]
344 bar = "0.1.0"
345 "#,
346 )
347 .file(
348 "src/lib.rs",
349 "extern crate bar; pub fn foo() { bar::bar(); }",
350 )
351 .build();
352
353 let cksum = Package::new("bar", "0.1.0")
354 .file("src/lib.rs", "pub fn bar() -> u32 { 0 }")
355 .publish();
356
357 p.cargo("build")
358 .with_stderr(
359 "\
360 [UPDATING] `[..]` index
361 [DOWNLOADING] crates ...
362 [DOWNLOADED] bar v0.1.0 ([..])
363 [COMPILING] bar v0.1.0
364 [COMPILING] foo v0.1.0 ([CWD])
365 [FINISHED] [..]
366 ",
367 )
368 .run();
369
370 setup();
371
372 let mut v = VendorPackage::new("bar");
373 v.file("Cargo.toml", &basic_manifest("bar", "0.1.0"));
374 v.file("src/lib.rs", "pub fn bar() -> u32 { 1 }");
375 v.cksum.package = Some(cksum);
376 v.build();
377
378 p.cargo("build")
379 .with_stderr(
380 "\
381 [COMPILING] bar v0.1.0
382 [COMPILING] foo v0.1.0 ([CWD])
383 [FINISHED] [..]
384 ",
385 )
386 .run();
387 }
388
389 #[cargo_test]
390 fn crates_io_then_bad_checksum() {
391 let p = project()
392 .file(
393 "Cargo.toml",
394 r#"
395 [package]
396 name = "foo"
397 version = "0.1.0"
398 authors = []
399
400 [dependencies]
401 bar = "0.1.0"
402 "#,
403 )
404 .file("src/lib.rs", "")
405 .build();
406
407 Package::new("bar", "0.1.0").publish();
408
409 p.cargo("build").run();
410 setup();
411
412 VendorPackage::new("bar")
413 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
414 .file("src/lib.rs", "")
415 .build();
416
417 p.cargo("build")
418 .with_status(101)
419 .with_stderr(
420 "\
421 error: checksum for `bar v0.1.0` changed between lock files
422
423 this could be indicative of a few possible errors:
424
425 * the lock file is corrupt
426 * a replacement source in use (e.g., a mirror) returned a different checksum
427 * the source itself may be corrupt in one way or another
428
429 unable to verify that `bar v0.1.0` is the same as when the lockfile was generated
430
431 ",
432 )
433 .run();
434 }
435
436 #[cargo_test]
437 fn bad_file_checksum() {
438 setup();
439
440 VendorPackage::new("bar")
441 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
442 .file("src/lib.rs", "")
443 .build();
444
445 t!(fs::write(
446 paths::root().join("index/bar/src/lib.rs"),
447 "fn bar() -> u32 { 0 }"
448 ));
449
450 let p = project()
451 .file(
452 "Cargo.toml",
453 r#"
454 [package]
455 name = "foo"
456 version = "0.1.0"
457 authors = []
458
459 [dependencies]
460 bar = "0.1.0"
461 "#,
462 )
463 .file("src/lib.rs", "")
464 .build();
465
466 p.cargo("build")
467 .with_status(101)
468 .with_stderr(
469 "\
470 error: the listed checksum of `[..]lib.rs` has changed:
471 expected: [..]
472 actual: [..]
473
474 directory sources are not intended to be edited, if modifications are \
475 required then it is recommended that [replace] is used with a forked copy of \
476 the source
477 ",
478 )
479 .run();
480 }
481
482 #[cargo_test]
483 fn only_dot_files_ok() {
484 setup();
485
486 VendorPackage::new("bar")
487 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
488 .file("src/lib.rs", "")
489 .build();
490 VendorPackage::new("foo")
491 .no_manifest()
492 .file(".bar", "")
493 .build();
494
495 let p = project()
496 .file(
497 "Cargo.toml",
498 r#"
499 [package]
500 name = "foo"
501 version = "0.1.0"
502 authors = []
503
504 [dependencies]
505 bar = "0.1.0"
506 "#,
507 )
508 .file("src/lib.rs", "")
509 .build();
510
511 p.cargo("build").run();
512 }
513
514 #[cargo_test]
515 fn random_files_ok() {
516 setup();
517
518 VendorPackage::new("bar")
519 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
520 .file("src/lib.rs", "")
521 .build();
522 VendorPackage::new("foo")
523 .no_manifest()
524 .file("bar", "")
525 .file("../test", "")
526 .build();
527
528 let p = project()
529 .file(
530 "Cargo.toml",
531 r#"
532 [package]
533 name = "foo"
534 version = "0.1.0"
535 authors = []
536
537 [dependencies]
538 bar = "0.1.0"
539 "#,
540 )
541 .file("src/lib.rs", "")
542 .build();
543
544 p.cargo("build").run();
545 }
546
547 #[cargo_test]
548 fn git_lock_file_doesnt_change() {
549 let git = git::new("git", |p| {
550 p.file("Cargo.toml", &basic_manifest("git", "0.5.0"))
551 .file("src/lib.rs", "")
552 });
553
554 VendorPackage::new("git")
555 .file("Cargo.toml", &basic_manifest("git", "0.5.0"))
556 .file("src/lib.rs", "")
557 .disable_checksum()
558 .build();
559
560 let p = project()
561 .file(
562 "Cargo.toml",
563 &format!(
564 r#"
565 [package]
566 name = "foo"
567 version = "0.0.1"
568 authors = []
569
570 [dependencies]
571 git = {{ git = '{0}' }}
572 "#,
573 git.url()
574 ),
575 )
576 .file("src/lib.rs", "")
577 .build();
578
579 p.cargo("build").run();
580
581 let lock1 = p.read_lockfile();
582
583 let root = paths::root();
584 t!(fs::create_dir(&root.join(".cargo")));
585 t!(fs::write(
586 root.join(".cargo/config"),
587 format!(
588 r#"
589 [source.my-git-repo]
590 git = '{}'
591 replace-with = 'my-awesome-local-registry'
592
593 [source.my-awesome-local-registry]
594 directory = 'index'
595 "#,
596 git.url()
597 )
598 ));
599
600 p.cargo("build")
601 .with_stderr(
602 "\
603 [COMPILING] [..]
604 [COMPILING] [..]
605 [FINISHED] [..]
606 ",
607 )
608 .run();
609
610 let lock2 = p.read_lockfile();
611 assert_eq!(lock1, lock2, "lock files changed");
612 }
613
614 #[cargo_test]
615 fn git_override_requires_lockfile() {
616 VendorPackage::new("git")
617 .file("Cargo.toml", &basic_manifest("git", "0.5.0"))
618 .file("src/lib.rs", "")
619 .disable_checksum()
620 .build();
621
622 let p = project()
623 .file(
624 "Cargo.toml",
625 r#"
626 [package]
627 name = "foo"
628 version = "0.0.1"
629 authors = []
630
631 [dependencies]
632 git = { git = 'https://example.com/' }
633 "#,
634 )
635 .file("src/lib.rs", "")
636 .build();
637
638 let root = paths::root();
639 t!(fs::create_dir(&root.join(".cargo")));
640 t!(fs::write(
641 root.join(".cargo/config"),
642 r#"
643 [source.my-git-repo]
644 git = 'https://example.com/'
645 replace-with = 'my-awesome-local-registry'
646
647 [source.my-awesome-local-registry]
648 directory = 'index'
649 "#
650 ));
651
652 p.cargo("build")
653 .with_status(101)
654 .with_stderr(
655 "\
656 [ERROR] failed to get `git` as a dependency of package `foo v0.0.1 ([..])`
657
658 Caused by:
659 failed to load source for dependency `git`
660
661 Caused by:
662 Unable to update [..]
663
664 Caused by:
665 the source my-git-repo requires a lock file to be present first before it can be
666 used against vendored source code
667
668 remove the source replacement configuration, generate a lock file, and then
669 restore the source replacement configuration to continue the build
670
671 ",
672 )
673 .run();
674 }
675
676 #[cargo_test]
677 fn workspace_different_locations() {
678 let p = project()
679 .no_manifest()
680 .file(
681 "foo/Cargo.toml",
682 r#"
683 [package]
684 name = 'foo'
685 version = '0.1.0'
686
687 [dependencies]
688 baz = "*"
689 "#,
690 )
691 .file("foo/src/lib.rs", "")
692 .file("foo/vendor/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
693 .file("foo/vendor/baz/src/lib.rs", "")
694 .file("foo/vendor/baz/.cargo-checksum.json", "{\"files\":{}}")
695 .file(
696 "bar/Cargo.toml",
697 r#"
698 [package]
699 name = 'bar'
700 version = '0.1.0'
701
702 [dependencies]
703 baz = "*"
704 "#,
705 )
706 .file("bar/src/lib.rs", "")
707 .file(
708 ".cargo/config",
709 r#"
710 [build]
711 target-dir = './target'
712
713 [source.crates-io]
714 replace-with = 'my-awesome-local-registry'
715
716 [source.my-awesome-local-registry]
717 directory = 'foo/vendor'
718 "#,
719 )
720 .build();
721
722 p.cargo("build").cwd("foo").run();
723 p.cargo("build")
724 .cwd("bar")
725 .with_stderr(
726 "\
727 [COMPILING] bar [..]
728 [FINISHED] [..]
729 ",
730 )
731 .run();
732 }
733
734 #[cargo_test]
735 fn version_missing() {
736 setup();
737
738 VendorPackage::new("foo")
739 .file("src/lib.rs", "pub fn foo() {}")
740 .build();
741
742 VendorPackage::new("bar")
743 .file(
744 "Cargo.toml",
745 r#"
746 [package]
747 name = "bar"
748 version = "0.1.0"
749 authors = []
750
751 [dependencies]
752 foo = "2"
753 "#,
754 )
755 .file("src/main.rs", "fn main() {}")
756 .build();
757
758 cargo_process("install bar")
759 .with_stderr(
760 "\
761 [INSTALLING] bar v0.1.0
762 error: failed to compile [..]
763
764 Caused by:
765 failed to select a version for the requirement `foo = \"^2\"`
766 candidate versions found which didn't match: 0.0.1
767 location searched: directory source `[..] (which is replacing registry `[..]`)
768 required by package `bar v0.1.0`
769 perhaps a crate was updated and forgotten to be re-vendored?
770 ",
771 )
772 .with_status(101)
773 .run();
774 }