]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/directory.rs
Auto merge of #5952 - dwijnand:fix-path-deep_dependencies_trigger_rebuild, r=alexcrichton
[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 support::cargo_process;
8 use support::git;
9 use support::paths;
10 use support::registry::{cksum, Package};
11 use 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] registry `[..]`
334 [DOWNLOADING] bar v0.1.0 ([..])
335 [COMPILING] bar v0.1.0
336 [COMPILING] foo v0.1.0 (CWD)
337 [FINISHED] [..]
338 ",
339 ).run();
340
341 setup();
342
343 let mut v = VendorPackage::new("bar");
344 v.file("Cargo.toml", &basic_manifest("bar", "0.1.0"));
345 v.file("src/lib.rs", "pub fn bar() -> u32 { 1 }");
346 v.cksum.package = Some(cksum);
347 v.build();
348
349 p.cargo("build")
350 .with_stderr(
351 "\
352 [COMPILING] bar v0.1.0
353 [COMPILING] foo v0.1.0 (CWD)
354 [FINISHED] [..]
355 ",
356 ).run();
357 }
358
359 #[test]
360 fn crates_io_then_bad_checksum() {
361 let p = project()
362 .file(
363 "Cargo.toml",
364 r#"
365 [package]
366 name = "foo"
367 version = "0.1.0"
368 authors = []
369
370 [dependencies]
371 bar = "0.1.0"
372 "#,
373 ).file("src/lib.rs", "")
374 .build();
375
376 Package::new("bar", "0.1.0").publish();
377
378 p.cargo("build").run();
379 setup();
380
381 VendorPackage::new("bar")
382 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
383 .file("src/lib.rs", "")
384 .build();
385
386 p.cargo("build")
387 .with_status(101)
388 .with_stderr(
389 "\
390 error: checksum for `bar v0.1.0` changed between lock files
391
392 this could be indicative of a few possible errors:
393
394 * the lock file is corrupt
395 * a replacement source in use (e.g. a mirror) returned a different checksum
396 * the source itself may be corrupt in one way or another
397
398 unable to verify that `bar v0.1.0` is the same as when the lockfile was generated
399
400 ",
401 ).run();
402 }
403
404 #[test]
405 fn bad_file_checksum() {
406 setup();
407
408 VendorPackage::new("bar")
409 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
410 .file("src/lib.rs", "")
411 .build();
412
413 let mut f = t!(File::create(paths::root().join("index/bar/src/lib.rs")));
414 t!(f.write_all(b"fn bar() -> u32 { 0 }"));
415
416 let p = project()
417 .file(
418 "Cargo.toml",
419 r#"
420 [package]
421 name = "foo"
422 version = "0.1.0"
423 authors = []
424
425 [dependencies]
426 bar = "0.1.0"
427 "#,
428 ).file("src/lib.rs", "")
429 .build();
430
431 p.cargo("build")
432 .with_status(101)
433 .with_stderr(
434 "\
435 error: the listed checksum of `[..]lib.rs` has changed:
436 expected: [..]
437 actual: [..]
438
439 directory sources are not intended to be edited, if modifications are \
440 required then it is recommended that [replace] is used with a forked copy of \
441 the source
442 ",
443 ).run();
444 }
445
446 #[test]
447 fn only_dot_files_ok() {
448 setup();
449
450 VendorPackage::new("bar")
451 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
452 .file("src/lib.rs", "")
453 .build();
454 VendorPackage::new("foo")
455 .no_manifest()
456 .file(".bar", "")
457 .build();
458
459 let p = project()
460 .file(
461 "Cargo.toml",
462 r#"
463 [package]
464 name = "foo"
465 version = "0.1.0"
466 authors = []
467
468 [dependencies]
469 bar = "0.1.0"
470 "#,
471 ).file("src/lib.rs", "")
472 .build();
473
474 p.cargo("build").run();
475 }
476
477 #[test]
478 fn random_files_ok() {
479 setup();
480
481 VendorPackage::new("bar")
482 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
483 .file("src/lib.rs", "")
484 .build();
485 VendorPackage::new("foo")
486 .no_manifest()
487 .file("bar", "")
488 .file("../test", "")
489 .build();
490
491 let p = project()
492 .file(
493 "Cargo.toml",
494 r#"
495 [package]
496 name = "foo"
497 version = "0.1.0"
498 authors = []
499
500 [dependencies]
501 bar = "0.1.0"
502 "#,
503 ).file("src/lib.rs", "")
504 .build();
505
506 p.cargo("build").run();
507 }
508
509 #[test]
510 fn git_lock_file_doesnt_change() {
511 let git = git::new("git", |p| {
512 p.file("Cargo.toml", &basic_manifest("git", "0.5.0"))
513 .file("src/lib.rs", "")
514 }).unwrap();
515
516 VendorPackage::new("git")
517 .file("Cargo.toml", &basic_manifest("git", "0.5.0"))
518 .file("src/lib.rs", "")
519 .disable_checksum()
520 .build();
521
522 let p = project()
523 .file(
524 "Cargo.toml",
525 &format!(
526 r#"
527 [package]
528 name = "foo"
529 version = "0.0.1"
530 authors = []
531
532 [dependencies]
533 git = {{ git = '{0}' }}
534 "#,
535 git.url()
536 ),
537 ).file("src/lib.rs", "")
538 .build();
539
540 p.cargo("build").run();
541
542 let mut lock1 = String::new();
543 t!(t!(File::open(p.root().join("Cargo.lock"))).read_to_string(&mut lock1));
544
545 let root = paths::root();
546 t!(fs::create_dir(&root.join(".cargo")));
547 t!(t!(File::create(root.join(".cargo/config"))).write_all(
548 &format!(
549 r#"
550 [source.my-git-repo]
551 git = '{}'
552 replace-with = 'my-awesome-local-registry'
553
554 [source.my-awesome-local-registry]
555 directory = 'index'
556 "#,
557 git.url()
558 ).as_bytes()
559 ));
560
561 p.cargo("build")
562 .with_stderr(
563 "\
564 [COMPILING] [..]
565 [COMPILING] [..]
566 [FINISHED] [..]
567 ",
568 ).run();
569
570 let mut lock2 = String::new();
571 t!(t!(File::open(p.root().join("Cargo.lock"))).read_to_string(&mut lock2));
572 assert_eq!(lock1, lock2, "lock files changed");
573 }
574
575 #[test]
576 fn git_override_requires_lockfile() {
577 VendorPackage::new("git")
578 .file("Cargo.toml", &basic_manifest("git", "0.5.0"))
579 .file("src/lib.rs", "")
580 .disable_checksum()
581 .build();
582
583 let p = project()
584 .file(
585 "Cargo.toml",
586 r#"
587 [package]
588 name = "foo"
589 version = "0.0.1"
590 authors = []
591
592 [dependencies]
593 git = { git = 'https://example.com/' }
594 "#,
595 ).file("src/lib.rs", "")
596 .build();
597
598 let root = paths::root();
599 t!(fs::create_dir(&root.join(".cargo")));
600 t!(t!(File::create(root.join(".cargo/config"))).write_all(
601 br#"
602 [source.my-git-repo]
603 git = 'https://example.com/'
604 replace-with = 'my-awesome-local-registry'
605
606 [source.my-awesome-local-registry]
607 directory = 'index'
608 "#
609 ));
610
611 p.cargo("build")
612 .with_status(101)
613 .with_stderr(
614 "\
615 error: failed to load source for a dependency on `git`
616
617 Caused by:
618 Unable to update [..]
619
620 Caused by:
621 the source my-git-repo requires a lock file to be present first before it can be
622 used against vendored source code
623
624 remove the source replacement configuration, generate a lock file, and then
625 restore the source replacement configuration to continue the build
626
627 ",
628 ).run();
629 }
630
631 #[test]
632 fn workspace_different_locations() {
633 let p = project()
634 .no_manifest()
635 .file(
636 "foo/Cargo.toml",
637 r#"
638 [package]
639 name = 'foo'
640 version = '0.1.0'
641
642 [dependencies]
643 baz = "*"
644 "#,
645 ).file("foo/src/lib.rs", "")
646 .file("foo/vendor/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
647 .file("foo/vendor/baz/src/lib.rs", "")
648 .file("foo/vendor/baz/.cargo-checksum.json", "{\"files\":{}}")
649 .file(
650 "bar/Cargo.toml",
651 r#"
652 [package]
653 name = 'bar'
654 version = '0.1.0'
655
656 [dependencies]
657 baz = "*"
658 "#,
659 ).file("bar/src/lib.rs", "")
660 .file(
661 ".cargo/config",
662 r#"
663 [build]
664 target-dir = './target'
665
666 [source.crates-io]
667 replace-with = 'my-awesome-local-registry'
668
669 [source.my-awesome-local-registry]
670 directory = 'foo/vendor'
671 "#,
672 ).build();
673
674 p.cargo("build").cwd(p.root().join("foo")).run();
675 p.cargo("build")
676 .cwd(p.root().join("bar"))
677 .with_status(0)
678 .with_stderr(
679 "\
680 [COMPILING] bar [..]
681 [FINISHED] [..]
682 ",
683 ).run();
684 }