Skip to main content

lux_cli/
sync.rs

1use clap::Args;
2use eyre::{OptionExt, Result};
3use lux_lib::{
4    config::Config, lockfile::LocalPackage, operations::Sync, progress::MultiProgress,
5    project::Project,
6};
7
8#[derive(Args)]
9pub struct SyncProject {
10    /// Skip the integrity checks for installed rocks when syncing the project lockfile.
11    #[arg(long)]
12    no_integrity_check: bool,
13}
14
15/// Sync the current project's installed packages with its lux.toml.
16pub async fn sync(args: SyncProject, config: Config) -> Result<()> {
17    let project = Project::current()?.ok_or_eyre("No project found")?;
18    let progress = MultiProgress::new_arc(&config);
19
20    let dep_report = Sync::new(&project, &config)
21        .progress(progress.clone())
22        .validate_integrity(!args.no_integrity_check)
23        .sync_dependencies()
24        .await?;
25
26    let build_report = Sync::new(&project, &config)
27        .progress(progress.clone())
28        .validate_integrity(false)
29        .sync_build_dependencies()
30        .await?;
31
32    let test_report = Sync::new(&project, &config)
33        .progress(progress.clone())
34        .validate_integrity(false)
35        .sync_test_dependencies()
36        .await?;
37
38    let added: Vec<&LocalPackage> = dep_report
39        .added()
40        .iter()
41        .chain(build_report.added().iter())
42        .chain(test_report.added().iter())
43        .collect();
44
45    let removed: Vec<&LocalPackage> = dep_report
46        .removed()
47        .iter()
48        .chain(build_report.removed().iter())
49        .chain(test_report.removed().iter())
50        .collect();
51
52    if added.is_empty() && removed.is_empty() {
53        println!("Already in sync.");
54        return Ok(());
55    }
56
57    for pkg in added {
58        println!("+ {} {}", pkg.name(), pkg.version());
59    }
60    for pkg in removed {
61        println!("- {} {}", pkg.name(), pkg.version());
62    }
63
64    Ok(())
65}