xtask/tasks/fuzz/
init_from_template.rsuse super::cargo_package_metadata;
use anyhow::Context;
#[derive(Clone, clap::ValueEnum)]
pub enum Template {
ChipsetDevice,
Basic,
}
pub(super) fn init_from_template(
ctx: &crate::XtaskCtx,
package: String,
template: Template,
) -> Result<(), anyhow::Error> {
let selected_crate = 'selected_crate: {
let cargo_tomls = ignore::Walk::new(&ctx.root).filter_map(|entry| match entry {
Ok(entry) if entry.file_name() == "Cargo.toml" => Some(entry.into_path()),
Err(err) => {
log::error!("error when walking over subdirectories: {}", err);
None
}
_ => None,
});
for cargo_toml_path in cargo_tomls {
let manifest = cargo_toml::Manifest::<cargo_package_metadata::PackageMetadata>::from_path_with_metadata(
&cargo_toml_path,
)?;
if manifest
.package
.as_ref()
.map(|x| x.name())
.unwrap_or_default()
== package
{
break 'selected_crate cargo_toml_path;
}
}
anyhow::bail!("unknown crate '{}'", package)
};
let new_fuzz_target = format!("fuzz_{}", package);
let new_fuzz_dir = selected_crate.parent().unwrap().join("fuzz");
if new_fuzz_dir.exists() {
anyhow::bail!("{} already has a `fuzz/` folder!", package)
}
fs_err::create_dir(&new_fuzz_dir)?;
fs_err::write(
new_fuzz_dir.join("Cargo.toml"),
match template {
Template::Basic => include_str!("./templates/basic.template.toml"),
Template::ChipsetDevice => include_str!("./templates/chipset_device.template.toml"),
}
.to_string()
.replacen("$FUZZ_CRATE_NAME$", &new_fuzz_target, usize::MAX)
.replacen("$PARENT$", &package, usize::MAX)
.replacen("$FUZZ_TARGET_NAME$", &new_fuzz_target, usize::MAX),
)?;
fs_err::write(
new_fuzz_dir.join(format!("{}.rs", new_fuzz_target)),
match template {
Template::Basic => include_str!("./templates/basic.template.rs"),
Template::ChipsetDevice => include_str!("./templates/chipset_device.template.rs"),
},
)?;
let new_workspace_entry = new_fuzz_dir.strip_prefix(&ctx.root)?.display().to_string();
let root_toml_raw = fs_err::read_to_string(ctx.root.join("Cargo.toml"))?;
let mut root_toml = root_toml_raw
.parse::<toml_edit::DocumentMut>()
.context("invalid root workspace Cargo.toml")?;
let members = &mut root_toml["workspace"]["members"].as_array_mut().unwrap();
members.push_formatted(toml_edit::Value::from(new_workspace_entry).decorated("\n ", ""));
fs_err::write(ctx.root.join("Cargo.toml"), root_toml.to_string())?;
Ok(())
}