workspacer_bump/
update_downstreams_recursively.rs

1// ---------------- [ File: workspacer-bump/src/update_downstreams_recursively.rs ]
2crate::ix!();
3
4#[async_trait]
5pub trait WorkspaceDownstreamExt {
6    async fn update_downstreams_recursively(
7        &mut self,
8        dep_name: &str,
9        new_version: &semver::Version,
10        visited: &mut HashSet<String>,
11    ) -> Result<(), WorkspaceError>;
12}
13
14#[async_trait]
15impl<P, H> WorkspaceDownstreamExt for Workspace<P, H>
16where
17    for<'async_trait> P: From<PathBuf> + AsRef<Path> + Send + Sync + 'async_trait,
18    H: CrateHandleInterface<P> + Bump<Error = CrateError> + Send + Sync,
19{
20    async fn update_downstreams_recursively(
21        &mut self,
22        dep_name: &str,
23        new_version: &semver::Version,
24        visited: &mut HashSet<String>,
25    ) -> Result<(), WorkspaceError> {
26
27        // 1) local copy of crates
28        let crate_list: Vec<_> = self.crates().iter().cloned().collect();
29
30        for arc_crate in crate_list {
31            let crate_name = {
32                let h = arc_crate.lock().await;
33                h.name().to_string()
34            };
35            if visited.contains(&crate_name) {
36                continue;
37            }
38
39            // 2) lock for short, synchronous update
40            let changed = {
41
42                let h          = arc_crate.lock().await;
43                let toml           = h.cargo_toml();
44                let mut toml_guard = toml.lock().await;
45
46                // do in-memory updates
47                let changed = toml_guard.update_dependency_version(dep_name, &new_version.to_string())?;
48
49                changed
50                // guard dropped
51            };
52
53            if changed {
54                // 3) do async save, once the guard is dropped
55                {
56                    let crate_guard = arc_crate.lock().await;
57
58                    let toml = crate_guard.cargo_toml();
59
60                    let toml_guard = toml.lock().await;
61
62                    toml_guard.save_to_disk().await?;
63                }
64
65                visited.insert(crate_name.clone());
66                self.update_downstreams_recursively(&crate_name, new_version, visited).await?;
67            }
68        }
69
70        Ok(())
71    }
72}