shulkerscript_cli/subcommands/
clean.rs1use std::{borrow::Cow, path::PathBuf};
2
3use anyhow::Result;
4use path_absolutize::Absolutize as _;
5
6use crate::{
7 terminal_output::{print_error, print_info, print_success},
8 util,
9};
10
11#[derive(Debug, clap::Args, Clone)]
12pub struct CleanArgs {
13 #[arg(default_value = ".")]
15 pub path: PathBuf,
16 #[arg(short, long, env = "DATAPACK_DIR")]
18 pub output: Option<PathBuf>,
19 #[arg(short, long)]
21 pub all: bool,
22 #[arg(short, long)]
24 pub force: bool,
25 #[arg(short, long)]
27 pub verbose: bool,
28}
29
30pub fn clean(args: &CleanArgs) -> Result<()> {
31 let verbose = args.verbose;
32 let path = util::get_project_path(&args.path).unwrap_or(args.path.clone());
33 let dist_path = args
34 .output
35 .as_ref()
36 .map(Cow::Borrowed)
37 .unwrap_or_else(|| Cow::Owned(path.join("dist")));
38
39 let mut delete_paths = Vec::new();
40
41 let (project_config, _) = super::build::get_pack_config(&path)?;
42
43 if args.all {
44 if args.force {
45 delete_paths.push(dist_path.clone().into_owned());
46 } else {
47 print_error("You must use the --force flag to clean the whole output folder.")
48 }
49 } else {
50 delete_paths.push(dist_path.join(&project_config.pack.name));
51 delete_paths.push(dist_path.join(project_config.pack.name + ".zip"));
52 }
53
54 print_info(format!(
55 "Cleaning project at {}",
56 path.absolutize_from(&path)?.display()
57 ));
58
59 for delete_path in delete_paths {
60 if delete_path.exists() {
61 if verbose {
62 print_info(&format!("Deleting {:?}", delete_path));
63 }
64 if delete_path.is_file() {
65 std::fs::remove_file(&delete_path)?;
66 } else {
67 std::fs::remove_dir_all(&delete_path)?;
68 }
69 }
70 }
71
72 if dist_path.is_dir()
73 && dist_path.file_name().is_some_and(|s| s != "datapacks")
74 && dist_path.read_dir()?.next().is_none()
75 {
76 if verbose {
77 print_info(format!("Deleting {:?}, as it is empty", dist_path));
78 }
79 std::fs::remove_dir(dist_path.as_ref())?;
80 }
81
82 print_success("Project cleaned successfully.");
83
84 Ok(())
85}