Add output formatters
This commit is contained in:
parent
476fa90200
commit
f05461f1f7
5 changed files with 62 additions and 47 deletions
|
@ -78,7 +78,7 @@ Find issues currently assigned to you
|
||||||
Usage: jirac list [OPTIONS]
|
Usage: jirac list [OPTIONS]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--json Print json rather than pretty print
|
-o, --output <OUTPUT> Pick an output formatter [default: pretty] [possible values: pretty, json]
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ Arguments:
|
||||||
<JQL> A JQL string
|
<JQL> A JQL string
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--json Print JSON rather than pretty print
|
-o, --output <OUTPUT> Pick an output formatter [default: pretty] [possible values: pretty, json]
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ Arguments:
|
||||||
<ISSUE> An issue key, for example, KEY-123
|
<ISSUE> An issue key, for example, KEY-123
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--json Print JSON rather than pretty print
|
-o, --output <OUTPUT> Pick an output formatter [default: pretty] [possible values: pretty, json]
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
37
src/cli.rs
37
src/cli.rs
|
@ -1,4 +1,4 @@
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand, ValueEnum};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
|
@ -8,12 +8,27 @@ pub struct Cli {
|
||||||
pub command: Commands,
|
pub command: Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub enum FormatMode {
|
||||||
|
Pretty,
|
||||||
|
Json,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for FormatMode {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.to_possible_value()
|
||||||
|
.expect("no values are skipped")
|
||||||
|
.get_name()
|
||||||
|
.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
/// Create an issue
|
/// Create an issue
|
||||||
Create {
|
Create {
|
||||||
/// The project key in which to create the issue
|
/// The project key in which to create the issue
|
||||||
#[arg(long)]
|
#[arg(short, long)]
|
||||||
project: Option<String>,
|
project: Option<String>,
|
||||||
|
|
||||||
/// Open the new issue in a browser
|
/// Open the new issue in a browser
|
||||||
|
@ -26,15 +41,15 @@ pub enum Commands {
|
||||||
},
|
},
|
||||||
/// Find issues currently assigned to you
|
/// Find issues currently assigned to you
|
||||||
List {
|
List {
|
||||||
/// Print JSON rather than pretty print
|
/// Pick an output formatter
|
||||||
#[arg(long)]
|
#[arg(short, long, default_value_t = FormatMode::Pretty)]
|
||||||
json: bool,
|
output: FormatMode,
|
||||||
},
|
},
|
||||||
/// Search for issues
|
/// Search for issues
|
||||||
Search {
|
Search {
|
||||||
/// Print JSON rather than pretty print
|
/// Pick an output formatter
|
||||||
#[arg(long)]
|
#[arg(short, long, default_value_t = FormatMode::Pretty)]
|
||||||
json: bool,
|
output: FormatMode,
|
||||||
|
|
||||||
/// A JQL string
|
/// A JQL string
|
||||||
#[arg(value_name = "JQL")]
|
#[arg(value_name = "JQL")]
|
||||||
|
@ -42,9 +57,9 @@ pub enum Commands {
|
||||||
},
|
},
|
||||||
/// View an issue
|
/// View an issue
|
||||||
View {
|
View {
|
||||||
/// Print JSON rather than pretty print
|
/// Pick an output formatter
|
||||||
#[arg(long)]
|
#[arg(short, long, default_value_t = FormatMode::Pretty)]
|
||||||
json: bool,
|
output: FormatMode,
|
||||||
|
|
||||||
/// An issue key, for example, KEY-123
|
/// An issue key, for example, KEY-123
|
||||||
#[arg(value_name = "ISSUE")]
|
#[arg(value_name = "ISSUE")]
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
|
use crate::cli::FormatMode;
|
||||||
use crate::jira_config::JiraConfig;
|
use crate::jira_config::JiraConfig;
|
||||||
use crate::types::issue::{display_issues_json, display_issues_pretty};
|
use crate::types::issue::{display_issues_json, display_issues_pretty};
|
||||||
|
|
||||||
pub async fn exec(json: bool, jql: &str) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn exec(output: FormatMode, jql: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?;
|
let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?;
|
||||||
if !json {
|
if output != FormatMode::Json {
|
||||||
println!("Searching for issues...");
|
println!("Searching for issues...");
|
||||||
}
|
}
|
||||||
|
|
||||||
match crate::jql::run(&config, jql).await {
|
let result = match crate::jql::run(&config, jql).await {
|
||||||
Ok(response) => {
|
Ok(x) => x,
|
||||||
if json {
|
Err(reason) => {
|
||||||
if response.issues.is_empty() {
|
eprintln!("Error fetching issues: {}", reason);
|
||||||
println!("[]");
|
|
||||||
} else {
|
|
||||||
display_issues_json(&response.issues)?;
|
|
||||||
}
|
|
||||||
} else if response.issues.is_empty() {
|
|
||||||
println!("No results found for query.");
|
|
||||||
} else {
|
|
||||||
display_issues_pretty(&response.issues)?;
|
|
||||||
println!("Total issues: {}", response.total);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Error fetching issues: {}", e);
|
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match (output, result.issues.is_empty()) {
|
||||||
|
(FormatMode::Pretty, false) => {
|
||||||
|
display_issues_pretty(&result.issues)?;
|
||||||
|
println!("Total issues: {}", result.total);
|
||||||
|
}
|
||||||
|
(FormatMode::Pretty, true) => {
|
||||||
|
println!("No results found for query.");
|
||||||
|
}
|
||||||
|
(FormatMode::Json, false) => display_issues_json(&result.issues)?,
|
||||||
|
(FormatMode::Json, true) => println!("[]"),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cli::FormatMode;
|
||||||
use crate::jira_config::JiraConfig;
|
use crate::jira_config::JiraConfig;
|
||||||
use crate::types::issue::JiraIssue;
|
use crate::types::issue::JiraIssue;
|
||||||
use crossterm::style::{Color, Stylize};
|
use crossterm::style::{Color, Stylize};
|
||||||
|
@ -112,9 +113,9 @@ pub fn json_print(issues: &JiraIssue) -> Result<(), Box<dyn std::error::Error>>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn exec(json: bool, issue_key: &str) -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn exec(output: FormatMode, issue_key: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?;
|
let config = JiraConfig::load().map_err(|e| format!("Configuration error: {}", e))?;
|
||||||
if !json {
|
if output != FormatMode::Json {
|
||||||
println!("Loading issue data");
|
println!("Loading issue data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +139,10 @@ pub async fn exec(json: bool, issue_key: &str) -> Result<(), Box<dyn std::error:
|
||||||
|
|
||||||
let fetched_issue = fetch_issue(&config, &matched_issue.href).await?;
|
let fetched_issue = fetch_issue(&config, &matched_issue.href).await?;
|
||||||
|
|
||||||
if json {
|
match output {
|
||||||
json_print(&fetched_issue)?;
|
FormatMode::Pretty => pretty_print(&fetched_issue)?,
|
||||||
} else {
|
FormatMode::Json => json_print(&fetched_issue)?,
|
||||||
pretty_print(&fetched_issue)?;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
open,
|
open,
|
||||||
markdown_file,
|
markdown_file,
|
||||||
} => cmd::create::create(project, open, markdown_file).await?,
|
} => cmd::create::create(project, open, markdown_file).await?,
|
||||||
Commands::List { json } => {
|
Commands::List { output } => {
|
||||||
let jql = "assignee = currentUser() AND resolution = Unresolved order by updated DESC";
|
let jql = "assignee = currentUser() AND resolution = Unresolved order by updated DESC";
|
||||||
cmd::search::exec(json, jql).await?
|
cmd::search::exec(output, jql).await?
|
||||||
}
|
}
|
||||||
Commands::Search { json, jql } => cmd::search::exec(json, &jql).await?,
|
Commands::Search { output, jql } => cmd::search::exec(output, &jql).await?,
|
||||||
Commands::View { json, issue } => cmd::view::exec(json, &issue).await?,
|
Commands::View { output, issue } => cmd::view::exec(output, &issue).await?,
|
||||||
Commands::Init { url, email, token } => {
|
Commands::Init { url, email, token } => {
|
||||||
JiraConfig::init(url, email, token).await?;
|
JiraConfig::init(url, email, token).await?;
|
||||||
println!("Configuration initialized successfully!");
|
println!("Configuration initialized successfully!");
|
||||||
|
|
Loading…
Reference in a new issue