Skip to main content

jira_cli/commands/
projects.rs

1use 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 versions(
125    client: &JiraClient,
126    out: &OutputConfig,
127    project_key: &str,
128) -> Result<(), ApiError> {
129    let vers = client.list_versions(project_key).await?;
130
131    if out.json {
132        out.print_data(
133            &serde_json::to_string_pretty(&serde_json::json!({
134                "project": project_key,
135                "total": vers.len(),
136                "versions": vers.iter().map(|v| serde_json::json!({
137                    "id": v.id,
138                    "name": v.name,
139                    "description": v.description,
140                    "released": v.released,
141                    "archived": v.archived,
142                    "releaseDate": v.release_date,
143                })).collect::<Vec<_>>(),
144            }))
145            .expect("failed to serialize JSON"),
146        );
147    } else {
148        if vers.is_empty() {
149            out.print_message(&format!("No versions found for project {project_key}."));
150            return Ok(());
151        }
152
153        let color = use_color();
154        let name_w = vers.iter().map(|v| v.name.len()).max().unwrap_or(4).max(4) + 2;
155        let id_w = vers.iter().map(|v| v.id.len()).max().unwrap_or(2).max(2) + 2;
156
157        let header = format!(
158            "{:<name_w$} {:<id_w$} {:<10} {}",
159            "Name", "ID", "Released", "Release Date"
160        );
161        if color {
162            println!("{}", header.bold());
163        } else {
164            println!("{header}");
165        }
166
167        for v in &vers {
168            let released = match v.released {
169                Some(true) => "yes",
170                Some(false) => "no",
171                None => "-",
172            };
173            let release_date = v.release_date.as_deref().unwrap_or("-");
174            if color {
175                println!(
176                    "{} {:<id_w$} {:<10} {}",
177                    format!("{:<name_w$}", v.name).yellow(),
178                    v.id,
179                    released,
180                    release_date,
181                );
182            } else {
183                println!(
184                    "{:<name_w$} {:<id_w$} {:<10} {}",
185                    v.name, v.id, released, release_date
186                );
187            }
188        }
189        out.print_message(&format!("{} versions", vers.len()));
190    }
191    Ok(())
192}
193
194pub async fn show(client: &JiraClient, out: &OutputConfig, key: &str) -> Result<(), ApiError> {
195    let project = client.get_project(key).await?;
196
197    if out.json {
198        out.print_data(
199            &serde_json::to_string_pretty(&serde_json::json!({
200                "key": project.key,
201                "name": project.name,
202                "id": project.id,
203                "type": project.project_type,
204            }))
205            .expect("failed to serialize JSON"),
206        );
207    } else {
208        let color = use_color();
209        let key_str = if color {
210            project.key.yellow().bold().to_string()
211        } else {
212            project.key.clone()
213        };
214        println!("{key_str}  {}", project.name);
215        println!("  ID:   {}", project.id);
216        if let Some(ref t) = project.project_type {
217            println!("  Type: {t}");
218        }
219    }
220    Ok(())
221}