1use clap::Args;
2use eyre::{eyre, Context, OptionExt, Result};
3use itertools::Itertools;
4use lux_lib::package::{PackageName, PackageReq};
5use lux_lib::progress::{MultiProgress, Progress, ProgressBar};
6use lux_lib::project::Project;
7use lux_lib::remote_package_db::RemotePackageDB;
8use lux_lib::rockspec::lua_dependency;
9use lux_lib::{config::Config, operations};
10
11#[derive(Args)]
12pub struct Update {
13 #[arg(long)]
15 no_integrity_check: bool,
16
17 #[arg(long)]
19 toml: bool,
20
21 packages: Option<Vec<PackageReq>>,
24
25 #[arg(short, long, alias = "dev", visible_short_aliases = ['d', 'b'])]
29 build: Option<Vec<PackageReq>>,
30
31 #[arg(short, long)]
34 test: Option<Vec<PackageReq>>,
35}
36
37pub async fn update(args: Update, config: Config) -> Result<()> {
38 let progress = MultiProgress::new_arc();
39 progress.map(|p| p.add(ProgressBar::from("🔎 Looking for updates...".to_string())));
40
41 if args.toml {
42 let mut project = Project::current()?.ok_or_eyre("No project found")?;
43
44 let db =
45 RemotePackageDB::from_config(&config, &Progress::Progress(ProgressBar::new())).await?;
46 let package_names = to_package_names(args.packages.as_ref())?;
47 let mut upgrade_all = true;
48 if let Some(packages) = package_names {
49 upgrade_all = false;
50 project
51 .upgrade(lua_dependency::LuaDependencyType::Regular(packages), &db)
52 .await?;
53 }
54 let build_package_names = to_package_names(args.build.as_ref())?;
55 if let Some(packages) = build_package_names {
56 upgrade_all = false;
57 project
58 .upgrade(lua_dependency::LuaDependencyType::Build(packages), &db)
59 .await?;
60 }
61 let test_package_names = to_package_names(args.test.as_ref())?;
62 if let Some(packages) = test_package_names {
63 upgrade_all = false;
64 project
65 .upgrade(lua_dependency::LuaDependencyType::Test(packages), &db)
66 .await?;
67 }
68 if upgrade_all {
69 project.upgrade_all(&db).await?;
70 }
71 }
72
73 let updated_packages = operations::Update::new(&config)
74 .progress(progress)
75 .packages(args.packages)
76 .build_dependencies(args.build)
77 .test_dependencies(args.test)
78 .validate_integrity(!args.no_integrity_check)
79 .update()
80 .await
81 .wrap_err("update failed.")?;
82
83 if updated_packages.is_empty() {
84 println!("Nothing to update.");
85 return Ok(());
86 }
87
88 Ok(())
89}
90
91fn to_package_names(packages: Option<&Vec<PackageReq>>) -> Result<Option<Vec<PackageName>>> {
92 if packages.is_some_and(|pkgs| !pkgs.iter().any(|pkg| pkg.version_req().is_any())) {
93 return Err(eyre!(
94 "Cannot use version constraints to upgrade dependencies in lux.toml."
95 ));
96 }
97 Ok(packages
98 .as_ref()
99 .map(|pkgs| pkgs.iter().map(|pkg| pkg.name()).cloned().collect_vec()))
100}