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