]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/workspaces.rs
Document lib before bin.
[cargo.git] / tests / testsuite / workspaces.rs
CommitLineData
83571aee
EH
1//! Tests for workspaces.
2
9115b2c3 3use cargo_test_support::registry::Package;
4ae79d2f
EH
4use cargo_test_support::{basic_lib_manifest, basic_manifest, git, project, sleep_ms};
5use std::env;
6use std::fs;
58ddb28a 7
0e0d9688 8#[cargo_test]
58ddb28a 9fn simple_explicit() {
7fe2fbc8 10 let p = project()
1e682848
AC
11 .file(
12 "Cargo.toml",
13 r#"
6f8c7d5a
EH
14 [project]
15 name = "foo"
16 version = "0.1.0"
17 authors = []
58ddb28a 18
6f8c7d5a
EH
19 [workspace]
20 members = ["bar"]
21 "#,
fecb7246
AC
22 )
23 .file("src/main.rs", "fn main() {}")
1e682848
AC
24 .file(
25 "bar/Cargo.toml",
26 r#"
6f8c7d5a
EH
27 [project]
28 name = "bar"
29 version = "0.1.0"
30 authors = []
31 workspace = ".."
32 "#,
fecb7246
AC
33 )
34 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 35 let p = p.build();
58ddb28a 36
85984a87 37 p.cargo("build").run();
570fe892
DW
38 assert!(p.bin("foo").is_file());
39 assert!(!p.bin("bar").is_file());
58ddb28a 40
e7124ba2 41 p.cargo("build").cwd("bar").run();
570fe892
DW
42 assert!(p.bin("foo").is_file());
43 assert!(p.bin("bar").is_file());
58ddb28a 44
570fe892
DW
45 assert!(p.root().join("Cargo.lock").is_file());
46 assert!(!p.root().join("bar/Cargo.lock").is_file());
58ddb28a
AC
47}
48
0e0d9688 49#[cargo_test]
8d5e73c6 50fn simple_explicit_default_members() {
7fe2fbc8 51 let p = project()
1e682848
AC
52 .file(
53 "Cargo.toml",
54 r#"
6f8c7d5a
EH
55 [project]
56 name = "foo"
57 version = "0.1.0"
58 authors = []
8d5e73c6 59
6f8c7d5a
EH
60 [workspace]
61 members = ["bar"]
62 default-members = ["bar"]
63 "#,
fecb7246
AC
64 )
65 .file("src/main.rs", "fn main() {}")
1e682848
AC
66 .file(
67 "bar/Cargo.toml",
68 r#"
6f8c7d5a
EH
69 [project]
70 name = "bar"
71 version = "0.1.0"
72 authors = []
73 workspace = ".."
74 "#,
fecb7246
AC
75 )
76 .file("bar/src/main.rs", "fn main() {}");
8d5e73c6
SS
77 let p = p.build();
78
85984a87 79 p.cargo("build").run();
570fe892
DW
80 assert!(p.bin("bar").is_file());
81 assert!(!p.bin("foo").is_file());
8d5e73c6
SS
82}
83
53e84c57
WL
84#[cargo_test]
85fn non_virtual_default_members_build_other_member() {
86 let p = project()
87 .file(
88 "Cargo.toml",
89 r#"
6f8c7d5a
EH
90 [project]
91 name = "foo"
92 version = "0.1.0"
93 authors = []
53e84c57 94
6f8c7d5a
EH
95 [workspace]
96 members = [".", "bar", "baz"]
97 default-members = ["baz"]
98 "#,
53e84c57
WL
99 )
100 .file("src/main.rs", "fn main() {}")
101 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
102 .file("bar/src/lib.rs", "pub fn bar() {}")
103 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
104 .file("baz/src/lib.rs", "pub fn baz() {}")
105 .build();
106
107 p.cargo("build")
108 .with_stderr(
109 "[..] Compiling baz v0.1.0 ([..])\n\
110 [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n",
111 )
112 .run();
113
114 p.cargo("build --manifest-path bar/Cargo.toml")
115 .with_stderr(
116 "[..] Compiling bar v0.1.0 ([..])\n\
117 [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n",
118 )
119 .run();
120}
121
0e0d9688 122#[cargo_test]
58ddb28a 123fn inferred_root() {
7fe2fbc8 124 let p = project()
1e682848
AC
125 .file(
126 "Cargo.toml",
127 r#"
6f8c7d5a
EH
128 [project]
129 name = "foo"
130 version = "0.1.0"
131 authors = []
58ddb28a 132
6f8c7d5a
EH
133 [workspace]
134 members = ["bar"]
135 "#,
fecb7246
AC
136 )
137 .file("src/main.rs", "fn main() {}")
ab19c483 138 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a 139 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 140 let p = p.build();
58ddb28a 141
85984a87 142 p.cargo("build").run();
570fe892
DW
143 assert!(p.bin("foo").is_file());
144 assert!(!p.bin("bar").is_file());
58ddb28a 145
e7124ba2 146 p.cargo("build").cwd("bar").run();
570fe892
DW
147 assert!(p.bin("foo").is_file());
148 assert!(p.bin("bar").is_file());
58ddb28a 149
570fe892
DW
150 assert!(p.root().join("Cargo.lock").is_file());
151 assert!(!p.root().join("bar/Cargo.lock").is_file());
58ddb28a
AC
152}
153
0e0d9688 154#[cargo_test]
58ddb28a 155fn inferred_path_dep() {
7fe2fbc8 156 let p = project()
1e682848
AC
157 .file(
158 "Cargo.toml",
159 r#"
6f8c7d5a
EH
160 [project]
161 name = "foo"
162 version = "0.1.0"
163 authors = []
58ddb28a 164
6f8c7d5a
EH
165 [dependencies]
166 bar = { path = "bar" }
58ddb28a 167
6f8c7d5a
EH
168 [workspace]
169 "#,
fecb7246
AC
170 )
171 .file("src/main.rs", "fn main() {}")
ab19c483 172 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a
AC
173 .file("bar/src/main.rs", "fn main() {}")
174 .file("bar/src/lib.rs", "");
d43ee1dd 175 let p = p.build();
58ddb28a 176
85984a87 177 p.cargo("build").run();
570fe892
DW
178 assert!(p.bin("foo").is_file());
179 assert!(!p.bin("bar").is_file());
58ddb28a 180
e7124ba2 181 p.cargo("build").cwd("bar").run();
570fe892
DW
182 assert!(p.bin("foo").is_file());
183 assert!(p.bin("bar").is_file());
58ddb28a 184
570fe892
DW
185 assert!(p.root().join("Cargo.lock").is_file());
186 assert!(!p.root().join("bar/Cargo.lock").is_file());
58ddb28a
AC
187}
188
0e0d9688 189#[cargo_test]
58ddb28a 190fn transitive_path_dep() {
7fe2fbc8 191 let p = project()
1e682848
AC
192 .file(
193 "Cargo.toml",
194 r#"
6f8c7d5a
EH
195 [project]
196 name = "foo"
197 version = "0.1.0"
198 authors = []
58ddb28a 199
6f8c7d5a
EH
200 [dependencies]
201 bar = { path = "bar" }
58ddb28a 202
6f8c7d5a
EH
203 [workspace]
204 "#,
fecb7246
AC
205 )
206 .file("src/main.rs", "fn main() {}")
1e682848
AC
207 .file(
208 "bar/Cargo.toml",
209 r#"
6f8c7d5a
EH
210 [project]
211 name = "bar"
212 version = "0.1.0"
213 authors = []
58ddb28a 214
6f8c7d5a
EH
215 [dependencies]
216 baz = { path = "../baz" }
217 "#,
fecb7246
AC
218 )
219 .file("bar/src/main.rs", "fn main() {}")
58ddb28a 220 .file("bar/src/lib.rs", "")
ab19c483 221 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
58ddb28a
AC
222 .file("baz/src/main.rs", "fn main() {}")
223 .file("baz/src/lib.rs", "");
d43ee1dd 224 let p = p.build();
58ddb28a 225
85984a87 226 p.cargo("build").run();
570fe892
DW
227 assert!(p.bin("foo").is_file());
228 assert!(!p.bin("bar").is_file());
229 assert!(!p.bin("baz").is_file());
58ddb28a 230
e7124ba2 231 p.cargo("build").cwd("bar").run();
570fe892
DW
232 assert!(p.bin("foo").is_file());
233 assert!(p.bin("bar").is_file());
234 assert!(!p.bin("baz").is_file());
58ddb28a 235
e7124ba2 236 p.cargo("build").cwd("baz").run();
570fe892
DW
237 assert!(p.bin("foo").is_file());
238 assert!(p.bin("bar").is_file());
239 assert!(p.bin("baz").is_file());
58ddb28a 240
570fe892
DW
241 assert!(p.root().join("Cargo.lock").is_file());
242 assert!(!p.root().join("bar/Cargo.lock").is_file());
243 assert!(!p.root().join("baz/Cargo.lock").is_file());
58ddb28a
AC
244}
245
0e0d9688 246#[cargo_test]
58ddb28a 247fn parent_pointer_works() {
7fe2fbc8 248 let p = project()
1e682848
AC
249 .file(
250 "foo/Cargo.toml",
251 r#"
6f8c7d5a
EH
252 [project]
253 name = "foo"
254 version = "0.1.0"
255 authors = []
58ddb28a 256
6f8c7d5a
EH
257 [dependencies]
258 bar = { path = "../bar" }
58ddb28a 259
6f8c7d5a
EH
260 [workspace]
261 "#,
fecb7246
AC
262 )
263 .file("foo/src/main.rs", "fn main() {}")
1e682848
AC
264 .file(
265 "bar/Cargo.toml",
266 r#"
6f8c7d5a
EH
267 [project]
268 name = "bar"
269 version = "0.1.0"
270 authors = []
271 workspace = "../foo"
272 "#,
fecb7246
AC
273 )
274 .file("bar/src/main.rs", "fn main() {}")
58ddb28a 275 .file("bar/src/lib.rs", "");
d43ee1dd 276 let p = p.build();
58ddb28a 277
e7124ba2
EH
278 p.cargo("build").cwd("foo").run();
279 p.cargo("build").cwd("bar").run();
570fe892
DW
280 assert!(p.root().join("foo/Cargo.lock").is_file());
281 assert!(!p.root().join("bar/Cargo.lock").is_file());
58ddb28a
AC
282}
283
0e0d9688 284#[cargo_test]
58ddb28a 285fn same_names_in_workspace() {
7fe2fbc8 286 let p = project()
1e682848
AC
287 .file(
288 "Cargo.toml",
289 r#"
6f8c7d5a
EH
290 [project]
291 name = "foo"
292 version = "0.1.0"
293 authors = []
58ddb28a 294
6f8c7d5a
EH
295 [workspace]
296 members = ["bar"]
297 "#,
fecb7246
AC
298 )
299 .file("src/main.rs", "fn main() {}")
1e682848
AC
300 .file(
301 "bar/Cargo.toml",
302 r#"
6f8c7d5a
EH
303 [project]
304 name = "foo"
305 version = "0.1.0"
306 authors = []
307 workspace = ".."
308 "#,
fecb7246
AC
309 )
310 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 311 let p = p.build();
58ddb28a 312
85984a87
DW
313 p.cargo("build")
314 .with_status(101)
315 .with_stderr(
1e682848 316 "\
58ddb28a
AC
317error: two packages named `foo` in this workspace:
318- [..]Cargo.toml
319- [..]Cargo.toml
1e682848 320",
fecb7246
AC
321 )
322 .run();
58ddb28a
AC
323}
324
0e0d9688 325#[cargo_test]
58ddb28a 326fn parent_doesnt_point_to_child() {
7fe2fbc8 327 let p = project()
1e682848
AC
328 .file(
329 "Cargo.toml",
330 r#"
6f8c7d5a
EH
331 [project]
332 name = "foo"
333 version = "0.1.0"
334 authors = []
58ddb28a 335
6f8c7d5a
EH
336 [workspace]
337 "#,
fecb7246
AC
338 )
339 .file("src/main.rs", "fn main() {}")
ab19c483 340 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a 341 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 342 let p = p.build();
58ddb28a 343
85984a87 344 p.cargo("build")
e7124ba2 345 .cwd("bar")
85984a87
DW
346 .with_status(101)
347 .with_stderr(
1e682848 348 "\
58ddb28a
AC
349error: current package believes it's in a workspace when it's not:
350current: [..]Cargo.toml
351workspace: [..]Cargo.toml
352
353this may be fixable [..]
d7a92124 354[..]
1e682848 355",
fecb7246
AC
356 )
357 .run();
58ddb28a
AC
358}
359
0e0d9688 360#[cargo_test]
58ddb28a 361fn invalid_parent_pointer() {
7fe2fbc8 362 let p = project()
1e682848
AC
363 .file(
364 "Cargo.toml",
365 r#"
6f8c7d5a
EH
366 [project]
367 name = "foo"
368 version = "0.1.0"
369 authors = []
370 workspace = "foo"
371 "#,
fecb7246
AC
372 )
373 .file("src/main.rs", "fn main() {}");
d43ee1dd 374 let p = p.build();
58ddb28a 375
85984a87
DW
376 p.cargo("build")
377 .with_status(101)
378 .with_stderr(
1e682848 379 "\
58ddb28a
AC
380error: failed to read `[..]Cargo.toml`
381
382Caused by:
383 [..]
1e682848 384",
fecb7246
AC
385 )
386 .run();
58ddb28a
AC
387}
388
0e0d9688 389#[cargo_test]
58ddb28a 390fn invalid_members() {
7fe2fbc8 391 let p = project()
1e682848
AC
392 .file(
393 "Cargo.toml",
394 r#"
6f8c7d5a
EH
395 [project]
396 name = "foo"
397 version = "0.1.0"
398 authors = []
58ddb28a 399
6f8c7d5a
EH
400 [workspace]
401 members = ["foo"]
402 "#,
fecb7246
AC
403 )
404 .file("src/main.rs", "fn main() {}");
d43ee1dd 405 let p = p.build();
58ddb28a 406
85984a87
DW
407 p.cargo("build")
408 .with_status(101)
409 .with_stderr(
1e682848 410 "\
832fff8d
WL
411[ERROR] failed to load manifest for workspace member `[..]/foo`
412
413Caused by:
414 failed to read `[..]foo/foo/Cargo.toml`
58ddb28a
AC
415
416Caused by:
417 [..]
1e682848 418",
fecb7246
AC
419 )
420 .run();
58ddb28a
AC
421}
422
0e0d9688 423#[cargo_test]
58ddb28a 424fn bare_workspace_ok() {
7fe2fbc8 425 let p = project()
1e682848
AC
426 .file(
427 "Cargo.toml",
428 r#"
6f8c7d5a
EH
429 [project]
430 name = "foo"
431 version = "0.1.0"
432 authors = []
58ddb28a 433
6f8c7d5a
EH
434 [workspace]
435 "#,
fecb7246
AC
436 )
437 .file("src/main.rs", "fn main() {}");
d43ee1dd 438 let p = p.build();
58ddb28a 439
85984a87 440 p.cargo("build").run();
58ddb28a
AC
441}
442
0e0d9688 443#[cargo_test]
58ddb28a 444fn two_roots() {
7fe2fbc8 445 let p = project()
1e682848
AC
446 .file(
447 "Cargo.toml",
448 r#"
6f8c7d5a
EH
449 [project]
450 name = "foo"
451 version = "0.1.0"
452 authors = []
58ddb28a 453
6f8c7d5a
EH
454 [workspace]
455 members = ["bar"]
456 "#,
fecb7246
AC
457 )
458 .file("src/main.rs", "fn main() {}")
1e682848
AC
459 .file(
460 "bar/Cargo.toml",
461 r#"
6f8c7d5a
EH
462 [project]
463 name = "bar"
464 version = "0.1.0"
465 authors = []
58ddb28a 466
6f8c7d5a
EH
467 [workspace]
468 members = [".."]
469 "#,
fecb7246
AC
470 )
471 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 472 let p = p.build();
58ddb28a 473
85984a87
DW
474 p.cargo("build")
475 .with_status(101)
476 .with_stderr(
1e682848 477 "\
58ddb28a
AC
478error: multiple workspace roots found in the same workspace:
479 [..]
480 [..]
1e682848 481",
fecb7246
AC
482 )
483 .run();
58ddb28a
AC
484}
485
0e0d9688 486#[cargo_test]
58ddb28a 487fn workspace_isnt_root() {
7fe2fbc8 488 let p = project()
1e682848
AC
489 .file(
490 "Cargo.toml",
491 r#"
6f8c7d5a
EH
492 [project]
493 name = "foo"
494 version = "0.1.0"
495 authors = []
496 workspace = "bar"
497 "#,
fecb7246
AC
498 )
499 .file("src/main.rs", "fn main() {}")
ab19c483 500 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a 501 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 502 let p = p.build();
58ddb28a 503
85984a87
DW
504 p.cargo("build")
505 .with_status(101)
506 .with_stderr("error: root of a workspace inferred but wasn't a root: [..]")
507 .run();
58ddb28a
AC
508}
509
0e0d9688 510#[cargo_test]
58ddb28a 511fn dangling_member() {
7fe2fbc8 512 let p = project()
1e682848
AC
513 .file(
514 "Cargo.toml",
515 r#"
6f8c7d5a
EH
516 [project]
517 name = "foo"
518 version = "0.1.0"
519 authors = []
58ddb28a 520
6f8c7d5a
EH
521 [workspace]
522 members = ["bar"]
523 "#,
fecb7246
AC
524 )
525 .file("src/main.rs", "fn main() {}")
1e682848
AC
526 .file(
527 "bar/Cargo.toml",
528 r#"
6f8c7d5a
EH
529 [project]
530 name = "bar"
531 version = "0.1.0"
532 authors = []
533 workspace = "../baz"
534 "#,
fecb7246
AC
535 )
536 .file("bar/src/main.rs", "fn main() {}")
1e682848
AC
537 .file(
538 "baz/Cargo.toml",
539 r#"
6f8c7d5a
EH
540 [project]
541 name = "baz"
542 version = "0.1.0"
543 authors = []
544 workspace = "../baz"
545 "#,
fecb7246
AC
546 )
547 .file("baz/src/main.rs", "fn main() {}");
d43ee1dd 548 let p = p.build();
58ddb28a 549
85984a87
DW
550 p.cargo("build")
551 .with_status(101)
552 .with_stderr(
1e682848 553 "\
58ddb28a
AC
554error: package `[..]` is a member of the wrong workspace
555expected: [..]
556actual: [..]
1e682848 557",
fecb7246
AC
558 )
559 .run();
58ddb28a
AC
560}
561
0e0d9688 562#[cargo_test]
58ddb28a 563fn cycle() {
7fe2fbc8 564 let p = project()
1e682848
AC
565 .file(
566 "Cargo.toml",
567 r#"
6f8c7d5a
EH
568 [project]
569 name = "foo"
570 version = "0.1.0"
571 authors = []
572 workspace = "bar"
573 "#,
fecb7246
AC
574 )
575 .file("src/main.rs", "fn main() {}")
1e682848
AC
576 .file(
577 "bar/Cargo.toml",
578 r#"
6f8c7d5a
EH
579 [project]
580 name = "bar"
581 version = "0.1.0"
582 authors = []
583 workspace = ".."
584 "#,
fecb7246
AC
585 )
586 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 587 let p = p.build();
58ddb28a 588
f58d107e
EH
589 p.cargo("build")
590 .with_status(101)
591 .with_stderr(
592 "[ERROR] root of a workspace inferred but wasn't a root: [..]/foo/bar/Cargo.toml",
593 )
594 .run();
58ddb28a
AC
595}
596
0e0d9688 597#[cargo_test]
58ddb28a 598fn share_dependencies() {
7fe2fbc8 599 let p = project()
1e682848
AC
600 .file(
601 "Cargo.toml",
602 r#"
6f8c7d5a
EH
603 [project]
604 name = "foo"
605 version = "0.1.0"
606 authors = []
58ddb28a 607
6f8c7d5a
EH
608 [dependencies]
609 dep1 = "0.1"
58ddb28a 610
6f8c7d5a
EH
611 [workspace]
612 members = ["bar"]
613 "#,
fecb7246
AC
614 )
615 .file("src/main.rs", "fn main() {}")
1e682848
AC
616 .file(
617 "bar/Cargo.toml",
618 r#"
6f8c7d5a
EH
619 [project]
620 name = "bar"
621 version = "0.1.0"
622 authors = []
58ddb28a 623
6f8c7d5a
EH
624 [dependencies]
625 dep1 = "< 0.1.5"
626 "#,
fecb7246
AC
627 )
628 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 629 let p = p.build();
58ddb28a
AC
630
631 Package::new("dep1", "0.1.3").publish();
632 Package::new("dep1", "0.1.8").publish();
633
85984a87
DW
634 p.cargo("build")
635 .with_stderr(
1e682848 636 "\
41aa6fba 637[UPDATING] `[..]` index
e2637b65
AC
638[DOWNLOADING] crates ...
639[DOWNLOADED] dep1 v0.1.3 ([..])
8214bb95 640[COMPILING] dep1 v0.1.3
58ddb28a 641[COMPILING] foo v0.1.0 ([..])
34628b65 642[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 643",
fecb7246
AC
644 )
645 .run();
58ddb28a
AC
646}
647
0e0d9688 648#[cargo_test]
58ddb28a 649fn fetch_fetches_all() {
7fe2fbc8 650 let p = project()
1e682848
AC
651 .file(
652 "Cargo.toml",
653 r#"
6f8c7d5a
EH
654 [project]
655 name = "foo"
656 version = "0.1.0"
657 authors = []
58ddb28a 658
6f8c7d5a
EH
659 [workspace]
660 members = ["bar"]
661 "#,
fecb7246
AC
662 )
663 .file("src/main.rs", "fn main() {}")
1e682848
AC
664 .file(
665 "bar/Cargo.toml",
666 r#"
6f8c7d5a
EH
667 [project]
668 name = "bar"
669 version = "0.1.0"
670 authors = []
58ddb28a 671
6f8c7d5a
EH
672 [dependencies]
673 dep1 = "*"
674 "#,
fecb7246
AC
675 )
676 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 677 let p = p.build();
58ddb28a
AC
678
679 Package::new("dep1", "0.1.3").publish();
680
85984a87
DW
681 p.cargo("fetch")
682 .with_stderr(
1e682848 683 "\
41aa6fba 684[UPDATING] `[..]` index
e2637b65
AC
685[DOWNLOADING] crates ...
686[DOWNLOADED] dep1 v0.1.3 ([..])
1e682848 687",
fecb7246
AC
688 )
689 .run();
58ddb28a
AC
690}
691
0e0d9688 692#[cargo_test]
58ddb28a 693fn lock_works_for_everyone() {
7fe2fbc8 694 let p = project()
1e682848
AC
695 .file(
696 "Cargo.toml",
697 r#"
6f8c7d5a
EH
698 [project]
699 name = "foo"
700 version = "0.1.0"
701 authors = []
58ddb28a 702
6f8c7d5a
EH
703 [dependencies]
704 dep2 = "0.1"
58ddb28a 705
6f8c7d5a
EH
706 [workspace]
707 members = ["bar"]
708 "#,
fecb7246
AC
709 )
710 .file("src/main.rs", "fn main() {}")
1e682848
AC
711 .file(
712 "bar/Cargo.toml",
713 r#"
6f8c7d5a
EH
714 [project]
715 name = "bar"
716 version = "0.1.0"
717 authors = []
58ddb28a 718
6f8c7d5a
EH
719 [dependencies]
720 dep1 = "0.1"
721 "#,
fecb7246
AC
722 )
723 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 724 let p = p.build();
58ddb28a
AC
725
726 Package::new("dep1", "0.1.0").publish();
727 Package::new("dep2", "0.1.0").publish();
728
85984a87 729 p.cargo("generate-lockfile")
41aa6fba 730 .with_stderr("[UPDATING] `[..]` index")
85984a87 731 .run();
58ddb28a
AC
732
733 Package::new("dep1", "0.1.1").publish();
734 Package::new("dep2", "0.1.1").publish();
735
85984a87
DW
736 p.cargo("build")
737 .with_stderr(
1e682848 738 "\
e2637b65
AC
739[DOWNLOADING] crates ...
740[DOWNLOADED] dep2 v0.1.0 ([..])
8214bb95 741[COMPILING] dep2 v0.1.0
58ddb28a 742[COMPILING] foo v0.1.0 ([..])
34628b65 743[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 744",
fecb7246
AC
745 )
746 .run();
1e682848 747
85984a87 748 p.cargo("build")
e7124ba2 749 .cwd("bar")
85984a87 750 .with_stderr(
1e682848 751 "\
e2637b65
AC
752[DOWNLOADING] crates ...
753[DOWNLOADED] dep1 v0.1.0 ([..])
8214bb95 754[COMPILING] dep1 v0.1.0
58ddb28a 755[COMPILING] bar v0.1.0 ([..])
34628b65 756[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 757",
fecb7246
AC
758 )
759 .run();
58ddb28a
AC
760}
761
0e0d9688 762#[cargo_test]
58ddb28a 763fn virtual_works() {
7fe2fbc8 764 let p = project()
1e682848
AC
765 .file(
766 "Cargo.toml",
767 r#"
6f8c7d5a
EH
768 [workspace]
769 members = ["bar"]
770 "#,
fecb7246
AC
771 )
772 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a 773 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 774 let p = p.build();
e7124ba2 775 p.cargo("build").cwd("bar").run();
570fe892
DW
776 assert!(p.root().join("Cargo.lock").is_file());
777 assert!(p.bin("bar").is_file());
778 assert!(!p.root().join("bar/Cargo.lock").is_file());
58ddb28a
AC
779}
780
0e0d9688 781#[cargo_test]
23faf5c9 782fn explicit_package_argument_works_with_virtual_manifest() {
7fe2fbc8 783 let p = project()
1e682848
AC
784 .file(
785 "Cargo.toml",
786 r#"
6f8c7d5a
EH
787 [workspace]
788 members = ["bar"]
789 "#,
fecb7246
AC
790 )
791 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
23faf5c9 792 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 793 let p = p.build();
4415c728 794 p.cargo("build --package bar").run();
570fe892
DW
795 assert!(p.root().join("Cargo.lock").is_file());
796 assert!(p.bin("bar").is_file());
797 assert!(!p.root().join("bar/Cargo.lock").is_file());
23faf5c9
AK
798}
799
0e0d9688 800#[cargo_test]
58ddb28a 801fn virtual_misconfigure() {
7fe2fbc8 802 let p = project()
1e682848
AC
803 .file(
804 "Cargo.toml",
805 r#"
6f8c7d5a
EH
806 [workspace]
807 "#,
fecb7246
AC
808 )
809 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
58ddb28a 810 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 811 let p = p.build();
85984a87 812 p.cargo("build")
e7124ba2 813 .cwd("bar")
85984a87
DW
814 .with_status(101)
815 .with_stderr(
1e682848 816 "\
58ddb28a 817error: current package believes it's in a workspace when it's not:
89f43938 818current: [CWD]/Cargo.toml
58ddb28a
AC
819workspace: [..]Cargo.toml
820
821this may be fixable by adding `bar` to the `workspace.members` array of the \
822manifest located at: [..]
d7a92124 823[..]
1e682848 824",
fecb7246
AC
825 )
826 .run();
58ddb28a
AC
827}
828
0e0d9688 829#[cargo_test]
15791c74 830fn virtual_build_all_implied() {
7fe2fbc8 831 let p = project()
1e682848
AC
832 .file(
833 "Cargo.toml",
834 r#"
6f8c7d5a
EH
835 [workspace]
836 members = ["bar"]
837 "#,
fecb7246
AC
838 )
839 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
25518da7 840 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 841 let p = p.build();
85984a87 842 p.cargo("build").run();
25518da7
AR
843}
844
0e0d9688 845#[cargo_test]
ba7911dd 846fn virtual_default_members() {
7fe2fbc8 847 let p = project()
1e682848
AC
848 .file(
849 "Cargo.toml",
850 r#"
6f8c7d5a
EH
851 [workspace]
852 members = ["bar", "baz"]
853 default-members = ["bar"]
854 "#,
fecb7246
AC
855 )
856 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
ab19c483 857 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
ba7911dd
SS
858 .file("bar/src/main.rs", "fn main() {}")
859 .file("baz/src/main.rs", "fn main() {}");
860 let p = p.build();
85984a87 861 p.cargo("build").run();
570fe892
DW
862 assert!(p.bin("bar").is_file());
863 assert!(!p.bin("baz").is_file());
ba7911dd
SS
864}
865
0e0d9688 866#[cargo_test]
ba7911dd 867fn virtual_default_member_is_not_a_member() {
7fe2fbc8 868 let p = project()
1e682848
AC
869 .file(
870 "Cargo.toml",
871 r#"
6f8c7d5a
EH
872 [workspace]
873 members = ["bar"]
874 default-members = ["something-else"]
875 "#,
fecb7246
AC
876 )
877 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
ba7911dd
SS
878 .file("bar/src/main.rs", "fn main() {}");
879 let p = p.build();
85984a87
DW
880 p.cargo("build")
881 .with_status(101)
882 .with_stderr(
1e682848 883 "\
ba7911dd
SS
884error: package `[..]something-else` is listed in workspace’s default-members \
885but is not a member.
1e682848 886",
fecb7246
AC
887 )
888 .run();
ba7911dd
SS
889}
890
53e84c57
WL
891#[cargo_test]
892fn virtual_default_members_build_other_member() {
893 let p = project()
894 .file(
895 "Cargo.toml",
896 r#"
6f8c7d5a
EH
897 [workspace]
898 members = ["bar", "baz"]
899 default-members = ["baz"]
900 "#,
53e84c57
WL
901 )
902 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
903 .file("bar/src/lib.rs", "pub fn bar() {}")
904 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
905 .file("baz/src/lib.rs", "pub fn baz() {}")
906 .build();
907
908 p.cargo("build --manifest-path bar/Cargo.toml")
909 .with_stderr(
910 "[..] Compiling bar v0.1.0 ([..])\n\
911 [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n",
912 )
913 .run();
914}
915
0e0d9688 916#[cargo_test]
25518da7 917fn virtual_build_no_members() {
7fe2fbc8 918 let p = project().file(
1e682848
AC
919 "Cargo.toml",
920 r#"
58ddb28a 921 [workspace]
1e682848
AC
922 "#,
923 );
d43ee1dd 924 let p = p.build();
85984a87
DW
925 p.cargo("build")
926 .with_status(101)
927 .with_stderr(
1e682848 928 "\
56274af0
RJ
929error: manifest path `[..]` contains no package: The manifest is virtual, \
930and the workspace has no members.
1e682848 931",
fecb7246
AC
932 )
933 .run();
58ddb28a
AC
934}
935
0e0d9688 936#[cargo_test]
58ddb28a 937fn include_virtual() {
7fe2fbc8 938 let p = project()
1e682848
AC
939 .file(
940 "Cargo.toml",
941 r#"
6f8c7d5a
EH
942 [project]
943 name = "bar"
944 version = "0.1.0"
945 authors = []
946 [workspace]
947 members = ["bar"]
948 "#,
fecb7246
AC
949 )
950 .file("src/main.rs", "")
1e682848
AC
951 .file(
952 "bar/Cargo.toml",
953 r#"
6f8c7d5a
EH
954 [workspace]
955 "#,
1e682848 956 );
d43ee1dd 957 let p = p.build();
85984a87
DW
958 p.cargo("build")
959 .with_status(101)
960 .with_stderr(
1e682848 961 "\
58ddb28a
AC
962error: multiple workspace roots found in the same workspace:
963 [..]
964 [..]
1e682848 965",
fecb7246
AC
966 )
967 .run();
58ddb28a
AC
968}
969
0e0d9688 970#[cargo_test]
58ddb28a 971fn members_include_path_deps() {
7fe2fbc8 972 let p = project()
1e682848
AC
973 .file(
974 "Cargo.toml",
975 r#"
6f8c7d5a
EH
976 [project]
977 name = "foo"
978 version = "0.1.0"
979 authors = []
58ddb28a 980
6f8c7d5a
EH
981 [workspace]
982 members = ["p1"]
58ddb28a 983
6f8c7d5a
EH
984 [dependencies]
985 p3 = { path = "p3" }
986 "#,
fecb7246
AC
987 )
988 .file("src/lib.rs", "")
1e682848
AC
989 .file(
990 "p1/Cargo.toml",
991 r#"
6f8c7d5a
EH
992 [project]
993 name = "p1"
994 version = "0.1.0"
995 authors = []
58ddb28a 996
6f8c7d5a
EH
997 [dependencies]
998 p2 = { path = "../p2" }
999 "#,
fecb7246
AC
1000 )
1001 .file("p1/src/lib.rs", "")
ab19c483 1002 .file("p2/Cargo.toml", &basic_manifest("p2", "0.1.0"))
58ddb28a 1003 .file("p2/src/lib.rs", "")
ab19c483 1004 .file("p3/Cargo.toml", &basic_manifest("p3", "0.1.0"))
58ddb28a 1005 .file("p3/src/lib.rs", "");
d43ee1dd 1006 let p = p.build();
58ddb28a 1007
e7124ba2
EH
1008 p.cargo("build").cwd("p1").run();
1009 p.cargo("build").cwd("p2").run();
1010 p.cargo("build").cwd("p3").run();
85984a87 1011 p.cargo("build").run();
58ddb28a 1012
6fd1b54c
DW
1013 assert!(p.root().join("target").is_dir());
1014 assert!(!p.root().join("p1/target").is_dir());
1015 assert!(!p.root().join("p2/target").is_dir());
1016 assert!(!p.root().join("p3/target").is_dir());
58ddb28a
AC
1017}
1018
0e0d9688 1019#[cargo_test]
58ddb28a 1020fn new_warns_you_this_will_not_work() {
7fe2fbc8 1021 let p = project()
1e682848
AC
1022 .file(
1023 "Cargo.toml",
1024 r#"
6f8c7d5a
EH
1025 [project]
1026 name = "foo"
1027 version = "0.1.0"
1028 authors = []
58ddb28a 1029
6f8c7d5a
EH
1030 [workspace]
1031 "#,
fecb7246
AC
1032 )
1033 .file("src/lib.rs", "");
d43ee1dd 1034 let p = p.build();
58ddb28a 1035
85984a87 1036 p.cargo("new --lib bar")
85984a87 1037 .with_stderr(
1e682848 1038 "\
fdb8ea1e 1039warning: compiling this new package may not work due to invalid workspace configuration
58ddb28a
AC
1040
1041current package believes it's in a workspace when it's not:
1042current: [..]
1043workspace: [..]
1044
1045this may be fixable by ensuring that this crate is depended on by the workspace \
1046root: [..]
d7a92124 1047[..]
3492a390 1048[CREATED] library `bar` package
1e682848 1049",
fecb7246
AC
1050 )
1051 .run();
58ddb28a 1052}
c33dddd5 1053
0e0d9688 1054#[cargo_test]
3c062627
EH
1055fn new_warning_with_corrupt_ws() {
1056 let p = project().file("Cargo.toml", "asdf").build();
1057 p.cargo("new bar")
1058 .with_stderr(
1059 "\
fdb8ea1e 1060[WARNING] compiling this new package may not work due to invalid workspace configuration
3c062627
EH
1061
1062failed to parse manifest at `[..]foo/Cargo.toml`
d7d8ca1e 1063
3c062627 1064Caused by:
b64d0f36
EH
1065 could not parse input as TOML
1066
1067Caused by:
1068 expected an equals, found eof at line 1 column 5
3c062627
EH
1069 Created binary (application) `bar` package
1070",
1071 )
1072 .run();
1073}
1074
0e0d9688 1075#[cargo_test]
c33dddd5 1076fn lock_doesnt_change_depending_on_crate() {
7fe2fbc8 1077 let p = project()
1e682848
AC
1078 .file(
1079 "Cargo.toml",
1080 r#"
6f8c7d5a
EH
1081 [project]
1082 name = "foo"
1083 version = "0.1.0"
1084 authors = []
c33dddd5 1085
6f8c7d5a
EH
1086 [workspace]
1087 members = ['baz']
c33dddd5 1088
6f8c7d5a
EH
1089 [dependencies]
1090 foo = "*"
1091 "#,
fecb7246
AC
1092 )
1093 .file("src/lib.rs", "")
1e682848
AC
1094 .file(
1095 "baz/Cargo.toml",
1096 r#"
6f8c7d5a
EH
1097 [project]
1098 name = "baz"
1099 version = "0.1.0"
1100 authors = []
c33dddd5 1101
6f8c7d5a
EH
1102 [dependencies]
1103 bar = "*"
1104 "#,
fecb7246
AC
1105 )
1106 .file("baz/src/lib.rs", "");
d43ee1dd 1107 let p = p.build();
c33dddd5
AC
1108
1109 Package::new("foo", "1.0.0").publish();
1110 Package::new("bar", "1.0.0").publish();
1111
85984a87 1112 p.cargo("build").run();
c33dddd5 1113
4ae79d2f 1114 let lockfile = p.read_lockfile();
c33dddd5 1115
e7124ba2 1116 p.cargo("build").cwd("baz").run();
c33dddd5 1117
4ae79d2f 1118 let lockfile2 = p.read_lockfile();
c33dddd5
AC
1119
1120 assert_eq!(lockfile, lockfile2);
1121}
0863469c 1122
0e0d9688 1123#[cargo_test]
0863469c 1124fn rebuild_please() {
7fe2fbc8 1125 let p = project()
1e682848
AC
1126 .file(
1127 "Cargo.toml",
1128 r#"
6f8c7d5a
EH
1129 [workspace]
1130 members = ['lib', 'bin']
1131 "#,
fecb7246
AC
1132 )
1133 .file("lib/Cargo.toml", &basic_manifest("lib", "0.1.0"))
1e682848
AC
1134 .file(
1135 "lib/src/lib.rs",
1136 r#"
6f8c7d5a
EH
1137 pub fn foo() -> u32 { 0 }
1138 "#,
fecb7246
AC
1139 )
1140 .file(
1e682848
AC
1141 "bin/Cargo.toml",
1142 r#"
6f8c7d5a
EH
1143 [package]
1144 name = "bin"
1145 version = "0.1.0"
0863469c 1146
6f8c7d5a
EH
1147 [dependencies]
1148 lib = { path = "../lib" }
1149 "#,
fecb7246
AC
1150 )
1151 .file(
1e682848
AC
1152 "bin/src/main.rs",
1153 r#"
6f8c7d5a 1154 extern crate lib;
0863469c 1155
6f8c7d5a
EH
1156 fn main() {
1157 assert_eq!(lib::foo(), 0);
1158 }
1159 "#,
1e682848 1160 );
d43ee1dd 1161 let p = p.build();
0863469c 1162
e7124ba2 1163 p.cargo("run").cwd("bin").run();
0863469c 1164
0f973c2f
AC
1165 sleep_ms(1000);
1166
4ae79d2f 1167 p.change_file("lib/src/lib.rs", "pub fn foo() -> u32 { 1 }");
1e682848 1168
e7124ba2 1169 p.cargo("build").cwd("lib").run();
1e682848 1170
85984a87 1171 p.cargo("run")
e7124ba2 1172 .cwd("bin")
85984a87 1173 .with_status(101)
f58d107e 1174 .with_stderr_contains("[..]assertion[..]")
85984a87 1175 .run();
0863469c 1176}
9243f06d 1177
0e0d9688 1178#[cargo_test]
9243f06d
AC
1179fn workspace_in_git() {
1180 let git_project = git::new("dep1", |project| {
1181 project
1e682848
AC
1182 .file(
1183 "Cargo.toml",
1184 r#"
6f8c7d5a
EH
1185 [workspace]
1186 members = ["foo"]
1187 "#,
fecb7246
AC
1188 )
1189 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
9243f06d 1190 .file("foo/src/lib.rs", "")
3c20a243 1191 });
7fe2fbc8 1192 let p = project()
1e682848
AC
1193 .file(
1194 "Cargo.toml",
1195 &format!(
1196 r#"
6f8c7d5a
EH
1197 [package]
1198 name = "lib"
1199 version = "0.1.0"
9243f06d 1200
6f8c7d5a
EH
1201 [dependencies.foo]
1202 git = '{}'
1203 "#,
1e682848
AC
1204 git_project.url()
1205 ),
fecb7246
AC
1206 )
1207 .file(
1e682848
AC
1208 "src/lib.rs",
1209 r#"
6f8c7d5a
EH
1210 pub fn foo() -> u32 { 0 }
1211 "#,
1e682848 1212 );
d43ee1dd 1213 let p = p.build();
9243f06d 1214
85984a87 1215 p.cargo("build").run();
9243f06d 1216}
ab3a1c53 1217
0e0d9688 1218#[cargo_test]
ab3a1c53 1219fn lockfile_can_specify_nonexistant_members() {
7fe2fbc8 1220 let p = project()
1e682848
AC
1221 .file(
1222 "Cargo.toml",
1223 r#"
6f8c7d5a
EH
1224 [workspace]
1225 members = ["a"]
1226 "#,
fecb7246
AC
1227 )
1228 .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
ab3a1c53 1229 .file("a/src/main.rs", "fn main() {}")
1e682848
AC
1230 .file(
1231 "Cargo.lock",
1232 r#"
6f8c7d5a
EH
1233 [[package]]
1234 name = "a"
1235 version = "0.1.0"
ab3a1c53 1236
6f8c7d5a
EH
1237 [[package]]
1238 name = "b"
1239 version = "0.1.0"
1240 "#,
1e682848 1241 );
ab3a1c53 1242
d43ee1dd 1243 let p = p.build();
ab3a1c53 1244
e7124ba2 1245 p.cargo("build").cwd("a").run();
ab3a1c53 1246}
015e7972 1247
0e0d9688 1248#[cargo_test]
015e7972 1249fn you_cannot_generate_lockfile_for_empty_workspaces() {
7fe2fbc8 1250 let p = project()
1e682848
AC
1251 .file(
1252 "Cargo.toml",
1253 r#"
6f8c7d5a
EH
1254 [workspace]
1255 "#,
fecb7246
AC
1256 )
1257 .file("bar/Cargo.toml", &basic_manifest("foo", "0.1.0"))
015e7972 1258 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 1259 let p = p.build();
015e7972 1260
85984a87
DW
1261 p.cargo("update")
1262 .with_status(101)
1263 .with_stderr("error: you can't generate a lockfile for an empty workspace.")
1264 .run();
015e7972 1265}
bb058d9c 1266
0e0d9688 1267#[cargo_test]
bb058d9c 1268fn workspace_with_transitive_dev_deps() {
7fe2fbc8 1269 let p = project()
1e682848
AC
1270 .file(
1271 "Cargo.toml",
1272 r#"
6f8c7d5a
EH
1273 [project]
1274 name = "foo"
1275 version = "0.5.0"
1276 authors = ["mbrubeck@example.com"]
bb058d9c 1277
6f8c7d5a
EH
1278 [dependencies.bar]
1279 path = "bar"
bb058d9c 1280
6f8c7d5a
EH
1281 [workspace]
1282 "#,
fecb7246
AC
1283 )
1284 .file("src/main.rs", r#"fn main() {}"#)
1e682848
AC
1285 .file(
1286 "bar/Cargo.toml",
1287 r#"
6f8c7d5a
EH
1288 [project]
1289 name = "bar"
1290 version = "0.5.0"
1291 authors = ["mbrubeck@example.com"]
bb058d9c 1292
6f8c7d5a
EH
1293 [dev-dependencies.baz]
1294 path = "../baz"
1295 "#,
fecb7246
AC
1296 )
1297 .file(
1e682848
AC
1298 "bar/src/lib.rs",
1299 r#"
6f8c7d5a 1300 pub fn init() {}
bb058d9c 1301
6f8c7d5a 1302 #[cfg(test)]
bb058d9c 1303
6f8c7d5a
EH
1304 #[test]
1305 fn test() {
1306 extern crate baz;
1307 baz::do_stuff();
1308 }
1309 "#,
fecb7246
AC
1310 )
1311 .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0"))
bb058d9c 1312 .file("baz/src/lib.rs", r#"pub fn do_stuff() {}"#);
d43ee1dd 1313 let p = p.build();
bb058d9c 1314
85984a87 1315 p.cargo("test -p bar").run();
bb058d9c 1316}
6d704921 1317
0e0d9688 1318#[cargo_test]
6d704921 1319fn error_if_parent_cargo_toml_is_invalid() {
7fe2fbc8 1320 let p = project()
6d704921 1321 .file("Cargo.toml", "Totally not a TOML file")
ab19c483 1322 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
6d704921 1323 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 1324 let p = p.build();
6d704921 1325
85984a87 1326 p.cargo("build")
e7124ba2 1327 .cwd("bar")
85984a87
DW
1328 .with_status(101)
1329 .with_stderr_contains("[ERROR] failed to parse manifest at `[..]`")
1330 .run();
6d704921 1331}
083da141 1332
0e0d9688 1333#[cargo_test]
083da141 1334fn relative_path_for_member_works() {
7fe2fbc8 1335 let p = project()
1e682848
AC
1336 .file(
1337 "foo/Cargo.toml",
1338 r#"
6f8c7d5a
EH
1339 [project]
1340 name = "foo"
1341 version = "0.1.0"
1342 authors = []
083da141 1343
6f8c7d5a
EH
1344 [workspace]
1345 members = ["../bar"]
1346 "#,
fecb7246
AC
1347 )
1348 .file("foo/src/main.rs", "fn main() {}")
1e682848
AC
1349 .file(
1350 "bar/Cargo.toml",
1351 r#"
6f8c7d5a
EH
1352 [project]
1353 name = "bar"
1354 version = "0.1.0"
1355 authors = []
1356 workspace = "../foo"
1357 "#,
fecb7246
AC
1358 )
1359 .file("bar/src/main.rs", "fn main() {}");
d43ee1dd 1360 let p = p.build();
083da141 1361
e7124ba2
EH
1362 p.cargo("build").cwd("foo").run();
1363 p.cargo("build").cwd("bar").run();
07c667fb
AK
1364}
1365
0e0d9688 1366#[cargo_test]
0a3db8b7 1367fn relative_path_for_root_works() {
7fe2fbc8 1368 let p = project()
1e682848
AC
1369 .file(
1370 "Cargo.toml",
1371 r#"
6f8c7d5a
EH
1372 [project]
1373 name = "foo"
1374 version = "0.1.0"
1375 authors = []
0a3db8b7 1376
6f8c7d5a 1377 [workspace]
0a3db8b7 1378
6f8c7d5a
EH
1379 [dependencies]
1380 subproj = { path = "./subproj" }
1381 "#,
fecb7246
AC
1382 )
1383 .file("src/main.rs", "fn main() {}")
ab19c483 1384 .file("subproj/Cargo.toml", &basic_manifest("subproj", "0.1.0"))
0a3db8b7 1385 .file("subproj/src/main.rs", "fn main() {}");
d43ee1dd 1386 let p = p.build();
0a3db8b7 1387
fecb7246 1388 p.cargo("build --manifest-path ./Cargo.toml").run();
1e682848 1389
85984a87 1390 p.cargo("build --manifest-path ../Cargo.toml")
e7124ba2 1391 .cwd("subproj")
85984a87 1392 .run();
0a3db8b7
AK
1393}
1394
0e0d9688 1395#[cargo_test]
07c667fb 1396fn path_dep_outside_workspace_is_not_member() {
7fe2fbc8 1397 let p = project()
252f6e8e 1398 .no_manifest()
1e682848
AC
1399 .file(
1400 "ws/Cargo.toml",
1401 r#"
6f8c7d5a
EH
1402 [project]
1403 name = "ws"
1404 version = "0.1.0"
1405 authors = []
07c667fb 1406
6f8c7d5a
EH
1407 [dependencies]
1408 foo = { path = "../foo" }
07c667fb 1409
6f8c7d5a
EH
1410 [workspace]
1411 "#,
fecb7246 1412 )
6f8c7d5a 1413 .file("ws/src/lib.rs", "extern crate foo;")
ab19c483 1414 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
07c667fb 1415 .file("foo/src/lib.rs", "");
d43ee1dd 1416 let p = p.build();
07c667fb 1417
e7124ba2 1418 p.cargo("build").cwd("ws").run();
7429347e
AK
1419}
1420
0e0d9688 1421#[cargo_test]
7429347e 1422fn test_in_and_out_of_workspace() {
7fe2fbc8 1423 let p = project()
252f6e8e 1424 .no_manifest()
1e682848
AC
1425 .file(
1426 "ws/Cargo.toml",
1427 r#"
6f8c7d5a
EH
1428 [project]
1429 name = "ws"
1430 version = "0.1.0"
1431 authors = []
7429347e 1432
6f8c7d5a
EH
1433 [dependencies]
1434 foo = { path = "../foo" }
7429347e 1435
6f8c7d5a
EH
1436 [workspace]
1437 members = [ "../bar" ]
1438 "#,
fecb7246 1439 )
6f8c7d5a 1440 .file("ws/src/lib.rs", "extern crate foo; pub fn f() { foo::f() }")
fecb7246 1441 .file(
1e682848
AC
1442 "foo/Cargo.toml",
1443 r#"
6f8c7d5a
EH
1444 [project]
1445 name = "foo"
1446 version = "0.1.0"
1447 authors = []
7429347e 1448
6f8c7d5a
EH
1449 [dependencies]
1450 bar = { path = "../bar" }
1451 "#,
fecb7246
AC
1452 )
1453 .file(
85984a87
DW
1454 "foo/src/lib.rs",
1455 "extern crate bar; pub fn f() { bar::f() }",
fecb7246
AC
1456 )
1457 .file(
1e682848
AC
1458 "bar/Cargo.toml",
1459 r#"
6f8c7d5a
EH
1460 [project]
1461 workspace = "../ws"
1462 name = "bar"
1463 version = "0.1.0"
1464 authors = []
1465 "#,
fecb7246
AC
1466 )
1467 .file("bar/src/lib.rs", "pub fn f() { }");
d43ee1dd 1468 let p = p.build();
7429347e 1469
e7124ba2 1470 p.cargo("build").cwd("ws").run();
7429347e 1471
570fe892 1472 assert!(p.root().join("ws/Cargo.lock").is_file());
6fd1b54c 1473 assert!(p.root().join("ws/target").is_dir());
570fe892 1474 assert!(!p.root().join("foo/Cargo.lock").is_file());
6fd1b54c 1475 assert!(!p.root().join("foo/target").is_dir());
570fe892 1476 assert!(!p.root().join("bar/Cargo.lock").is_file());
6fd1b54c 1477 assert!(!p.root().join("bar/target").is_dir());
7429347e 1478
e7124ba2 1479 p.cargo("build").cwd("foo").run();
570fe892 1480 assert!(p.root().join("foo/Cargo.lock").is_file());
6fd1b54c 1481 assert!(p.root().join("foo/target").is_dir());
570fe892 1482 assert!(!p.root().join("bar/Cargo.lock").is_file());
6fd1b54c 1483 assert!(!p.root().join("bar/target").is_dir());
7429347e
AK
1484}
1485
0e0d9688 1486#[cargo_test]
7429347e 1487fn test_path_dependency_under_member() {
7fe2fbc8 1488 let p = project()
1e682848
AC
1489 .file(
1490 "ws/Cargo.toml",
1491 r#"
6f8c7d5a
EH
1492 [project]
1493 name = "ws"
1494 version = "0.1.0"
1495 authors = []
7429347e 1496
6f8c7d5a
EH
1497 [dependencies]
1498 foo = { path = "../foo" }
7429347e 1499
6f8c7d5a
EH
1500 [workspace]
1501 "#,
fecb7246 1502 )
6f8c7d5a 1503 .file("ws/src/lib.rs", "extern crate foo; pub fn f() { foo::f() }")
fecb7246 1504 .file(
1e682848
AC
1505 "foo/Cargo.toml",
1506 r#"
6f8c7d5a
EH
1507 [project]
1508 workspace = "../ws"
1509 name = "foo"
1510 version = "0.1.0"
1511 authors = []
7429347e 1512
6f8c7d5a
EH
1513 [dependencies]
1514 bar = { path = "./bar" }
1515 "#,
fecb7246
AC
1516 )
1517 .file(
85984a87
DW
1518 "foo/src/lib.rs",
1519 "extern crate bar; pub fn f() { bar::f() }",
fecb7246
AC
1520 )
1521 .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
7429347e 1522 .file("foo/bar/src/lib.rs", "pub fn f() { }");
d43ee1dd 1523 let p = p.build();
7429347e 1524
e7124ba2 1525 p.cargo("build").cwd("ws").run();
7429347e 1526
570fe892 1527 assert!(!p.root().join("foo/bar/Cargo.lock").is_file());
6fd1b54c 1528 assert!(!p.root().join("foo/bar/target").is_dir());
7429347e 1529
e7124ba2 1530 p.cargo("build").cwd("foo/bar").run();
3435414e 1531
570fe892 1532 assert!(!p.root().join("foo/bar/Cargo.lock").is_file());
6fd1b54c 1533 assert!(!p.root().join("foo/bar/target").is_dir());
7429347e 1534}
67364baa 1535
0e0d9688 1536#[cargo_test]
67364baa 1537fn excluded_simple() {
7fe2fbc8 1538 let p = project()
1e682848
AC
1539 .file(
1540 "Cargo.toml",
1541 r#"
6f8c7d5a
EH
1542 [project]
1543 name = "ws"
1544 version = "0.1.0"
1545 authors = []
67364baa 1546
6f8c7d5a
EH
1547 [workspace]
1548 exclude = ["foo"]
1549 "#,
fecb7246
AC
1550 )
1551 .file("src/lib.rs", "")
ab19c483 1552 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
67364baa 1553 .file("foo/src/lib.rs", "");
d43ee1dd 1554 let p = p.build();
67364baa 1555
85984a87 1556 p.cargo("build").run();
6fd1b54c 1557 assert!(p.root().join("target").is_dir());
e7124ba2 1558 p.cargo("build").cwd("foo").run();
6fd1b54c 1559 assert!(p.root().join("foo/target").is_dir());
67364baa
AC
1560}
1561
0e0d9688 1562#[cargo_test]
67364baa 1563fn exclude_members_preferred() {
7fe2fbc8 1564 let p = project()
1e682848
AC
1565 .file(
1566 "Cargo.toml",
1567 r#"
6f8c7d5a
EH
1568 [project]
1569 name = "ws"
1570 version = "0.1.0"
1571 authors = []
67364baa 1572
6f8c7d5a
EH
1573 [workspace]
1574 members = ["foo/bar"]
1575 exclude = ["foo"]
1576 "#,
fecb7246
AC
1577 )
1578 .file("src/lib.rs", "")
ab19c483 1579 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
67364baa 1580 .file("foo/src/lib.rs", "")
ab19c483 1581 .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
67364baa 1582 .file("foo/bar/src/lib.rs", "");
d43ee1dd 1583 let p = p.build();
67364baa 1584
85984a87 1585 p.cargo("build").run();
6fd1b54c 1586 assert!(p.root().join("target").is_dir());
e7124ba2 1587 p.cargo("build").cwd("foo").run();
6fd1b54c 1588 assert!(p.root().join("foo/target").is_dir());
e7124ba2 1589 p.cargo("build").cwd("foo/bar").run();
6fd1b54c 1590 assert!(!p.root().join("foo/bar/target").is_dir());
67364baa
AC
1591}
1592
0e0d9688 1593#[cargo_test]
67364baa 1594fn exclude_but_also_depend() {
7fe2fbc8 1595 let p = project()
1e682848
AC
1596 .file(
1597 "Cargo.toml",
1598 r#"
6f8c7d5a
EH
1599 [project]
1600 name = "ws"
1601 version = "0.1.0"
1602 authors = []
67364baa 1603
6f8c7d5a
EH
1604 [dependencies]
1605 bar = { path = "foo/bar" }
67364baa 1606
6f8c7d5a
EH
1607 [workspace]
1608 exclude = ["foo"]
1609 "#,
fecb7246
AC
1610 )
1611 .file("src/lib.rs", "")
ab19c483 1612 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
67364baa 1613 .file("foo/src/lib.rs", "")
ab19c483 1614 .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
67364baa 1615 .file("foo/bar/src/lib.rs", "");
d43ee1dd 1616 let p = p.build();
67364baa 1617
85984a87 1618 p.cargo("build").run();
6fd1b54c 1619 assert!(p.root().join("target").is_dir());
e7124ba2 1620 p.cargo("build").cwd("foo").run();
6fd1b54c 1621 assert!(p.root().join("foo/target").is_dir());
e7124ba2 1622 p.cargo("build").cwd("foo/bar").run();
6fd1b54c 1623 assert!(p.root().join("foo/bar/target").is_dir());
67364baa 1624}
b3a747cf 1625
b70a5962
TC
1626#[cargo_test]
1627fn excluded_default_members_still_must_be_members() {
1628 let p = project()
1629 .file(
1630 "Cargo.toml",
1631 r#"
6f8c7d5a
EH
1632 [workspace]
1633 members = ["foo"]
1634 default-members = ["foo", "bar"]
1635 exclude = ["bar"]
1636 "#,
b70a5962
TC
1637 )
1638 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
1639 .file("foo/src/lib.rs", "")
1640 .file("bar/something.txt", "");
1641 let p = p.build();
1642 p.cargo("build")
1643 .with_status(101)
1644 .with_stderr(
1645 "\
1646error: package `[..]bar` is listed in workspace’s default-members \
1647but is not a member.
1648",
1649 )
1650 .run();
1651}
1652
1653#[cargo_test]
1654fn excluded_default_members_crate_glob() {
1655 let p = project()
1656 .file(
1657 "Cargo.toml",
1658 r#"
6f8c7d5a
EH
1659 [workspace]
1660 members = ["foo", "bar/*"]
1661 default-members = ["bar/*"]
1662 exclude = ["bar/quux"]
1663 "#,
b70a5962
TC
1664 )
1665 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
1666 .file("foo/src/main.rs", "fn main() {}")
1667 .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
1668 .file("bar/baz/src/main.rs", "fn main() {}")
1669 .file("bar/quux/Cargo.toml", &basic_manifest("quux", "0.1.0"))
b377c4bb 1670 .file("bar/quux/src/main.rs", "fn main() {}");
b70a5962
TC
1671
1672 let p = p.build();
1673 p.cargo("build").run();
1674
1675 assert!(p.root().join("target").is_dir());
1676 assert!(!p.bin("foo").is_file());
1677 assert!(p.bin("baz").is_file());
b377c4bb 1678 assert!(!p.bin("quux").exists());
b70a5962
TC
1679
1680 p.cargo("build --workspace").run();
1681 assert!(p.root().join("target").is_dir());
1682 assert!(p.bin("foo").is_file());
b377c4bb 1683 assert!(!p.bin("quux").exists());
b70a5962
TC
1684
1685 p.cargo("build").cwd("bar/quux").run();
1686 assert!(p.root().join("bar/quux/target").is_dir());
1687}
1688
1689#[cargo_test]
1690fn excluded_default_members_not_crate_glob() {
1691 let p = project()
1692 .file(
1693 "Cargo.toml",
1694 r#"
6f8c7d5a
EH
1695 [workspace]
1696 members = ["foo", "bar/*"]
1697 default-members = ["bar/*"]
1698 exclude = ["bar/docs"]
1699 "#,
b70a5962
TC
1700 )
1701 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
1702 .file("foo/src/main.rs", "fn main() {}")
1703 .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
1704 .file("bar/baz/src/main.rs", "fn main() {}")
1705 .file("bar/docs/readme.txt", "This folder is not a crate!");
1706
1707 let p = p.build();
1708 p.cargo("build").run();
1709
1710 assert!(!p.bin("foo").is_file());
1711 assert!(p.bin("baz").is_file());
1712 p.cargo("build --workspace").run();
1713 assert!(p.bin("foo").is_file());
1714}
1715
0e0d9688 1716#[cargo_test]
b3a747cf 1717fn glob_syntax() {
7fe2fbc8 1718 let p = project()
fecb7246
AC
1719 .file(
1720 "Cargo.toml",
1721 r#"
6f8c7d5a
EH
1722 [project]
1723 name = "foo"
1724 version = "0.1.0"
1725 authors = []
b3a747cf 1726
6f8c7d5a
EH
1727 [workspace]
1728 members = ["crates/*"]
1729 exclude = ["crates/qux"]
1730 "#,
fecb7246 1731 )
b3a747cf 1732 .file("src/main.rs", "fn main() {}")
fecb7246
AC
1733 .file(
1734 "crates/bar/Cargo.toml",
1735 r#"
6f8c7d5a
EH
1736 [project]
1737 name = "bar"
1738 version = "0.1.0"
1739 authors = []
1740 workspace = "../.."
1741 "#,
fecb7246 1742 )
b3a747cf 1743 .file("crates/bar/src/main.rs", "fn main() {}")
fecb7246
AC
1744 .file(
1745 "crates/baz/Cargo.toml",
1746 r#"
6f8c7d5a
EH
1747 [project]
1748 name = "baz"
1749 version = "0.1.0"
1750 authors = []
1751 workspace = "../.."
1752 "#,
fecb7246 1753 )
b3a747cf 1754 .file("crates/baz/src/main.rs", "fn main() {}")
fecb7246
AC
1755 .file(
1756 "crates/qux/Cargo.toml",
1757 r#"
6f8c7d5a
EH
1758 [project]
1759 name = "qux"
1760 version = "0.1.0"
1761 authors = []
1762 "#,
fecb7246 1763 )
b3a747cf 1764 .file("crates/qux/src/main.rs", "fn main() {}");
d43ee1dd 1765 let p = p.build();
b3a747cf 1766
85984a87 1767 p.cargo("build").run();
570fe892
DW
1768 assert!(p.bin("foo").is_file());
1769 assert!(!p.bin("bar").is_file());
1770 assert!(!p.bin("baz").is_file());
b3a747cf 1771
e7124ba2 1772 p.cargo("build").cwd("crates/bar").run();
570fe892
DW
1773 assert!(p.bin("foo").is_file());
1774 assert!(p.bin("bar").is_file());
b3a747cf 1775
e7124ba2 1776 p.cargo("build").cwd("crates/baz").run();
570fe892
DW
1777 assert!(p.bin("foo").is_file());
1778 assert!(p.bin("baz").is_file());
b3a747cf 1779
e7124ba2 1780 p.cargo("build").cwd("crates/qux").run();
570fe892 1781 assert!(!p.bin("qux").is_file());
b3a747cf 1782
570fe892
DW
1783 assert!(p.root().join("Cargo.lock").is_file());
1784 assert!(!p.root().join("crates/bar/Cargo.lock").is_file());
1785 assert!(!p.root().join("crates/baz/Cargo.lock").is_file());
1786 assert!(p.root().join("crates/qux/Cargo.lock").is_file());
b3a747cf 1787}
06a13714 1788
f320997f 1789/*FIXME: This fails because of how workspace.exclude and workspace.members are working.
0e0d9688 1790#[cargo_test]
f320997f 1791fn glob_syntax_2() {
6da2ada2 1792 let p = project()
f320997f
BE
1793 .file("Cargo.toml", r#"
1794 [project]
1795 name = "foo"
1796 version = "0.1.0"
1797 authors = []
1798
1799 [workspace]
1800 members = ["crates/b*"]
1801 exclude = ["crates/q*"]
1802 "#)
1803 .file("src/main.rs", "fn main() {}")
1804 .file("crates/bar/Cargo.toml", r#"
1805 [project]
1806 name = "bar"
1807 version = "0.1.0"
1808 authors = []
1809 workspace = "../.."
1810 "#)
1811 .file("crates/bar/src/main.rs", "fn main() {}")
1812 .file("crates/baz/Cargo.toml", r#"
1813 [project]
1814 name = "baz"
1815 version = "0.1.0"
1816 authors = []
1817 workspace = "../.."
1818 "#)
1819 .file("crates/baz/src/main.rs", "fn main() {}")
1820 .file("crates/qux/Cargo.toml", r#"
1821 [project]
1822 name = "qux"
1823 version = "0.1.0"
1824 authors = []
1825 "#)
1826 .file("crates/qux/src/main.rs", "fn main() {}");
1827 p.build();
1828
85984a87 1829 p.cargo("build").run();
570fe892
DW
1830 assert!(p.bin("foo").is_file());
1831 assert!(!p.bin("bar").is_file());
1832 assert!(!p.bin("baz").is_file());
f320997f 1833
e7124ba2 1834 p.cargo("build").cwd("crates/bar").run();
570fe892
DW
1835 assert!(p.bin("foo").is_file());
1836 assert!(p.bin("bar").is_file());
f320997f 1837
e7124ba2 1838 p.cargo("build").cwd("crates/baz").run();
570fe892
DW
1839 assert!(p.bin("foo").is_file());
1840 assert!(p.bin("baz").is_file());
f320997f 1841
e7124ba2 1842 p.cargo("build").cwd("crates/qux").run();
570fe892 1843 assert!(!p.bin("qux").is_file());
f320997f 1844
570fe892
DW
1845 assert!(p.root().join("Cargo.lock").is_file());
1846 assert!(!p.root().join("crates/bar/Cargo.lock").is_file());
1847 assert!(!p.root().join("crates/baz/Cargo.lock").is_file());
1848 assert!(p.root().join("crates/qux/Cargo.lock").is_file());
f320997f
BE
1849}
1850*/
1851
0e0d9688 1852#[cargo_test]
98170335 1853fn glob_syntax_invalid_members() {
7fe2fbc8 1854 let p = project()
fecb7246
AC
1855 .file(
1856 "Cargo.toml",
1857 r#"
6f8c7d5a
EH
1858 [project]
1859 name = "foo"
1860 version = "0.1.0"
1861 authors = []
06a13714 1862
6f8c7d5a
EH
1863 [workspace]
1864 members = ["crates/*"]
1865 "#,
fecb7246 1866 )
06a13714
HRI
1867 .file("src/main.rs", "fn main() {}")
1868 .file("crates/bar/src/main.rs", "fn main() {}");
d43ee1dd 1869 let p = p.build();
06a13714 1870
85984a87
DW
1871 p.cargo("build")
1872 .with_status(101)
1873 .with_stderr(
1e682848 1874 "\
832fff8d
WL
1875[ERROR] failed to load manifest for workspace member `[..]/crates/bar`
1876
1877Caused by:
1878 failed to read `[..]foo/crates/bar/Cargo.toml`
06a13714 1879
98170335
HRI
1880Caused by:
1881 [..]
1e682848 1882",
fecb7246
AC
1883 )
1884 .run();
06a13714
HRI
1885}
1886
f7c91ba6 1887/// This is a freshness test for feature use with workspaces.
46a5fe9a 1888///
f7c91ba6
AR
1889/// `feat_lib` is used by `caller1` and `caller2`, but with different features enabled.
1890/// This test ensures that alternating building `caller1`, `caller2` doesn't force
1891/// recompile of `feat_lib`.
46a5fe9a 1892///
f7c91ba6
AR
1893/// Ideally, once we solve rust-lang/cargo#3620, then a single Cargo build at the top level
1894/// will be enough.
0e0d9688 1895#[cargo_test]
46a5fe9a 1896fn dep_used_with_separate_features() {
7fe2fbc8 1897 let p = project()
1e682848
AC
1898 .file(
1899 "Cargo.toml",
1900 r#"
6f8c7d5a
EH
1901 [workspace]
1902 members = ["feat_lib", "caller1", "caller2"]
1903 "#,
fecb7246
AC
1904 )
1905 .file(
1e682848
AC
1906 "feat_lib/Cargo.toml",
1907 r#"
6f8c7d5a
EH
1908 [project]
1909 name = "feat_lib"
1910 version = "0.1.0"
1911 authors = []
46a5fe9a 1912
6f8c7d5a
EH
1913 [features]
1914 myfeature = []
1915 "#,
fecb7246
AC
1916 )
1917 .file("feat_lib/src/lib.rs", "")
1e682848
AC
1918 .file(
1919 "caller1/Cargo.toml",
1920 r#"
6f8c7d5a
EH
1921 [project]
1922 name = "caller1"
1923 version = "0.1.0"
1924 authors = []
46a5fe9a 1925
6f8c7d5a
EH
1926 [dependencies]
1927 feat_lib = { path = "../feat_lib" }
1928 "#,
fecb7246
AC
1929 )
1930 .file("caller1/src/main.rs", "fn main() {}")
46a5fe9a 1931 .file("caller1/src/lib.rs", "")
1e682848
AC
1932 .file(
1933 "caller2/Cargo.toml",
1934 r#"
6f8c7d5a
EH
1935 [project]
1936 name = "caller2"
1937 version = "0.1.0"
1938 authors = []
46a5fe9a 1939
6f8c7d5a
EH
1940 [dependencies]
1941 feat_lib = { path = "../feat_lib", features = ["myfeature"] }
1942 caller1 = { path = "../caller1" }
1943 "#,
fecb7246
AC
1944 )
1945 .file("caller2/src/main.rs", "fn main() {}")
46a5fe9a 1946 .file("caller2/src/lib.rs", "");
d43ee1dd 1947 let p = p.build();
46a5fe9a 1948
f7c91ba6 1949 // Build the entire workspace.
7176df01 1950 p.cargo("build --workspace")
85984a87 1951 .with_stderr(
1e682848 1952 "\
46a5fe9a
NK
1953[..]Compiling feat_lib v0.1.0 ([..])
1954[..]Compiling caller1 v0.1.0 ([..])
1955[..]Compiling caller2 v0.1.0 ([..])
1956[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 1957",
fecb7246
AC
1958 )
1959 .run();
570fe892
DW
1960 assert!(p.bin("caller1").is_file());
1961 assert!(p.bin("caller2").is_file());
46a5fe9a 1962
f7c91ba6 1963 // Build `caller1`. Should build the dep library. Because the features
46a5fe9a 1964 // are different than the full workspace, it rebuilds.
f7c91ba6
AR
1965 // Ideally once we solve rust-lang/cargo#3620, then a single Cargo build at the top level
1966 // will be enough.
85984a87 1967 p.cargo("build")
e7124ba2 1968 .cwd("caller1")
85984a87 1969 .with_stderr(
1e682848 1970 "\
46a5fe9a
NK
1971[..]Compiling feat_lib v0.1.0 ([..])
1972[..]Compiling caller1 v0.1.0 ([..])
1973[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1e682848 1974",
fecb7246
AC
1975 )
1976 .run();
46a5fe9a 1977
f7c91ba6
AR
1978 // Alternate building `caller2`/`caller1` a few times, just to make sure
1979 // features are being built separately. Should not rebuild anything.
85984a87 1980 p.cargo("build")
e7124ba2 1981 .cwd("caller2")
85984a87
DW
1982 .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1983 .run();
1984 p.cargo("build")
e7124ba2 1985 .cwd("caller1")
85984a87
DW
1986 .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1987 .run();
1988 p.cargo("build")
e7124ba2 1989 .cwd("caller2")
85984a87
DW
1990 .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1991 .run();
46a5fe9a 1992}
f320997f 1993
0e0d9688 1994#[cargo_test]
3ce50d02
AR
1995fn dont_recurse_out_of_cargo_home() {
1996 let git_project = git::new("dep", |project| {
1997 project
ab19c483 1998 .file("Cargo.toml", &basic_manifest("dep", "0.1.0"))
3ce50d02 1999 .file("src/lib.rs", "")
1e682848
AC
2000 .file(
2001 "build.rs",
2002 r#"
6f8c7d5a
EH
2003 use std::env;
2004 use std::path::Path;
2005 use std::process::{self, Command};
2006
2007 fn main() {
2008 let cargo = env::var_os("CARGO").unwrap();
2009 let cargo_manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
2010 let output = Command::new(cargo)
2011 .args(&["metadata", "--format-version", "1", "--manifest-path"])
2012 .arg(&Path::new(&cargo_manifest_dir).join("Cargo.toml"))
2013 .output()
2014 .unwrap();
2015 if !output.status.success() {
2016 eprintln!("{}", String::from_utf8(output.stderr).unwrap());
2017 process::exit(1);
2018 }
3ce50d02 2019 }
6f8c7d5a 2020 "#,
1e682848 2021 )
3c20a243 2022 });
f8c9928c 2023 let p = project()
1e682848
AC
2024 .file(
2025 "Cargo.toml",
2026 &format!(
2027 r#"
6f8c7d5a
EH
2028 [package]
2029 name = "foo"
2030 version = "0.1.0"
3ce50d02 2031
6f8c7d5a
EH
2032 [dependencies.dep]
2033 git = "{}"
3ce50d02 2034
6f8c7d5a
EH
2035 [workspace]
2036 "#,
1e682848
AC
2037 git_project.url()
2038 ),
fecb7246
AC
2039 )
2040 .file("src/lib.rs", "");
3ce50d02
AR
2041 let p = p.build();
2042
85984a87
DW
2043 p.cargo("build")
2044 .env("CARGO_HOME", p.root().join(".cargo"))
2045 .run();
3ce50d02
AR
2046}
2047
f7c91ba6
AR
2048// FIXME: this fails because of how workspace.exclude and workspace.members are working.
2049/*
0e0d9688 2050#[cargo_test]
f320997f 2051fn include_and_exclude() {
6da2ada2 2052 let p = project()
f320997f
BE
2053 .file("Cargo.toml", r#"
2054 [workspace]
2055 members = ["foo"]
2056 exclude = ["foo/bar"]
2057 "#)
ab19c483 2058 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
f320997f 2059 .file("foo/src/lib.rs", "")
ab19c483 2060 .file("foo/bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
f320997f
BE
2061 .file("foo/bar/src/lib.rs", "");
2062 p.build();
2063
e7124ba2 2064 p.cargo("build").cwd("foo").run();
6fd1b54c
DW
2065 assert!(p.root().join("target").is_dir());
2066 assert!(!p.root().join("foo/target").is_dir());
e7124ba2 2067 p.cargo("build").cwd("foo/bar").run();
6fd1b54c 2068 assert!(p.root().join("foo/bar/target").is_dir());
f320997f
BE
2069}
2070*/
4f28bc1a 2071
0e0d9688 2072#[cargo_test]
4f28bc1a 2073fn cargo_home_at_root_works() {
f8c9928c 2074 let p = project()
1e682848
AC
2075 .file(
2076 "Cargo.toml",
2077 r#"
6f8c7d5a
EH
2078 [package]
2079 name = "foo"
2080 version = "0.1.0"
4f28bc1a 2081
6f8c7d5a
EH
2082 [workspace]
2083 members = ["a"]
2084 "#,
fecb7246
AC
2085 )
2086 .file("src/lib.rs", "")
ab19c483 2087 .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
4f28bc1a
AC
2088 .file("a/src/lib.rs", "");
2089 let p = p.build();
2090
85984a87
DW
2091 p.cargo("build").run();
2092 p.cargo("build --frozen").env("CARGO_HOME", p.root()).run();
4f28bc1a 2093}
e4f32bf3 2094
0e0d9688 2095#[cargo_test]
e4f32bf3 2096fn relative_rustc() {
f8c9928c 2097 let p = project()
1e682848
AC
2098 .file(
2099 "src/main.rs",
2100 r#"
6f8c7d5a
EH
2101 use std::process::Command;
2102 use std::env;
e4f32bf3 2103
6f8c7d5a
EH
2104 fn main() {
2105 let mut cmd = Command::new("rustc");
2106 for arg in env::args_os().skip(1) {
2107 cmd.arg(arg);
2108 }
2109 std::process::exit(cmd.status().unwrap().code().unwrap());
e4f32bf3 2110 }
6f8c7d5a 2111 "#,
fecb7246
AC
2112 )
2113 .build();
85984a87 2114 p.cargo("build").run();
e4f32bf3 2115
85984a87
DW
2116 let src = p
2117 .root()
e4f32bf3
AC
2118 .join("target/debug/foo")
2119 .with_extension(env::consts::EXE_EXTENSION);
2120
2121 Package::new("a", "0.1.0").publish();
2122
85984a87
DW
2123 let p = project()
2124 .at("lib")
1e682848
AC
2125 .file(
2126 "Cargo.toml",
2127 r#"
6f8c7d5a
EH
2128 [package]
2129 name = "lib"
2130 version = "0.1.0"
e4f32bf3 2131
6f8c7d5a
EH
2132 [dependencies]
2133 a = "0.1"
2134 "#,
fecb7246
AC
2135 )
2136 .file("src/lib.rs", "")
e4f32bf3
AC
2137 .build();
2138
2139 fs::copy(&src, p.root().join(src.file_name().unwrap())).unwrap();
2140
2141 let file = format!("./foo{}", env::consts::EXE_SUFFIX);
85984a87 2142 p.cargo("build").env("RUSTC", &file).run();
e4f32bf3 2143}
037a879d 2144
0e0d9688 2145#[cargo_test]
037a879d 2146fn ws_rustc_err() {
f8c9928c 2147 let p = project()
037a879d
EH
2148 .file(
2149 "Cargo.toml",
2150 r#"
6f8c7d5a
EH
2151 [workspace]
2152 members = ["a"]
2153 "#,
fecb7246
AC
2154 )
2155 .file("a/Cargo.toml", &basic_lib_manifest("a"))
037a879d
EH
2156 .file("a/src/lib.rs", "")
2157 .build();
2158
85984a87
DW
2159 p.cargo("rustc")
2160 .with_status(101)
2161 .with_stderr("[ERROR] [..]against an actual package[..]")
2162 .run();
037a879d 2163
85984a87
DW
2164 p.cargo("rustdoc")
2165 .with_status(101)
2166 .with_stderr("[ERROR] [..]against an actual package[..]")
2167 .run();
037a879d 2168}
5b2b5f95 2169
0e0d9688 2170#[cargo_test]
5b2b5f95
EH
2171fn ws_err_unused() {
2172 for key in &[
2173 "[lib]",
2174 "[[bin]]",
2175 "[[example]]",
2176 "[[test]]",
2177 "[[bench]]",
2178 "[dependencies]",
2179 "[dev-dependencies]",
2180 "[build-dependencies]",
2181 "[features]",
2182 "[target]",
2183 "[badges]",
2184 ] {
2185 let p = project()
2186 .file(
2187 "Cargo.toml",
2188 &format!(
2189 r#"
2190 [workspace]
2191 members = ["a"]
2192
2193 {}
2194 "#,
2195 key
2196 ),
2197 )
2198 .file("a/Cargo.toml", &basic_lib_manifest("a"))
2199 .file("a/src/lib.rs", "")
2200 .build();
2201 p.cargo("check")
2202 .with_status(101)
2203 .with_stderr(&format!(
2204 "\
2205[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
2206
2207Caused by:
d6a14286 2208 this virtual manifest specifies a {} section, which is not allowed
5b2b5f95
EH
2209",
2210 key
2211 ))
2212 .run();
2213 }
2214}
2215
0e0d9688 2216#[cargo_test]
5b2b5f95
EH
2217fn ws_warn_unused() {
2218 for (key, name) in &[
2219 ("[profile.dev]\nopt-level = 1", "profiles"),
2220 ("[replace]\n\"bar:0.1.0\" = { path = \"bar\" }", "replace"),
2221 ("[patch.crates-io]\nbar = { path = \"bar\" }", "patch"),
2222 ] {
2223 let p = project()
2224 .file(
2225 "Cargo.toml",
2226 r#"
2227 [workspace]
2228 members = ["a"]
2229 "#,
2230 )
2231 .file(
2232 "a/Cargo.toml",
2233 &format!(
2234 r#"
2235 [package]
2236 name = "a"
2237 version = "0.1.0"
2238
2239 {}
2240 "#,
2241 key
2242 ),
2243 )
2244 .file("a/src/lib.rs", "")
2245 .build();
2246 p.cargo("check")
5b2b5f95
EH
2247 .with_stderr_contains(&format!(
2248 "\
2249[WARNING] {} for the non root package will be ignored, specify {} at the workspace root:
2250package: [..]/foo/a/Cargo.toml
2251workspace: [..]/foo/Cargo.toml
2252",
2253 name, name
2254 ))
2255 .run();
2256 }
2257}
6ad77940 2258
0e0d9688 2259#[cargo_test]
6ad77940
EH
2260fn ws_warn_path() {
2261 // Warnings include path to manifest.
2262 let p = project()
2263 .file(
2264 "Cargo.toml",
2265 r#"
2266 [workspace]
2267 members = ["a"]
2268 "#,
2269 )
2270 .file(
2271 "a/Cargo.toml",
2272 r#"
2273 cargo-features = ["edition"]
2274 [package]
2275 name = "foo"
2276 version = "0.1.0"
2277 "#,
2278 )
2279 .file("a/src/lib.rs", "")
2280 .build();
2281
2282 p.cargo("check")
6ad77940
EH
2283 .with_stderr_contains("[WARNING] [..]/foo/a/Cargo.toml: the cargo feature `edition`[..]")
2284 .run();
2285}
bdb0ce84
AC
2286
2287#[cargo_test]
2288fn invalid_missing() {
a07fec1b 2289 // Make sure errors are not suppressed with -q.
bdb0ce84
AC
2290 let p = project()
2291 .file(
2292 "Cargo.toml",
2293 r#"
2294 [package]
2295 name = "foo"
2296 version = "0.1.0"
2297
2298 [dependencies]
2299 x = { path = 'x' }
2300 "#,
2301 )
2302 .file("src/lib.rs", "")
2303 .build();
2304
2305 p.cargo("build -q")
2306 .with_status(101)
2307 .with_stderr(
2308 "\
1eca786d 2309[ERROR] failed to get `x` as a dependency of package `foo v0.1.0 [..]`
bdb0ce84
AC
2310
2311Caused by:
a07fec1b 2312 failed to load source for dependency `x`
bdb0ce84
AC
2313
2314Caused by:
a07fec1b 2315 Unable to update [..]/foo/x
bdb0ce84
AC
2316
2317Caused by:
a07fec1b
EH
2318 failed to read `[..]foo/x/Cargo.toml`
2319
2320Caused by:
2321 [..]
2322",
bdb0ce84
AC
2323 )
2324 .run();
2325}
c12aed2f 2326
9c0d8653
WL
2327#[cargo_test]
2328fn member_dep_missing() {
2329 // Make sure errors are not suppressed with -q.
2330 let p = project()
2331 .file(
2332 "Cargo.toml",
2333 r#"
2334 [project]
2335 name = "foo"
2336 version = "0.1.0"
2337
2338 [workspace]
2339 members = ["bar"]
2340 "#,
2341 )
2342 .file("src/main.rs", "fn main() {}")
2343 .file(
2344 "bar/Cargo.toml",
2345 r#"
2346 [project]
2347 name = "bar"
2348 version = "0.1.0"
2349
2350 [dependencies]
2351 baz = { path = "baz" }
2352 "#,
2353 )
2354 .file("bar/src/main.rs", "fn main() {}")
2355 .build();
2356
2357 p.cargo("build -q")
2358 .with_status(101)
2359 .with_stderr(
2360 "\
2361[ERROR] failed to load manifest for workspace member `[..]/bar`
2362
2363Caused by:
2364 failed to load manifest for dependency `baz`
2365
2366Caused by:
2367 failed to read `[..]foo/bar/baz/Cargo.toml`
2368
2369Caused by:
2370 [..]
2371",
2372 )
2373 .run();
2374}
2375
c12aed2f
EB
2376#[cargo_test]
2377fn simple_primary_package_env_var() {
fb02ade2
EB
2378 let is_primary_package = r#"
2379 #[test]
2380 fn verify_primary_package() {{
2381 assert!(option_env!("CARGO_PRIMARY_PACKAGE").is_some());
2382 }}
2383 "#;
2384
c12aed2f
EB
2385 let p = project()
2386 .file(
2387 "Cargo.toml",
2388 r#"
2389 [project]
2390 name = "foo"
2391 version = "0.1.0"
2392 authors = []
2393
2394 [workspace]
2395 members = ["bar"]
2396 "#,
2397 )
fb02ade2 2398 .file("src/lib.rs", is_primary_package)
c12aed2f
EB
2399 .file(
2400 "bar/Cargo.toml",
2401 r#"
2402 [project]
2403 name = "bar"
2404 version = "0.1.0"
2405 authors = []
2406 workspace = ".."
2407 "#,
2408 )
fb02ade2 2409 .file("bar/src/lib.rs", is_primary_package);
c12aed2f
EB
2410 let p = p.build();
2411
fb02ade2 2412 p.cargo("test").run();
c12aed2f
EB
2413
2414 // Again, this time selecting a specific crate
2415 p.cargo("clean").run();
fb02ade2 2416 p.cargo("test -p bar").run();
c12aed2f
EB
2417
2418 // Again, this time selecting all crates
2419 p.cargo("clean").run();
fb02ade2 2420 p.cargo("test --all").run();
c12aed2f
EB
2421}
2422
2423#[cargo_test]
2424fn virtual_primary_package_env_var() {
fb02ade2
EB
2425 let is_primary_package = r#"
2426 #[test]
2427 fn verify_primary_package() {{
2428 assert!(option_env!("CARGO_PRIMARY_PACKAGE").is_some());
2429 }}
2430 "#;
2431
c12aed2f
EB
2432 let p = project()
2433 .file(
2434 "Cargo.toml",
2435 r#"
2436 [workspace]
2437 members = ["foo", "bar"]
2438 "#,
2439 )
2440 .file("foo/Cargo.toml", &basic_manifest("foo", "0.1.0"))
fb02ade2 2441 .file("foo/src/lib.rs", is_primary_package)
c12aed2f 2442 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
fb02ade2 2443 .file("bar/src/lib.rs", is_primary_package);
c12aed2f
EB
2444 let p = p.build();
2445
fb02ade2 2446 p.cargo("test").run();
c12aed2f
EB
2447
2448 // Again, this time selecting a specific crate
2449 p.cargo("clean").run();
fb02ade2 2450 p.cargo("test -p foo").run();
c12aed2f 2451}