use anyhow::Ok;
use anyhow::Result;
use glob::glob;
use std::env;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use uuid::Uuid;
pub fn set_wasmcov_dir(wasmcov_dir: Option<&PathBuf>) -> Result<String> {
let default_directory = &env::current_dir().unwrap().join("wasmcov");
let coverage_directory = wasmcov_dir.unwrap_or(default_directory);
env::set_var("WASMCOV_DIR", coverage_directory);
env::set_var("CARGO_TARGET_DIR", coverage_directory.join("target"));
if !Path::new(&coverage_directory).exists() {
fs::create_dir_all(coverage_directory).unwrap();
}
Ok(format!(
"export WASMCOV_DIR={}; export CARGO_TARGET_DIR={}",
coverage_directory.display(),
coverage_directory.join("target").display()
))
}
pub fn get_wasmcov_dir() -> Result<PathBuf> {
let default_directory = env::current_dir().unwrap().join("wasmcov");
let coverage_directory = env::var("WASMCOV_DIR")
.map(PathBuf::from)
.unwrap_or(default_directory);
if !Path::new(&coverage_directory).exists() {
fs::create_dir_all(&coverage_directory).unwrap();
}
Ok(coverage_directory)
}
pub fn get_profraw_dir() -> Result<PathBuf> {
let wasmcov_dir = get_wasmcov_dir().unwrap();
let profraw_dir = wasmcov_dir.join("profraw");
if !Path::new(&profraw_dir).exists() {
fs::create_dir_all(&profraw_dir).unwrap();
}
Ok(profraw_dir)
}
pub fn get_output_dir() -> Result<PathBuf> {
let wasmcov_dir = get_wasmcov_dir().unwrap();
let output_dir = wasmcov_dir.join("output");
if !Path::new(&output_dir).exists() {
fs::create_dir_all(&output_dir).unwrap();
}
Ok(output_dir)
}
pub fn get_target_dir() -> Result<PathBuf> {
let wasmcov_dir = get_wasmcov_dir().unwrap();
let output_dir = wasmcov_dir.join("target");
if !Path::new(&output_dir).exists() {
fs::create_dir_all(&output_dir).unwrap();
}
Ok(output_dir)
}
pub fn write_profraw(data: Vec<u8>) {
let id = Uuid::new_v4();
let profraw_dir = get_profraw_dir().unwrap();
if !Path::new(&profraw_dir).exists() {
fs::create_dir_all(&profraw_dir).unwrap();
}
let profraw_path = profraw_dir.join(format!("{}.profraw", id));
fs::write(profraw_path, data).unwrap();
}
pub fn extract_compiled_artefacts() -> Result<()> {
let target_dir = get_target_dir()?;
let output_dir = get_output_dir()?;
let wasm_files = glob(&format!("{}/**/deps/*.wasm", target_dir.to_str().unwrap()))?;
for wasm_file in wasm_files {
let wasm_file = wasm_file?;
let wasm_file_name = wasm_file.file_name().unwrap().to_str().unwrap();
let wasm_file_stem = wasm_file.file_stem().unwrap().to_str().unwrap();
let wasm_file_path = wasm_file.parent().unwrap();
let ll_file_path = wasm_file_path.join(format!("{}.ll", wasm_file_stem));
if !ll_file_path.exists() {
return Err(anyhow::anyhow!(
"No .ll file found for wasm file {}",
wasm_file_name
));
}
let wasm_file_output_path = output_dir.join(wasm_file_name);
let ll_file_output_path = output_dir.join(format!("{}.ll", wasm_file_stem));
fs::copy(wasm_file, wasm_file_output_path)?;
fs::copy(ll_file_path, ll_file_output_path)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::tempdir;
#[test]
fn test_set_wasmcov_dir() {
let temp_dir = tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_path_buf();
set_wasmcov_dir(Some(&temp_dir_path));
let wasmcov_dir = get_wasmcov_dir().unwrap();
assert_eq!(&wasmcov_dir, &temp_dir_path);
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_get_wasmcov_dir() {
let temp_dir = tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_path_buf();
set_wasmcov_dir(Some(&temp_dir_path));
let wasmcov_dir = get_wasmcov_dir().unwrap();
assert_eq!(wasmcov_dir, temp_dir_path);
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_get_profraw_dir() {
let temp_dir = tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_path_buf();
set_wasmcov_dir(Some(&temp_dir_path));
let profraw_dir = get_profraw_dir().unwrap();
assert_eq!(profraw_dir, temp_dir_path.join("profraw"));
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_get_output_dir() {
let temp_dir = tempdir().unwrap();
let temp_dir_path = &temp_dir.path().to_path_buf();
set_wasmcov_dir(Some(&temp_dir_path));
let output_dir = get_output_dir().unwrap();
assert_eq!(output_dir, temp_dir_path.join("output"));
assert!(Path::new(&output_dir).exists());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_write_profraw() {
let temp_dir = tempdir().unwrap();
let temp_dir_path = temp_dir.path().to_path_buf();
set_wasmcov_dir(Some(&temp_dir_path));
let data = vec![1, 2, 3];
write_profraw(data);
let profraw_dir = temp_dir_path.join("profraw");
let profraw_files = fs::read_dir(profraw_dir).unwrap();
let profraw_file = profraw_files.into_iter().next().unwrap().unwrap();
let profraw_path = profraw_file.path();
assert!(Path::new(&profraw_path).exists());
}
}