diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index c54cc6530..9ad6bfd34 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -186,6 +186,9 @@ impl TargetTypes { pub enum CargoAction { Build, Clippy, + Coverage { + open: bool, + }, Doc { open: bool, document_private_items: bool, @@ -251,6 +254,13 @@ impl Cargo { tool_args.extend(["-D", "warnings"]); } } + CargoAction::Coverage { open } => { + action = "llvm-cov"; + extra_args.push("--html"); + if open { + extra_args.push("--open"); + } + } CargoAction::Doc { open, document_private_items, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f735486cd..70abee65f 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -12,12 +12,12 @@ mod tpm; mod util; use crate::opt::{FmtOpt, TestOpt}; -use anyhow::Result; +use anyhow::{bail, Result}; use arch::UefiArch; use cargo::{Cargo, CargoAction, Feature, Package, TargetTypes}; use clap::Parser; use itertools::Itertools; -use opt::{Action, BuildOpt, ClippyOpt, DocOpt, Opt, QemuOpt, TpmVersion}; +use opt::{Action, BuildOpt, ClippyOpt, CovOpt, DocOpt, Opt, QemuOpt, TpmVersion}; use std::process::Command; use util::run_cmd; @@ -85,6 +85,27 @@ fn clippy(opt: &ClippyOpt) -> Result<()> { run_cmd(cargo.command()?) } +/// Generate a code coverage report. +fn code_coverage(opt: &CovOpt) -> Result<()> { + if has_cmd("cargo-llvm-cov") { + let cargo = Cargo { + action: CargoAction::Coverage { open: opt.open }, + features: Feature::more_code(*opt.unstable, false), + // Leave out uefi-macros; the compilation tests will just make + // things slower without contributing anything to the coverage + // report. + packages: vec![Package::UefiRaw, Package::Uefi], + release: false, + target: None, + warnings_as_errors: false, + target_types: TargetTypes::Default, + }; + run_cmd(cargo.command()?) + } else { + bail!("cargo-llvm-cov not found, see https://github.com/taiki-e/cargo-llvm-cov"); + } +} + /// Build docs. fn doc(opt: &DocOpt) -> Result<()> { let cargo = Cargo { @@ -305,6 +326,7 @@ fn main() -> Result<()> { Action::Build(build_opt) => build(build_opt), Action::CheckRaw(_) => check_raw::check_raw(), Action::Clippy(clippy_opt) => clippy(clippy_opt), + Action::Cov(cov_opt) => code_coverage(cov_opt), Action::Doc(doc_opt) => doc(doc_opt), Action::GenCode(gen_opt) => device_path::gen_code(gen_opt), Action::Miri(_) => run_miri(), diff --git a/xtask/src/opt.rs b/xtask/src/opt.rs index af3f06250..a5ee7496f 100644 --- a/xtask/src/opt.rs +++ b/xtask/src/opt.rs @@ -68,6 +68,7 @@ pub enum Action { Build(BuildOpt), CheckRaw(CheckRawOpt), Clippy(ClippyOpt), + Cov(CovOpt), Doc(DocOpt), GenCode(GenCodeOpt), Miri(MiriOpt), @@ -105,6 +106,17 @@ pub struct ClippyOpt { pub warning: WarningOpt, } +/// Generate a code coverage report. +#[derive(Debug, Parser)] +pub struct CovOpt { + /// Open the output in a browser. + #[clap(long, action)] + pub open: bool, + + #[clap(flatten)] + pub unstable: UnstableOpt, +} + /// Build the docs for the uefi packages. #[derive(Debug, Parser)] pub struct DocOpt {