]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/tree.rs
Auto merge of #8713 - ehuss:filters_target-cross, r=alexcrichton
[cargo.git] / tests / testsuite / tree.rs
1 //! Tests for the `cargo tree` command.
2
3 use cargo_test_support::cross_compile::{self, alternate};
4 use cargo_test_support::registry::{Dependency, Package};
5 use cargo_test_support::{basic_manifest, git, project, rustc_host, Project};
6
7 fn make_simple_proj() -> Project {
8 Package::new("c", "1.0.0").publish();
9 Package::new("b", "1.0.0").dep("c", "1.0").publish();
10 Package::new("a", "1.0.0").dep("b", "1.0").publish();
11 Package::new("bdep", "1.0.0").dep("b", "1.0").publish();
12 Package::new("devdep", "1.0.0").dep("b", "1.0.0").publish();
13
14 project()
15 .file(
16 "Cargo.toml",
17 r#"
18 [package]
19 name = "foo"
20 version = "0.1.0"
21
22 [dependencies]
23 a = "1.0"
24 c = "1.0"
25
26 [build-dependencies]
27 bdep = "1.0"
28
29 [dev-dependencies]
30 devdep = "1.0"
31 "#,
32 )
33 .file("src/lib.rs", "")
34 .file("build.rs", "fn main() {}")
35 .build()
36 }
37
38 #[cargo_test]
39 fn simple() {
40 // A simple test with a few different dependencies.
41 let p = make_simple_proj();
42
43 p.cargo("tree")
44 .with_stdout(
45 "\
46 foo v0.1.0 ([..]/foo)
47 ├── a v1.0.0
48 │ └── b v1.0.0
49 │ └── c v1.0.0
50 └── c v1.0.0
51 [build-dependencies]
52 └── bdep v1.0.0
53 └── b v1.0.0 (*)
54 [dev-dependencies]
55 └── devdep v1.0.0
56 └── b v1.0.0 (*)
57 ",
58 )
59 .run();
60
61 p.cargo("tree -p bdep")
62 .with_stdout(
63 "\
64 bdep v1.0.0
65 └── b v1.0.0
66 └── c v1.0.0
67 ",
68 )
69 .run();
70 }
71
72 #[cargo_test]
73 fn virtual_workspace() {
74 // Multiple packages in a virtual workspace.
75 Package::new("somedep", "1.0.0").publish();
76 let p = project()
77 .file(
78 "Cargo.toml",
79 r#"
80 [workspace]
81 members = ["a", "b", "c"]
82 "#,
83 )
84 .file("a/Cargo.toml", &basic_manifest("a", "1.0.0"))
85 .file("a/src/lib.rs", "")
86 .file(
87 "b/Cargo.toml",
88 r#"
89 [package]
90 name = "b"
91 version = "0.1.0"
92
93 [dependencies]
94 c = { path = "../c" }
95 somedep = "1.0"
96 "#,
97 )
98 .file("b/src/lib.rs", "")
99 .file("c/Cargo.toml", &basic_manifest("c", "1.0.0"))
100 .file("c/src/lib.rs", "")
101 .build();
102
103 p.cargo("tree")
104 .with_stdout(
105 "\
106 a v1.0.0 ([..]/foo/a)
107
108 b v0.1.0 ([..]/foo/b)
109 ├── c v1.0.0 ([..]/foo/c)
110 └── somedep v1.0.0
111
112 c v1.0.0 ([..]/foo/c)
113 ",
114 )
115 .run();
116
117 p.cargo("tree -p a").with_stdout("a v1.0.0 [..]").run();
118
119 p.cargo("tree")
120 .cwd("b")
121 .with_stdout(
122 "\
123 b v0.1.0 ([..]/foo/b)
124 ├── c v1.0.0 ([..]/foo/c)
125 └── somedep v1.0.0
126 ",
127 )
128 .run();
129 }
130
131 #[cargo_test]
132 fn dedupe_edges() {
133 // Works around https://github.com/rust-lang/cargo/issues/7985
134 Package::new("bitflags", "1.0.0").publish();
135 Package::new("manyfeat", "1.0.0")
136 .feature("f1", &[])
137 .feature("f2", &[])
138 .feature("f3", &[])
139 .dep("bitflags", "1.0")
140 .publish();
141 Package::new("a", "1.0.0")
142 .feature_dep("manyfeat", "1.0", &["f1"])
143 .publish();
144 Package::new("b", "1.0.0")
145 .feature_dep("manyfeat", "1.0", &["f2"])
146 .publish();
147 Package::new("c", "1.0.0")
148 .feature_dep("manyfeat", "1.0", &["f3"])
149 .publish();
150
151 let p = project()
152 .file(
153 "Cargo.toml",
154 r#"
155 [package]
156 name = "foo"
157 version = "0.1.0"
158
159 [dependencies]
160 a = "1.0"
161 b = "1.0"
162 c = "1.0"
163 "#,
164 )
165 .file("src/lib.rs", "")
166 .build();
167
168 p.cargo("tree")
169 .with_stdout(
170 "\
171 foo v0.1.0 ([..]/foo)
172 ├── a v1.0.0
173 │ └── manyfeat v1.0.0
174 │ └── bitflags v1.0.0
175 ├── b v1.0.0
176 │ └── manyfeat v1.0.0 (*)
177 └── c v1.0.0
178 └── manyfeat v1.0.0 (*)
179 ",
180 )
181 .run();
182 }
183
184 #[cargo_test]
185 fn renamed_deps() {
186 // Handles renamed dependencies.
187 Package::new("one", "1.0.0").publish();
188 Package::new("two", "1.0.0").publish();
189 Package::new("bar", "1.0.0").dep("one", "1.0").publish();
190 Package::new("bar", "2.0.0").dep("two", "1.0").publish();
191 let p = project()
192 .file(
193 "Cargo.toml",
194 r#"
195 [package]
196 name = "foo"
197 version = "1.0.0"
198
199 [dependencies]
200 bar1 = {version = "1.0", package="bar"}
201 bar2 = {version = "2.0", package="bar"}
202 "#,
203 )
204 .file("src/lib.rs", "")
205 .build();
206
207 p.cargo("tree")
208 .with_stdout(
209 "\
210 foo v1.0.0 ([..]/foo)
211 ├── bar v1.0.0
212 │ └── one v1.0.0
213 └── bar v2.0.0
214 └── two v1.0.0
215 ",
216 )
217 .run();
218 }
219
220 #[cargo_test]
221 fn source_kinds() {
222 // Handles git and path sources.
223 Package::new("regdep", "1.0.0").publish();
224 let git_project = git::new("gitdep", |p| {
225 p.file("Cargo.toml", &basic_manifest("gitdep", "1.0.0"))
226 .file("src/lib.rs", "")
227 });
228 let p = project()
229 .file(
230 "Cargo.toml",
231 &format!(
232 r#"
233 [package]
234 name = "foo"
235 version = "0.1.0"
236
237 [dependencies]
238 regdep = "1.0"
239 pathdep = {{ path = "pathdep" }}
240 gitdep = {{ git = "{}" }}
241 "#,
242 git_project.url()
243 ),
244 )
245 .file("src/lib.rs", "")
246 .file("pathdep/Cargo.toml", &basic_manifest("pathdep", "1.0.0"))
247 .file("pathdep/src/lib.rs", "")
248 .build();
249
250 p.cargo("tree")
251 .with_stdout(
252 "\
253 foo v0.1.0 ([..]/foo)
254 ├── gitdep v1.0.0 (file://[..]/gitdep#[..])
255 ├── pathdep v1.0.0 ([..]/foo/pathdep)
256 └── regdep v1.0.0
257 ",
258 )
259 .run();
260 }
261
262 #[cargo_test]
263 fn features() {
264 // Exercises a variety of feature behaviors.
265 Package::new("optdep_default", "1.0.0").publish();
266 Package::new("optdep", "1.0.0").publish();
267 let p = project()
268 .file(
269 "Cargo.toml",
270 r#"
271 [package]
272 name = "a"
273 version = "0.1.0"
274
275 [dependencies]
276 optdep_default = { version = "1.0", optional = true }
277 optdep = { version = "1.0", optional = true }
278
279 [features]
280 default = ["optdep_default"]
281 "#,
282 )
283 .file("src/lib.rs", "")
284 .build();
285
286 p.cargo("tree")
287 .with_stdout(
288 "\
289 a v0.1.0 ([..]/foo)
290 └── optdep_default v1.0.0
291 ",
292 )
293 .run();
294
295 p.cargo("tree --no-default-features")
296 .with_stdout(
297 "\
298 a v0.1.0 ([..]/foo)
299 ",
300 )
301 .run();
302
303 p.cargo("tree --all-features")
304 .with_stdout(
305 "\
306 a v0.1.0 ([..]/foo)
307 ├── optdep v1.0.0
308 └── optdep_default v1.0.0
309 ",
310 )
311 .run();
312
313 p.cargo("tree --features optdep")
314 .with_stdout(
315 "\
316 a v0.1.0 ([..]/foo)
317 ├── optdep v1.0.0
318 └── optdep_default v1.0.0
319 ",
320 )
321 .run();
322 }
323
324 #[cargo_test]
325 fn filters_target() {
326 // --target flag
327 if cross_compile::disabled() {
328 return;
329 }
330 Package::new("targetdep", "1.0.0").publish();
331 Package::new("hostdep", "1.0.0").publish();
332 Package::new("devdep", "1.0.0").publish();
333 Package::new("build_target_dep", "1.0.0").publish();
334 Package::new("build_host_dep", "1.0.0")
335 .target_dep("targetdep", "1.0", alternate())
336 .target_dep("hostdep", "1.0", &rustc_host())
337 .publish();
338 Package::new("pm_target", "1.0.0")
339 .proc_macro(true)
340 .publish();
341 Package::new("pm_host", "1.0.0").proc_macro(true).publish();
342
343 let p = project()
344 .file(
345 "Cargo.toml",
346 &format!(
347 r#"
348 [package]
349 name = "foo"
350 version = "0.1.0"
351
352 [target.'{alt}'.dependencies]
353 targetdep = "1.0"
354 pm_target = "1.0"
355
356 [target.'{host}'.dependencies]
357 hostdep = "1.0"
358 pm_host = "1.0"
359
360 [target.'{alt}'.dev-dependencies]
361 devdep = "1.0"
362
363 [target.'{alt}'.build-dependencies]
364 build_target_dep = "1.0"
365
366 [target.'{host}'.build-dependencies]
367 build_host_dep = "1.0"
368 "#,
369 alt = alternate(),
370 host = rustc_host()
371 ),
372 )
373 .file("src/lib.rs", "")
374 .file("build.rs", "fn main() {}")
375 .build();
376
377 p.cargo("tree")
378 .with_stdout(
379 "\
380 foo v0.1.0 ([..]/foo)
381 ├── hostdep v1.0.0
382 └── pm_host v1.0.0
383 [build-dependencies]
384 └── build_host_dep v1.0.0
385 └── hostdep v1.0.0
386 ",
387 )
388 .run();
389
390 p.cargo("tree --target")
391 .arg(alternate())
392 .with_stdout(
393 "\
394 foo v0.1.0 ([..]/foo)
395 ├── pm_target v1.0.0
396 └── targetdep v1.0.0
397 [build-dependencies]
398 └── build_host_dep v1.0.0
399 └── hostdep v1.0.0
400 [dev-dependencies]
401 └── devdep v1.0.0
402 ",
403 )
404 .run();
405
406 p.cargo("tree --target")
407 .arg(rustc_host())
408 .with_stdout(
409 "\
410 foo v0.1.0 ([..]/foo)
411 ├── hostdep v1.0.0
412 └── pm_host v1.0.0
413 [build-dependencies]
414 └── build_host_dep v1.0.0
415 └── hostdep v1.0.0
416 ",
417 )
418 .run();
419
420 p.cargo("tree --target=all")
421 .with_stdout(
422 "\
423 foo v0.1.0 ([..]/foo)
424 ├── hostdep v1.0.0
425 ├── pm_host v1.0.0
426 ├── pm_target v1.0.0
427 └── targetdep v1.0.0
428 [build-dependencies]
429 ├── build_host_dep v1.0.0
430 │ ├── hostdep v1.0.0
431 │ └── targetdep v1.0.0
432 └── build_target_dep v1.0.0
433 [dev-dependencies]
434 └── devdep v1.0.0
435 ",
436 )
437 .run();
438 }
439
440 #[cargo_test]
441 fn dep_kinds() {
442 Package::new("inner-devdep", "1.0.0").publish();
443 Package::new("inner-builddep", "1.0.0").publish();
444 Package::new("inner-normal", "1.0.0").publish();
445 Package::new("normaldep", "1.0.0")
446 .dep("inner-normal", "1.0")
447 .dev_dep("inner-devdep", "1.0")
448 .build_dep("inner-builddep", "1.0")
449 .publish();
450 Package::new("devdep", "1.0.0")
451 .dep("inner-normal", "1.0")
452 .dev_dep("inner-devdep", "1.0")
453 .build_dep("inner-builddep", "1.0")
454 .publish();
455 Package::new("builddep", "1.0.0")
456 .dep("inner-normal", "1.0")
457 .dev_dep("inner-devdep", "1.0")
458 .build_dep("inner-builddep", "1.0")
459 .publish();
460 let p = project()
461 .file(
462 "Cargo.toml",
463 r#"
464 [package]
465 name = "foo"
466 version = "0.1.0"
467
468 [dependencies]
469 normaldep = "1.0"
470
471 [dev-dependencies]
472 devdep = "1.0"
473
474 [build-dependencies]
475 builddep = "1.0"
476 "#,
477 )
478 .file("src/lib.rs", "")
479 .build();
480
481 p.cargo("tree")
482 .with_stdout(
483 "\
484 foo v0.1.0 ([..]/foo)
485 └── normaldep v1.0.0
486 └── inner-normal v1.0.0
487 [build-dependencies]
488 └── inner-builddep v1.0.0
489 [build-dependencies]
490 └── builddep v1.0.0
491 └── inner-normal v1.0.0
492 [build-dependencies]
493 └── inner-builddep v1.0.0
494 [dev-dependencies]
495 └── devdep v1.0.0
496 └── inner-normal v1.0.0
497 [build-dependencies]
498 └── inner-builddep v1.0.0
499 ",
500 )
501 .run();
502
503 p.cargo("tree -e no-dev")
504 .with_stdout(
505 "\
506 foo v0.1.0 ([..]/foo)
507 └── normaldep v1.0.0
508 └── inner-normal v1.0.0
509 [build-dependencies]
510 └── inner-builddep v1.0.0
511 [build-dependencies]
512 └── builddep v1.0.0
513 └── inner-normal v1.0.0
514 [build-dependencies]
515 └── inner-builddep v1.0.0
516 ",
517 )
518 .run();
519
520 p.cargo("tree -e normal")
521 .with_stdout(
522 "\
523 foo v0.1.0 ([..]/foo)
524 └── normaldep v1.0.0
525 └── inner-normal v1.0.0
526 ",
527 )
528 .run();
529
530 p.cargo("tree -e dev,build")
531 .with_stdout(
532 "\
533 foo v0.1.0 ([..]/foo)
534 [build-dependencies]
535 └── builddep v1.0.0
536 [build-dependencies]
537 └── inner-builddep v1.0.0
538 [dev-dependencies]
539 └── devdep v1.0.0
540 [build-dependencies]
541 └── inner-builddep v1.0.0
542 ",
543 )
544 .run();
545 }
546
547 #[cargo_test]
548 fn cyclic_dev_dep() {
549 // Cyclical dev-dependency and inverse flag.
550 let p = project()
551 .file(
552 "Cargo.toml",
553 r#"
554 [package]
555 name = "foo"
556 version = "0.1.0"
557
558 [dev-dependencies]
559 dev-dep = { path = "dev-dep" }
560 "#,
561 )
562 .file("src/lib.rs", "")
563 .file(
564 "dev-dep/Cargo.toml",
565 r#"
566 [package]
567 name = "dev-dep"
568 version = "0.1.0"
569
570 [dependencies]
571 foo = { path=".." }
572 "#,
573 )
574 .file("dev-dep/src/lib.rs", "")
575 .build();
576
577 p.cargo("tree")
578 .with_stdout(
579 "\
580 foo v0.1.0 ([..]/foo)
581 [dev-dependencies]
582 └── dev-dep v0.1.0 ([..]/foo/dev-dep)
583 └── foo v0.1.0 ([..]/foo) (*)
584 ",
585 )
586 .run();
587
588 p.cargo("tree --invert foo")
589 .with_stdout(
590 "\
591 foo v0.1.0 ([..]/foo)
592 └── dev-dep v0.1.0 ([..]/foo/dev-dep)
593 [dev-dependencies]
594 └── foo v0.1.0 ([..]/foo) (*)
595 ",
596 )
597 .run();
598 }
599
600 #[cargo_test]
601 fn invert() {
602 Package::new("b1", "1.0.0").dep("c", "1.0").publish();
603 Package::new("b2", "1.0.0").dep("d", "1.0").publish();
604 Package::new("c", "1.0.0").publish();
605 Package::new("d", "1.0.0").publish();
606 let p = project()
607 .file(
608 "Cargo.toml",
609 r#"
610 [package]
611 name = "foo"
612 version = "0.1.0"
613
614 [dependencies]
615 b1 = "1.0"
616 b2 = "1.0"
617 c = "1.0"
618 "#,
619 )
620 .file("src/lib.rs", "")
621 .build();
622
623 p.cargo("tree")
624 .with_stdout(
625 "\
626 foo v0.1.0 ([..]/foo)
627 ├── b1 v1.0.0
628 │ └── c v1.0.0
629 ├── b2 v1.0.0
630 │ └── d v1.0.0
631 └── c v1.0.0
632 ",
633 )
634 .run();
635
636 p.cargo("tree --invert c")
637 .with_stdout(
638 "\
639 c v1.0.0
640 ├── b1 v1.0.0
641 │ └── foo v0.1.0 ([..]/foo)
642 └── foo v0.1.0 ([..]/foo)
643 ",
644 )
645 .run();
646 }
647
648 #[cargo_test]
649 fn invert_with_build_dep() {
650 // -i for a common dependency between normal and build deps.
651 Package::new("common", "1.0.0").publish();
652 Package::new("bdep", "1.0.0").dep("common", "1.0").publish();
653 let p = project()
654 .file(
655 "Cargo.toml",
656 r#"
657 [package]
658 name = "foo"
659 version = "0.1.0"
660
661 [dependencies]
662 common = "1.0"
663
664 [build-dependencies]
665 bdep = "1.0"
666 "#,
667 )
668 .file("src/lib.rs", "")
669 .build();
670
671 p.cargo("tree")
672 .with_stdout(
673 "\
674 foo v0.1.0 ([..]/foo)
675 └── common v1.0.0
676 [build-dependencies]
677 └── bdep v1.0.0
678 └── common v1.0.0
679 ",
680 )
681 .run();
682
683 p.cargo("tree -i common")
684 .with_stdout(
685 "\
686 common v1.0.0
687 ├── bdep v1.0.0
688[build-dependencies]
689 │ └── foo v0.1.0 ([..]/foo)
690 └── foo v0.1.0 ([..]/foo)
691 ",
692 )
693 .run();
694 }
695
696 #[cargo_test]
697 fn no_indent() {
698 let p = make_simple_proj();
699
700 p.cargo("tree --prefix=none")
701 .with_stdout(
702 "\
703 foo v0.1.0 ([..]/foo)
704 a v1.0.0
705 b v1.0.0
706 c v1.0.0
707 c v1.0.0
708 bdep v1.0.0
709 b v1.0.0 (*)
710 devdep v1.0.0
711 b v1.0.0 (*)
712 ",
713 )
714 .run();
715 }
716
717 #[cargo_test]
718 fn prefix_depth() {
719 let p = make_simple_proj();
720
721 p.cargo("tree --prefix=depth")
722 .with_stdout(
723 "\
724 0foo v0.1.0 ([..]/foo)
725 1a v1.0.0
726 2b v1.0.0
727 3c v1.0.0
728 1c v1.0.0
729 1bdep v1.0.0
730 2b v1.0.0 (*)
731 1devdep v1.0.0
732 2b v1.0.0 (*)
733 ",
734 )
735 .run();
736 }
737
738 #[cargo_test]
739 fn no_dedupe() {
740 let p = make_simple_proj();
741
742 p.cargo("tree --no-dedupe")
743 .with_stdout(
744 "\
745 foo v0.1.0 ([..]/foo)
746 ├── a v1.0.0
747 │ └── b v1.0.0
748 │ └── c v1.0.0
749 └── c v1.0.0
750 [build-dependencies]
751 └── bdep v1.0.0
752 └── b v1.0.0
753 └── c v1.0.0
754 [dev-dependencies]
755 └── devdep v1.0.0
756 └── b v1.0.0
757 └── c v1.0.0
758 ",
759 )
760 .run();
761 }
762
763 #[cargo_test]
764 fn no_dedupe_cycle() {
765 // --no-dedupe with a dependency cycle
766 let p = project()
767 .file(
768 "Cargo.toml",
769 r#"
770 [package]
771 name = "foo"
772 version = "0.1.0"
773
774 [dev-dependencies]
775 bar = {path = "bar"}
776 "#,
777 )
778 .file("src/lib.rs", "")
779 .file(
780 "bar/Cargo.toml",
781 r#"
782 [package]
783 name = "bar"
784 version = "0.1.0"
785
786 [dependencies]
787 foo = {path=".."}
788 "#,
789 )
790 .file("bar/src/lib.rs", "")
791 .build();
792
793 p.cargo("tree")
794 .with_stdout(
795 "\
796 foo v0.1.0 ([..]/foo)
797 [dev-dependencies]
798 └── bar v0.1.0 ([..]/foo/bar)
799 └── foo v0.1.0 ([..]/foo) (*)
800 ",
801 )
802 .run();
803
804 p.cargo("tree --no-dedupe")
805 .with_stdout(
806 "\
807 foo v0.1.0 ([..]/foo)
808 [dev-dependencies]
809 └── bar v0.1.0 ([..]/foo/bar)
810 └── foo v0.1.0 ([..]/foo) (*)
811 ",
812 )
813 .run();
814 }
815
816 #[cargo_test]
817 fn duplicates() {
818 Package::new("dog", "1.0.0").publish();
819 Package::new("dog", "2.0.0").publish();
820 Package::new("cat", "1.0.0").publish();
821 Package::new("cat", "2.0.0").publish();
822 Package::new("dep", "1.0.0")
823 .dep("dog", "1.0")
824 .dep("cat", "1.0")
825 .publish();
826 let p = project()
827 .file(
828 "Cargo.toml",
829 r#"
830 [workspace]
831 members = ["a", "b"]
832 "#,
833 )
834 .file(
835 "a/Cargo.toml",
836 r#"
837 [package]
838 name = "a"
839 version = "0.1.0"
840
841 [dependencies]
842 dog1 = { version = "1.0", package = "dog" }
843 dog2 = { version = "2.0", package = "dog" }
844 "#,
845 )
846 .file("a/src/lib.rs", "")
847 .file(
848 "b/Cargo.toml",
849 r#"
850 [package]
851 name = "b"
852 version = "0.1.0"
853
854 [dependencies]
855 dep = "1.0"
856 cat = "2.0"
857 "#,
858 )
859 .file("b/src/lib.rs", "")
860 .build();
861
862 p.cargo("tree -p a")
863 .with_stdout(
864 "\
865 a v0.1.0 ([..]/foo/a)
866 ├── dog v1.0.0
867 └── dog v2.0.0
868 ",
869 )
870 .run();
871
872 p.cargo("tree -p b")
873 .with_stdout(
874 "\
875 b v0.1.0 ([..]/foo/b)
876 ├── cat v2.0.0
877 └── dep v1.0.0
878 ├── cat v1.0.0
879 └── dog v1.0.0
880 ",
881 )
882 .run();
883
884 p.cargo("tree -p a -d")
885 .with_stdout(
886 "\
887 dog v1.0.0
888 └── a v0.1.0 ([..]/foo/a)
889
890 dog v2.0.0
891 └── a v0.1.0 ([..]/foo/a)
892 ",
893 )
894 .run();
895
896 p.cargo("tree -p b -d")
897 .with_stdout(
898 "\
899 cat v1.0.0
900 └── dep v1.0.0
901 └── b v0.1.0 ([..]/foo/b)
902
903 cat v2.0.0
904 └── b v0.1.0 ([..]/foo/b)
905 ",
906 )
907 .run();
908 }
909
910 #[cargo_test]
911 fn charset() {
912 let p = make_simple_proj();
913 p.cargo("tree --charset ascii")
914 .with_stdout(
915 "\
916 foo v0.1.0 ([..]/foo)
917 |-- a v1.0.0
918 | `-- b v1.0.0
919 | `-- c v1.0.0
920 `-- c v1.0.0
921 [build-dependencies]
922 `-- bdep v1.0.0
923 `-- b v1.0.0 (*)
924 [dev-dependencies]
925 `-- devdep v1.0.0
926 `-- b v1.0.0 (*)
927 ",
928 )
929 .run();
930 }
931
932 #[cargo_test]
933 fn format() {
934 Package::new("dep", "1.0.0").publish();
935 let p = project()
936 .file(
937 "Cargo.toml",
938 r#"
939 [package]
940 name = "foo"
941 version = "0.1.0"
942 license = "MIT"
943 repository = "https://github.com/rust-lang/cargo"
944
945 [dependencies]
946 dep = {version="1.0", optional=true}
947
948 [features]
949 default = ["foo"]
950 foo = ["bar"]
951 bar = []
952 "#,
953 )
954 .file("src/lib.rs", "")
955 .build();
956
957 p.cargo("tree --format <<<{p}>>>")
958 .with_stdout("<<<foo v0.1.0 ([..]/foo)>>>")
959 .run();
960
961 p.cargo("tree --format {}")
962 .with_stderr(
963 "\
964 [ERROR] tree format `{}` not valid
965
966 Caused by:
967 unsupported pattern ``
968 ",
969 )
970 .with_status(101)
971 .run();
972
973 p.cargo("tree --format {p}-{{hello}}")
974 .with_stdout("foo v0.1.0 ([..]/foo)-{hello}")
975 .run();
976
977 p.cargo("tree --format")
978 .arg("{p} {l} {r}")
979 .with_stdout("foo v0.1.0 ([..]/foo) MIT https://github.com/rust-lang/cargo")
980 .run();
981
982 p.cargo("tree --format")
983 .arg("{p} {f}")
984 .with_stdout("foo v0.1.0 ([..]/foo) bar,default,foo")
985 .run();
986
987 p.cargo("tree --all-features --format")
988 .arg("{p} [{f}]")
989 .with_stdout(
990 "\
991 foo v0.1.0 ([..]/foo) [bar,default,dep,foo]
992 └── dep v1.0.0 []
993 ",
994 )
995 .run();
996 }
997
998 #[cargo_test]
999 fn dev_dep_feature() {
1000 // -Zfeatures=dev_dep with optional dep
1001 Package::new("optdep", "1.0.0").publish();
1002 Package::new("bar", "1.0.0")
1003 .add_dep(Dependency::new("optdep", "1.0").optional(true))
1004 .publish();
1005 let p = project()
1006 .file(
1007 "Cargo.toml",
1008 r#"
1009 [package]
1010 name = "foo"
1011 version = "0.1.0"
1012
1013 [dev-dependencies]
1014 bar = { version = "1.0", features = ["optdep"] }
1015
1016 [dependencies]
1017 bar = "1.0"
1018 "#,
1019 )
1020 .file("src/lib.rs", "")
1021 .build();
1022
1023 p.cargo("tree")
1024 .with_stdout(
1025 "\
1026 foo v0.1.0 ([..]/foo)
1027 └── bar v1.0.0
1028 └── optdep v1.0.0
1029 [dev-dependencies]
1030 └── bar v1.0.0 (*)
1031 ",
1032 )
1033 .run();
1034
1035 p.cargo("tree -e normal")
1036 .with_stdout(
1037 "\
1038 foo v0.1.0 ([..]/foo)
1039 └── bar v1.0.0
1040 └── optdep v1.0.0
1041 ",
1042 )
1043 .run();
1044
1045 p.cargo("tree -Zfeatures=dev_dep")
1046 .masquerade_as_nightly_cargo()
1047 .with_stdout(
1048 "\
1049 foo v0.1.0 ([..]/foo)
1050 └── bar v1.0.0
1051 └── optdep v1.0.0
1052 [dev-dependencies]
1053 └── bar v1.0.0 (*)
1054 ",
1055 )
1056 .run();
1057
1058 p.cargo("tree -e normal -Zfeatures=dev_dep")
1059 .masquerade_as_nightly_cargo()
1060 .with_stdout(
1061 "\
1062 foo v0.1.0 ([..]/foo)
1063 └── bar v1.0.0
1064 ",
1065 )
1066 .run();
1067 }
1068
1069 #[cargo_test]
1070 fn host_dep_feature() {
1071 // -Zfeatures=host_dep with optional dep
1072 Package::new("optdep", "1.0.0").publish();
1073 Package::new("bar", "1.0.0")
1074 .add_dep(Dependency::new("optdep", "1.0").optional(true))
1075 .publish();
1076 let p = project()
1077 .file(
1078 "Cargo.toml",
1079 r#"
1080 [package]
1081 name = "foo"
1082 version = "0.1.0"
1083
1084 [build-dependencies]
1085 bar = { version = "1.0", features = ["optdep"] }
1086
1087 [dependencies]
1088 bar = "1.0"
1089 "#,
1090 )
1091 .file("src/lib.rs", "")
1092 .file("build.rs", "fn main() {}")
1093 .build();
1094
1095 p.cargo("tree")
1096 .with_stdout(
1097 "\
1098 foo v0.1.0 ([..]/foo)
1099 └── bar v1.0.0
1100 └── optdep v1.0.0
1101 [build-dependencies]
1102 └── bar v1.0.0 (*)
1103 ",
1104 )
1105 .run();
1106
1107 p.cargo("tree -Zfeatures=host_dep")
1108 .masquerade_as_nightly_cargo()
1109 .with_stdout(
1110 "\
1111 foo v0.1.0 ([..]/foo)
1112 └── bar v1.0.0
1113 [build-dependencies]
1114 └── bar v1.0.0
1115 └── optdep v1.0.0
1116 ",
1117 )
1118 .run();
1119
1120 // -p
1121 p.cargo("tree -p bar")
1122 .with_stdout(
1123 "\
1124 bar v1.0.0
1125 └── optdep v1.0.0
1126 ",
1127 )
1128 .run();
1129
1130 p.cargo("tree -p bar -Zfeatures=host_dep")
1131 .masquerade_as_nightly_cargo()
1132 .with_stdout(
1133 "\
1134 bar v1.0.0
1135
1136 bar v1.0.0
1137 └── optdep v1.0.0
1138 ",
1139 )
1140 .run();
1141
1142 // invert
1143 p.cargo("tree -i optdep")
1144 .with_stdout(
1145 "\
1146 optdep v1.0.0
1147 └── bar v1.0.0
1148 └── foo v0.1.0 ([..]/foo)
1149 [build-dependencies]
1150 └── foo v0.1.0 ([..]/foo)
1151 ",
1152 )
1153 .run();
1154
1155 p.cargo("tree -i optdep -Zfeatures=host_dep")
1156 .masquerade_as_nightly_cargo()
1157 .with_stdout(
1158 "\
1159 optdep v1.0.0
1160 └── bar v1.0.0
1161 [build-dependencies]
1162 └── foo v0.1.0 ([..]/foo)
1163 ",
1164 )
1165 .run();
1166
1167 // Check that -d handles duplicates with features.
1168 p.cargo("tree -d -Zfeatures=host_dep")
1169 .masquerade_as_nightly_cargo()
1170 .with_stdout(
1171 "\
1172 bar v1.0.0
1173 └── foo v0.1.0 ([..]/foo)
1174
1175 bar v1.0.0
1176 [build-dependencies]
1177 └── foo v0.1.0 ([..]/foo)
1178 ",
1179 )
1180 .run();
1181 }
1182
1183 #[cargo_test]
1184 fn proc_macro_features() {
1185 // -Zfeatures=host_dep with a proc-macro
1186 Package::new("optdep", "1.0.0").publish();
1187 Package::new("somedep", "1.0.0")
1188 .add_dep(Dependency::new("optdep", "1.0").optional(true))
1189 .publish();
1190 Package::new("pm", "1.0.0")
1191 .proc_macro(true)
1192 .feature_dep("somedep", "1.0", &["optdep"])
1193 .publish();
1194 let p = project()
1195 .file(
1196 "Cargo.toml",
1197 r#"
1198 [package]
1199 name = "foo"
1200 version = "0.1.0"
1201
1202 [dependencies]
1203 pm = "1.0"
1204 somedep = "1.0"
1205 "#,
1206 )
1207 .file("src/lib.rs", "")
1208 .build();
1209
1210 p.cargo("tree")
1211 .with_stdout(
1212 "\
1213 foo v0.1.0 ([..]/foo)
1214 ├── pm v1.0.0
1215 │ └── somedep v1.0.0
1216 │ └── optdep v1.0.0
1217 └── somedep v1.0.0 (*)
1218 ",
1219 )
1220 .run();
1221
1222 // Note the missing (*)
1223 p.cargo("tree -Zfeatures=host_dep")
1224 .masquerade_as_nightly_cargo()
1225 .with_stdout(
1226 "\
1227 foo v0.1.0 ([..]/foo)
1228 ├── pm v1.0.0
1229 │ └── somedep v1.0.0
1230 │ └── optdep v1.0.0
1231 └── somedep v1.0.0
1232 ",
1233 )
1234 .run();
1235
1236 // -p
1237 p.cargo("tree -p somedep")
1238 .with_stdout(
1239 "\
1240 somedep v1.0.0
1241 └── optdep v1.0.0
1242 ",
1243 )
1244 .run();
1245
1246 p.cargo("tree -p somedep -Zfeatures=host_dep")
1247 .masquerade_as_nightly_cargo()
1248 .with_stdout(
1249 "\
1250 somedep v1.0.0
1251
1252 somedep v1.0.0
1253 └── optdep v1.0.0
1254 ",
1255 )
1256 .run();
1257
1258 // invert
1259 p.cargo("tree -i somedep")
1260 .with_stdout(
1261 "\
1262 somedep v1.0.0
1263 ├── foo v0.1.0 ([..]/foo)
1264 └── pm v1.0.0
1265 └── foo v0.1.0 ([..]/foo)
1266 ",
1267 )
1268 .run();
1269
1270 p.cargo("tree -i somedep -Zfeatures=host_dep")
1271 .masquerade_as_nightly_cargo()
1272 .with_stdout(
1273 "\
1274 somedep v1.0.0
1275 └── foo v0.1.0 ([..]/foo)
1276
1277 somedep v1.0.0
1278 └── pm v1.0.0
1279 └── foo v0.1.0 ([..]/foo)
1280 ",
1281 )
1282 .run();
1283 }
1284
1285 #[cargo_test]
1286 fn itarget_opt_dep() {
1287 // -Zfeatures=itarget with optional dep
1288 Package::new("optdep", "1.0.0").publish();
1289 Package::new("common", "1.0.0")
1290 .add_dep(Dependency::new("optdep", "1.0").optional(true))
1291 .publish();
1292
1293 let p = project()
1294 .file(
1295 "Cargo.toml",
1296 r#"
1297 [package]
1298 name = "foo"
1299 version = "1.0.0"
1300
1301 [dependencies]
1302 common = "1.0"
1303
1304 [target.'cfg(whatever)'.dependencies]
1305 common = { version = "1.0", features = ["optdep"] }
1306
1307 "#,
1308 )
1309 .file("src/lib.rs", "")
1310 .build();
1311
1312 p.cargo("tree")
1313 .with_stdout(
1314 "\
1315 foo v1.0.0 ([..]/foo)
1316 └── common v1.0.0
1317 └── optdep v1.0.0
1318 ",
1319 )
1320 .run();
1321
1322 p.cargo("tree -Zfeatures=itarget")
1323 .with_stdout(
1324 "\
1325 foo v1.0.0 ([..]/foo)
1326 └── common v1.0.0
1327 ",
1328 )
1329 .masquerade_as_nightly_cargo()
1330 .run();
1331 }
1332
1333 #[cargo_test]
1334 fn ambiguous_name() {
1335 // -p that is ambiguous.
1336 Package::new("dep", "1.0.0").publish();
1337 Package::new("dep", "2.0.0").publish();
1338 Package::new("bar", "1.0.0").dep("dep", "2.0").publish();
1339 let p = project()
1340 .file(
1341 "Cargo.toml",
1342 r#"
1343 [package]
1344 name = "foo"
1345 version = "0.1.0"
1346
1347 [dependencies]
1348 dep = "1.0"
1349 bar = "1.0"
1350 "#,
1351 )
1352 .file("src/lib.rs", "")
1353 .build();
1354
1355 p.cargo("tree -p dep")
1356 .with_stderr_contains(
1357 "\
1358 error: There are multiple `dep` packages in your project, and the specification `dep` is ambiguous.
1359 Please re-run this command with `-p <spec>` where `<spec>` is one of the following:
1360 dep:1.0.0
1361 dep:2.0.0
1362 ",
1363 )
1364 .with_status(101)
1365 .run();
1366 }
1367
1368 #[cargo_test]
1369 fn workspace_features_are_local() {
1370 // The features for workspace packages should be the same as `cargo build`
1371 // (i.e., the features selected depend on the "current" package).
1372 Package::new("optdep", "1.0.0").publish();
1373 Package::new("somedep", "1.0.0")
1374 .add_dep(Dependency::new("optdep", "1.0").optional(true))
1375 .publish();
1376 let p = project()
1377 .file(
1378 "Cargo.toml",
1379 r#"
1380 [workspace]
1381 members = ["a", "b"]
1382 "#,
1383 )
1384 .file(
1385 "a/Cargo.toml",
1386 r#"
1387 [package]
1388 name = "a"
1389 version = "0.1.0"
1390
1391 [dependencies]
1392 somedep = {version="1.0", features=["optdep"]}
1393 "#,
1394 )
1395 .file("a/src/lib.rs", "")
1396 .file(
1397 "b/Cargo.toml",
1398 r#"
1399 [package]
1400 name = "b"
1401 version = "0.1.0"
1402
1403 [dependencies]
1404 somedep = "1.0"
1405 "#,
1406 )
1407 .file("b/src/lib.rs", "")
1408 .build();
1409
1410 p.cargo("tree")
1411 .with_stdout(
1412 "\
1413 a v0.1.0 ([..]/foo/a)
1414 └── somedep v1.0.0
1415 └── optdep v1.0.0
1416
1417 b v0.1.0 ([..]/foo/b)
1418 └── somedep v1.0.0 (*)
1419 ",
1420 )
1421 .run();
1422
1423 p.cargo("tree -p a")
1424 .with_stdout(
1425 "\
1426 a v0.1.0 ([..]/foo/a)
1427 └── somedep v1.0.0
1428 └── optdep v1.0.0
1429 ",
1430 )
1431 .run();
1432
1433 p.cargo("tree -p b")
1434 .with_stdout(
1435 "\
1436 b v0.1.0 ([..]/foo/b)
1437 └── somedep v1.0.0
1438 ",
1439 )
1440 .run();
1441 }