1use std::collections::HashMap;
2
3use clap::Args;
4use eyre::Result;
5use itertools::Itertools;
6use text_trees::{FormatCharacters, StringTreeNode, TreeFormatting};
7
8use lux_lib::{
9 config::Config,
10 package::{PackageName, PackageReq, PackageVersion},
11 progress::{MultiProgress, Progress},
12 remote_package_db::RemotePackageDB,
13};
14
15#[derive(Args)]
16pub struct Search {
17 lua_package_req: PackageReq,
18 #[arg(long)]
21 porcelain: bool,
22}
23
24pub async fn search(data: Search, config: Config) -> Result<()> {
25 let progress = MultiProgress::new();
26 let bar = Progress::Progress(progress.new_bar());
27 let formatting = TreeFormatting::dir_tree(FormatCharacters::box_chars());
28
29 let package_db = RemotePackageDB::from_config(&config, &bar).await?;
30
31 bar.map(|b| b.set_message(format!("🔎 Searching for `{}`...", data.lua_package_req)));
32
33 let lua_package_req = data.lua_package_req;
34
35 let result = package_db.search(&lua_package_req);
36
37 bar.map(|b| b.finish_and_clear());
38
39 if data.porcelain {
40 let rock_to_version_map: HashMap<&PackageName, Vec<&PackageVersion>> =
41 HashMap::from_iter(result);
42 println!("{}", serde_json::to_string(&rock_to_version_map)?);
43 } else {
44 for (key, versions) in result.into_iter().sorted() {
45 let mut tree = StringTreeNode::new(key.to_string().to_owned());
46
47 for version in versions {
48 tree.push(version.to_string());
49 }
50
51 println!("{}", tree.to_string_with_format(&formatting).unwrap());
52 }
53 }
54
55 Ok(())
56}