use super::Host;
use super::config::Config;
use crate::Result;
use camino::Utf8PathBuf;
use cargo_metadata::MetadataCommand;
use clap::Parser;
use ohno::IntoAppError;
use std::io::Write;
#[derive(Parser, Debug)]
pub struct InitArgs {
#[arg(value_name = "PATH")]
pub output: Option<Utf8PathBuf>,
#[arg(long, default_value = "Cargo.toml", value_name = "PATH")]
pub manifest_path: Utf8PathBuf,
}
pub fn init_config<H: Host>(host: &mut H, args: &InitArgs) -> Result<()> {
let output = if let Some(path) = &args.output {
path.clone()
} else {
let mut metadata_cmd = MetadataCommand::new();
let _ = metadata_cmd.manifest_path(&args.manifest_path);
let metadata = metadata_cmd.exec().into_app_err("retrieving workspace metadata")?;
metadata.workspace_root.join("aprz.toml")
};
Config::save_default(&output)?;
let _ = writeln!(host.output(), "Generated default configuration file: {output}");
Ok(())
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
use crate::commands::host::TestHost;
#[test]
#[cfg_attr(miri, ignore = "Miri cannot call GetModuleFileNameW")]
fn test_init_config_default_output_path() {
let mut host = TestHost::new();
let args = InitArgs {
output: None,
manifest_path: Utf8PathBuf::from("Cargo.toml"),
};
let metadata = MetadataCommand::new().exec().expect("metadata");
let generated = metadata.workspace_root.join("aprz.toml");
let had_existing = generated.as_std_path().exists();
let existing_contents = had_existing
.then(|| std::fs::read(generated.as_std_path()).expect("read existing aprz.toml"));
let result = init_config(&mut host, &args);
assert!(result.is_ok(), "init_config should succeed: {result:?}");
let output_text = String::from_utf8_lossy(&host.output_buf);
assert!(
output_text.contains("aprz.toml"),
"output should mention aprz.toml, got: {output_text}"
);
if let Some(contents) = existing_contents {
std::fs::write(generated.as_std_path(), contents).expect("restore aprz.toml");
} else {
let _ = std::fs::remove_file(generated.as_std_path());
}
}
}