1mod cargo;
9mod external;
10mod manifest;
11mod metadata;
12
13pub mod test {
15 use bake::{Context, Error, Result};
16
17 use crate::{cargo, external, manifest, metadata};
18
19 fn run_before_test_hook(context: &mut Context) -> Result<()> {
20 context.call_if_registered("test:before", &[])?;
21 Ok(())
22 }
23
24 #[bake::task(name = "test")]
26 pub fn run(
27 context: &mut Context,
28 #[bake(named, default = false, help = "Also test examples and benchmarks.")]
29 all_targets: bool,
30 ) -> Result<String> {
31 run_before_test_hook(context)?;
32
33 let mut arguments = vec![
34 "test".to_owned(),
35 "--workspace".to_owned(),
36 "--locked".to_owned(),
37 ];
38 if all_targets {
39 arguments.push("--all-targets".to_owned());
40 }
41
42 cargo::run(context, &arguments)?;
43 Ok("Cargo workspace tests passed".to_owned())
44 }
45
46 #[bake::task(name = "test:external")]
48 pub fn external(
49 context: &mut Context,
50 #[bake(named, default = false, help = "Also test examples and benchmarks.")]
51 all_targets: bool,
52 ) -> Result<String> {
53 let workspace = metadata::read_workspace(context)?;
54 if workspace.external_repositories.is_empty() {
55 return Ok("No downstream repositories are configured for external tests".to_owned());
56 }
57 if workspace.packages.is_empty() {
58 return Err(Error::new(
59 "the current workspace has no crates.io packages to patch into downstream tests",
60 ));
61 }
62
63 let mut checkouts = Vec::with_capacity(workspace.external_repositories.len());
64 for repository in &workspace.external_repositories {
65 let checkout = external::checkout(context, repository)?;
66 manifest::patch_checkout(&checkout, &workspace.packages)?;
67 external::ensure_local_patches_are_selected(&checkout, &workspace.packages)?;
68 checkouts.push(checkout);
69 }
70
71 run_before_test_hook(context)?;
72
73 for checkout in &checkouts {
74 let mut arguments = vec!["test".to_owned(), "--workspace".to_owned()];
75 if all_targets {
76 arguments.push("--all-targets".to_owned());
77 }
78 external::run_cargo(checkout, &arguments)?;
79 }
80
81 let repository_count = checkouts.len();
82 let repository_label = if repository_count == 1 {
83 "repository"
84 } else {
85 "repositories"
86 };
87 Ok(format!(
88 "External tests passed for {repository_count} downstream {repository_label}"
89 ))
90 }
91}