shulkerscript_cli/subcommands/
clean.rs

1use 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    /// The path of the project to clean.
14    #[arg(default_value = ".")]
15    pub path: PathBuf,
16    /// The path of the directory where the compiled datapacks are placed.
17    #[arg(short, long, env = "DATAPACK_DIR")]
18    pub output: Option<PathBuf>,
19    /// Clean the whole output folder
20    #[arg(short, long)]
21    pub all: bool,
22    /// Force clean
23    #[arg(short, long)]
24    pub force: bool,
25    /// Enable verbose output.
26    #[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}