tracel_xtask/commands/
coverage.rs

1use anyhow::Ok;
2use clap::Args;
3
4use crate::{
5    endgroup, group,
6    prelude::{Context, Environment},
7    utils::{
8        cargo::ensure_cargo_crate_is_installed, process::run_process, rustup::rustup_add_component,
9    },
10    versions::GRCOV_VERSION,
11};
12
13use super::Profile;
14
15#[tracel_xtask_macros::declare_command_args(None, CoverageSubCommand)]
16pub struct CoverageCmdArgs {}
17
18impl Default for CoverageSubCommand {
19    fn default() -> Self {
20        CoverageSubCommand::Generate(GenerateCmdArgs::default())
21    }
22}
23
24#[derive(Args, Default, Clone, PartialEq)]
25pub struct GenerateCmdArgs {
26    /// Build profile to use.
27    #[arg(short, long, value_enum, default_value_t = Profile::default())]
28    profile: Profile,
29    /// Comma-separated list of excluded crates.
30    #[arg(
31        short = 'i',
32        long,
33        value_name = "PATH,PATH,...",
34        value_delimiter = ',',
35        required = false
36    )]
37    pub ignore: Vec<String>,
38}
39
40pub fn handle_command(
41    args: CoverageCmdArgs,
42    _env: Environment,
43    _ctx: Context,
44) -> anyhow::Result<()> {
45    match args.get_command() {
46        CoverageSubCommand::Install => install_grcov(),
47        CoverageSubCommand::Generate(gen_args) => run_grcov(&gen_args),
48    }
49}
50
51fn install_grcov() -> anyhow::Result<()> {
52    rustup_add_component("llvm-tools-preview")?;
53    if std::env::var("CI").is_err() {
54        ensure_cargo_crate_is_installed("grcov", None, Some(GRCOV_VERSION), false)?;
55    }
56    Ok(())
57}
58
59fn run_grcov(generate_args: &GenerateCmdArgs) -> anyhow::Result<()> {
60    group!("Grcov");
61    let binary_path = format!("./target/{}/", generate_args.profile);
62    #[rustfmt::skip]
63    let mut args = vec![
64        ".",
65        "--binary-path", &binary_path,
66        "-s", ".",
67        "-t", "lcov",
68        "-o", "lcov.info",
69        "--branch",
70        "--ignore-not-existing",
71    ];
72    generate_args
73        .ignore
74        .iter()
75        .for_each(|i| args.extend(vec!["--ignore", i]));
76    run_process("grcov", &args, None, None, "Error executing grcov")?;
77    endgroup!();
78    Ok(())
79}