Skip to main content

lux_cli/
sync.rs

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