]>
Commit | Line | Data |
---|---|---|
0a29b90c FG |
1 | //! Tests for the `cargo tree` command. |
2 | ||
3 | use super::features2::switch_to_resolver_2; | |
4 | use cargo_test_support::cross_compile::{self, alternate}; | |
5 | use cargo_test_support::registry::{Dependency, Package}; | |
6 | use cargo_test_support::{basic_manifest, git, project, rustc_host, Project}; | |
7 | ||
8 | fn make_simple_proj() -> Project { | |
9 | Package::new("c", "1.0.0").publish(); | |
10 | Package::new("b", "1.0.0").dep("c", "1.0").publish(); | |
11 | Package::new("a", "1.0.0").dep("b", "1.0").publish(); | |
12 | Package::new("bdep", "1.0.0").dep("b", "1.0").publish(); | |
13 | Package::new("devdep", "1.0.0").dep("b", "1.0.0").publish(); | |
14 | ||
15 | project() | |
16 | .file( | |
17 | "Cargo.toml", | |
18 | r#" | |
19 | [package] | |
20 | name = "foo" | |
21 | version = "0.1.0" | |
22 | ||
23 | [dependencies] | |
24 | a = "1.0" | |
25 | c = "1.0" | |
26 | ||
27 | [build-dependencies] | |
28 | bdep = "1.0" | |
29 | ||
30 | [dev-dependencies] | |
31 | devdep = "1.0" | |
32 | "#, | |
33 | ) | |
34 | .file("src/lib.rs", "") | |
35 | .file("build.rs", "fn main() {}") | |
36 | .build() | |
37 | } | |
38 | ||
39 | #[cargo_test] | |
40 | fn simple() { | |
41 | // A simple test with a few different dependencies. | |
42 | let p = make_simple_proj(); | |
43 | ||
44 | p.cargo("tree") | |
45 | .with_stdout( | |
46 | "\ | |
47 | foo v0.1.0 ([..]/foo) | |
48 | ├── a v1.0.0 | |
49 | │ └── b v1.0.0 | |
50 | │ └── c v1.0.0 | |
51 | └── c v1.0.0 | |
52 | [build-dependencies] | |
53 | └── bdep v1.0.0 | |
54 | └── b v1.0.0 (*) | |
55 | [dev-dependencies] | |
56 | └── devdep v1.0.0 | |
57 | └── b v1.0.0 (*) | |
58 | ", | |
59 | ) | |
60 | .run(); | |
61 | ||
62 | p.cargo("tree -p bdep") | |
63 | .with_stdout( | |
64 | "\ | |
65 | bdep v1.0.0 | |
66 | └── b v1.0.0 | |
67 | └── c v1.0.0 | |
68 | ", | |
69 | ) | |
70 | .run(); | |
71 | } | |
72 | ||
73 | #[cargo_test] | |
74 | fn virtual_workspace() { | |
75 | // Multiple packages in a virtual workspace. | |
76 | Package::new("somedep", "1.0.0").publish(); | |
77 | let p = project() | |
78 | .file( | |
79 | "Cargo.toml", | |
80 | r#" | |
81 | [workspace] | |
82 | members = ["a", "baz", "c"] | |
83 | "#, | |
84 | ) | |
85 | .file("a/Cargo.toml", &basic_manifest("a", "1.0.0")) | |
86 | .file("a/src/lib.rs", "") | |
87 | .file( | |
88 | "baz/Cargo.toml", | |
89 | r#" | |
90 | [package] | |
91 | name = "baz" | |
92 | version = "0.1.0" | |
93 | ||
94 | [dependencies] | |
95 | c = { path = "../c" } | |
96 | somedep = "1.0" | |
97 | "#, | |
98 | ) | |
99 | .file("baz/src/lib.rs", "") | |
100 | .file("c/Cargo.toml", &basic_manifest("c", "1.0.0")) | |
101 | .file("c/src/lib.rs", "") | |
102 | .build(); | |
103 | ||
104 | p.cargo("tree") | |
105 | .with_stdout( | |
106 | "\ | |
107 | a v1.0.0 ([..]/foo/a) | |
108 | ||
109 | baz v0.1.0 ([..]/foo/baz) | |
110 | ├── c v1.0.0 ([..]/foo/c) | |
111 | └── somedep v1.0.0 | |
112 | ||
113 | c v1.0.0 ([..]/foo/c) | |
114 | ", | |
115 | ) | |
116 | .run(); | |
117 | ||
118 | p.cargo("tree -p a").with_stdout("a v1.0.0 [..]").run(); | |
119 | ||
120 | p.cargo("tree") | |
121 | .cwd("baz") | |
122 | .with_stdout( | |
123 | "\ | |
124 | baz v0.1.0 ([..]/foo/baz) | |
125 | ├── c v1.0.0 ([..]/foo/c) | |
126 | └── somedep v1.0.0 | |
127 | ", | |
128 | ) | |
129 | .run(); | |
130 | ||
131 | // exclude baz | |
132 | p.cargo("tree --workspace --exclude baz") | |
133 | .with_stdout( | |
134 | "\ | |
135 | a v1.0.0 ([..]/foo/a) | |
136 | ||
137 | c v1.0.0 ([..]/foo/c) | |
138 | ", | |
139 | ) | |
140 | .run(); | |
141 | ||
142 | // exclude glob '*z' | |
143 | p.cargo("tree --workspace --exclude '*z'") | |
144 | .with_stdout( | |
145 | "\ | |
146 | a v1.0.0 ([..]/foo/a) | |
147 | ||
148 | c v1.0.0 ([..]/foo/c) | |
149 | ", | |
150 | ) | |
151 | .run(); | |
152 | ||
153 | // include glob '*z' | |
154 | p.cargo("tree -p '*z'") | |
155 | .with_stdout( | |
156 | "\ | |
157 | baz v0.1.0 ([..]/foo/baz) | |
158 | ├── c v1.0.0 ([..]/foo/c) | |
159 | └── somedep v1.0.0 | |
160 | ", | |
161 | ) | |
162 | .run(); | |
163 | } | |
164 | ||
165 | #[cargo_test] | |
166 | fn dedupe_edges() { | |
167 | // Works around https://github.com/rust-lang/cargo/issues/7985 | |
168 | Package::new("bitflags", "1.0.0").publish(); | |
169 | Package::new("manyfeat", "1.0.0") | |
170 | .feature("f1", &[]) | |
171 | .feature("f2", &[]) | |
172 | .feature("f3", &[]) | |
173 | .dep("bitflags", "1.0") | |
174 | .publish(); | |
175 | Package::new("a", "1.0.0") | |
176 | .feature_dep("manyfeat", "1.0", &["f1"]) | |
177 | .publish(); | |
178 | Package::new("b", "1.0.0") | |
179 | .feature_dep("manyfeat", "1.0", &["f2"]) | |
180 | .publish(); | |
181 | Package::new("c", "1.0.0") | |
182 | .feature_dep("manyfeat", "1.0", &["f3"]) | |
183 | .publish(); | |
184 | ||
185 | let p = project() | |
186 | .file( | |
187 | "Cargo.toml", | |
188 | r#" | |
189 | [package] | |
190 | name = "foo" | |
191 | version = "0.1.0" | |
192 | ||
193 | [dependencies] | |
194 | a = "1.0" | |
195 | b = "1.0" | |
196 | c = "1.0" | |
197 | "#, | |
198 | ) | |
199 | .file("src/lib.rs", "") | |
200 | .build(); | |
201 | ||
202 | p.cargo("tree") | |
203 | .with_stdout( | |
204 | "\ | |
205 | foo v0.1.0 ([..]/foo) | |
206 | ├── a v1.0.0 | |
207 | │ └── manyfeat v1.0.0 | |
208 | │ └── bitflags v1.0.0 | |
209 | ├── b v1.0.0 | |
210 | │ └── manyfeat v1.0.0 (*) | |
211 | └── c v1.0.0 | |
212 | └── manyfeat v1.0.0 (*) | |
213 | ", | |
214 | ) | |
215 | .run(); | |
216 | } | |
217 | ||
218 | #[cargo_test] | |
219 | fn renamed_deps() { | |
220 | // Handles renamed dependencies. | |
221 | Package::new("one", "1.0.0").publish(); | |
222 | Package::new("two", "1.0.0").publish(); | |
223 | Package::new("bar", "1.0.0").dep("one", "1.0").publish(); | |
224 | Package::new("bar", "2.0.0").dep("two", "1.0").publish(); | |
225 | let p = project() | |
226 | .file( | |
227 | "Cargo.toml", | |
228 | r#" | |
229 | [package] | |
230 | name = "foo" | |
231 | version = "1.0.0" | |
232 | ||
233 | [dependencies] | |
234 | bar1 = {version = "1.0", package="bar"} | |
235 | bar2 = {version = "2.0", package="bar"} | |
236 | "#, | |
237 | ) | |
238 | .file("src/lib.rs", "") | |
239 | .build(); | |
240 | ||
241 | p.cargo("tree") | |
242 | .with_stdout( | |
243 | "\ | |
244 | foo v1.0.0 ([..]/foo) | |
245 | ├── bar v1.0.0 | |
246 | │ └── one v1.0.0 | |
247 | └── bar v2.0.0 | |
248 | └── two v1.0.0 | |
249 | ", | |
250 | ) | |
251 | .run(); | |
252 | } | |
253 | ||
254 | #[cargo_test] | |
255 | fn source_kinds() { | |
256 | // Handles git and path sources. | |
257 | Package::new("regdep", "1.0.0").publish(); | |
258 | let git_project = git::new("gitdep", |p| { | |
259 | p.file("Cargo.toml", &basic_manifest("gitdep", "1.0.0")) | |
260 | .file("src/lib.rs", "") | |
261 | }); | |
262 | let p = project() | |
263 | .file( | |
264 | "Cargo.toml", | |
265 | &format!( | |
266 | r#" | |
267 | [package] | |
268 | name = "foo" | |
269 | version = "0.1.0" | |
270 | ||
271 | [dependencies] | |
272 | regdep = "1.0" | |
273 | pathdep = {{ path = "pathdep" }} | |
274 | gitdep = {{ git = "{}" }} | |
275 | "#, | |
276 | git_project.url() | |
277 | ), | |
278 | ) | |
279 | .file("src/lib.rs", "") | |
280 | .file("pathdep/Cargo.toml", &basic_manifest("pathdep", "1.0.0")) | |
281 | .file("pathdep/src/lib.rs", "") | |
282 | .build(); | |
283 | ||
284 | p.cargo("tree") | |
285 | .with_stdout( | |
286 | "\ | |
287 | foo v0.1.0 ([..]/foo) | |
288 | ├── gitdep v1.0.0 (file://[..]/gitdep#[..]) | |
289 | ├── pathdep v1.0.0 ([..]/foo/pathdep) | |
290 | └── regdep v1.0.0 | |
291 | ", | |
292 | ) | |
293 | .run(); | |
294 | } | |
295 | ||
296 | #[cargo_test] | |
297 | fn features() { | |
298 | // Exercises a variety of feature behaviors. | |
299 | Package::new("optdep_default", "1.0.0").publish(); | |
300 | Package::new("optdep", "1.0.0").publish(); | |
301 | let p = project() | |
302 | .file( | |
303 | "Cargo.toml", | |
304 | r#" | |
305 | [package] | |
306 | name = "a" | |
307 | version = "0.1.0" | |
308 | ||
309 | [dependencies] | |
310 | optdep_default = { version = "1.0", optional = true } | |
311 | optdep = { version = "1.0", optional = true } | |
312 | ||
313 | [features] | |
314 | default = ["optdep_default"] | |
315 | "#, | |
316 | ) | |
317 | .file("src/lib.rs", "") | |
318 | .build(); | |
319 | ||
320 | p.cargo("tree") | |
321 | .with_stdout( | |
322 | "\ | |
323 | a v0.1.0 ([..]/foo) | |
324 | └── optdep_default v1.0.0 | |
325 | ", | |
326 | ) | |
327 | .run(); | |
328 | ||
329 | p.cargo("tree --no-default-features") | |
330 | .with_stdout( | |
331 | "\ | |
332 | a v0.1.0 ([..]/foo) | |
333 | ", | |
334 | ) | |
335 | .run(); | |
336 | ||
337 | p.cargo("tree --all-features") | |
338 | .with_stdout( | |
339 | "\ | |
340 | a v0.1.0 ([..]/foo) | |
341 | ├── optdep v1.0.0 | |
342 | └── optdep_default v1.0.0 | |
343 | ", | |
344 | ) | |
345 | .run(); | |
346 | ||
347 | p.cargo("tree --features optdep") | |
348 | .with_stdout( | |
349 | "\ | |
350 | a v0.1.0 ([..]/foo) | |
351 | ├── optdep v1.0.0 | |
352 | └── optdep_default v1.0.0 | |
353 | ", | |
354 | ) | |
355 | .run(); | |
356 | } | |
357 | ||
358 | #[cargo_test] | |
359 | fn filters_target() { | |
360 | // --target flag | |
361 | if cross_compile::disabled() { | |
362 | return; | |
363 | } | |
364 | Package::new("targetdep", "1.0.0").publish(); | |
365 | Package::new("hostdep", "1.0.0").publish(); | |
366 | Package::new("devdep", "1.0.0").publish(); | |
367 | Package::new("build_target_dep", "1.0.0").publish(); | |
368 | Package::new("build_host_dep", "1.0.0") | |
369 | .target_dep("targetdep", "1.0", alternate()) | |
370 | .target_dep("hostdep", "1.0", rustc_host()) | |
371 | .publish(); | |
372 | Package::new("pm_target", "1.0.0") | |
373 | .proc_macro(true) | |
374 | .publish(); | |
375 | Package::new("pm_host", "1.0.0").proc_macro(true).publish(); | |
376 | ||
377 | let p = project() | |
378 | .file( | |
379 | "Cargo.toml", | |
380 | &format!( | |
381 | r#" | |
382 | [package] | |
383 | name = "foo" | |
384 | version = "0.1.0" | |
385 | ||
386 | [target.'{alt}'.dependencies] | |
387 | targetdep = "1.0" | |
388 | pm_target = "1.0" | |
389 | ||
390 | [target.'{host}'.dependencies] | |
391 | hostdep = "1.0" | |
392 | pm_host = "1.0" | |
393 | ||
394 | [target.'{alt}'.dev-dependencies] | |
395 | devdep = "1.0" | |
396 | ||
397 | [target.'{alt}'.build-dependencies] | |
398 | build_target_dep = "1.0" | |
399 | ||
400 | [target.'{host}'.build-dependencies] | |
401 | build_host_dep = "1.0" | |
402 | "#, | |
403 | alt = alternate(), | |
404 | host = rustc_host() | |
405 | ), | |
406 | ) | |
407 | .file("src/lib.rs", "") | |
408 | .file("build.rs", "fn main() {}") | |
409 | .build(); | |
410 | ||
411 | p.cargo("tree") | |
412 | .with_stdout( | |
413 | "\ | |
414 | foo v0.1.0 ([..]/foo) | |
415 | ├── hostdep v1.0.0 | |
416 | └── pm_host v1.0.0 (proc-macro) | |
417 | [build-dependencies] | |
418 | └── build_host_dep v1.0.0 | |
419 | └── hostdep v1.0.0 | |
420 | ", | |
421 | ) | |
422 | .run(); | |
423 | ||
424 | p.cargo("tree --target") | |
425 | .arg(alternate()) | |
426 | .with_stdout( | |
427 | "\ | |
428 | foo v0.1.0 ([..]/foo) | |
429 | ├── pm_target v1.0.0 (proc-macro) | |
430 | └── targetdep v1.0.0 | |
431 | [build-dependencies] | |
432 | └── build_host_dep v1.0.0 | |
433 | └── hostdep v1.0.0 | |
434 | [dev-dependencies] | |
435 | └── devdep v1.0.0 | |
436 | ", | |
437 | ) | |
438 | .run(); | |
439 | ||
440 | p.cargo("tree --target") | |
441 | .arg(rustc_host()) | |
442 | .with_stdout( | |
443 | "\ | |
444 | foo v0.1.0 ([..]/foo) | |
445 | ├── hostdep v1.0.0 | |
446 | └── pm_host v1.0.0 (proc-macro) | |
447 | [build-dependencies] | |
448 | └── build_host_dep v1.0.0 | |
449 | └── hostdep v1.0.0 | |
450 | ", | |
451 | ) | |
452 | .run(); | |
453 | ||
454 | p.cargo("tree --target=all") | |
455 | .with_stdout( | |
456 | "\ | |
457 | foo v0.1.0 ([..]/foo) | |
458 | ├── hostdep v1.0.0 | |
459 | ├── pm_host v1.0.0 (proc-macro) | |
460 | ├── pm_target v1.0.0 (proc-macro) | |
461 | └── targetdep v1.0.0 | |
462 | [build-dependencies] | |
463 | ├── build_host_dep v1.0.0 | |
464 | │ ├── hostdep v1.0.0 | |
465 | │ └── targetdep v1.0.0 | |
466 | └── build_target_dep v1.0.0 | |
467 | [dev-dependencies] | |
468 | └── devdep v1.0.0 | |
469 | ", | |
470 | ) | |
471 | .run(); | |
472 | ||
473 | // no-proc-macro | |
474 | p.cargo("tree --target=all -e no-proc-macro") | |
475 | .with_stdout( | |
476 | "\ | |
477 | foo v0.1.0 ([..]/foo) | |
478 | ├── hostdep v1.0.0 | |
479 | └── targetdep v1.0.0 | |
480 | [build-dependencies] | |
481 | ├── build_host_dep v1.0.0 | |
482 | │ ├── hostdep v1.0.0 | |
483 | │ └── targetdep v1.0.0 | |
484 | └── build_target_dep v1.0.0 | |
485 | [dev-dependencies] | |
486 | └── devdep v1.0.0 | |
487 | ", | |
488 | ) | |
489 | .run(); | |
490 | } | |
491 | ||
492 | #[cargo_test] | |
493 | fn no_selected_target_dependency() { | |
494 | // --target flag | |
495 | if cross_compile::disabled() { | |
496 | return; | |
497 | } | |
498 | Package::new("targetdep", "1.0.0").publish(); | |
499 | ||
500 | let p = project() | |
501 | .file( | |
502 | "Cargo.toml", | |
503 | &format!( | |
504 | r#" | |
505 | [package] | |
506 | name = "foo" | |
507 | version = "0.1.0" | |
508 | ||
509 | [target.'{alt}'.dependencies] | |
510 | targetdep = "1.0" | |
511 | ||
512 | "#, | |
513 | alt = alternate(), | |
514 | ), | |
515 | ) | |
516 | .file("src/lib.rs", "") | |
517 | .file("build.rs", "fn main() {}") | |
518 | .build(); | |
519 | ||
520 | p.cargo("tree") | |
521 | .with_stdout( | |
522 | "\ | |
523 | foo v0.1.0 ([..]/foo) | |
524 | ", | |
525 | ) | |
526 | .run(); | |
527 | ||
528 | p.cargo("tree -i targetdep") | |
529 | .with_stderr( | |
530 | "\ | |
531 | [WARNING] nothing to print. | |
532 | ||
533 | To find dependencies that require specific target platforms, \ | |
534 | try to use option `--target all` first, and then narrow your search scope accordingly. | |
535 | ", | |
536 | ) | |
537 | .run(); | |
538 | p.cargo("tree -i targetdep --target all") | |
539 | .with_stdout( | |
540 | "\ | |
541 | targetdep v1.0.0 | |
542 | └── foo v0.1.0 ([..]/foo) | |
543 | ", | |
544 | ) | |
545 | .run(); | |
546 | } | |
547 | ||
548 | #[cargo_test] | |
549 | fn dep_kinds() { | |
550 | Package::new("inner-devdep", "1.0.0").publish(); | |
551 | Package::new("inner-builddep", "1.0.0").publish(); | |
552 | Package::new("inner-normal", "1.0.0").publish(); | |
553 | Package::new("inner-pm", "1.0.0").proc_macro(true).publish(); | |
554 | Package::new("inner-buildpm", "1.0.0") | |
555 | .proc_macro(true) | |
556 | .publish(); | |
557 | Package::new("normaldep", "1.0.0") | |
558 | .dep("inner-normal", "1.0") | |
559 | .dev_dep("inner-devdep", "1.0") | |
560 | .build_dep("inner-builddep", "1.0") | |
561 | .publish(); | |
562 | Package::new("devdep", "1.0.0") | |
563 | .dep("inner-normal", "1.0") | |
564 | .dep("inner-pm", "1.0") | |
565 | .dev_dep("inner-devdep", "1.0") | |
566 | .build_dep("inner-builddep", "1.0") | |
567 | .build_dep("inner-buildpm", "1.0") | |
568 | .publish(); | |
569 | Package::new("builddep", "1.0.0") | |
570 | .dep("inner-normal", "1.0") | |
571 | .dev_dep("inner-devdep", "1.0") | |
572 | .build_dep("inner-builddep", "1.0") | |
573 | .publish(); | |
574 | let p = project() | |
575 | .file( | |
576 | "Cargo.toml", | |
577 | r#" | |
578 | [package] | |
579 | name = "foo" | |
580 | version = "0.1.0" | |
581 | ||
582 | [dependencies] | |
583 | normaldep = "1.0" | |
584 | ||
585 | [dev-dependencies] | |
586 | devdep = "1.0" | |
587 | ||
588 | [build-dependencies] | |
589 | builddep = "1.0" | |
590 | "#, | |
591 | ) | |
592 | .file("src/lib.rs", "") | |
593 | .build(); | |
594 | ||
595 | p.cargo("tree") | |
596 | .with_stdout( | |
597 | "\ | |
598 | foo v0.1.0 ([..]/foo) | |
599 | └── normaldep v1.0.0 | |
600 | └── inner-normal v1.0.0 | |
601 | [build-dependencies] | |
602 | └── inner-builddep v1.0.0 | |
603 | [build-dependencies] | |
604 | └── builddep v1.0.0 | |
605 | └── inner-normal v1.0.0 | |
606 | [build-dependencies] | |
607 | └── inner-builddep v1.0.0 | |
608 | [dev-dependencies] | |
609 | └── devdep v1.0.0 | |
610 | ├── inner-normal v1.0.0 | |
611 | └── inner-pm v1.0.0 (proc-macro) | |
612 | [build-dependencies] | |
613 | ├── inner-builddep v1.0.0 | |
614 | └── inner-buildpm v1.0.0 (proc-macro) | |
615 | ", | |
616 | ) | |
617 | .run(); | |
618 | ||
619 | p.cargo("tree -e no-dev") | |
620 | .with_stdout( | |
621 | "\ | |
622 | foo v0.1.0 ([..]/foo) | |
623 | └── normaldep v1.0.0 | |
624 | └── inner-normal v1.0.0 | |
625 | [build-dependencies] | |
626 | └── inner-builddep v1.0.0 | |
627 | [build-dependencies] | |
628 | └── builddep v1.0.0 | |
629 | └── inner-normal v1.0.0 | |
630 | [build-dependencies] | |
631 | └── inner-builddep v1.0.0 | |
632 | ", | |
633 | ) | |
634 | .run(); | |
635 | ||
636 | p.cargo("tree -e normal") | |
637 | .with_stdout( | |
638 | "\ | |
639 | foo v0.1.0 ([..]/foo) | |
640 | └── normaldep v1.0.0 | |
641 | └── inner-normal v1.0.0 | |
642 | ", | |
643 | ) | |
644 | .run(); | |
645 | ||
646 | p.cargo("tree -e dev,build") | |
647 | .with_stdout( | |
648 | "\ | |
649 | foo v0.1.0 ([..]/foo) | |
650 | [build-dependencies] | |
651 | └── builddep v1.0.0 | |
652 | [build-dependencies] | |
653 | └── inner-builddep v1.0.0 | |
654 | [dev-dependencies] | |
655 | └── devdep v1.0.0 | |
656 | [build-dependencies] | |
657 | ├── inner-builddep v1.0.0 | |
658 | └── inner-buildpm v1.0.0 (proc-macro) | |
659 | ", | |
660 | ) | |
661 | .run(); | |
662 | ||
663 | p.cargo("tree -e dev,build,no-proc-macro") | |
664 | .with_stdout( | |
665 | "\ | |
666 | foo v0.1.0 ([..]/foo) | |
667 | [build-dependencies] | |
668 | └── builddep v1.0.0 | |
669 | [build-dependencies] | |
670 | └── inner-builddep v1.0.0 | |
671 | [dev-dependencies] | |
672 | └── devdep v1.0.0 | |
673 | [build-dependencies] | |
674 | └── inner-builddep v1.0.0 | |
675 | ", | |
676 | ) | |
677 | .run(); | |
678 | } | |
679 | ||
680 | #[cargo_test] | |
681 | fn cyclic_dev_dep() { | |
682 | // Cyclical dev-dependency and inverse flag. | |
683 | let p = project() | |
684 | .file( | |
685 | "Cargo.toml", | |
686 | r#" | |
687 | [package] | |
688 | name = "foo" | |
689 | version = "0.1.0" | |
690 | ||
691 | [dev-dependencies] | |
692 | dev-dep = { path = "dev-dep" } | |
693 | "#, | |
694 | ) | |
695 | .file("src/lib.rs", "") | |
696 | .file( | |
697 | "dev-dep/Cargo.toml", | |
698 | r#" | |
699 | [package] | |
700 | name = "dev-dep" | |
701 | version = "0.1.0" | |
702 | ||
703 | [dependencies] | |
704 | foo = { path=".." } | |
705 | "#, | |
706 | ) | |
707 | .file("dev-dep/src/lib.rs", "") | |
708 | .build(); | |
709 | ||
710 | p.cargo("tree") | |
711 | .with_stdout( | |
712 | "\ | |
713 | foo v0.1.0 ([..]/foo) | |
714 | [dev-dependencies] | |
715 | └── dev-dep v0.1.0 ([..]/foo/dev-dep) | |
716 | └── foo v0.1.0 ([..]/foo) (*) | |
717 | ", | |
718 | ) | |
719 | .run(); | |
720 | ||
721 | p.cargo("tree --invert foo") | |
722 | .with_stdout( | |
723 | "\ | |
724 | foo v0.1.0 ([..]/foo) | |
725 | └── dev-dep v0.1.0 ([..]/foo/dev-dep) | |
726 | [dev-dependencies] | |
727 | └── foo v0.1.0 ([..]/foo) (*) | |
728 | ", | |
729 | ) | |
730 | .run(); | |
731 | } | |
732 | ||
733 | #[cargo_test] | |
734 | fn invert() { | |
735 | Package::new("b1", "1.0.0").dep("c", "1.0").publish(); | |
736 | Package::new("b2", "1.0.0").dep("d", "1.0").publish(); | |
737 | Package::new("c", "1.0.0").publish(); | |
738 | Package::new("d", "1.0.0").publish(); | |
739 | let p = project() | |
740 | .file( | |
741 | "Cargo.toml", | |
742 | r#" | |
743 | [package] | |
744 | name = "foo" | |
745 | version = "0.1.0" | |
746 | ||
747 | [dependencies] | |
748 | b1 = "1.0" | |
749 | b2 = "1.0" | |
750 | c = "1.0" | |
751 | "#, | |
752 | ) | |
753 | .file("src/lib.rs", "") | |
754 | .build(); | |
755 | ||
756 | p.cargo("tree") | |
757 | .with_stdout( | |
758 | "\ | |
759 | foo v0.1.0 ([..]/foo) | |
760 | ├── b1 v1.0.0 | |
761 | │ └── c v1.0.0 | |
762 | ├── b2 v1.0.0 | |
763 | │ └── d v1.0.0 | |
764 | └── c v1.0.0 | |
765 | ", | |
766 | ) | |
767 | .run(); | |
768 | ||
769 | p.cargo("tree --invert c") | |
770 | .with_stdout( | |
771 | "\ | |
772 | c v1.0.0 | |
773 | ├── b1 v1.0.0 | |
774 | │ └── foo v0.1.0 ([..]/foo) | |
775 | └── foo v0.1.0 ([..]/foo) | |
776 | ", | |
777 | ) | |
778 | .run(); | |
779 | } | |
780 | ||
781 | #[cargo_test] | |
782 | fn invert_with_build_dep() { | |
783 | // -i for a common dependency between normal and build deps. | |
784 | Package::new("common", "1.0.0").publish(); | |
785 | Package::new("bdep", "1.0.0").dep("common", "1.0").publish(); | |
786 | let p = project() | |
787 | .file( | |
788 | "Cargo.toml", | |
789 | r#" | |
790 | [package] | |
791 | name = "foo" | |
792 | version = "0.1.0" | |
793 | ||
794 | [dependencies] | |
795 | common = "1.0" | |
796 | ||
797 | [build-dependencies] | |
798 | bdep = "1.0" | |
799 | "#, | |
800 | ) | |
801 | .file("src/lib.rs", "") | |
802 | .build(); | |
803 | ||
804 | p.cargo("tree") | |
805 | .with_stdout( | |
806 | "\ | |
807 | foo v0.1.0 ([..]/foo) | |
808 | └── common v1.0.0 | |
809 | [build-dependencies] | |
810 | └── bdep v1.0.0 | |
811 | └── common v1.0.0 | |
812 | ", | |
813 | ) | |
814 | .run(); | |
815 | ||
816 | p.cargo("tree -i common") | |
817 | .with_stdout( | |
818 | "\ | |
819 | common v1.0.0 | |
820 | ├── bdep v1.0.0 | |
821 | │ [build-dependencies] | |
822 | │ └── foo v0.1.0 ([..]/foo) | |
823 | └── foo v0.1.0 ([..]/foo) | |
824 | ", | |
825 | ) | |
826 | .run(); | |
827 | } | |
828 | ||
829 | #[cargo_test] | |
830 | fn no_indent() { | |
831 | let p = make_simple_proj(); | |
832 | ||
833 | p.cargo("tree --prefix=none") | |
834 | .with_stdout( | |
835 | "\ | |
836 | foo v0.1.0 ([..]/foo) | |
837 | a v1.0.0 | |
838 | b v1.0.0 | |
839 | c v1.0.0 | |
840 | c v1.0.0 | |
841 | bdep v1.0.0 | |
842 | b v1.0.0 (*) | |
843 | devdep v1.0.0 | |
844 | b v1.0.0 (*) | |
845 | ", | |
846 | ) | |
847 | .run(); | |
848 | } | |
849 | ||
850 | #[cargo_test] | |
851 | fn prefix_depth() { | |
852 | let p = make_simple_proj(); | |
853 | ||
854 | p.cargo("tree --prefix=depth") | |
855 | .with_stdout( | |
856 | "\ | |
857 | 0foo v0.1.0 ([..]/foo) | |
858 | 1a v1.0.0 | |
859 | 2b v1.0.0 | |
860 | 3c v1.0.0 | |
861 | 1c v1.0.0 | |
862 | 1bdep v1.0.0 | |
863 | 2b v1.0.0 (*) | |
864 | 1devdep v1.0.0 | |
865 | 2b v1.0.0 (*) | |
866 | ", | |
867 | ) | |
868 | .run(); | |
869 | } | |
870 | ||
871 | #[cargo_test] | |
872 | fn no_dedupe() { | |
873 | let p = make_simple_proj(); | |
874 | ||
875 | p.cargo("tree --no-dedupe") | |
876 | .with_stdout( | |
877 | "\ | |
878 | foo v0.1.0 ([..]/foo) | |
879 | ├── a v1.0.0 | |
880 | │ └── b v1.0.0 | |
881 | │ └── c v1.0.0 | |
882 | └── c v1.0.0 | |
883 | [build-dependencies] | |
884 | └── bdep v1.0.0 | |
885 | └── b v1.0.0 | |
886 | └── c v1.0.0 | |
887 | [dev-dependencies] | |
888 | └── devdep v1.0.0 | |
889 | └── b v1.0.0 | |
890 | └── c v1.0.0 | |
891 | ", | |
892 | ) | |
893 | .run(); | |
894 | } | |
895 | ||
896 | #[cargo_test] | |
897 | fn no_dedupe_cycle() { | |
898 | // --no-dedupe with a dependency cycle | |
899 | let p = project() | |
900 | .file( | |
901 | "Cargo.toml", | |
902 | r#" | |
903 | [package] | |
904 | name = "foo" | |
905 | version = "0.1.0" | |
906 | ||
907 | [dev-dependencies] | |
908 | bar = {path = "bar"} | |
909 | "#, | |
910 | ) | |
911 | .file("src/lib.rs", "") | |
912 | .file( | |
913 | "bar/Cargo.toml", | |
914 | r#" | |
915 | [package] | |
916 | name = "bar" | |
917 | version = "0.1.0" | |
918 | ||
919 | [dependencies] | |
920 | foo = {path=".."} | |
921 | "#, | |
922 | ) | |
923 | .file("bar/src/lib.rs", "") | |
924 | .build(); | |
925 | ||
926 | p.cargo("tree") | |
927 | .with_stdout( | |
928 | "\ | |
929 | foo v0.1.0 ([..]/foo) | |
930 | [dev-dependencies] | |
931 | └── bar v0.1.0 ([..]/foo/bar) | |
932 | └── foo v0.1.0 ([..]/foo) (*) | |
933 | ", | |
934 | ) | |
935 | .run(); | |
936 | ||
937 | p.cargo("tree --no-dedupe") | |
938 | .with_stdout( | |
939 | "\ | |
940 | foo v0.1.0 ([..]/foo) | |
941 | [dev-dependencies] | |
942 | └── bar v0.1.0 ([..]/foo/bar) | |
943 | └── foo v0.1.0 ([..]/foo) (*) | |
944 | ", | |
945 | ) | |
946 | .run(); | |
947 | } | |
948 | ||
949 | #[cargo_test] | |
950 | fn duplicates() { | |
951 | Package::new("dog", "1.0.0").publish(); | |
952 | Package::new("dog", "2.0.0").publish(); | |
953 | Package::new("cat", "1.0.0").publish(); | |
954 | Package::new("cat", "2.0.0").publish(); | |
955 | Package::new("dep", "1.0.0") | |
956 | .dep("dog", "1.0") | |
957 | .dep("cat", "1.0") | |
958 | .publish(); | |
959 | let p = project() | |
960 | .file( | |
961 | "Cargo.toml", | |
962 | r#" | |
963 | [workspace] | |
964 | members = ["a", "b"] | |
965 | "#, | |
966 | ) | |
967 | .file( | |
968 | "a/Cargo.toml", | |
969 | r#" | |
970 | [package] | |
971 | name = "a" | |
972 | version = "0.1.0" | |
973 | ||
974 | [dependencies] | |
975 | dog1 = { version = "1.0", package = "dog" } | |
976 | dog2 = { version = "2.0", package = "dog" } | |
977 | "#, | |
978 | ) | |
979 | .file("a/src/lib.rs", "") | |
980 | .file( | |
981 | "b/Cargo.toml", | |
982 | r#" | |
983 | [package] | |
984 | name = "b" | |
985 | version = "0.1.0" | |
986 | ||
987 | [dependencies] | |
988 | dep = "1.0" | |
989 | cat = "2.0" | |
990 | "#, | |
991 | ) | |
992 | .file("b/src/lib.rs", "") | |
993 | .build(); | |
994 | ||
995 | p.cargo("tree -p a") | |
996 | .with_stdout( | |
997 | "\ | |
998 | a v0.1.0 ([..]/foo/a) | |
999 | ├── dog v1.0.0 | |
1000 | └── dog v2.0.0 | |
1001 | ", | |
1002 | ) | |
1003 | .run(); | |
1004 | ||
1005 | p.cargo("tree -p b") | |
1006 | .with_stdout( | |
1007 | "\ | |
1008 | b v0.1.0 ([..]/foo/b) | |
1009 | ├── cat v2.0.0 | |
1010 | └── dep v1.0.0 | |
1011 | ├── cat v1.0.0 | |
1012 | └── dog v1.0.0 | |
1013 | ", | |
1014 | ) | |
1015 | .run(); | |
1016 | ||
1017 | p.cargo("tree -p a -d") | |
1018 | .with_stdout( | |
1019 | "\ | |
1020 | dog v1.0.0 | |
1021 | └── a v0.1.0 ([..]/foo/a) | |
1022 | ||
1023 | dog v2.0.0 | |
1024 | └── a v0.1.0 ([..]/foo/a) | |
1025 | ", | |
1026 | ) | |
1027 | .run(); | |
1028 | ||
1029 | p.cargo("tree -p b -d") | |
1030 | .with_stdout( | |
1031 | "\ | |
1032 | cat v1.0.0 | |
1033 | └── dep v1.0.0 | |
1034 | └── b v0.1.0 ([..]/foo/b) | |
1035 | ||
1036 | cat v2.0.0 | |
1037 | └── b v0.1.0 ([..]/foo/b) | |
1038 | ", | |
1039 | ) | |
1040 | .run(); | |
1041 | } | |
1042 | ||
1043 | #[cargo_test] | |
1044 | fn duplicates_with_target() { | |
1045 | // --target flag | |
1046 | if cross_compile::disabled() { | |
1047 | return; | |
1048 | } | |
1049 | Package::new("a", "1.0.0").publish(); | |
1050 | Package::new("dog", "1.0.0").publish(); | |
1051 | ||
1052 | let p = project() | |
1053 | .file( | |
1054 | "Cargo.toml", | |
1055 | r#" | |
1056 | [package] | |
1057 | name = "foo" | |
1058 | version = "0.1.0" | |
1059 | ||
1060 | [dependencies] | |
1061 | a = "1.0" | |
1062 | dog = "1.0" | |
1063 | ||
1064 | [build-dependencies] | |
1065 | a = "1.0" | |
1066 | dog = "1.0" | |
1067 | ||
1068 | "#, | |
1069 | ) | |
1070 | .file("src/lib.rs", "") | |
1071 | .file("build.rs", "fn main() {}") | |
1072 | .build(); | |
1073 | p.cargo("tree -d").with_stdout("").run(); | |
1074 | ||
1075 | p.cargo("tree -d --target") | |
1076 | .arg(alternate()) | |
1077 | .with_stdout("") | |
1078 | .run(); | |
1079 | ||
1080 | p.cargo("tree -d --target") | |
1081 | .arg(rustc_host()) | |
1082 | .with_stdout("") | |
1083 | .run(); | |
1084 | ||
1085 | p.cargo("tree -d --target=all").with_stdout("").run(); | |
1086 | } | |
1087 | ||
49aad941 FG |
1088 | #[cargo_test] |
1089 | fn duplicates_with_proc_macro() { | |
1090 | Package::new("dupe-dep", "1.0.0").publish(); | |
1091 | Package::new("dupe-dep", "2.0.0").publish(); | |
1092 | Package::new("proc", "1.0.0") | |
1093 | .proc_macro(true) | |
1094 | .dep("dupe-dep", "1.0") | |
1095 | .publish(); | |
1096 | let p = project() | |
1097 | .file( | |
1098 | "Cargo.toml", | |
1099 | r#" | |
1100 | [package] | |
1101 | name = "foo" | |
1102 | version = "0.1.0" | |
1103 | ||
1104 | [dependencies] | |
1105 | proc = "1.0" | |
1106 | dupe-dep = "2.0" | |
1107 | "#, | |
1108 | ) | |
1109 | .file("src/lib.rs", "") | |
1110 | .build(); | |
1111 | ||
1112 | p.cargo("tree") | |
1113 | .with_stdout( | |
1114 | "\ | |
1115 | foo v0.1.0 ([..]/foo) | |
1116 | ├── dupe-dep v2.0.0 | |
1117 | └── proc v1.0.0 (proc-macro) | |
1118 | └── dupe-dep v1.0.0 | |
1119 | ", | |
1120 | ) | |
1121 | .run(); | |
1122 | ||
1123 | p.cargo("tree --duplicates") | |
1124 | .with_stdout( | |
1125 | "\ | |
1126 | dupe-dep v1.0.0 | |
1127 | └── proc v1.0.0 (proc-macro) | |
1128 | └── foo v0.1.0 ([..]/foo) | |
1129 | ||
1130 | dupe-dep v2.0.0 | |
1131 | └── foo v0.1.0 ([..]/foo) | |
1132 | ", | |
1133 | ) | |
1134 | .run(); | |
1135 | ||
1136 | p.cargo("tree --duplicates --edges no-proc-macro") | |
1137 | .with_stdout("") | |
1138 | .run(); | |
1139 | } | |
1140 | ||
0a29b90c FG |
1141 | #[cargo_test] |
1142 | fn charset() { | |
1143 | let p = make_simple_proj(); | |
1144 | p.cargo("tree --charset ascii") | |
1145 | .with_stdout( | |
1146 | "\ | |
1147 | foo v0.1.0 ([..]/foo) | |
1148 | |-- a v1.0.0 | |
1149 | | `-- b v1.0.0 | |
1150 | | `-- c v1.0.0 | |
1151 | `-- c v1.0.0 | |
1152 | [build-dependencies] | |
1153 | `-- bdep v1.0.0 | |
1154 | `-- b v1.0.0 (*) | |
1155 | [dev-dependencies] | |
1156 | `-- devdep v1.0.0 | |
1157 | `-- b v1.0.0 (*) | |
1158 | ", | |
1159 | ) | |
1160 | .run(); | |
1161 | } | |
1162 | ||
1163 | #[cargo_test] | |
1164 | fn format() { | |
1165 | Package::new("dep", "1.0.0").publish(); | |
1166 | Package::new("other-dep", "1.0.0").publish(); | |
1167 | ||
1168 | Package::new("dep_that_is_awesome", "1.0.0") | |
1169 | .file( | |
1170 | "Cargo.toml", | |
1171 | r#" | |
1172 | [package] | |
1173 | name = "dep_that_is_awesome" | |
1174 | version = "1.0.0" | |
1175 | ||
1176 | [lib] | |
1177 | name = "awesome_dep" | |
1178 | "#, | |
1179 | ) | |
1180 | .file("src/lib.rs", "pub struct Straw;") | |
1181 | .publish(); | |
1182 | ||
1183 | let p = project() | |
1184 | .file( | |
1185 | "Cargo.toml", | |
1186 | r#" | |
1187 | [package] | |
1188 | name = "foo" | |
1189 | version = "0.1.0" | |
1190 | license = "MIT" | |
1191 | repository = "https://github.com/rust-lang/cargo" | |
1192 | ||
1193 | [dependencies] | |
1194 | dep = {version="1.0", optional=true} | |
1195 | other-dep = {version="1.0", optional=true} | |
1196 | dep_that_is_awesome = {version="1.0", optional=true} | |
1197 | ||
1198 | ||
1199 | [features] | |
1200 | default = ["foo"] | |
1201 | foo = ["bar"] | |
1202 | bar = [] | |
1203 | "#, | |
1204 | ) | |
1205 | .file("src/main.rs", "") | |
1206 | .build(); | |
1207 | ||
1208 | p.cargo("tree --format <<<{p}>>>") | |
1209 | .with_stdout("<<<foo v0.1.0 ([..]/foo)>>>") | |
1210 | .run(); | |
1211 | ||
1212 | p.cargo("tree --format {}") | |
1213 | .with_stderr( | |
1214 | "\ | |
1215 | [ERROR] tree format `{}` not valid | |
1216 | ||
1217 | Caused by: | |
1218 | unsupported pattern `` | |
1219 | ", | |
1220 | ) | |
1221 | .with_status(101) | |
1222 | .run(); | |
1223 | ||
1224 | p.cargo("tree --format {p}-{{hello}}") | |
1225 | .with_stdout("foo v0.1.0 ([..]/foo)-{hello}") | |
1226 | .run(); | |
1227 | ||
1228 | p.cargo("tree --format") | |
1229 | .arg("{p} {l} {r}") | |
1230 | .with_stdout("foo v0.1.0 ([..]/foo) MIT https://github.com/rust-lang/cargo") | |
1231 | .run(); | |
1232 | ||
1233 | p.cargo("tree --format") | |
1234 | .arg("{p} {f}") | |
1235 | .with_stdout("foo v0.1.0 ([..]/foo) bar,default,foo") | |
1236 | .run(); | |
1237 | ||
1238 | p.cargo("tree --all-features --format") | |
1239 | .arg("{p} [{f}]") | |
1240 | .with_stdout( | |
1241 | "\ | |
1242 | foo v0.1.0 ([..]/foo) [bar,default,dep,dep_that_is_awesome,foo,other-dep] | |
1243 | ├── dep v1.0.0 [] | |
1244 | ├── dep_that_is_awesome v1.0.0 [] | |
1245 | └── other-dep v1.0.0 [] | |
1246 | ", | |
1247 | ) | |
1248 | .run(); | |
1249 | ||
1250 | p.cargo("tree") | |
1251 | .arg("--features=other-dep,dep_that_is_awesome") | |
1252 | .arg("--format={lib}") | |
1253 | .with_stdout( | |
1254 | " | |
1255 | ├── awesome_dep | |
1256 | └── other_dep | |
1257 | ", | |
1258 | ) | |
1259 | .run(); | |
1260 | } | |
1261 | ||
1262 | #[cargo_test] | |
1263 | fn dev_dep_feature() { | |
1264 | // New feature resolver with optional dep | |
1265 | Package::new("optdep", "1.0.0").publish(); | |
1266 | Package::new("bar", "1.0.0") | |
1267 | .add_dep(Dependency::new("optdep", "1.0").optional(true)) | |
1268 | .publish(); | |
1269 | let p = project() | |
1270 | .file( | |
1271 | "Cargo.toml", | |
1272 | r#" | |
1273 | [package] | |
1274 | name = "foo" | |
1275 | version = "0.1.0" | |
1276 | ||
1277 | [dev-dependencies] | |
1278 | bar = { version = "1.0", features = ["optdep"] } | |
1279 | ||
1280 | [dependencies] | |
1281 | bar = "1.0" | |
1282 | "#, | |
1283 | ) | |
1284 | .file("src/lib.rs", "") | |
1285 | .build(); | |
1286 | ||
1287 | // Old behavior. | |
1288 | p.cargo("tree") | |
1289 | .with_stdout( | |
1290 | "\ | |
1291 | foo v0.1.0 ([..]/foo) | |
1292 | └── bar v1.0.0 | |
1293 | └── optdep v1.0.0 | |
1294 | [dev-dependencies] | |
1295 | └── bar v1.0.0 (*) | |
1296 | ", | |
1297 | ) | |
1298 | .run(); | |
1299 | ||
1300 | p.cargo("tree -e normal") | |
1301 | .with_stdout( | |
1302 | "\ | |
1303 | foo v0.1.0 ([..]/foo) | |
1304 | └── bar v1.0.0 | |
1305 | └── optdep v1.0.0 | |
1306 | ", | |
1307 | ) | |
1308 | .run(); | |
1309 | ||
1310 | // New behavior. | |
1311 | switch_to_resolver_2(&p); | |
1312 | ||
1313 | p.cargo("tree") | |
1314 | .with_stdout( | |
1315 | "\ | |
1316 | foo v0.1.0 ([..]/foo) | |
1317 | └── bar v1.0.0 | |
1318 | └── optdep v1.0.0 | |
1319 | [dev-dependencies] | |
1320 | └── bar v1.0.0 (*) | |
1321 | ", | |
1322 | ) | |
1323 | .run(); | |
1324 | ||
1325 | p.cargo("tree -e normal") | |
1326 | .with_stdout( | |
1327 | "\ | |
1328 | foo v0.1.0 ([..]/foo) | |
1329 | └── bar v1.0.0 | |
1330 | ", | |
1331 | ) | |
1332 | .run(); | |
1333 | } | |
1334 | ||
1335 | #[cargo_test] | |
1336 | fn host_dep_feature() { | |
1337 | // New feature resolver with optional build dep | |
1338 | Package::new("optdep", "1.0.0").publish(); | |
1339 | Package::new("bar", "1.0.0") | |
1340 | .add_dep(Dependency::new("optdep", "1.0").optional(true)) | |
1341 | .publish(); | |
1342 | let p = project() | |
1343 | .file( | |
1344 | "Cargo.toml", | |
1345 | r#" | |
1346 | [package] | |
1347 | name = "foo" | |
1348 | version = "0.1.0" | |
1349 | ||
1350 | [build-dependencies] | |
1351 | bar = { version = "1.0", features = ["optdep"] } | |
1352 | ||
1353 | [dependencies] | |
1354 | bar = "1.0" | |
1355 | "#, | |
1356 | ) | |
1357 | .file("src/lib.rs", "") | |
1358 | .file("build.rs", "fn main() {}") | |
1359 | .build(); | |
1360 | ||
1361 | // Old behavior | |
1362 | p.cargo("tree") | |
1363 | .with_stdout( | |
1364 | "\ | |
1365 | foo v0.1.0 ([..]/foo) | |
1366 | └── bar v1.0.0 | |
1367 | └── optdep v1.0.0 | |
1368 | [build-dependencies] | |
1369 | └── bar v1.0.0 (*) | |
1370 | ", | |
1371 | ) | |
1372 | .run(); | |
1373 | ||
1374 | // -p | |
1375 | p.cargo("tree -p bar") | |
1376 | .with_stdout( | |
1377 | "\ | |
1378 | bar v1.0.0 | |
1379 | └── optdep v1.0.0 | |
1380 | ", | |
1381 | ) | |
1382 | .run(); | |
1383 | ||
1384 | // invert | |
1385 | p.cargo("tree -i optdep") | |
1386 | .with_stdout( | |
1387 | "\ | |
1388 | optdep v1.0.0 | |
1389 | └── bar v1.0.0 | |
1390 | └── foo v0.1.0 ([..]/foo) | |
1391 | [build-dependencies] | |
1392 | └── foo v0.1.0 ([..]/foo) | |
1393 | ", | |
1394 | ) | |
1395 | .run(); | |
1396 | ||
1397 | // New behavior. | |
1398 | switch_to_resolver_2(&p); | |
1399 | ||
1400 | p.cargo("tree") | |
1401 | .with_stdout( | |
1402 | "\ | |
1403 | foo v0.1.0 ([..]/foo) | |
1404 | └── bar v1.0.0 | |
1405 | [build-dependencies] | |
1406 | └── bar v1.0.0 | |
1407 | └── optdep v1.0.0 | |
1408 | ", | |
1409 | ) | |
1410 | .run(); | |
1411 | ||
1412 | p.cargo("tree -p bar") | |
1413 | .with_stdout( | |
1414 | "\ | |
1415 | bar v1.0.0 | |
1416 | ||
1417 | bar v1.0.0 | |
1418 | └── optdep v1.0.0 | |
1419 | ", | |
1420 | ) | |
1421 | .run(); | |
1422 | ||
1423 | p.cargo("tree -i optdep") | |
1424 | .with_stdout( | |
1425 | "\ | |
1426 | optdep v1.0.0 | |
1427 | └── bar v1.0.0 | |
1428 | [build-dependencies] | |
1429 | └── foo v0.1.0 ([..]/foo) | |
1430 | ", | |
1431 | ) | |
1432 | .run(); | |
1433 | ||
1434 | // Check that -d handles duplicates with features. | |
1435 | p.cargo("tree -d") | |
1436 | .with_stdout( | |
1437 | "\ | |
1438 | bar v1.0.0 | |
1439 | └── foo v0.1.0 ([..]/foo) | |
1440 | ||
1441 | bar v1.0.0 | |
1442 | [build-dependencies] | |
1443 | └── foo v0.1.0 ([..]/foo) | |
1444 | ", | |
1445 | ) | |
1446 | .run(); | |
1447 | } | |
1448 | ||
1449 | #[cargo_test] | |
1450 | fn proc_macro_features() { | |
1451 | // New feature resolver with a proc-macro | |
1452 | Package::new("optdep", "1.0.0").publish(); | |
1453 | Package::new("somedep", "1.0.0") | |
1454 | .add_dep(Dependency::new("optdep", "1.0").optional(true)) | |
1455 | .publish(); | |
1456 | Package::new("pm", "1.0.0") | |
1457 | .proc_macro(true) | |
1458 | .feature_dep("somedep", "1.0", &["optdep"]) | |
1459 | .publish(); | |
1460 | let p = project() | |
1461 | .file( | |
1462 | "Cargo.toml", | |
1463 | r#" | |
1464 | [package] | |
1465 | name = "foo" | |
1466 | version = "0.1.0" | |
1467 | ||
1468 | [dependencies] | |
1469 | pm = "1.0" | |
1470 | somedep = "1.0" | |
1471 | "#, | |
1472 | ) | |
1473 | .file("src/lib.rs", "") | |
1474 | .build(); | |
1475 | ||
1476 | // Old behavior | |
1477 | p.cargo("tree") | |
1478 | .with_stdout( | |
1479 | "\ | |
1480 | foo v0.1.0 ([..]/foo) | |
1481 | ├── pm v1.0.0 (proc-macro) | |
1482 | │ └── somedep v1.0.0 | |
1483 | │ └── optdep v1.0.0 | |
1484 | └── somedep v1.0.0 (*) | |
1485 | ", | |
1486 | ) | |
1487 | .run(); | |
1488 | ||
1489 | // Old behavior + no-proc-macro | |
1490 | p.cargo("tree -e no-proc-macro") | |
1491 | .with_stdout( | |
1492 | "\ | |
1493 | foo v0.1.0 ([..]/foo) | |
1494 | └── somedep v1.0.0 | |
1495 | └── optdep v1.0.0 | |
1496 | ", | |
1497 | ) | |
1498 | .run(); | |
1499 | ||
1500 | // -p | |
1501 | p.cargo("tree -p somedep") | |
1502 | .with_stdout( | |
1503 | "\ | |
1504 | somedep v1.0.0 | |
1505 | └── optdep v1.0.0 | |
1506 | ", | |
1507 | ) | |
1508 | .run(); | |
1509 | ||
1510 | // -p -e no-proc-macro | |
1511 | p.cargo("tree -p somedep -e no-proc-macro") | |
1512 | .with_stdout( | |
1513 | "\ | |
1514 | somedep v1.0.0 | |
1515 | └── optdep v1.0.0 | |
1516 | ", | |
1517 | ) | |
1518 | .run(); | |
1519 | ||
1520 | // invert | |
1521 | p.cargo("tree -i somedep") | |
1522 | .with_stdout( | |
1523 | "\ | |
1524 | somedep v1.0.0 | |
1525 | ├── foo v0.1.0 ([..]/foo) | |
1526 | └── pm v1.0.0 (proc-macro) | |
1527 | └── foo v0.1.0 ([..]/foo) | |
1528 | ", | |
1529 | ) | |
1530 | .run(); | |
1531 | ||
1532 | // invert + no-proc-macro | |
1533 | p.cargo("tree -i somedep -e no-proc-macro") | |
1534 | .with_stdout( | |
1535 | "\ | |
1536 | somedep v1.0.0 | |
1537 | └── foo v0.1.0 ([..]/foo) | |
1538 | ", | |
1539 | ) | |
1540 | .run(); | |
1541 | ||
1542 | // New behavior. | |
1543 | switch_to_resolver_2(&p); | |
1544 | ||
1545 | // Note the missing (*) | |
1546 | p.cargo("tree") | |
1547 | .with_stdout( | |
1548 | "\ | |
1549 | foo v0.1.0 ([..]/foo) | |
1550 | ├── pm v1.0.0 (proc-macro) | |
1551 | │ └── somedep v1.0.0 | |
1552 | │ └── optdep v1.0.0 | |
1553 | └── somedep v1.0.0 | |
1554 | ", | |
1555 | ) | |
1556 | .run(); | |
1557 | ||
1558 | p.cargo("tree -e no-proc-macro") | |
1559 | .with_stdout( | |
1560 | "\ | |
1561 | foo v0.1.0 ([..]/foo) | |
1562 | └── somedep v1.0.0 | |
1563 | ", | |
1564 | ) | |
1565 | .run(); | |
1566 | ||
1567 | p.cargo("tree -p somedep") | |
1568 | .with_stdout( | |
1569 | "\ | |
1570 | somedep v1.0.0 | |
1571 | ||
1572 | somedep v1.0.0 | |
1573 | └── optdep v1.0.0 | |
1574 | ", | |
1575 | ) | |
1576 | .run(); | |
1577 | ||
1578 | p.cargo("tree -i somedep") | |
1579 | .with_stdout( | |
1580 | "\ | |
1581 | somedep v1.0.0 | |
1582 | └── foo v0.1.0 ([..]/foo) | |
1583 | ||
1584 | somedep v1.0.0 | |
1585 | └── pm v1.0.0 (proc-macro) | |
1586 | └── foo v0.1.0 ([..]/foo) | |
1587 | ", | |
1588 | ) | |
1589 | .run(); | |
1590 | ||
1591 | p.cargo("tree -i somedep -e no-proc-macro") | |
1592 | .with_stdout( | |
1593 | "\ | |
1594 | somedep v1.0.0 | |
1595 | └── foo v0.1.0 ([..]/foo) | |
0a29b90c FG |
1596 | ", |
1597 | ) | |
1598 | .run(); | |
1599 | } | |
1600 | ||
1601 | #[cargo_test] | |
1602 | fn itarget_opt_dep() { | |
1603 | // New feature resolver with optional target dep | |
1604 | Package::new("optdep", "1.0.0").publish(); | |
1605 | Package::new("common", "1.0.0") | |
1606 | .add_dep(Dependency::new("optdep", "1.0").optional(true)) | |
1607 | .publish(); | |
1608 | ||
1609 | let p = project() | |
1610 | .file( | |
1611 | "Cargo.toml", | |
1612 | r#" | |
1613 | [package] | |
1614 | name = "foo" | |
1615 | version = "1.0.0" | |
1616 | ||
1617 | [dependencies] | |
1618 | common = "1.0" | |
1619 | ||
1620 | [target.'cfg(whatever)'.dependencies] | |
1621 | common = { version = "1.0", features = ["optdep"] } | |
1622 | ||
1623 | "#, | |
1624 | ) | |
1625 | .file("src/lib.rs", "") | |
1626 | .build(); | |
1627 | ||
1628 | // Old behavior | |
1629 | p.cargo("tree") | |
1630 | .with_stdout( | |
1631 | "\ | |
1632 | foo v1.0.0 ([..]/foo) | |
1633 | └── common v1.0.0 | |
1634 | └── optdep v1.0.0 | |
1635 | ", | |
1636 | ) | |
1637 | .run(); | |
1638 | ||
1639 | // New behavior. | |
1640 | switch_to_resolver_2(&p); | |
1641 | ||
1642 | p.cargo("tree") | |
1643 | .with_stdout( | |
1644 | "\ | |
1645 | foo v1.0.0 ([..]/foo) | |
1646 | └── common v1.0.0 | |
1647 | ", | |
1648 | ) | |
1649 | .run(); | |
1650 | } | |
1651 | ||
1652 | #[cargo_test] | |
1653 | fn ambiguous_name() { | |
1654 | // -p that is ambiguous. | |
1655 | Package::new("dep", "1.0.0").publish(); | |
1656 | Package::new("dep", "2.0.0").publish(); | |
1657 | Package::new("bar", "1.0.0").dep("dep", "2.0").publish(); | |
1658 | let p = project() | |
1659 | .file( | |
1660 | "Cargo.toml", | |
1661 | r#" | |
1662 | [package] | |
1663 | name = "foo" | |
1664 | version = "0.1.0" | |
1665 | ||
1666 | [dependencies] | |
1667 | dep = "1.0" | |
1668 | bar = "1.0" | |
1669 | "#, | |
1670 | ) | |
1671 | .file("src/lib.rs", "") | |
1672 | .build(); | |
1673 | ||
1674 | p.cargo("tree -p dep") | |
1675 | .with_stderr_contains( | |
1676 | "\ | |
1677 | error: There are multiple `dep` packages in your project, and the specification `dep` is ambiguous. | |
781aab86 | 1678 | Please re-run this command with one of the following specifications: |
0a29b90c FG |
1679 | dep@1.0.0 |
1680 | dep@2.0.0 | |
1681 | ", | |
1682 | ) | |
1683 | .with_status(101) | |
1684 | .run(); | |
1685 | } | |
1686 | ||
1687 | #[cargo_test] | |
1688 | fn workspace_features_are_local() { | |
1689 | // The features for workspace packages should be the same as `cargo build` | |
1690 | // (i.e., the features selected depend on the "current" package). | |
1691 | Package::new("optdep", "1.0.0").publish(); | |
1692 | Package::new("somedep", "1.0.0") | |
1693 | .add_dep(Dependency::new("optdep", "1.0").optional(true)) | |
1694 | .publish(); | |
1695 | let p = project() | |
1696 | .file( | |
1697 | "Cargo.toml", | |
1698 | r#" | |
1699 | [workspace] | |
1700 | members = ["a", "b"] | |
1701 | "#, | |
1702 | ) | |
1703 | .file( | |
1704 | "a/Cargo.toml", | |
1705 | r#" | |
1706 | [package] | |
1707 | name = "a" | |
1708 | version = "0.1.0" | |
1709 | ||
1710 | [dependencies] | |
1711 | somedep = {version="1.0", features=["optdep"]} | |
1712 | "#, | |
1713 | ) | |
1714 | .file("a/src/lib.rs", "") | |
1715 | .file( | |
1716 | "b/Cargo.toml", | |
1717 | r#" | |
1718 | [package] | |
1719 | name = "b" | |
1720 | version = "0.1.0" | |
1721 | ||
1722 | [dependencies] | |
1723 | somedep = "1.0" | |
1724 | "#, | |
1725 | ) | |
1726 | .file("b/src/lib.rs", "") | |
1727 | .build(); | |
1728 | ||
1729 | p.cargo("tree") | |
1730 | .with_stdout( | |
1731 | "\ | |
1732 | a v0.1.0 ([..]/foo/a) | |
1733 | └── somedep v1.0.0 | |
1734 | └── optdep v1.0.0 | |
1735 | ||
1736 | b v0.1.0 ([..]/foo/b) | |
1737 | └── somedep v1.0.0 (*) | |
1738 | ", | |
1739 | ) | |
1740 | .run(); | |
1741 | ||
1742 | p.cargo("tree -p a") | |
1743 | .with_stdout( | |
1744 | "\ | |
1745 | a v0.1.0 ([..]/foo/a) | |
1746 | └── somedep v1.0.0 | |
1747 | └── optdep v1.0.0 | |
1748 | ", | |
1749 | ) | |
1750 | .run(); | |
1751 | ||
1752 | p.cargo("tree -p b") | |
1753 | .with_stdout( | |
1754 | "\ | |
1755 | b v0.1.0 ([..]/foo/b) | |
1756 | └── somedep v1.0.0 | |
1757 | ", | |
1758 | ) | |
1759 | .run(); | |
1760 | } | |
1761 | ||
1762 | #[cargo_test] | |
1763 | fn unknown_edge_kind() { | |
1764 | let p = project() | |
1765 | .file("Cargo.toml", "") | |
1766 | .file("src/lib.rs", "") | |
1767 | .build(); | |
1768 | ||
1769 | p.cargo("tree -e unknown") | |
1770 | .with_stderr( | |
1771 | "\ | |
1772 | [ERROR] unknown edge kind `unknown`, valid values are \ | |
1773 | \"normal\", \"build\", \"dev\", \ | |
1774 | \"no-normal\", \"no-build\", \"no-dev\", \"no-proc-macro\", \ | |
1775 | \"features\", or \"all\" | |
1776 | ", | |
1777 | ) | |
1778 | .with_status(101) | |
1779 | .run(); | |
1780 | } | |
1781 | ||
1782 | #[cargo_test] | |
1783 | fn mixed_no_edge_kinds() { | |
1784 | let p = project() | |
1785 | .file( | |
1786 | "Cargo.toml", | |
1787 | r#" | |
1788 | [package] | |
1789 | name = "foo" | |
1790 | version = "0.1.0" | |
1791 | "#, | |
1792 | ) | |
1793 | .file("src/lib.rs", "") | |
1794 | .build(); | |
1795 | ||
1796 | p.cargo("tree -e no-build,normal") | |
1797 | .with_stderr( | |
1798 | "\ | |
1799 | [ERROR] `normal` dependency kind cannot be mixed with \ | |
1800 | \"no-normal\", \"no-build\", or \"no-dev\" dependency kinds | |
1801 | ", | |
1802 | ) | |
1803 | .with_status(101) | |
1804 | .run(); | |
1805 | ||
1806 | // `no-proc-macro` can be mixed with others | |
1807 | p.cargo("tree -e no-proc-macro,normal") | |
1808 | .with_stdout( | |
1809 | "\ | |
1810 | foo v0.1.0 ([..]/foo) | |
1811 | ", | |
1812 | ) | |
1813 | .run(); | |
1814 | } | |
1815 | ||
1816 | #[cargo_test] | |
1817 | fn depth_limit() { | |
1818 | let p = make_simple_proj(); | |
1819 | ||
1820 | p.cargo("tree --depth 0") | |
1821 | .with_stdout( | |
1822 | "\ | |
1823 | foo v0.1.0 ([..]/foo) | |
1824 | [build-dependencies] | |
1825 | [dev-dependencies] | |
1826 | ", | |
1827 | ) | |
1828 | .run(); | |
1829 | ||
1830 | p.cargo("tree --depth 1") | |
1831 | .with_stdout( | |
1832 | "\ | |
1833 | foo v0.1.0 ([..]/foo) | |
1834 | ├── a v1.0.0 | |
1835 | └── c v1.0.0 | |
1836 | [build-dependencies] | |
1837 | └── bdep v1.0.0 | |
1838 | [dev-dependencies] | |
1839 | └── devdep v1.0.0 | |
1840 | ", | |
1841 | ) | |
1842 | .run(); | |
1843 | ||
1844 | p.cargo("tree --depth 2") | |
1845 | .with_stdout( | |
1846 | "\ | |
1847 | foo v0.1.0 ([..]/foo) | |
1848 | ├── a v1.0.0 | |
1849 | │ └── b v1.0.0 | |
1850 | └── c v1.0.0 | |
1851 | [build-dependencies] | |
1852 | └── bdep v1.0.0 | |
1853 | └── b v1.0.0 (*) | |
1854 | [dev-dependencies] | |
1855 | └── devdep v1.0.0 | |
1856 | └── b v1.0.0 (*) | |
1857 | ", | |
1858 | ) | |
1859 | .run(); | |
1860 | ||
1861 | // specify a package | |
1862 | p.cargo("tree -p bdep --depth 1") | |
1863 | .with_stdout( | |
1864 | "\ | |
1865 | bdep v1.0.0 | |
1866 | └── b v1.0.0 | |
1867 | ", | |
1868 | ) | |
1869 | .run(); | |
1870 | ||
1871 | // different prefix | |
1872 | p.cargo("tree --depth 1 --prefix depth") | |
1873 | .with_stdout( | |
1874 | "\ | |
1875 | 0foo v0.1.0 ([..]/foo) | |
1876 | 1a v1.0.0 | |
1877 | 1c v1.0.0 | |
1878 | 1bdep v1.0.0 | |
1879 | 1devdep v1.0.0 | |
1880 | ", | |
1881 | ) | |
1882 | .run(); | |
1883 | ||
1884 | // with edge-kinds | |
1885 | p.cargo("tree --depth 1 -e no-dev") | |
1886 | .with_stdout( | |
1887 | "\ | |
1888 | foo v0.1.0 ([..]/foo) | |
1889 | ├── a v1.0.0 | |
1890 | └── c v1.0.0 | |
1891 | [build-dependencies] | |
1892 | └── bdep v1.0.0 | |
1893 | ", | |
1894 | ) | |
1895 | .run(); | |
1896 | ||
1897 | // invert | |
1898 | p.cargo("tree --depth 1 --invert c") | |
1899 | .with_stdout( | |
1900 | "\ | |
1901 | c v1.0.0 | |
1902 | ├── b v1.0.0 | |
1903 | └── foo v0.1.0 ([..]/foo) | |
1904 | ", | |
1905 | ) | |
1906 | .run(); | |
1907 | } | |
1908 | ||
1909 | #[cargo_test] | |
1910 | fn prune() { | |
1911 | let p = make_simple_proj(); | |
1912 | ||
1913 | p.cargo("tree --prune c") | |
1914 | .with_stdout( | |
1915 | "\ | |
1916 | foo v0.1.0 ([..]/foo) | |
1917 | └── a v1.0.0 | |
1918 | └── b v1.0.0 | |
1919 | [build-dependencies] | |
1920 | └── bdep v1.0.0 | |
1921 | └── b v1.0.0 (*) | |
1922 | [dev-dependencies] | |
1923 | └── devdep v1.0.0 | |
1924 | └── b v1.0.0 (*) | |
1925 | ", | |
1926 | ) | |
1927 | .run(); | |
1928 | ||
1929 | // multiple prune | |
1930 | p.cargo("tree --prune c --prune bdep") | |
1931 | .with_stdout( | |
1932 | "\ | |
1933 | foo v0.1.0 ([..]/foo) | |
1934 | └── a v1.0.0 | |
1935 | └── b v1.0.0 | |
1936 | [build-dependencies] | |
1937 | [dev-dependencies] | |
1938 | └── devdep v1.0.0 | |
1939 | └── b v1.0.0 (*) | |
1940 | ", | |
1941 | ) | |
1942 | .run(); | |
1943 | ||
1944 | // with edge-kinds | |
1945 | p.cargo("tree --prune c -e normal") | |
1946 | .with_stdout( | |
1947 | "\ | |
1948 | foo v0.1.0 ([..]/foo) | |
1949 | └── a v1.0.0 | |
1950 | └── b v1.0.0 | |
1951 | ", | |
1952 | ) | |
1953 | .run(); | |
1954 | ||
1955 | // pruning self does not works | |
1956 | p.cargo("tree --prune foo") | |
1957 | .with_stdout( | |
1958 | "\ | |
1959 | foo v0.1.0 ([..]/foo) | |
1960 | ├── a v1.0.0 | |
1961 | │ └── b v1.0.0 | |
1962 | │ └── c v1.0.0 | |
1963 | └── c v1.0.0 | |
1964 | [build-dependencies] | |
1965 | └── bdep v1.0.0 | |
1966 | └── b v1.0.0 (*) | |
1967 | [dev-dependencies] | |
1968 | └── devdep v1.0.0 | |
1969 | └── b v1.0.0 (*) | |
1970 | ", | |
1971 | ) | |
1972 | .run(); | |
1973 | ||
1974 | // dep not exist | |
1975 | p.cargo("tree --prune no-dep") | |
1976 | .with_stderr( | |
1977 | "\ | |
1978 | [ERROR] package ID specification `no-dep` did not match any packages | |
1979 | ||
1980 | <tab>Did you mean `bdep`? | |
1981 | ", | |
1982 | ) | |
1983 | .with_status(101) | |
1984 | .run(); | |
1985 | } | |
1986 | ||
1987 | #[cargo_test] | |
1988 | fn cyclic_features() { | |
1989 | // Check for stack overflow with cyclic features (oops!). | |
1990 | let p = project() | |
1991 | .file( | |
1992 | "Cargo.toml", | |
1993 | r#" | |
1994 | [package] | |
1995 | name = "foo" | |
1996 | version = "1.0.0" | |
1997 | ||
1998 | [features] | |
1999 | a = ["b"] | |
2000 | b = ["a"] | |
2001 | default = ["a"] | |
2002 | "#, | |
2003 | ) | |
2004 | .file("src/lib.rs", "") | |
2005 | .build(); | |
2006 | ||
2007 | p.cargo("tree -e features") | |
2008 | .with_stdout("foo v1.0.0 ([ROOT]/foo)") | |
2009 | .run(); | |
2010 | ||
2011 | p.cargo("tree -e features -i foo") | |
2012 | .with_stdout( | |
2013 | "\ | |
2014 | foo v1.0.0 ([ROOT]/foo) | |
2015 | ├── foo feature \"a\" | |
2016 | │ ├── foo feature \"b\" | |
2017 | │ │ └── foo feature \"a\" (*) | |
2018 | │ └── foo feature \"default\" (command-line) | |
2019 | ├── foo feature \"b\" (*) | |
2020 | └── foo feature \"default\" (command-line) | |
2021 | ", | |
2022 | ) | |
2023 | .run(); | |
2024 | } | |
2025 | ||
2026 | #[cargo_test] | |
2027 | fn dev_dep_cycle_with_feature() { | |
2028 | // Cycle with features and a dev-dependency. | |
2029 | let p = project() | |
2030 | .file( | |
2031 | "Cargo.toml", | |
2032 | r#" | |
2033 | [package] | |
2034 | name = "foo" | |
2035 | version = "1.0.0" | |
2036 | ||
2037 | [dev-dependencies] | |
2038 | bar = { path = "bar" } | |
2039 | ||
2040 | [features] | |
2041 | a = ["bar/feat1"] | |
2042 | "#, | |
2043 | ) | |
2044 | .file("src/lib.rs", "") | |
2045 | .file( | |
2046 | "bar/Cargo.toml", | |
2047 | r#" | |
2048 | [package] | |
2049 | name = "bar" | |
2050 | version = "1.0.0" | |
2051 | ||
2052 | [dependencies] | |
2053 | foo = { path = ".." } | |
2054 | ||
2055 | [features] | |
2056 | feat1 = ["foo/a"] | |
2057 | "#, | |
2058 | ) | |
2059 | .file("bar/src/lib.rs", "") | |
2060 | .build(); | |
2061 | ||
2062 | p.cargo("tree -e features --features a") | |
2063 | .with_stdout( | |
2064 | "\ | |
2065 | foo v1.0.0 ([ROOT]/foo) | |
2066 | [dev-dependencies] | |
2067 | └── bar feature \"default\" | |
2068 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2069 | └── foo feature \"default\" (command-line) | |
2070 | └── foo v1.0.0 ([ROOT]/foo) (*) | |
2071 | ", | |
2072 | ) | |
2073 | .run(); | |
2074 | ||
2075 | p.cargo("tree -e features --features a -i foo") | |
2076 | .with_stdout( | |
2077 | "\ | |
2078 | foo v1.0.0 ([ROOT]/foo) | |
2079 | ├── foo feature \"a\" (command-line) | |
2080 | │ └── bar feature \"feat1\" | |
2081 | │ └── foo feature \"a\" (command-line) (*) | |
2082 | └── foo feature \"default\" (command-line) | |
2083 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2084 | ├── bar feature \"default\" | |
2085 | │ [dev-dependencies] | |
2086 | │ └── foo v1.0.0 ([ROOT]/foo) (*) | |
2087 | └── bar feature \"feat1\" (*) | |
2088 | ", | |
2089 | ) | |
2090 | .run(); | |
2091 | } | |
2092 | ||
2093 | #[cargo_test] | |
2094 | fn dev_dep_cycle_with_feature_nested() { | |
2095 | // Checks for an issue where a cyclic dev dependency tries to activate a | |
2096 | // feature on its parent that tries to activate the feature back on the | |
2097 | // dev-dependency. | |
2098 | let p = project() | |
2099 | .file( | |
2100 | "Cargo.toml", | |
2101 | r#" | |
2102 | [package] | |
2103 | name = "foo" | |
2104 | version = "1.0.0" | |
2105 | ||
2106 | [dev-dependencies] | |
2107 | bar = { path = "bar" } | |
2108 | ||
2109 | [features] | |
2110 | a = ["bar/feat1"] | |
2111 | b = ["a"] | |
2112 | "#, | |
2113 | ) | |
2114 | .file("src/lib.rs", "") | |
2115 | .file( | |
2116 | "bar/Cargo.toml", | |
2117 | r#" | |
2118 | [package] | |
2119 | name = "bar" | |
2120 | version = "1.0.0" | |
2121 | ||
2122 | [dependencies] | |
2123 | foo = { path = ".." } | |
2124 | ||
2125 | [features] | |
2126 | feat1 = ["foo/b"] | |
2127 | "#, | |
2128 | ) | |
2129 | .file("bar/src/lib.rs", "") | |
2130 | .build(); | |
2131 | ||
2132 | p.cargo("tree -e features") | |
2133 | .with_stdout( | |
2134 | "\ | |
2135 | foo v1.0.0 ([ROOT]/foo) | |
2136 | [dev-dependencies] | |
2137 | └── bar feature \"default\" | |
2138 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2139 | └── foo feature \"default\" (command-line) | |
2140 | └── foo v1.0.0 ([ROOT]/foo) (*) | |
2141 | ", | |
2142 | ) | |
2143 | .run(); | |
2144 | ||
2145 | p.cargo("tree -e features --features a -i foo") | |
2146 | .with_stdout( | |
2147 | "\ | |
2148 | foo v1.0.0 ([ROOT]/foo) | |
2149 | ├── foo feature \"a\" (command-line) | |
2150 | │ └── foo feature \"b\" | |
2151 | │ └── bar feature \"feat1\" | |
2152 | │ └── foo feature \"a\" (command-line) (*) | |
2153 | ├── foo feature \"b\" (*) | |
2154 | └── foo feature \"default\" (command-line) | |
2155 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2156 | ├── bar feature \"default\" | |
2157 | │ [dev-dependencies] | |
2158 | │ └── foo v1.0.0 ([ROOT]/foo) (*) | |
2159 | └── bar feature \"feat1\" (*) | |
2160 | ", | |
2161 | ) | |
2162 | .run(); | |
2163 | ||
2164 | p.cargo("tree -e features --features b -i foo") | |
2165 | .with_stdout( | |
2166 | "\ | |
2167 | foo v1.0.0 ([ROOT]/foo) | |
2168 | ├── foo feature \"a\" | |
2169 | │ └── foo feature \"b\" (command-line) | |
2170 | │ └── bar feature \"feat1\" | |
2171 | │ └── foo feature \"a\" (*) | |
2172 | ├── foo feature \"b\" (command-line) (*) | |
2173 | └── foo feature \"default\" (command-line) | |
2174 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2175 | ├── bar feature \"default\" | |
2176 | │ [dev-dependencies] | |
2177 | │ └── foo v1.0.0 ([ROOT]/foo) (*) | |
2178 | └── bar feature \"feat1\" (*) | |
2179 | ", | |
2180 | ) | |
2181 | .run(); | |
2182 | ||
2183 | p.cargo("tree -e features --features bar/feat1 -i foo") | |
2184 | .with_stdout( | |
2185 | "\ | |
2186 | foo v1.0.0 ([ROOT]/foo) | |
2187 | ├── foo feature \"a\" | |
2188 | │ └── foo feature \"b\" | |
2189 | │ └── bar feature \"feat1\" (command-line) | |
2190 | │ └── foo feature \"a\" (*) | |
2191 | ├── foo feature \"b\" (*) | |
2192 | └── foo feature \"default\" (command-line) | |
2193 | └── bar v1.0.0 ([ROOT]/foo/bar) | |
2194 | ├── bar feature \"default\" | |
2195 | │ [dev-dependencies] | |
2196 | │ └── foo v1.0.0 ([ROOT]/foo) (*) | |
2197 | └── bar feature \"feat1\" (command-line) (*) | |
2198 | ", | |
2199 | ) | |
2200 | .run(); | |
2201 | } |