1use std::collections::HashMap;
2
3use clap::Args;
4use eyre::Result;
5use itertools::Itertools;
6use lux_lib::{
7 config::{Config, LuaVersion},
8 progress::{MultiProgress, Progress},
9 project::Project,
10 remote_package_db::RemotePackageDB,
11};
12use text_trees::{FormatCharacters, StringTreeNode, TreeFormatting};
13
14use crate::utils::project::sync_dependencies_if_locked;
15
16#[derive(Args)]
17pub struct Outdated {
18 #[arg(long)]
19 porcelain: bool,
20}
21
22pub async fn outdated(outdated_data: Outdated, config: Config) -> Result<()> {
25 let progress = MultiProgress::new();
26 let bar = Progress::Progress(progress.new_bar());
27 let project = Project::current()?;
28 let tree = match &project {
29 Some(project) => {
30 sync_dependencies_if_locked(project, MultiProgress::new_arc(), &config).await?;
32 project.tree(&config)?
33 }
34 None => {
35 let lua_version = LuaVersion::from(&config)?.clone();
36 config.user_tree(lua_version)?
37 }
38 };
39
40 let package_db = RemotePackageDB::from_config(&config, &bar).await?;
41
42 bar.map(|b| b.set_message("🔎 Checking for outdated rocks...".to_string()));
43
44 let rock_list = tree.as_rock_list()?;
49 let rock_list = rock_list
50 .iter()
51 .filter_map(|rock| {
52 rock.to_package()
53 .has_update(&package_db)
54 .expect("TODO")
55 .map(|version| (rock, version))
56 })
57 .sorted_by_key(|(rock, _)| rock.name().to_owned())
58 .into_group_map_by(|(rock, _)| rock.name().to_owned());
59
60 bar.map(|b| b.finish_and_clear());
61
62 if outdated_data.porcelain {
63 let jsonified_rock_list = rock_list
64 .iter()
65 .map(|(key, values)| {
66 (
67 key,
68 values
69 .iter()
70 .map(|(k, v)| (k.version().to_string(), v.to_string()))
71 .collect::<HashMap<_, _>>(),
72 )
73 })
74 .collect::<HashMap<_, _>>();
75
76 println!("{}", serde_json::to_string(&jsonified_rock_list)?);
77 } else {
78 let formatting = TreeFormatting::dir_tree(FormatCharacters::box_chars());
79
80 for (rock_name, updates) in rock_list {
81 let mut tree = StringTreeNode::new(rock_name.to_string());
82
83 for (rock, latest_version) in updates {
84 tree.push(format!("{} => {}", rock.version(), latest_version));
85 }
86
87 println!("{}", tree.to_string_with_format(&formatting)?);
88 }
89 }
90
91 Ok(())
92}