leo_lang/cli/commands/
remove.rs1use super::*;
18use leo_package::{Location, Lock, Manifest, Workspace};
19
20#[derive(Parser, Debug)]
22#[clap(name = "leo", author = "The Leo Team <leo@provable.com>", version)]
23pub struct LeoRemove {
24 #[clap(
25 name = "NAME",
26 help = "The dependency name. Ex: `credits.aleo` or `credits`.",
27 required_unless_present = "all"
28 )]
29 pub(crate) name: Option<String>,
30
31 #[clap(
32 long,
33 help = "Clear all previous dependencies (or dev dependencies, if used with --dev).",
34 default_value = "false"
35 )]
36 pub(crate) all: bool,
37
38 #[clap(long, help = "This is a dev dependency.", default_value = "false")]
39 pub(crate) dev: bool,
40}
41
42impl Command for LeoRemove {
43 type Input = ();
44 type Output = ();
45
46 fn log_span(&self) -> Span {
47 tracing::span!(tracing::Level::INFO, "Leo")
48 }
49
50 fn prelude(&self, _: Context) -> Result<Self::Input> {
51 Ok(())
52 }
53
54 fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
55 let path = context.dir()?;
56
57 let manifest_path = path.join(leo_package::MANIFEST_FILENAME);
58 let mut manifest = Manifest::read_from_file(&manifest_path)?;
59
60 let dependencies = if self.dev {
61 if manifest.dev_dependencies.is_none() {
62 manifest.dev_dependencies = Some(Vec::new())
63 }
64 manifest.dev_dependencies.as_mut().unwrap()
65 } else {
66 if manifest.dependencies.is_none() {
67 manifest.dependencies = Some(Vec::new())
68 }
69 manifest.dependencies.as_mut().unwrap()
70 };
71
72 let mut removed_git_names: Vec<String> = Vec::new();
74
75 if self.all {
76 removed_git_names
77 .extend(dependencies.iter().filter(|dep| dep.location == Location::Git).map(|dep| dep.name.clone()));
78 *dependencies = Vec::new();
79 } else {
80 let raw = self.name.unwrap();
84 let alt =
85 if raw.ends_with(".aleo") { raw.trim_end_matches(".aleo").to_string() } else { format!("{raw}.aleo") };
86 let name = dependencies
87 .iter()
88 .find_map(|dep| if dep.name == raw || dep.name == alt { Some(dep.name.clone()) } else { None })
89 .unwrap_or(alt); let original_len = dependencies.len();
92 for dependency in dependencies.iter() {
93 if dependency.name == name {
94 match dependency.location {
95 leo_package::Location::Local | leo_package::Location::Test => tracing::warn!(
96 "✅ Successfully removed the local dependency {} with path {}.",
97 dependency.name,
98 dependency.path.as_ref().map(|p| p.display().to_string()).unwrap_or_default()
99 ),
100 leo_package::Location::Workspace => {
101 tracing::warn!("✅ Successfully removed the workspace dependency {}.", dependency.name)
102 }
103 leo_package::Location::Git => {
104 removed_git_names.push(dependency.name.clone());
105 tracing::warn!("✅ Successfully removed the git dependency {}.", dependency.name)
106 }
107 leo_package::Location::Network => {
108 tracing::warn!("✅ Successfully removed the network dependency {}.", dependency.name)
109 }
110 }
111 }
112 }
113
114 dependencies.retain(|dep| dep.name != name);
115
116 if dependencies.len() == original_len {
117 return Err(crate::errors::dependency_not_found(name).into());
118 }
119 }
120
121 manifest.write_to_file(&manifest_path)?;
122
123 if !removed_git_names.is_empty() {
125 let lock_dir = Workspace::discover_root(&path)?.unwrap_or_else(|| path.clone());
126 let mut lock = Lock::read(&lock_dir);
127 for name in &removed_git_names {
128 lock.remove_name(name);
129 }
130 lock.write(&lock_dir)?;
131 }
132
133 Ok(())
134 }
135}