Skip to content

Commit

Permalink
Add initial support for wasm-pack
Browse files Browse the repository at this point in the history
  • Loading branch information
aDogCalledSpot committed Jan 16, 2024
1 parent bab7732 commit cacb1a3
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 24 deletions.
3 changes: 2 additions & 1 deletion src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ fn locate_project(cargo: &OsStr) -> Result<String> {
// https://doc.rust-lang.org/nightly/cargo/commands/cargo-test.html
// https://doc.rust-lang.org/nightly/cargo/commands/cargo-run.html
pub(crate) fn test_or_run_args(cx: &Context, cmd: &mut ProcessBuilder) {
if matches!(cx.args.subcommand, Subcommand::None | Subcommand::Test) && !cx.args.doctests {
if matches!(cx.args.subcommand, Subcommand::None | Subcommand::Test { .. }) && !cx.args.doctests
{
let has_target_selection_options = cx.args.lib
| cx.args.bins
| cx.args.examples
Expand Down
37 changes: 25 additions & 12 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ impl Args {
if matches!(
subcommand,
Subcommand::None
| Subcommand::Test
| Subcommand::Test { .. }
| Subcommand::Run
| Subcommand::Nextest { .. }
| Subcommand::NextestArchive
Expand All @@ -462,7 +462,7 @@ impl Args {
) if matches!(
subcommand,
Subcommand::None
| Subcommand::Test
| Subcommand::Test { .. }
| Subcommand::Run
| Subcommand::Nextest { .. }
| Subcommand::NextestArchive
Expand Down Expand Up @@ -514,6 +514,14 @@ impl Args {

term::set_coloring(&mut color);

if matches!(subcommand, Subcommand::Test { .. }) {
let wasm = cargo_args.iter().any(|a| a == "--wasm");
subcommand = Subcommand::Test { wasm };
if wasm {
cargo_args.retain(|x| *x != "--wasm");
}
}

if matches!(subcommand, Subcommand::Nextest { .. }) {
subcommand = Subcommand::Nextest {
archive_file: cargo_args.iter().any(|a| a == "--archive-file"),
Expand All @@ -532,7 +540,7 @@ impl Args {
if doc || doctests {
let flag = if doc { "--doc" } else { "--doctests" };
match subcommand {
Subcommand::None | Subcommand::Test => {}
Subcommand::None | Subcommand::Test { .. } => {}
Subcommand::ShowEnv | Subcommand::Report if doctests => {}
Subcommand::Nextest { .. } | Subcommand::NextestArchive => {
bail!("doctest is not supported for nextest")
Expand All @@ -542,7 +550,7 @@ impl Args {
}
match subcommand {
Subcommand::None | Subcommand::Nextest { .. } | Subcommand::NextestArchive => {}
Subcommand::Test => {
Subcommand::Test { .. } => {
if no_run {
unexpected("--no-run", subcommand)?;
}
Expand Down Expand Up @@ -588,7 +596,7 @@ impl Args {
}
match subcommand {
Subcommand::None
| Subcommand::Test
| Subcommand::Test { .. }
| Subcommand::Run
| Subcommand::Nextest { .. }
| Subcommand::NextestArchive => {}
Expand All @@ -615,7 +623,7 @@ impl Args {
}
match subcommand {
Subcommand::None
| Subcommand::Test
| Subcommand::Test { .. }
| Subcommand::Run
| Subcommand::Nextest { .. }
| Subcommand::NextestArchive
Expand All @@ -631,7 +639,7 @@ impl Args {
}
match subcommand {
Subcommand::None
| Subcommand::Test
| Subcommand::Test { .. }
| Subcommand::Nextest { .. }
| Subcommand::NextestArchive
| Subcommand::Clean => {}
Expand Down Expand Up @@ -908,7 +916,9 @@ pub(crate) enum Subcommand {
None,

/// Run tests and generate coverage report.
Test,
Test {
wasm: bool,
},

/// Run a binary or example and generate coverage report.
Run,
Expand Down Expand Up @@ -946,13 +956,16 @@ static CARGO_LLVM_COV_NEXTEST_ARCHIVE_USAGE: &str =

impl Subcommand {
fn can_passthrough(subcommand: Self) -> bool {
matches!(subcommand, Self::Test | Self::Run | Self::Nextest { .. } | Self::NextestArchive)
matches!(
subcommand,
Self::Test { .. } | Self::Run | Self::Nextest { .. } | Self::NextestArchive
)
}

fn help_text(subcommand: Self) -> &'static str {
match subcommand {
Self::None => CARGO_LLVM_COV_USAGE,
Self::Test => CARGO_LLVM_COV_TEST_USAGE,
Self::Test { .. } => CARGO_LLVM_COV_TEST_USAGE,
Self::Run => CARGO_LLVM_COV_RUN_USAGE,
Self::Report => CARGO_LLVM_COV_REPORT_USAGE,
Self::Clean => CARGO_LLVM_COV_CLEAN_USAGE,
Expand All @@ -966,7 +979,7 @@ impl Subcommand {
fn as_str(self) -> &'static str {
match self {
Self::None => "",
Self::Test => "test",
Self::Test { .. } => "test",
Self::Run => "run",
Self::Report => "report",
Self::Clean => "clean",
Expand All @@ -987,7 +1000,7 @@ impl FromStr for Subcommand {

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"test" | "t" => Ok(Self::Test),
"test" | "t" => Ok(Self::Test { wasm: false }),
"run" | "r" => Ok(Self::Run),
"report" => Ok(Self::Report),
"clean" => Ok(Self::Clean),
Expand Down
80 changes: 69 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
collections::{BTreeSet, HashMap},
ffi::{OsStr, OsString},
io::{self, BufRead, Write},
path::Path,
path::{Path, PathBuf},
time::SystemTime,
};

Expand Down Expand Up @@ -105,19 +105,23 @@ fn try_main() -> Result<()> {
create_dirs(cx)?;
archive_nextest(cx)?;
}
Subcommand::None | Subcommand::Test => {
let cx = &Context::new(args)?;
clean::clean_partial(cx)?;
create_dirs(cx)?;
run_test(cx)?;
if !cx.args.cov.no_report {
generate_report(cx)?;
}
}
Subcommand::Test { wasm } => test(args, wasm)?,
Subcommand::None => test(args, false)?,
}
Ok(())
}

fn test(args: Args, wasm: bool) -> Result<()> {
let cx = &Context::new(args)?;
clean::clean_partial(cx)?;
create_dirs(cx)?;
run_test(cx, wasm)?;
if !cx.args.cov.no_report {
generate_report(cx)?;
};
Ok(())
}

fn create_dirs(cx: &Context) -> Result<()> {
fs::create_dir_all(&cx.ws.target_dir)?;

Expand Down Expand Up @@ -342,7 +346,46 @@ fn has_z_flag(args: &[String], name: &str) -> bool {
false
}

fn run_test(cx: &Context) -> Result<()> {
fn run_wasm_test(cx: &Context) -> Result<()> {
let mut cmd = cmd!("wasm-pack");
cmd.arg("test");
cmd.arg("--coverage");
cmd.args(["--profraw-out", &format!("{}/{}-wasm.profraw", cx.ws.target_dir, cx.ws.name)]);
cmd.args(cx.args.cargo_args.clone());

// Emit llvm-ir to obtain debug info (https://github.com/hknio/code-coverage-for-webassembly)
cmd.env("RUSTFLAGS", "-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir");
cmd.run()?;

// Find the new wasm object file
let path = "target/wasm32-unknown-unknown/debug/deps";
let mut newest: Option<PathBuf> = None;
let ctime = |p: &Path| crate::fs::metadata(p).unwrap().created().unwrap();
for file in glob::glob(Utf8Path::new(&glob::Pattern::escape(path)).join("*.ll").as_str())?
.filter_map(Result::ok)
{
newest = match &newest {
Some(newest) if ctime(newest) > ctime(&file) => Some(newest.clone()),
None | Some(_) => Some(file),
};
}
let newest = newest.unwrap();

// Compile the wasm object file
let mut cmd = cmd!("clang");
cmd.arg(newest.clone());
cmd.arg("-Wno-override-module");
cmd.arg("-c");
cmd.arg("-o");
cmd.arg(format!("{}/{}.o", cx.ws.target_dir, newest.file_stem().unwrap().to_str().unwrap()));
cmd.run()?;
Ok(())
}

fn run_test(cx: &Context, wasm: bool) -> Result<()> {
if wasm {
return run_wasm_test(cx);
}
let mut cargo = cx.cargo();

set_env(cx, &mut cargo, IsNextest(false))?;
Expand Down Expand Up @@ -798,6 +841,20 @@ fn object_files(cx: &Context) -> Result<Vec<OsString>> {
}
}

let mut wasm = None;

// There can only be at most one was;wue
for file in cx.ws.target_dir.read_dir().unwrap().map(|x| x.unwrap()) {
let path = file.path();
if path.extension() == Some("o".as_ref()) {
wasm = Some(path);
break;
}
}
if let Some(path) = wasm {
files.push(path.into());
}

// This sort is necessary to make the result of `llvm-cov show` match between macos and linux.
files.sort_unstable();

Expand Down Expand Up @@ -944,6 +1001,7 @@ impl Format {
cmd.arg("-ignore-filename-regex");
cmd.arg(ignore_filename_regex);
}
cmd.args(["--sources", "."]);

match self {
Self::Text | Self::Html => {
Expand Down

0 comments on commit cacb1a3

Please sign in to comment.