From 56693d6169efb791c58d436ff8a1fd60e58476e1 Mon Sep 17 00:00:00 2001 From: sycured <60801403+sycured@users.noreply.github.com> Date: Wed, 20 Dec 2023 23:55:57 -0500 Subject: [PATCH] fix #219 --- src/cli/project.rs | 6 +++ src/cli/project/cli_commands.rs | 37 +++++++++++++++ src/cli/project/cli_logic.rs | 22 +++++++++ src/library/project.rs | 81 ++++++++++++++++++++++++++++++++- src/library/urls.rs | 1 + 5 files changed, 146 insertions(+), 1 deletion(-) diff --git a/src/cli/project.rs b/src/cli/project.rs index 7d0d8f0..cfe59f7 100644 --- a/src/cli/project.rs +++ b/src/cli/project.rs @@ -19,8 +19,11 @@ pub fn cli_commands() -> Command { .subcommand_required(true) .arg_required_else_help(true) .subcommand(cli_commands::get_id()) + .subcommand(cli_commands::add_component()) .subcommand(cli_commands::create()) + .subcommand(cli_commands::delete_component()) .subcommand(cli_commands::delete_project()) + .subcommand(cli_commands::list_components()) .subcommand(cli_commands::list_features()) .subcommand(cli_commands::list_projects()) .subcommand(cli_commands::list_versions()) @@ -30,9 +33,12 @@ pub fn cli_commands() -> Command { pub fn logic_commands(global: &Global, args: &ArgMatches) { match args.subcommand() { + Some(("add_component", args)) => cli_logic::add_component(global, args), Some(("create", args)) => cli_logic::create(global, args), + Some(("delete_component", args)) => cli_logic::delete_component(global, args), Some(("delete_project", args)) => cli_logic::delete_project(global, args), Some(("get_id", args)) => cli_logic::get_id(global, args), + Some(("list_components", args)) => cli_logic::list_components(global, args), Some(("list_features", args)) => cli_logic::list_features(global, args), Some(("list_projects", args)) => cli_logic::list_projects(global, args), Some(("list_versions", args)) => cli_logic::list_versions(global, args), diff --git a/src/cli/project/cli_commands.rs b/src/cli/project/cli_commands.rs index 8bbfb8d..4ea25ce 100644 --- a/src/cli/project/cli_commands.rs +++ b/src/cli/project/cli_commands.rs @@ -7,6 +7,19 @@ use clap::{Arg, ArgAction::SetTrue, Command}; +pub fn add_component() -> Command { + Command::new("add_component") + .about("Create component") + .arg_required_else_help(true) + .arg(Arg::new("name").help("Component name").required(true)) + .arg(Arg::new("project_key").help("Project key").required(true)) + .arg( + Arg::new("jira_project_leadaccountid") + .help("Project lead (account id)") + .required(true), + ) +} + pub fn create() -> Command { Command::new("create") .about("Create project") @@ -41,6 +54,22 @@ pub fn create() -> Command { ) } +pub fn delete_component() -> Command { + Command::new("delete_component") + .about("Delete component") + .arg_required_else_help(true) + .arg( + Arg::new("component_id") + .help("Id of the component to delete") + .required(true), + ) + .arg( + Arg::new("move_issues_to") + .help("The ID of the component to replace the deleted component") + .required(false), + ) +} + pub fn delete_project() -> Command { Command::new("delete_project") .visible_aliases(["destroy", "destroy_project"]) @@ -64,6 +93,14 @@ pub fn get_id() -> Command { .arg(Arg::new("project_key").help("Project key").required(true)) } +pub fn list_components() -> Command { + Command::new("list_components") + .about("List project components") + .visible_aliases(["list-components"]) + .arg_required_else_help(true) + .arg(Arg::new("project_key").help("Project key").required(true)) +} + pub fn list_features() -> Command { Command::new("list_features") .about("List project features") diff --git a/src/cli/project/cli_logic.rs b/src/cli/project/cli_logic.rs index d284e86..dbde046 100644 --- a/src/cli/project/cli_logic.rs +++ b/src/cli/project/cli_logic.rs @@ -22,6 +22,15 @@ fn get_feature_keys(args: &ArgMatches) -> Vec<&String> { .unwrap() } +pub fn add_component(global: &Global, args: &ArgMatches) { + let (name, project_key, jira_project_leadaccountid) = ( + get_single_arg(args, "name"), + get_single_arg(args, "project_key"), + get_single_arg(args, "jira_project_leadaccountid"), + ); + project::add_component(global, name, project_key, jira_project_leadaccountid); +} + pub fn create(global: &Global, args: &ArgMatches) { let (project_name, project_key, jira_project_leadaccountid, project_type, project_template) = ( get_single_arg(args, "project_name"), @@ -40,6 +49,14 @@ pub fn create(global: &Global, args: &ArgMatches) { ); } +pub fn delete_component(global: &Global, args: &ArgMatches) { + let (component_id, move_issues_to) = ( + get_single_arg(args, "component_id"), + get_single_arg(args, "move_issues_to"), + ); + project::delete_component(global, component_id, Some(move_issues_to)); +} + pub fn delete_project(global: &Global, args: &ArgMatches) { let project_keys = get_project_keys(args); project_keys @@ -52,6 +69,11 @@ pub fn get_id(global: &Global, args: &ArgMatches) { project::get_id(global, project_key); } +pub fn list_components(global: &Global, args: &ArgMatches) { + let project_key = get_single_arg(args, "project_key"); + project::list_components(global, project_key); +} + pub fn list_features(global: &Global, args: &ArgMatches) { let project_key = get_single_arg(args, "project_key"); project::list_features(global, project_key); diff --git a/src/library/project.rs b/src/library/project.rs index fdf6d8a..1164ca3 100644 --- a/src/library/project.rs +++ b/src/library/project.rs @@ -19,6 +19,23 @@ use crate::{ Authorization, Global, HttpRequest, }; +pub fn add_component(global: &Global, name: &str, project_key: &str, lead_account_id: &str) { + let url: String = generate_url(&global.domain, "component", None); + let payload: Value = json!({ + "leadAccountId": lead_account_id, + "name": name, + "project": project_key + }); + match request(&HttpRequest::POST, &url, Some(&payload), global) { + Ok(_) => print_output(&format!( + "Component {name} created in project {project_key}" + )), + Err(e) => handle_error_and_exit(&format!( + "Impossible to create the component {name} in project {project_key}: {e}" + )), + } +} + #[allow(clippy::too_many_arguments)] pub fn create( global: &Global, @@ -66,6 +83,30 @@ pub fn delete(global: &Global, project_key: &str, enable_undo: bool) { } } +pub fn delete_component(global: &Global, component_id: &str, move_issues_to: Option<&str>) { + let mut url: String = generate_url( + &global.domain, + "component", + Some(&format!("/{component_id}")), + ); + if let Some(move_to) = move_issues_to { + url.push_str(&format!("?moveIssuesTo={move_to}")); + } + + if confirm(format!( + "Are you sure you want to delete the component {component_id}?" + )) { + match request(&HttpRequest::DELETE, &url, None, global) { + Ok(_) => print_output(&format!("Component {component_id} deleted")), + Err(e) => handle_error_and_exit(&format!( + "Impossible to create the component {component_id}: {e}" + )), + } + } else { + println!("Component {component_id} not deleted"); + } +} + #[allow(clippy::missing_panics_doc)] pub fn get_id(global: &Global, project_key: &str) { let url: String = generate_url(&global.domain, "project", Some(&format!("/{project_key}"))); @@ -87,6 +128,44 @@ pub fn get_id(global: &Global, project_key: &str) { } } +#[allow(clippy::missing_panics_doc)] +pub fn list_components(global: &Global, project_key: &str) { + let url: String = generate_url( + &global.domain, + "project", + Some(&format!("/{project_key}/components")), + ); + match request(&HttpRequest::GET, &url, None, global) { + Err(e) => handle_error_and_exit(&format!( + "Impossible to list components for project {project_key}: {e}" + )), + Ok(r) => { + let json: Value = r.json().expect("Failed to parse json"); + let rows: Vec> = json + .as_array() + .unwrap() + .par_iter() + .map(|x| { + vec![ + Cell::new(x["id"].as_str().unwrap()), + Cell::new(x["name"].as_str().unwrap()), + Cell::new(x["lead"]["accountId"].as_str().unwrap()), + ] + }) + .collect(); + create_and_print_table( + vec!["id", "name", "leadaccountid"], + &HashMap::from([ + (0, CellAlignment::Center), + (1, CellAlignment::Center), + (2, CellAlignment::Center), + ]), + rows, + ); + } + } +} + #[allow(clippy::missing_panics_doc)] pub fn list_features(global: &Global, project_key: &str) { let url: String = generate_url( @@ -99,7 +178,7 @@ pub fn list_features(global: &Global, project_key: &str) { "Impossible to list features for project {project_key}: {e}" )), Ok(r) => { - let json: Value = r.json().expect("Faield to parse json"); + let json: Value = r.json().expect("Failed to parse json"); let rows: Vec> = json["features"] .as_array() .unwrap() diff --git a/src/library/urls.rs b/src/library/urls.rs index e9b0433..59c2438 100644 --- a/src/library/urls.rs +++ b/src/library/urls.rs @@ -8,6 +8,7 @@ use phf::phf_map; pub(crate) static URLS: phf::Map<&'static str, &'static str> = phf_map! { + "component" => "/rest/api/3/component", "group" => "/rest/api/3/group", "group_user_picker" => "/rest/api/3/groupuserpicker", "groups" => "/rest/api/3/groups",