in build2cmake/src/main.rs [253:364]
fn clean(
build_toml: PathBuf,
target_dir: Option<PathBuf>,
dry_run: bool,
force: bool,
ops_id: Option<String>,
) -> Result<()> {
let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?;
let build_compat = parse_and_validate(build_toml)?;
if matches!(build_compat, BuildCompat::V1(_)) {
eprintln!(
"build.toml is in the deprecated V1 format, use `build2cmake update-build` to update."
)
}
let build: Build = build_compat
.try_into()
.context("Cannot update build configuration")?;
let mut env = Environment::new();
env.set_trim_blocks(true);
minijinja_embed::load_templates!(&mut env);
let generated_files = get_generated_files(&env, &build, target_dir.clone(), ops_id)?;
if generated_files.is_empty() {
eprintln!("No generated artifacts found to clean.");
return Ok(());
}
if dry_run {
println!("Files that would be deleted:");
for file in &generated_files {
if file.exists() {
println!(" {}", file.to_string_lossy());
}
}
return Ok(());
}
let existing_files: Vec<_> = generated_files.iter().filter(|f| f.exists()).collect();
if existing_files.is_empty() {
eprintln!("No generated artifacts found to clean.");
return Ok(());
}
if !force {
println!("Files to be deleted:");
for file in &existing_files {
println!(" {}", file.to_string_lossy());
}
print!("Continue? [y/N] ");
std::io::stdout().flush()?;
let mut response = String::new();
std::io::stdin().read_line(&mut response)?;
let response = response.trim().to_lowercase();
if response != "y" && response != "yes" {
eprintln!("Aborted.");
return Ok(());
}
}
let mut deleted_count = 0;
let mut errors = Vec::new();
for file in existing_files {
match fs::remove_file(file) {
Ok(_) => {
deleted_count += 1;
println!("Deleted: {}", file.to_string_lossy());
}
Err(e) => {
errors.push(format!(
"Failed to delete {}: {}",
file.to_string_lossy(),
e
));
}
}
}
// Clean up empty directories
let dirs_to_check = [
target_dir.join("cmake"),
target_dir.join("torch-ext").join(&build.general.name),
target_dir.join("torch-ext"),
];
for dir in dirs_to_check {
if dir.exists() && is_empty_dir(&dir)? {
match fs::remove_dir(&dir) {
Ok(_) => println!("Removed empty directory: {}", dir.to_string_lossy()),
Err(e) => eyre::bail!("Failed to remove directory `{}`: {e:?}", dir.display()),
}
}
}
if !errors.is_empty() {
for error in errors {
eprintln!("Error: {error}");
}
bail!("Some files could not be deleted");
}
println!("Cleaned {deleted_count} generated artifacts.");
Ok(())
}