Call everything an issue rather than ticket consistently

This commit is contained in:
Daan Boerlage 2025-01-21 21:38:07 +01:00
parent 21203eed43
commit 476fa90200
Signed by: daan
GPG key ID: FCE070E1E4956606
2 changed files with 29 additions and 29 deletions

View file

@ -1,13 +1,13 @@
# Jirac # Jirac
A CLI for creating and managing Jira tickets directly from your terminal. A CLI for creating and managing Jira issues directly from your terminal.
## Features ## Features
- Create Jira tickets from markdown files or using your preferred editor - Create Jira issues from Markdown files or using your preferred editor
- List tickets assigned to specific users - List issues assigned to specific users
- Simple configuration using TOML - Simple configuration using TOML
- Interactive ticket creation with templates - Interactive issue creation with templates
- Execute JQL - Execute JQL
## Installation ## Installation
@ -36,10 +36,10 @@ Options:
-V, --version Print version -V, --version Print version
``` ```
### Creating a ticket ### Creating ab issue
``` ```
Create a ticket Create an issue
Usage: jirac create [OPTIONS] [MARKDOWN_FILE] Usage: jirac create [OPTIONS] [MARKDOWN_FILE]
@ -47,8 +47,8 @@ Arguments:
[MARKDOWN_FILE] A markdown file [MARKDOWN_FILE] A markdown file
Options: Options:
--project <PROJECT> The project key in which to create the ticket --project <PROJECT> The project key in which to create the issue
--open Open the new ticket in a browser --open Open the new issue in a browser
-h, --help Print help -h, --help Print help
``` ```
@ -58,10 +58,10 @@ Options:
jirac create jirac create
``` ```
*From a markdown file* *From a Markdown file*
```sh ```sh
jirac create ticket.md jirac create issue.md
``` ```
*Specify a project* *Specify a project*
@ -70,10 +70,10 @@ jirac create ticket.md
jirac create --project KEY jirac create --project KEY
``` ```
### Listing tickets ### Listing issues
``` ```
Find tickets currently assigned to you Find issues currently assigned to you
Usage: jirac list [OPTIONS] Usage: jirac list [OPTIONS]
@ -82,7 +82,7 @@ Options:
-h, --help Print help -h, --help Print help
``` ```
### Search for tickets ### Search for issues
``` ```
Search for issues Search for issues
@ -99,7 +99,7 @@ Options:
Use [JQL](https://support.atlassian.com/jira-software-cloud/docs/use-advanced-search-with-jira-query-language-jql/) to search for Issues. Use [JQL](https://support.atlassian.com/jira-software-cloud/docs/use-advanced-search-with-jira-query-language-jql/) to search for Issues.
*Find all in-progress tickets in a project* *Find all in-progress issues in a project*
``` ```
jirac search 'project = KEY AND status = "In Progress" ORDER BY created DESC' jirac search 'project = KEY AND status = "In Progress" ORDER BY created DESC'

View file

@ -10,7 +10,7 @@ use std::path::PathBuf;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
struct TicketMetadata { struct IssueMetadata {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
status: Option<String>, status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -101,15 +101,15 @@ struct Status {
name: String, name: String,
} }
fn get_ticket_template( fn get_issue_template(
ticket_metadata: &TicketMetadata, issue_metadata: &IssueMetadata,
) -> Result<String, Box<dyn std::error::Error>> { ) -> Result<String, Box<dyn std::error::Error>> {
let matter = toml::to_string(ticket_metadata)?; let matter = toml::to_string(issue_metadata)?;
let has_project = ticket_metadata.project.is_some(); let has_project = issue_metadata.project.is_some();
let template = format!( let template = format!(
r#"--- r#"---
# The ticket can contain the following properties: # The issue can contain the following properties:
# - status # - status
# - project (required) # - project (required)
# - assignee # - assignee
@ -139,9 +139,9 @@ fn get_editor() -> String {
fn parse_markdown( fn parse_markdown(
content: &str, content: &str,
) -> Result<(String, String, TicketMetadata), Box<dyn std::error::Error>> { ) -> Result<(String, String, IssueMetadata), Box<dyn std::error::Error>> {
let matter = Matter::<TOML>::new(); let matter = Matter::<TOML>::new();
let result = matter.parse_with_struct::<TicketMetadata>(content); let result = matter.parse_with_struct::<IssueMetadata>(content);
let (metadata, content) = match result { let (metadata, content) = match result {
Some(x) => (x.data, x.content), Some(x) => (x.data, x.content),
@ -153,7 +153,7 @@ fn parse_markdown(
// let metadata = result.data // let metadata = result.data
// .and_then(|d| toml::from_str(d).ok()) // .and_then(|d| toml::from_str(d).ok())
// .unwrap_or_else(|| TicketMetadata { // .unwrap_or_else(|| IssueMetadata {
// status: None, // status: None,
// project: None, // project: None,
// assignee: None, // assignee: None,
@ -182,7 +182,7 @@ fn parse_markdown(
fn create_temp_markdown(project_key: Option<String>) -> Result<String, Box<dyn std::error::Error>> { fn create_temp_markdown(project_key: Option<String>) -> Result<String, Box<dyn std::error::Error>> {
let mut temp_file = NamedTempFile::new()?; let mut temp_file = NamedTempFile::new()?;
let metadata = TicketMetadata { let metadata = IssueMetadata {
status: None, status: None,
project: project_key, project: project_key,
assignee: None, assignee: None,
@ -190,7 +190,7 @@ fn create_temp_markdown(project_key: Option<String>) -> Result<String, Box<dyn s
extra: Default::default(), extra: Default::default(),
}; };
let template = get_ticket_template(&metadata)?; let template = get_issue_template(&metadata)?;
temp_file.write_all(template.as_bytes())?; temp_file.write_all(template.as_bytes())?;
temp_file.flush()?; temp_file.flush()?;
@ -215,7 +215,7 @@ async fn create_jira_issue(
project_key: &str, project_key: &str,
title: &str, title: &str,
description: &str, description: &str,
metadata: &TicketMetadata, metadata: &IssueMetadata,
) -> Result<JiraResponse, Box<dyn std::error::Error>> { ) -> Result<JiraResponse, Box<dyn std::error::Error>> {
let client = reqwest::Client::new(); let client = reqwest::Client::new();
@ -356,7 +356,7 @@ pub async fn create(
}; };
if content.trim().is_empty() { if content.trim().is_empty() {
return Err("Empty content. Aborting ticket creation.".into()); return Err("Empty content. Aborting issue creation.".into());
} }
let (title, description, metadata) = parse_markdown(&content)?; let (title, description, metadata) = parse_markdown(&content)?;
@ -375,7 +375,7 @@ pub async fn create(
} }
// Confirm creation // Confirm creation
println!("\nAbout to create ticket:"); println!("\nAbout to create an issue:");
println!("Project: {}", selected_project); println!("Project: {}", selected_project);
if let Some(status) = &metadata.status { if let Some(status) = &metadata.status {
println!("Status: {}", status); println!("Status: {}", status);
@ -399,7 +399,7 @@ pub async fn create(
let url = format!("{}/browse/{}", config.url, response.key); let url = format!("{}/browse/{}", config.url, response.key);
println!("Successfully created ticket: {}", response.key); println!("Successfully created issue: {}", response.key);
println!("URL: {}", url); println!("URL: {}", url);
if open { if open {