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