diff --git a/Cargo.lock b/Cargo.lock index 7ba21ac..7bacea6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,7 +90,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -101,7 +101,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -208,7 +208,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -220,7 +220,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -235,6 +235,41 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "deranged" version = "0.4.0" @@ -244,6 +279,37 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -252,7 +318,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -338,7 +404,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -377,6 +443,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fzf-wrapped" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c61a44d13f57f2bb4c181a380dbb2e0367d1af53ca6721b5c9fc6b9c7e345d" +dependencies = [ + "derive_builder", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -412,9 +487,10 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "github-cli" -version = "1.12.0" +version = "1.13.0" dependencies = [ "clap", + "fzf-wrapped", "octorust", "paste", "rstest", @@ -636,6 +712,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -1381,7 +1463,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn", + "syn 2.0.103", "unicode-ident", ] @@ -1478,7 +1560,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.103", ] [[package]] @@ -1510,7 +1592,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1521,7 +1603,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1606,6 +1688,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -1618,6 +1706,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.103" @@ -1646,7 +1745,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1675,7 +1774,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1686,7 +1785,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1771,7 +1870,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1865,7 +1964,7 @@ checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -1983,7 +2082,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.103", "wasm-bindgen-shared", ] @@ -2018,7 +2117,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2224,7 +2323,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", "synstructure", ] @@ -2245,7 +2344,7 @@ checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] [[package]] @@ -2265,7 +2364,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", "synstructure", ] @@ -2305,5 +2404,5 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.103", ] diff --git a/Cargo.toml b/Cargo.toml index c43ff3f..c62f162 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "github-cli" -version = "1.12.0" +version = "1.13.0" edition = "2021" [dependencies] @@ -9,3 +9,4 @@ clap = { version = "4.5.39", features = ["derive"] } tokio = { version = "1.45.1", features = ["full"] } rstest = "0.26.1" paste = "1.0.15" +fzf-wrapped = "0.1.4" diff --git a/Readme.md b/Readme.md index 68c7774..6b140b1 100644 --- a/Readme.md +++ b/Readme.md @@ -60,7 +60,8 @@ github-cli release --help ### issue - [x] Сделать автораспознование гит репозитория - [x] Сделать получение всех issues -- [ ] Сделать выбор issue через fzf или аналоги из списка всех issues +- [x] Сделать получение issue +- [x] Сделать выбор issue через fzf из списка всех issues - [x] Сделать создание issue - [x] Сделать закрытие issue - [x] Сделать редактирование issue diff --git a/src/cli_in/issue_command.rs b/src/cli_in/issue_command.rs index 5338497..d4ebe5c 100644 --- a/src/cli_in/issue_command.rs +++ b/src/cli_in/issue_command.rs @@ -33,6 +33,47 @@ pub enum IssueCommand { iss_on_page: i64, }, + /// Get issue by number + Get { + /// Repo owner (optional) + #[clap(long, short, default_value = None)] + owner: Option, + /// Repo name (optional) + #[clap(long, short, default_value = None)] + repo: Option, + /// Get issue with number + #[clap(long, short)] + number: i64, + }, + + /// Get issue with comment from issues list + GetFromList { + /// Repo owner (optional) + #[clap(long, short, default_value = None)] + owner: Option, + /// Repo name (optional) + #[clap(long, short, default_value = None)] + repo: Option, + /// The user that created the issues (optional) + #[clap(long, short, default_value = "")] + creator: String, + /// Can be the name of a user. Pass in `none` for issues with no assigned user, and `*` for issues assigned to any user (optional) + #[clap(long, short, default_value = "none")] + assignee: String, + /// Indicates the state of the issues to return. Can be either `open`, `closed`, or `all` (optional) + #[clap(long, short, default_value = "open")] + state: IssuesListStates, + /// A list of comma separated label names. Example: `bug,ui,@high` (optional) + #[clap(long, short, default_value = "")] + labels: String, + /// Page number of the results to fetch (optional) + #[clap(long, short, default_value = "1")] + numb_of_page: i64, + /// Results on page (max 100) (optional) + #[clap(long, short, default_value = "30", value_parser = clap::value_parser!(i64).range(1..=100))] + iss_on_page: i64, + }, + /// Create issue Create { /// Repo owner (optional) diff --git a/src/cli_out/fuzzy_select.rs b/src/cli_out/fuzzy_select.rs new file mode 100644 index 0000000..1a99043 --- /dev/null +++ b/src/cli_out/fuzzy_select.rs @@ -0,0 +1,37 @@ +use std::error::Error; + +use fzf_wrapped::{run_with_output, Border, Fzf}; +use octorust::types::IssueSimple; + +pub fn choose_issue(list_issues: Vec) -> Result, Box> { + let issue_titles: Vec = list_issues + .iter() + .map(|iss| format!("({}) Title: {}", iss.number, iss.title)) + .collect(); + + let fzf = Fzf::builder() + .border(Border::Rounded) + .border_label("List issues") + .header("Pick needed issue form list") + .build()?; + + let choosed_issue = run_with_output(fzf, issue_titles); + + let issue_num = match choosed_issue { + Some(ch_i) => { + let index = match ch_i.find(')') { + Some(c) => c, + None => return Ok(None), + }; + ch_i[1..index].parse::() + } + None => return Ok(None), + }?; + + for issue in list_issues { + if issue.number == issue_num { + return Ok(Some(issue)); + } + } + Ok(None) +} diff --git a/src/cli_out/mod.rs b/src/cli_out/mod.rs index 5c37a6d..513cfbf 100644 --- a/src/cli_out/mod.rs +++ b/src/cli_out/mod.rs @@ -1 +1,2 @@ pub mod print_in_cli; +pub mod fuzzy_select; diff --git a/src/cli_out/print_in_cli.rs b/src/cli_out/print_in_cli.rs index bd8cebd..e1f56c1 100644 --- a/src/cli_out/print_in_cli.rs +++ b/src/cli_out/print_in_cli.rs @@ -1,20 +1,51 @@ -use std::process; +use std::error::Error; +use std::fmt; + +/// Errors returned by the tried print result +#[derive(Debug, PartialEq, Eq)] +pub struct PrintError { + kind: PrintErrorKind, + description: String, +} + +/// Type of PrintError +#[derive(Debug, PartialEq, Eq)] +enum PrintErrorKind { + /// Github response was wrong + BadResponse, +} + +impl Error for PrintError {} + +impl fmt::Display for PrintError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.kind { + PrintErrorKind::BadResponse => { + write!( + f, + "tried print, but the github response turned out to be invalid.\nDescription: {}", + &self.description + ) + } + } + } +} use octorust::types::{ - IssueComment, IssueSimple, MinimalRepository, PullRequestReviewComment, Release, + Issue, IssueComment, IssueSimple, MinimalRepository, PullRequestReviewComment, Release, }; use crate::cli_in::set_vars::IssuesListStates; pub fn print_release(result: Release) { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│Release tag: {}", result.tag_name); - println!("│Release id: {}", result.id); - println!("│Release title: {}", result.name); - println!("│Release body: {}", result.body); - println!("│Release tag_commit: {}", result.target_commitish); - println!("│Release url: {}", result.url); - println!("│Release upload_url: {}", result.upload_url); + println!(" Release tag: {}", result.tag_name); + println!(" Release id: {}", result.id); + println!(" Release title: {}", result.name); + println!(" Release body: {}", result.body); + println!(" Release tag_commit: {}", result.target_commitish); + println!(" Release url: {}", result.url); + println!(" Release upload_url: {}", result.upload_url); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } @@ -28,16 +59,66 @@ pub fn print_issues(list_issues: Vec, state: IssuesListStates, numb println!(); for issue in list_issues { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│Issue {}: {};", issue.number, issue.title); - println!("│Body: {}", issue.body); - println!("│Time: {}", issue.timeline_url); + println!(" Issue {}: {};", issue.number, issue.title); + println!(" Body: {}", issue.body); + println!(" labels:"); + for label in issue.labels { + println!(" {}: {}", label.name, label.description); + } + match issue.created_at { + Some(time) => { + println!(" Created at: {}", time); + } + None => {} + }; println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } } +pub fn print_simple_issue(issue: IssueSimple) { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!(" Issue {}: {};", issue.number, issue.title); + println!(" State: {}", issue.state); + println!(" Body: {}", issue.body); + println!(" labels:"); + for label in issue.labels { + println!(" {}: {}", label.name, label.description); + } + match issue.created_at { + Some(time) => { + println!(" Created at: {}", time); + } + None => {} + }; + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); +} + +pub fn print_issue(issue: Issue) { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!(" Issue {}: {};", issue.number, issue.title); + println!(" State: {}", issue.state); + println!(" Body: {}", issue.body); + println!(" labels:"); + for label in issue.labels { + match label.labels_data() { + Some(data) => { + println!(" {}: {}", data.name, data.description); + } + None => {} + } + } + match issue.created_at { + Some(time) => { + println!(" Created at: {}", time); + } + None => {} + }; + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); +} + pub fn print_url(result: String, description: &str) { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│{} : {}", description, result.replace(" ", "-")); + println!(" {} : {}", description, result.replace(" ", "-")); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } @@ -46,54 +127,62 @@ pub fn print_repos(repos: Vec, owner: String, owner_type: &st for repo in repos { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│Repo {}: {}", repo.id, repo.full_name); - println!("│Language: {}", repo.language); - println!("│Url: {}", repo.url); - println!("│Description: {}", repo.description); + println!(" Repo {}: {}", repo.id, repo.full_name); + println!(" Language: {}", repo.language); + println!(" Url: {}", repo.url); + println!(" Description: {}", repo.description); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } } -pub fn print_comments(list_comments: Vec) { +pub fn print_comments(list_comments: Vec) -> Result<(), Box> { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│Comments:"); + println!(" Comments:"); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); for comment in list_comments { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); println!( - "│Who create: {}", + " Who create: {}", match comment.user { Some(u) => u.login, None => { - eprintln!("Bad response from github"); - process::exit(1); + return Err(Box::new(PrintError { + kind: PrintErrorKind::BadResponse, + description: "User who create comment not find".to_string(), + })); } } ); - println!("│Body: {}", comment.body); + println!(" Body: {}", comment.body); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } + Ok(()) } -pub fn print_review_comments(list_comments: Vec) { +pub fn print_review_comments( + list_comments: Vec, +) -> Result<(), Box> { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); - println!("│Review comments:"); + println!(" Review comments:"); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); for comment in list_comments { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); println!( - "│Who create: {}", + " Who create: {}", match comment.user { Some(u) => u.login, None => { - eprintln!("Bad response from github"); - process::exit(1); + return Err(Box::new(PrintError { + kind: PrintErrorKind::BadResponse, + description: "User who create comment not find".to_string(), + })); } } ); - println!("│Body: {}", comment.body); - println!("│For line: {}", comment.line); - println!("│In file: {}", comment.path); + println!(" Body: {}", comment.body); + println!(" For line: {}", comment.line); + println!(" In file: {}", comment.path); println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } + Ok(()) } diff --git a/src/cli_parse/handle_commands/handle_comment.rs b/src/cli_parse/handle_commands/handle_comment.rs index 5e7a311..952e010 100644 --- a/src/cli_parse/handle_commands/handle_comment.rs +++ b/src/cli_parse/handle_commands/handle_comment.rs @@ -22,10 +22,12 @@ pub async fn handle_comment_command( Ok(()) } - CommentCommand::GetAll { + CommentCommand::GetAll { owner, repo, - number, target } => { + number, + target, + } => { handle_get_all(github_client, owner, repo, number, target).await?; Ok(()) } @@ -74,7 +76,7 @@ async fn handle_get_all( let result = comments::get_all(&github_client, &repo_info, &number).await?; - print_comments(result); + print_comments(result)?; let review_comments = match target { CommentTarget::PullRequest => { @@ -90,7 +92,7 @@ async fn handle_get_all( CommentTarget::Issue => Vec::new(), }; if !review_comments.is_empty() { - print_review_comments(review_comments); + print_review_comments(review_comments)?; } Ok(()) } @@ -111,6 +113,6 @@ async fn handle_get_all_from_review( let result = comments::get_all_from_review(&github_client, &repo_info, &number, sort.0, order.0).await?; - print_review_comments(result); + print_review_comments(result)?; Ok(()) } diff --git a/src/cli_parse/handle_commands/handle_issue.rs b/src/cli_parse/handle_commands/handle_issue.rs index bcbc8ad..a7679d1 100644 --- a/src/cli_parse/handle_commands/handle_issue.rs +++ b/src/cli_parse/handle_commands/handle_issue.rs @@ -4,7 +4,12 @@ use std::error::Error; use crate::cli_in::issue_command::IssueCommand; use crate::cli_in::set_vars::IssuesListStates; use crate::cli_in::set_vars::States; +use crate::cli_out::fuzzy_select::choose_issue; +use crate::cli_out::print_in_cli::print_comments; +use crate::cli_out::print_in_cli::print_issue; use crate::cli_out::print_in_cli::print_issues; +use crate::cli_out::print_in_cli::print_simple_issue; +use crate::git_utils::comments; use crate::git_utils::issues; use crate::git_utils::repo_info::Repo; use crate::git_utils::repo_info::RepoInfo; @@ -40,6 +45,40 @@ pub async fn handle_issue_command( Ok(()) } + IssueCommand::Get { + owner, + repo, + number, + } => { + handle_get(github_client, owner, repo, number).await?; + Ok(()) + } + + IssueCommand::GetFromList { + owner, + repo, + creator, + assignee, + state, + labels, + numb_of_page, + iss_on_page, + } => { + handle_get_form_list( + github_client, + owner, + repo, + creator, + assignee, + state, + labels, + numb_of_page, + iss_on_page, + ) + .await?; + Ok(()) + } + IssueCommand::Create { owner, repo, @@ -121,6 +160,68 @@ async fn handle_list( Ok(()) } +async fn handle_get( + github_client: Client, + owner: Option, + repo: Option, + number: i64, +) -> Result<(), Box> { + let repo_info = match owner { + Some(_) => RepoInfo::new(Repo::Input, owner, repo)?, + None => RepoInfo::new(Repo::Current, None, None)?, + }; + + let result = issues::get(&github_client, &repo_info, number).await?; + + let list_comments = comments::get_all(&github_client, &repo_info, &number).await?; + + print_issue(result); + print_comments(list_comments)?; + Ok(()) +} + +async fn handle_get_form_list( + github_client: Client, + owner: Option, + repo: Option, + creator: String, + assignee: String, + state: IssuesListStates, + labels: String, + numb_of_page: i64, + iss_on_page: i64, +) -> Result<(), Box> { + let repo_info = match owner { + Some(_) => RepoInfo::new(Repo::Input, owner, repo)?, + None => RepoInfo::new(Repo::Current, None, None)?, + }; + + let list_issues = issues::get_list( + &github_client, + &repo_info, + &creator, + &assignee, + &state.0, + &labels, + &numb_of_page, + &iss_on_page, + ) + .await?; + + let choosed_issue = choose_issue(list_issues)?; + + if let Some(ch_i) = choosed_issue { + let list_comments = comments::get_all(&github_client, &repo_info, &ch_i.number).await?; + + print_simple_issue(ch_i); + print_comments(list_comments)?; + } else { + println!("Issue not choosed or not find"); + } + + Ok(()) +} + async fn handle_create( github_client: Client, owner: Option, diff --git a/src/git_utils/issues.rs b/src/git_utils/issues.rs index 30cc28a..31fa38c 100644 --- a/src/git_utils/issues.rs +++ b/src/git_utils/issues.rs @@ -1,7 +1,7 @@ use std::error::Error; use octorust::types::{ - self, IssuesCreateRequest, IssuesCreateRequestLabelsOneOf, IssuesUpdateRequest, State, + self, Issue, IssuesCreateRequest, IssuesCreateRequestLabelsOneOf, IssuesUpdateRequest, State, TitleOneOf, }; use octorust::Client; @@ -9,6 +9,19 @@ use octorust::Client; use crate::git_utils::comments; use crate::git_utils::repo_info::RepoInfo; +pub async fn get( + github_client: &Client, + repo_info: &RepoInfo, + issue_number: i64, +) -> Result> { + let issue = github_client + .issues() + .get(&repo_info.get_owner(), &repo_info.get_name(), issue_number) + .await?; + + Ok(issue.body) +} + pub async fn get_list( github_client: &Client, repo_info: &RepoInfo, @@ -106,9 +119,9 @@ fn get_update_request( state: &State, ) -> IssuesUpdateRequest { let new_title = match title { - Some(t) => Some(TitleOneOf::String(t.to_string())), - None => None - }; + Some(t) => Some(TitleOneOf::String(t.to_string())), + None => None, + }; let new_labels = match labels { Some(l) => l