git_workspace/commands/
lock.rs

1use crate::config::Config;
2use crate::lockfile::Lockfile;
3use crate::repository::Repository;
4use anyhow::Context;
5use indicatif::ParallelProgressIterator;
6use indicatif::{ProgressBar, ProgressStyle};
7use rayon::prelude::*;
8use std::path::Path;
9
10/// Update our lockfile
11pub fn lock(workspace: &Path) -> anyhow::Result<()> {
12    let config = Config::from_workspace(workspace)?;
13
14    // Read the configuration sources
15    let sources = config
16        .read()
17        .with_context(|| "Error reading config files")?;
18
19    let total_bar = ProgressBar::new(sources.len() as u64);
20    total_bar.set_style(
21        ProgressStyle::default_bar()
22            .template("[{elapsed_precise}] {percent}% [{wide_bar:.cyan/blue}] {pos}/{len} (ETA: {eta_precise})").expect("Invalid template")
23            .progress_chars("#>-"),
24    );
25
26    println!("Fetching repositories...");
27
28    // For each source, in sequence, fetch the repositories
29    let results = sources
30        .par_iter()
31        .map(|source| {
32            source
33                .fetch_repositories()
34                .with_context(|| format!("Error fetching repositories from {}", source))
35        })
36        .progress_with(total_bar)
37        .collect::<anyhow::Result<Vec<_>>>()?;
38    let mut all_repositories: Vec<Repository> = results.into_iter().flatten().collect();
39    // let all_repositories: Vec<Repository> = all_repository_results.iter().collect::<anyhow::Result<Vec<Repository>>>()?;
40    // We may have duplicated repositories here. Make sure they are unique based on the full path.
41    all_repositories.sort();
42    all_repositories.dedup();
43    // Write the lockfile out
44    let lockfile = Lockfile::new(workspace.join("workspace-lock.toml"));
45    lockfile.write(&all_repositories)?;
46    Ok(())
47}