jira_cli/commands/
projects.rs1use owo_colors::OwoColorize;
2
3use crate::api::{ApiError, JiraClient};
4use crate::output::{OutputConfig, use_color};
5
6pub async fn list(client: &JiraClient, out: &OutputConfig) -> Result<(), ApiError> {
7 let projects = client.list_projects().await?;
8
9 if out.json {
10 out.print_data(
11 &serde_json::to_string_pretty(&serde_json::json!({
12 "total": projects.len(),
13 "projects": projects.iter().map(|p| serde_json::json!({
14 "key": p.key,
15 "name": p.name,
16 "id": p.id,
17 "type": p.project_type,
18 })).collect::<Vec<_>>(),
19 }))
20 .expect("failed to serialize JSON"),
21 );
22 } else {
23 if projects.is_empty() {
24 out.print_message("No projects found.");
25 return Ok(());
26 }
27
28 let color = use_color();
29 let key_w = projects
30 .iter()
31 .map(|p| p.key.len())
32 .max()
33 .unwrap_or(3)
34 .max(3)
35 + 2;
36 let name_w = projects
37 .iter()
38 .map(|p| p.name.len())
39 .max()
40 .unwrap_or(4)
41 .max(4)
42 + 2;
43
44 let header = format!("{:<key_w$} {:<name_w$} {}", "Key", "Name", "Type");
45 if color {
46 println!("{}", header.bold());
47 } else {
48 println!("{header}");
49 }
50
51 for p in &projects {
52 let ptype = p.project_type.as_deref().unwrap_or("-");
53 if color {
54 println!(
55 "{} {:<name_w$} {}",
56 format!("{:<key_w$}", p.key).yellow(),
57 p.name,
58 ptype,
59 );
60 } else {
61 println!("{:<key_w$} {:<name_w$} {}", p.key, p.name, ptype);
62 }
63 }
64 out.print_message(&format!("{} projects", projects.len()));
65 }
66 Ok(())
67}
68
69pub async fn components(
70 client: &JiraClient,
71 out: &OutputConfig,
72 project_key: &str,
73) -> Result<(), ApiError> {
74 let comps = client.list_components(project_key).await?;
75
76 if out.json {
77 out.print_data(
78 &serde_json::to_string_pretty(&serde_json::json!({
79 "project": project_key,
80 "total": comps.len(),
81 "components": comps.iter().map(|c| serde_json::json!({
82 "id": c.id,
83 "name": c.name,
84 "description": c.description,
85 })).collect::<Vec<_>>(),
86 }))
87 .expect("failed to serialize JSON"),
88 );
89 } else {
90 if comps.is_empty() {
91 out.print_message(&format!("No components found for project {project_key}."));
92 return Ok(());
93 }
94
95 let color = use_color();
96 let name_w = comps.iter().map(|c| c.name.len()).max().unwrap_or(4).max(4) + 2;
97 let id_w = comps.iter().map(|c| c.id.len()).max().unwrap_or(2).max(2) + 2;
98
99 let header = format!("{:<name_w$} {:<id_w$} {}", "Name", "ID", "Description");
100 if color {
101 println!("{}", header.bold());
102 } else {
103 println!("{header}");
104 }
105
106 for c in &comps {
107 let desc = c.description.as_deref().unwrap_or("-");
108 if color {
109 println!(
110 "{} {:<id_w$} {}",
111 format!("{:<name_w$}", c.name).yellow(),
112 c.id,
113 desc,
114 );
115 } else {
116 println!("{:<name_w$} {:<id_w$} {}", c.name, c.id, desc);
117 }
118 }
119 out.print_message(&format!("{} components", comps.len()));
120 }
121 Ok(())
122}
123
124pub async fn show(client: &JiraClient, out: &OutputConfig, key: &str) -> Result<(), ApiError> {
125 let project = client.get_project(key).await?;
126
127 if out.json {
128 out.print_data(
129 &serde_json::to_string_pretty(&serde_json::json!({
130 "key": project.key,
131 "name": project.name,
132 "id": project.id,
133 "type": project.project_type,
134 }))
135 .expect("failed to serialize JSON"),
136 );
137 } else {
138 let color = use_color();
139 let key_str = if color {
140 project.key.yellow().bold().to_string()
141 } else {
142 project.key.clone()
143 };
144 println!("{key_str} {}", project.name);
145 println!(" ID: {}", project.id);
146 if let Some(ref t) = project.project_type {
147 println!(" Type: {t}");
148 }
149 }
150 Ok(())
151}