forge/cmd/
update.rs
1use clap::{Parser, ValueHint};
2use eyre::{Context, Result};
3use foundry_cli::{
4 opts::Dependency,
5 utils::{Git, LoadConfig},
6};
7use foundry_config::{impl_figment_convert_basic, Config};
8use std::path::PathBuf;
9
10#[derive(Clone, Debug, Parser)]
12pub struct UpdateArgs {
13 dependencies: Vec<Dependency>,
15
16 #[arg(long, value_hint = ValueHint::DirPath, value_name = "PATH")]
21 root: Option<PathBuf>,
22
23 #[arg(short, long)]
25 force: bool,
26
27 #[arg(short, long)]
29 recursive: bool,
30}
31impl_figment_convert_basic!(UpdateArgs);
32
33impl UpdateArgs {
34 pub fn run(self) -> Result<()> {
35 let config = self.load_config()?;
36 let (root, paths) = dependencies_paths(&self.dependencies, &config)?;
37 let git = Git::new(&root);
39 if self.recursive {
40 git.submodule_update(self.force, true, false, true, paths)
42 } else {
43 git.submodule_update(self.force, true, false, false, paths)?;
45 git.submodule_foreach(false, "git submodule update --init --progress --recursive")
48 }
49 }
50}
51
52pub fn dependencies_paths(deps: &[Dependency], config: &Config) -> Result<(PathBuf, Vec<PathBuf>)> {
55 let git_root = Git::root_of(&config.root)?;
56 let libs = config.install_lib_dir();
57
58 let mut paths = Vec::with_capacity(deps.len());
59 for dep in deps {
60 let name = dep.name();
61 let dep_path = libs.join(name);
62 let rel_path = dep_path
63 .strip_prefix(&git_root)
64 .wrap_err("Library directory is not relative to the repository root")?;
65 if !dep_path.exists() {
66 eyre::bail!("Could not find dependency {name:?} in {}", dep_path.display());
67 }
68 paths.push(rel_path.to_owned());
69 }
70 Ok((git_root, paths))
71}