warg_cli/commands/
info.rs1use super::CommonOptions;
2use anyhow::Result;
3use clap::{ArgAction, Args};
4use warg_client::{
5 keyring::Keyring,
6 storage::{ContentStorage, NamespaceMapStorage, PackageInfo, RegistryStorage},
7 Client,
8};
9use warg_crypto::hash::AnyHash;
10use warg_protocol::{registry::PackageName, Version};
11
12#[derive(Args)]
14pub struct InfoCommand {
15 #[clap(flatten)]
17 pub common: CommonOptions,
18
19 #[clap(value_name = "PACKAGE")]
21 pub package: Option<PackageName>,
22
23 #[clap(short, long, value_name = "NAMESPACES", action = ArgAction::SetTrue)]
25 pub namespaces: bool,
26}
27
28impl InfoCommand {
29 pub async fn exec(self) -> Result<()> {
31 let config = self.common.read_config()?;
32 let client = self.common.create_client(&config).await?;
33
34 print!("\nRegistry: {url} ", url = client.url().registry_domain());
35 if config.keyring_auth
36 && Keyring::from_config(&config)?
37 .get_auth_token(client.url())?
38 .is_some()
39 {
40 println!(
41 "(Using credentials{keyring_backend})",
42 keyring_backend = if let Some(keyring_backend) = &config.keyring_backend {
43 format!(" stored in `{keyring_backend}` keyring backend")
44 } else {
45 "".to_string()
46 }
47 );
48 } else {
49 println!("(Not logged in)");
50 }
51 println!("\nPackages in client storage:");
52 match self.package {
53 Some(package) => {
54 let info = client.package(&package).await?;
55 if let Some(registry) = client.get_warg_registry(package.namespace()).await? {
56 println!("Registry: {registry}");
57 }
58 Self::print_package_info(&info);
59 }
60 None => {
61 client
62 .registry()
63 .load_all_packages()
64 .await?
65 .iter()
66 .for_each(|(registry, packages)| {
67 println!("\nRegistry: {registry}");
68 packages.iter().for_each(Self::print_package_info);
69 });
70 }
71 }
72
73 if self.namespaces {
74 println!("\nNamespace mappings in client storage");
75 Self::print_namespace_map(&client).await?;
76 return Ok(());
77 }
78
79 println!();
80
81 Ok(())
82 }
83
84 fn print_package_info(info: &PackageInfo) {
85 println!(" Name: {name}", name = info.name);
86 println!(" Versions:");
87 info.state.releases().for_each(|r| {
88 if let Some(content) = r.content() {
89 Self::print_release(&r.version, content);
90 }
91 });
92 }
93
94 fn print_release(version: &Version, content: &AnyHash) {
95 println!(" {version} ({content})");
96 }
97
98 async fn print_namespace_map<R: RegistryStorage, C: ContentStorage, N: NamespaceMapStorage>(
99 client: &Client<R, C, N>,
100 ) -> Result<()> {
101 if let Some(map) = client.namespace_map().load_namespace_map().await? {
102 for (namespace, registry) in map {
103 println!(" {namespace}={registry}");
104 }
105 };
106
107 Ok(())
108 }
109}