forge/cmd/
remove.rs

1use clap::{Parser, ValueHint};
2use eyre::Result;
3use foundry_cli::{
4    opts::Dependency,
5    utils::{Git, LoadConfig},
6};
7use foundry_config::impl_figment_convert_basic;
8use std::path::PathBuf;
9
10/// CLI arguments for `forge remove`.
11#[derive(Clone, Debug, Parser)]
12pub struct RemoveArgs {
13    /// The dependencies you want to remove.
14    #[arg(required = true)]
15    dependencies: Vec<Dependency>,
16
17    /// The project's root path.
18    ///
19    /// By default root of the Git repository, if in one,
20    /// or the current working directory.
21    #[arg(long, value_hint = ValueHint::DirPath, value_name = "PATH")]
22    root: Option<PathBuf>,
23
24    /// Override the up-to-date check.
25    #[arg(short, long)]
26    force: bool,
27}
28impl_figment_convert_basic!(RemoveArgs);
29
30impl RemoveArgs {
31    pub fn run(self) -> Result<()> {
32        let config = self.load_config()?;
33        let (root, paths) = super::update::dependencies_paths(&self.dependencies, &config)?;
34        let git_modules = root.join(".git/modules");
35
36        // remove all the dependencies by invoking `git rm` only once with all the paths
37        Git::new(&root).rm(self.force, &paths)?;
38
39        // remove all the dependencies from .git/modules
40        for (Dependency { name, url, tag, .. }, path) in self.dependencies.iter().zip(&paths) {
41            sh_println!("Removing '{name}' in {}, (url: {url:?}, tag: {tag:?})", path.display())?;
42            std::fs::remove_dir_all(git_modules.join(path))?;
43        }
44
45        Ok(())
46    }
47}