From 6721dcb03683e3616ec69fae2a27688b73b58c60 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 01:29:33 +0400 Subject: [PATCH 01/24] Feat: add get all func for comments module Get all Comments for issue/pull request without review comments --- src/git_utils/comments.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/git_utils/comments.rs b/src/git_utils/comments.rs index e8b4d44..cd11592 100644 --- a/src/git_utils/comments.rs +++ b/src/git_utils/comments.rs @@ -1,6 +1,6 @@ use std::process; -use octorust::types::PullsUpdateReviewRequest; +use octorust::types::{IssueComment, PullsUpdateReviewRequest}; use octorust::Client; use crate::git_utils::repo_info::RepoInfo; @@ -31,3 +31,28 @@ pub async fn create( } }; } + +// Get all Comments for issue/pull request without review comments +pub async fn get_all( + github_client: &Client, + repo_info: &RepoInfo, + issue_number: &i64, +) -> Vec { + let list_comments = github_client + .issues() + .list_all_comments( + &repo_info.get_owner(), + &repo_info.get_name(), + issue_number.clone(), + None, + ) + .await; + + return match list_comments { + Ok(c) => c.body, + Err(message) => { + eprintln!("Error: {message}"); + process::exit(1); + } + }; +} From 0232aad25d0e7a3ecf7162b314c7483c56c31d6e Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 01:32:37 +0400 Subject: [PATCH 02/24] Feat: add CommentCommand in CliCommand with get all --- src/cli_in/comment_command.rs | 7 +++++++ src/git_utils/comments.rs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cli_in/comment_command.rs b/src/cli_in/comment_command.rs index e5c7922..4b91f38 100644 --- a/src/cli_in/comment_command.rs +++ b/src/cli_in/comment_command.rs @@ -11,4 +11,11 @@ pub enum CommentCommand { #[clap(long, short, default_value = "")] body: String, }, + + /// Get all comments from issue/pull request + GetAll{ + /// Get all comments from issue/pull request with number + #[clap(long, short)] + number: i64, + }, } diff --git a/src/git_utils/comments.rs b/src/git_utils/comments.rs index cd11592..596fa45 100644 --- a/src/git_utils/comments.rs +++ b/src/git_utils/comments.rs @@ -36,14 +36,14 @@ pub async fn create( pub async fn get_all( github_client: &Client, repo_info: &RepoInfo, - issue_number: &i64, + number: &i64, ) -> Vec { let list_comments = github_client .issues() .list_all_comments( &repo_info.get_owner(), &repo_info.get_name(), - issue_number.clone(), + number.clone(), None, ) .await; From 01bd36d3249f24431a3a7352bc49607ca45b7ed4 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 01:33:17 +0400 Subject: [PATCH 03/24] Feat: add print comments method for print in cli mod --- src/cli_out/print_in_cli.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cli_out/print_in_cli.rs b/src/cli_out/print_in_cli.rs index d2553bb..7d795eb 100644 --- a/src/cli_out/print_in_cli.rs +++ b/src/cli_out/print_in_cli.rs @@ -1,4 +1,6 @@ -use octorust::types::{IssueSimple, MinimalRepository, Release}; +use std::process; + +use octorust::types::{IssueComment, IssueSimple, MinimalRepository, Release}; use crate::cli_in::set_vars::IssuesListStates; @@ -48,3 +50,21 @@ pub fn print_repos(repos: Vec, owner: String, owner_type: &st println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } } + +pub fn print_comments(list_comments: Vec) { + for comment in list_comments { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!( + "│Who create: {}", + match comment.user { + Some(u) => u.login, + None => { + eprintln!("Bad response from github"); + process::exit(1); + } + } + ); + println!("│Body: {}", comment.body); + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); + } +} From 63cc540ccb313c3d5ed676cb66f4dcc526516f10 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 01:34:13 +0400 Subject: [PATCH 04/24] Feat: add handle comment get all --- .../handle_commands/handle_comment.rs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/cli_parse/handle_commands/handle_comment.rs b/src/cli_parse/handle_commands/handle_comment.rs index 7587b4b..861c39c 100644 --- a/src/cli_parse/handle_commands/handle_comment.rs +++ b/src/cli_parse/handle_commands/handle_comment.rs @@ -1,16 +1,22 @@ use octorust::{self, Client}; use std::process; +// use std::str::FromStr; use crate::cli_in::comment_command::CommentCommand; +use crate::cli_out::print_in_cli::print_comments; use crate::git_utils::comments; -use crate::git_utils::repo_info::Repo; -use crate::git_utils::repo_info::RepoInfo; +use crate::git_utils::repo_info::{Repo, RepoInfo}; +// use crate::git_utils::repo_info::{RepoName, RepoOwner}; pub async fn handle_comment_command(github_client: Client, subcommand: CommentCommand) { match subcommand { CommentCommand::Create { number, body } => { handle_create(github_client, number, body).await; } + + CommentCommand::GetAll { number } => { + handle_get_all_for_issue(github_client, number).await + } }; } @@ -27,3 +33,17 @@ async fn handle_create(github_client: Client, number: i64, body: String) { println!("{result}"); } + +async fn handle_get_all_for_issue(github_client: Client, number: i64) { + let repo_info: RepoInfo = match RepoInfo::new(Repo::Current, None, None) { + Ok(rep) => rep, + Err(message) => { + eprintln!("Error: {message}"); + process::exit(1); + } + }; + + let result = comments::get_all(&github_client, &repo_info, &number).await; + + print_comments(result); +} From 1e731c5fec85f5e33b2edf605750b4f1905823ba Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 17:53:03 +0400 Subject: [PATCH 05/24] Feat: add rstest for tests with different cases --- Cargo.lock | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + 2 files changed, 122 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index b53058e..4bdd1d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,6 +261,12 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "fnv" version = "1.0.7" @@ -347,6 +353,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -404,9 +416,22 @@ version = "1.9.2" dependencies = [ "clap", "octorust", + "rstest", "tokio", ] +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + [[package]] name = "heck" version = "0.5.0" @@ -631,6 +656,16 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "instant" version = "0.1.13" @@ -986,6 +1021,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.95" @@ -1171,6 +1215,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "reqwest" version = "0.12.20" @@ -1299,6 +1349,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rstest" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + [[package]] name = "rustc-demangle" version = "0.1.25" @@ -1311,6 +1391,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustls" version = "0.23.27" @@ -1392,6 +1481,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" version = "1.0.219" @@ -1683,6 +1778,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.5.2" @@ -2062,6 +2174,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/Cargo.toml b/Cargo.toml index 37faf4b..ee86efe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" octorust = "0.10.0" clap = { version = "4.5.39", features = ["derive"] } tokio = { version = "1.45.1", features = ["full"] } +rstest = "0.25.0" From 4426aab0069137166fb19487a173f9722ac06aaa Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 17:53:32 +0400 Subject: [PATCH 06/24] Feat: add RepoOwner valid cases test --- src/git_utils/repo_info.rs | 42 +++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 6061296..789909b 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -186,21 +186,39 @@ impl RepoInfo { owner: Option, name: Option, ) -> Result { - match type_repo { Repo::Current => { - - let new_repo = RepoInfo { - owner: RepoOwner(String::new()), - name: RepoName(String::new()), - url: RepoUrl(String::new()), - ssh: RepoSsh(String::new()), - }; - return Self::get_current_repo(new_repo); - } + let new_repo = RepoInfo { + owner: RepoOwner(String::new()), + name: RepoName(String::new()), + url: RepoUrl(String::new()), + ssh: RepoSsh(String::new()), + }; + return Self::get_current_repo(new_repo); + } Repo::Input => { - return Self::create_repo_info(owner, name); - } + return Self::create_repo_info(owner, name); + } } } } + +#[cfg(test)] +mod repo_info_tests { + use super::*; + use rstest::rstest; + + // RepoOwner tests + // Tests valid cases + #[rstest] + #[case("aragami3070", "aragami3070")] + #[case("SE-legacy", "SE-legacy")] + #[case("The Drot Team", "The Drot Team")] + fn valid_repo_owner(#[case] input: &str, #[case] expected: &str) { + assert_eq!( + RepoOwner::from_str(input).unwrap(), + RepoOwner(expected.to_string()) + ); + } + +} From 57701d11b69e66fb0687fba3c9ab91a49a259f79 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 17:54:03 +0400 Subject: [PATCH 07/24] Feat: add RepoOwner empty string test --- src/git_utils/repo_info.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 789909b..ec6384b 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -221,4 +221,12 @@ mod repo_info_tests { ); } + // Tests empty string + #[test] + fn empty_repo_owner() { + assert_eq!( + RepoOwner::from_str("").unwrap_err(), + "Repo owner cannot be empty" + ); + } } From b980ce8a850d2653791d55d0a441b75c61b382ae Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 18:01:52 +0400 Subject: [PATCH 08/24] Feat: change empty RepoOwner test to universal invalid_repo_owner test with 4 cases --- src/git_utils/repo_info.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index ec6384b..96f8152 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -206,14 +206,14 @@ impl RepoInfo { #[cfg(test)] mod repo_info_tests { use super::*; - use rstest::rstest; + use rstest::rstest; // RepoOwner tests // Tests valid cases #[rstest] - #[case("aragami3070", "aragami3070")] - #[case("SE-legacy", "SE-legacy")] - #[case("The Drot Team", "The Drot Team")] + #[case("aragami3070", "aragami3070")] + #[case("SE-legacy", "SE-legacy")] + #[case("The Drot Team", "The Drot Team")] fn valid_repo_owner(#[case] input: &str, #[case] expected: &str) { assert_eq!( RepoOwner::from_str(input).unwrap(), @@ -221,12 +221,13 @@ mod repo_info_tests { ); } - // Tests empty string - #[test] - fn empty_repo_owner() { - assert_eq!( - RepoOwner::from_str("").unwrap_err(), - "Repo owner cannot be empty" - ); + // Tests invalid cases + #[rstest] + #[case("", "Repo owner cannot be empty")] + #[case("owner/repo", "Repo owner cannot contain '/'")] + #[case("/owner", "Repo owner cannot contain '/'")] + #[case("/owner/repo/", "Repo owner cannot contain '/'")] + fn invalid_repo_owner(#[case] input: &str, #[case] error: &str) { + assert_eq!(RepoOwner::from_str(input).unwrap_err(), error); } } From 3bde6699158a408d204289f2938862014862841c Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Tue, 15 Jul 2025 18:09:30 +0400 Subject: [PATCH 09/24] Feat: add RepoName tests --- src/git_utils/repo_info.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 96f8152..fa9e5c6 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -230,4 +230,28 @@ mod repo_info_tests { fn invalid_repo_owner(#[case] input: &str, #[case] error: &str) { assert_eq!(RepoOwner::from_str(input).unwrap_err(), error); } + + + // RepoName tests + // Tests valid cases + #[rstest] + #[case("github-cli", "github-cli")] + #[case("repo", "repo")] + #[case("kg-exam-4sem", "kg-exam-4sem")] + fn valid_repo_name(#[case] input: &str, #[case] expected: &str) { + assert_eq!( + RepoName::from_str(input).unwrap(), + RepoName(expected.to_string()) + ); + } + + // Tests invalid cases + #[rstest] + #[case("", "Repo name cannot be empty")] + #[case("owner/repo", "Repo name cannot contain '/'")] + #[case("/owner", "Repo name cannot contain '/'")] + #[case("/owner/repo/", "Repo name cannot contain '/'")] + fn invalid_repo_name(#[case] input: &str, #[case] error: &str) { + assert_eq!(RepoName::from_str(input).unwrap_err(), error); + } } From 8a7f973806f9db249ec4762684fc0b22320c15f3 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 00:33:11 +0400 Subject: [PATCH 10/24] Feat: add paste! for RepoOwner and RepoName tests in macro rules --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + 2 files changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 4bdd1d6..129cab9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -416,6 +416,7 @@ version = "1.9.2" dependencies = [ "clap", "octorust", + "paste", "rstest", "tokio", ] @@ -969,6 +970,12 @@ dependencies = [ "regex", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pem" version = "3.0.5" diff --git a/Cargo.toml b/Cargo.toml index ee86efe..2c1923e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ octorust = "0.10.0" clap = { version = "4.5.39", features = ["derive"] } tokio = { version = "1.45.1", features = ["full"] } rstest = "0.25.0" +paste = "1.0.15" From 95c3f1ce19fbcdd18da178b9313a1de958a897dd Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 00:44:02 +0400 Subject: [PATCH 11/24] Feat: add RepoOwner and RepoName tests in macro rule --- src/git_utils/repo_info.rs | 73 ++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index fa9e5c6..9bc08b2 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -206,52 +206,41 @@ impl RepoInfo { #[cfg(test)] mod repo_info_tests { use super::*; + use paste::paste; use rstest::rstest; - // RepoOwner tests - // Tests valid cases - #[rstest] - #[case("aragami3070", "aragami3070")] - #[case("SE-legacy", "SE-legacy")] - #[case("The Drot Team", "The Drot Team")] - fn valid_repo_owner(#[case] input: &str, #[case] expected: &str) { - assert_eq!( - RepoOwner::from_str(input).unwrap(), - RepoOwner(expected.to_string()) - ); - } - - // Tests invalid cases - #[rstest] - #[case("", "Repo owner cannot be empty")] - #[case("owner/repo", "Repo owner cannot contain '/'")] - #[case("/owner", "Repo owner cannot contain '/'")] - #[case("/owner/repo/", "Repo owner cannot contain '/'")] - fn invalid_repo_owner(#[case] input: &str, #[case] error: &str) { - assert_eq!(RepoOwner::from_str(input).unwrap_err(), error); + // Macros for Repo owner and name tests + macro_rules! repo_main_field_valid_tests { + ($type: ident, $type_name: literal) => { + paste! { + // Tests valid cases + #[rstest] + #[case("aragami3070", "aragami3070")] + #[case("SE-legacy", "SE-legacy")] + #[case("The Drot Team", "The Drot Team")] + fn [](#[case] input: &str, #[case] expected: &str) { + assert_eq!( + $type::from_str(input).unwrap(), + $type(expected.to_string()) + ); + } + + // Tests invalid cases + #[rstest] + #[case("", concat!($type_name, " cannot be empty"))] + #[case("owner/repo", concat!($type_name, " cannot contain '/'"))] + #[case("/owner", concat!($type_name, " cannot contain '/'"))] + #[case("/owner/repo/", concat!($type_name, " cannot contain '/'"))] + fn [](#[case] input: &str, #[case] error: &str) { + assert_eq!($type::from_str(input).unwrap_err(), error); + } + } + }; } - + // RepoOwner tests + repo_main_field_valid_tests!(RepoOwner, "Repo owner"); // RepoName tests - // Tests valid cases - #[rstest] - #[case("github-cli", "github-cli")] - #[case("repo", "repo")] - #[case("kg-exam-4sem", "kg-exam-4sem")] - fn valid_repo_name(#[case] input: &str, #[case] expected: &str) { - assert_eq!( - RepoName::from_str(input).unwrap(), - RepoName(expected.to_string()) - ); - } + repo_main_field_valid_tests!(RepoName, "Repo name"); - // Tests invalid cases - #[rstest] - #[case("", "Repo name cannot be empty")] - #[case("owner/repo", "Repo name cannot contain '/'")] - #[case("/owner", "Repo name cannot contain '/'")] - #[case("/owner/repo/", "Repo name cannot contain '/'")] - fn invalid_repo_name(#[case] input: &str, #[case] error: &str) { - assert_eq!(RepoName::from_str(input).unwrap_err(), error); - } } From bcd8975f017f110c3d523a76427b13e53c8fdaed Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 00:47:15 +0400 Subject: [PATCH 12/24] Feat: add cargo test command in rust.yml --- .github/workflows/rust.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 269dbe7..08ff4f1 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -17,3 +17,5 @@ jobs: - uses: actions/checkout@v4 - name: Build run: cargo build --verbose + - name: Run tests + run: cargo test --verbose From a6183b4c8fd411a7283ca988e9b512aebda94ce3 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 00:51:13 +0400 Subject: [PATCH 13/24] Chore: code formatting --- src/cli_in/comment_command.rs | 6 +++--- src/cli_in/issue_command.rs | 2 +- src/cli_in/mod.rs | 8 ++++---- src/cli_in/release_command.rs | 8 ++++---- src/cli_in/repo_command.rs | 11 ++++++++--- src/cli_parse/handle_cli.rs | 4 ++-- src/cli_parse/handle_commands/handle_comment.rs | 4 +--- src/cli_parse/handle_commands/handle_release.rs | 1 - src/cli_parse/handle_commands/mod.rs | 4 ++-- src/git_utils/repo_info.rs | 1 - 10 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/cli_in/comment_command.rs b/src/cli_in/comment_command.rs index 4b91f38..07e62b1 100644 --- a/src/cli_in/comment_command.rs +++ b/src/cli_in/comment_command.rs @@ -1,4 +1,4 @@ -use clap::{Subcommand}; +use clap::Subcommand; #[derive(Subcommand)] pub enum CommentCommand { @@ -11,9 +11,9 @@ pub enum CommentCommand { #[clap(long, short, default_value = "")] body: String, }, - + /// Get all comments from issue/pull request - GetAll{ + GetAll { /// Get all comments from issue/pull request with number #[clap(long, short)] number: i64, diff --git a/src/cli_in/issue_command.rs b/src/cli_in/issue_command.rs index 7192b7d..a06a98e 100644 --- a/src/cli_in/issue_command.rs +++ b/src/cli_in/issue_command.rs @@ -1,4 +1,4 @@ -use clap::{Subcommand}; +use clap::Subcommand; use crate::cli_in::set_vars::{IssuesListStates, States}; diff --git a/src/cli_in/mod.rs b/src/cli_in/mod.rs index b0ea10e..015c4b0 100644 --- a/src/cli_in/mod.rs +++ b/src/cli_in/mod.rs @@ -1,6 +1,6 @@ -pub mod read_cli; -pub mod set_vars; -pub mod issue_command; pub mod comment_command; -pub mod repo_command; +pub mod issue_command; +pub mod read_cli; pub mod release_command; +pub mod repo_command; +pub mod set_vars; diff --git a/src/cli_in/release_command.rs b/src/cli_in/release_command.rs index e413a4b..8ba1c02 100644 --- a/src/cli_in/release_command.rs +++ b/src/cli_in/release_command.rs @@ -12,10 +12,10 @@ pub enum ReleaseCommand { /// Repo name #[clap(long, short)] repo: RepoName, - /// Tag name + /// Tag name #[clap(long)] tag_name: String, - /// Target commit hash (only long variant of commit hash) + /// Target commit hash (only long variant of commit hash) #[clap(long)] target_commitish: String, /// Release name @@ -27,10 +27,10 @@ pub enum ReleaseCommand { /// Name of discussion category (optional) #[clap(long, default_value = "")] discussion_category_name: String, - /// It's draft? (optional) + /// It's draft? (optional) #[clap(long, default_value = None)] draft: Option, - /// It's prerelease? (optional) + /// It's prerelease? (optional) #[clap(long, default_value = None)] prerelease: Option, }, diff --git a/src/cli_in/repo_command.rs b/src/cli_in/repo_command.rs index 66c6ba1..bb5c2fa 100644 --- a/src/cli_in/repo_command.rs +++ b/src/cli_in/repo_command.rs @@ -1,6 +1,11 @@ use clap::Subcommand; -use crate::{cli_in::set_vars::{Orders, ReposListOrgSorts, ReposListOrgTypes, ReposListUserTypes, Visibilities}, git_utils::repo_info::{RepoName, RepoOwner}}; +use crate::{ + cli_in::set_vars::{ + Orders, ReposListOrgSorts, ReposListOrgTypes, ReposListUserTypes, Visibilities, + }, + git_utils::repo_info::{RepoName, RepoOwner}, +}; #[derive(Subcommand)] pub enum RepoCommand { @@ -137,7 +142,7 @@ pub enum RepoCommand { /// Get all repos from user GetAllFromUser { - /// Owner name + /// Owner name #[clap(long)] owner: String, /// Order can be only 'asc' or 'desc' (optional) @@ -151,7 +156,7 @@ pub enum RepoCommand { #[clap(long, short, default_value = "all")] type_value: ReposListUserTypes, ///// NOT WORKING NOW BECAUSE OCTORUST BREAK THIS - ///// Can include: + ///// Can include: ///// - owner: Repositories that are owned by the authenticated user. ///// - collaborator: Repositories that the user has been added to as a collaborator. ///// - organization_member: Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on. diff --git a/src/cli_parse/handle_cli.rs b/src/cli_parse/handle_cli.rs index 89c15d2..fcf9b5b 100644 --- a/src/cli_parse/handle_cli.rs +++ b/src/cli_parse/handle_cli.rs @@ -22,7 +22,7 @@ pub async fn handle_cli_command(args: Args, github_client: Client) { } CliCommand::Release { subcommand } => { - handle_release_command(github_client, subcommand).await; - } + handle_release_command(github_client, subcommand).await; + } } } diff --git a/src/cli_parse/handle_commands/handle_comment.rs b/src/cli_parse/handle_commands/handle_comment.rs index 861c39c..9c19528 100644 --- a/src/cli_parse/handle_commands/handle_comment.rs +++ b/src/cli_parse/handle_commands/handle_comment.rs @@ -14,9 +14,7 @@ pub async fn handle_comment_command(github_client: Client, subcommand: CommentCo handle_create(github_client, number, body).await; } - CommentCommand::GetAll { number } => { - handle_get_all_for_issue(github_client, number).await - } + CommentCommand::GetAll { number } => handle_get_all_for_issue(github_client, number).await, }; } diff --git a/src/cli_parse/handle_commands/handle_release.rs b/src/cli_parse/handle_commands/handle_release.rs index 2e57d88..d32f4b2 100644 --- a/src/cli_parse/handle_commands/handle_release.rs +++ b/src/cli_parse/handle_commands/handle_release.rs @@ -10,7 +10,6 @@ use crate::git_utils::repo_info::RepoInfo; use crate::git_utils::repo_info::RepoName; use crate::git_utils::repo_info::RepoOwner; - pub async fn handle_release_command(github_client: Client, subcommand: ReleaseCommand) { match subcommand { ReleaseCommand::Create { diff --git a/src/cli_parse/handle_commands/mod.rs b/src/cli_parse/handle_commands/mod.rs index 7ede74b..197a4af 100644 --- a/src/cli_parse/handle_commands/mod.rs +++ b/src/cli_parse/handle_commands/mod.rs @@ -1,4 +1,4 @@ -pub mod handle_issue; pub mod handle_comment; -pub mod handle_repo; +pub mod handle_issue; pub mod handle_release; +pub mod handle_repo; diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 9bc08b2..097ce5f 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -242,5 +242,4 @@ mod repo_info_tests { repo_main_field_valid_tests!(RepoOwner, "Repo owner"); // RepoName tests repo_main_field_valid_tests!(RepoName, "Repo name"); - } From 9443dc8600ad73bbeba9b555ce378a9375904309 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 01:46:17 +0400 Subject: [PATCH 14/24] Feat: add repo_links_field_valid_test macros for RepoUrl and RepoSsh --- src/git_utils/repo_info.rs | 42 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 097ce5f..4b3d2da 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -169,8 +169,8 @@ impl RepoInfo { )); } else { let mut new_repo = RepoInfo { - owner: RepoOwner(owner.unwrap().0.trim_start().trim_end().to_string()), - name: RepoName(name.unwrap().0.trim_start().trim_end().to_string()), + owner: RepoOwner(owner.unwrap().0.trim().to_string()), + name: RepoName(name.unwrap().0.trim().to_string()), url: RepoUrl(String::new()), ssh: RepoSsh(String::new()), }; @@ -242,4 +242,42 @@ mod repo_info_tests { repo_main_field_valid_tests!(RepoOwner, "Repo owner"); // RepoName tests repo_main_field_valid_tests!(RepoName, "Repo name"); + + macro_rules! repo_links_field_valid_test { + ($type: ident, $field_name: ident, $start_link: literal, $end_link: literal) => { + paste! { + // Tests valid cases + #[rstest] + #[case( + "aragami3070", + "github-cli", + concat!($start_link, "aragami3070/github-cli", $end_link) + )] + #[case( + " SE-legacy ", + "kg-exam-4sem", + concat!($start_link, "SE-legacy/kg-exam-4sem", $end_link) + )] + #[case( + "The Drot Team", + " Trash-Hack-Back-end", + concat!($start_link, "The-Drot-Team/Trash-Hack-Back-end", $end_link) + )] + fn [](#[case] owner: &str, #[case] name: &str, #[case] expected: &str) { + let repo = RepoInfo::new( + Repo::Input, + Some(RepoOwner(owner.to_string())), + Some(RepoName(name.to_string())), + ); + assert_eq!(repo.unwrap().$field_name.0.replace(" ", "-"), expected); + } + } + }; + } + + // RepoUrl valid test + repo_links_field_valid_test!(RepoUrl, url, "https://github.com/", "/"); + + // RepoSsh valid test + repo_links_field_valid_test!(RepoSsh, ssh, "git@github.com:", ".git"); } From 03f576b0e4e7d6a4585e4d472cd967361ceb7bc2 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:18:01 +0400 Subject: [PATCH 15/24] Feat: add valid_new_repo_info test --- src/git_utils/repo_info.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index 4b3d2da..da07bcd 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -66,6 +66,7 @@ impl FromStr for RepoName { } } +#[derive(Debug, Clone, PartialEq, Eq)] pub struct RepoInfo { owner: RepoOwner, name: RepoName, @@ -280,4 +281,17 @@ mod repo_info_tests { // RepoSsh valid test repo_links_field_valid_test!(RepoSsh, ssh, "git@github.com:", ".git"); + + // Tests valid case + #[test] + fn valid_new_repo_info() { + let repo_input = RepoInfo::new( + Repo::Input, + Some(RepoOwner("aragami3070".to_string())), + Some(RepoName("github-cli".to_string())), + ); + let repo_current = RepoInfo::new(Repo::Current, None, None); + assert_eq!(repo_input.unwrap(), repo_current.unwrap()); + } + } From 8f968944d0ec25384a6a7059f81749ac97dbe71d Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:18:19 +0400 Subject: [PATCH 16/24] Feat: add invalid_new_input_repo_info --- src/git_utils/repo_info.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/git_utils/repo_info.rs b/src/git_utils/repo_info.rs index da07bcd..4693151 100644 --- a/src/git_utils/repo_info.rs +++ b/src/git_utils/repo_info.rs @@ -294,4 +294,16 @@ mod repo_info_tests { assert_eq!(repo_input.unwrap(), repo_current.unwrap()); } + // Tests invalid case + #[rstest] + #[case(None, None)] + #[case(Some(RepoOwner("aragami3070".to_string())), None)] + #[case(None, Some(RepoName("github-cli".to_string())))] + fn invalid_new_input_repo_info( + #[case] owner: Option, + #[case] name: Option, + ) { + let repo_current = RepoInfo::new(Repo::Input, owner, name); + assert_eq!(repo_current.unwrap_err().kind(), io::ErrorKind::NotFound); + } } From 7fbc7a88d92041458dfa8919fff56b2b928a6aff Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:54:30 +0400 Subject: [PATCH 17/24] Feat: add get all from review in comments module --- src/git_utils/comments.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/git_utils/comments.rs b/src/git_utils/comments.rs index 596fa45..8aeec4b 100644 --- a/src/git_utils/comments.rs +++ b/src/git_utils/comments.rs @@ -1,6 +1,8 @@ use std::process; -use octorust::types::{IssueComment, PullsUpdateReviewRequest}; +use octorust::types::{ + IssueComment, Order, PullRequestReviewComment, PullsUpdateReviewRequest, Sort, +}; use octorust::Client; use crate::git_utils::repo_info::RepoInfo; @@ -56,3 +58,30 @@ pub async fn get_all( } }; } +pub async fn get_all_from_review( + github_client: &Client, + repo_info: &RepoInfo, + number: &i64, + sort: Sort, + direction: Order, +) -> Vec { + let list_comments = github_client + .pulls() + .list_all_review_comments( + &repo_info.get_owner(), + &repo_info.get_name(), + number.clone(), + sort, + direction, + None, + ) + .await; + + return match list_comments { + Ok(c) => c.body, + Err(message) => { + eprintln!("Error: {message}"); + process::exit(1); + } + }; +} From a01c3f65cbc77b815d9df3dea128df290c64e3d7 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:54:56 +0400 Subject: [PATCH 18/24] Feat: add print review comments method for print in cli mod --- src/cli_out/print_in_cli.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/cli_out/print_in_cli.rs b/src/cli_out/print_in_cli.rs index 7d795eb..5368d2c 100644 --- a/src/cli_out/print_in_cli.rs +++ b/src/cli_out/print_in_cli.rs @@ -1,6 +1,8 @@ use std::process; -use octorust::types::{IssueComment, IssueSimple, MinimalRepository, Release}; +use octorust::types::{ + IssueComment, IssueSimple, MinimalRepository, PullRequestReviewComment, Release, +}; use crate::cli_in::set_vars::IssuesListStates; @@ -68,3 +70,26 @@ pub fn print_comments(list_comments: Vec) { println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); } } + +pub fn print_review_comments(list_comments: Vec) { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!("│Review comments:"); + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); + for comment in list_comments { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!( + "│Who create: {}", + match comment.user { + Some(u) => u.login, + None => { + eprintln!("Bad response from github"); + process::exit(1); + } + } + ); + println!("│Body: {}", comment.body); + println!("│For line: {}", comment.line); + println!("│In file: {}", comment.path); + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); + } +} From 8ddaaa25d8a4a6d049d9b6ebcd014687b77d9e0a Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:56:00 +0400 Subject: [PATCH 19/24] Feat: add CommentTarget enum and impl FromStr --- src/cli_in/set_vars.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/cli_in/set_vars.rs b/src/cli_in/set_vars.rs index 2db7441..5832138 100644 --- a/src/cli_in/set_vars.rs +++ b/src/cli_in/set_vars.rs @@ -135,3 +135,21 @@ impl ToString for IssuesListStates { } } } + +#[derive(Debug, Clone)] +pub enum CommentTarget { + Issue, + PullRequest, +} + +impl FromStr for CommentTarget { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "issue" => Ok(CommentTarget::Issue), + "pull-request" => Ok(CommentTarget::PullRequest), + _ => Err("Bad input. Comment target can be only 'issue' or 'pull-request'".to_string()), + } + } +} From 04b4ef2d2df16e8fd5ef7c130e74ebf84d58255b Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 02:59:27 +0400 Subject: [PATCH 20/24] Feat: add flag for select get comments from issue or pull request for get-all command --- src/cli_in/comment_command.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cli_in/comment_command.rs b/src/cli_in/comment_command.rs index 07e62b1..2b4a72a 100644 --- a/src/cli_in/comment_command.rs +++ b/src/cli_in/comment_command.rs @@ -1,5 +1,7 @@ use clap::Subcommand; +use crate::cli_in::set_vars::CommentTarget; + #[derive(Subcommand)] pub enum CommentCommand { /// Create new comment for issue/pull request @@ -17,5 +19,8 @@ pub enum CommentCommand { /// Get all comments from issue/pull request with number #[clap(long, short)] number: i64, + /// Get from issue or from pull request (can be only 'issue' or 'pull-request') + #[clap(long, short)] + target: CommentTarget, }, } From 9389ea4fd44c29aefda17409125dd31cfdf18c98 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 03:01:15 +0400 Subject: [PATCH 21/24] Feat: add get and print review comments for target 'pull-request' in handle_get_all func --- .../handle_commands/handle_comment.rs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cli_parse/handle_commands/handle_comment.rs b/src/cli_parse/handle_commands/handle_comment.rs index 9c19528..8bc25e4 100644 --- a/src/cli_parse/handle_commands/handle_comment.rs +++ b/src/cli_parse/handle_commands/handle_comment.rs @@ -3,7 +3,8 @@ use std::process; // use std::str::FromStr; use crate::cli_in::comment_command::CommentCommand; -use crate::cli_out::print_in_cli::print_comments; +use crate::cli_in::set_vars::CommentTarget; +use crate::cli_out::print_in_cli::{print_comments, print_review_comments}; use crate::git_utils::comments; use crate::git_utils::repo_info::{Repo, RepoInfo}; // use crate::git_utils::repo_info::{RepoName, RepoOwner}; @@ -14,7 +15,9 @@ pub async fn handle_comment_command(github_client: Client, subcommand: CommentCo handle_create(github_client, number, body).await; } - CommentCommand::GetAll { number } => handle_get_all_for_issue(github_client, number).await, + CommentCommand::GetAll { number, target } => { + handle_get_all(github_client, number, target).await + } }; } @@ -32,7 +35,7 @@ async fn handle_create(github_client: Client, number: i64, body: String) { println!("{result}"); } -async fn handle_get_all_for_issue(github_client: Client, number: i64) { +async fn handle_get_all(github_client: Client, number: i64, target: CommentTarget) { let repo_info: RepoInfo = match RepoInfo::new(Repo::Current, None, None) { Ok(rep) => rep, Err(message) => { @@ -44,4 +47,21 @@ async fn handle_get_all_for_issue(github_client: Client, number: i64) { let result = comments::get_all(&github_client, &repo_info, &number).await; print_comments(result); + + let review_comments = match target { + CommentTarget::PullRequest => { + comments::get_all_from_review( + &github_client, + &repo_info, + &number, + octorust::types::Sort::Created, + octorust::types::Order::Asc, + ) + .await + } + CommentTarget::Issue => Vec::new(), + }; + if !review_comments.is_empty() { + print_review_comments(review_comments); + } } From 39b2de6f48e45dac770d0045a680998e84b6c239 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 03:02:59 +0400 Subject: [PATCH 22/24] Chore: update print comments method --- src/cli_out/print_in_cli.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cli_out/print_in_cli.rs b/src/cli_out/print_in_cli.rs index 5368d2c..7844d42 100644 --- a/src/cli_out/print_in_cli.rs +++ b/src/cli_out/print_in_cli.rs @@ -54,6 +54,9 @@ pub fn print_repos(repos: Vec, owner: String, owner_type: &st } pub fn print_comments(list_comments: Vec) { + println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); + println!("│Comments:"); + println!("╰────────────────────────────────────────────────────────────────────────────────────────────────"); for comment in list_comments { println!("╭────────────────────────────────────────────────────────────────────────────────────────────────"); println!( From c93308c790b5d14d3548798babace7f8ad8fcd0d Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 03:03:33 +0400 Subject: [PATCH 23/24] Chore: update road map --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index d9b0721..835a018 100644 --- a/Readme.md +++ b/Readme.md @@ -52,7 +52,7 @@ github-cli release --help ### comment - [x] Сделать создание комментария в issue/pull request -- [ ] Сделать получение комментариев для issue/pull request +- [x] Сделать получение комментариев для issue/pull request - [ ] Сделать редактирование комментария для issue/pull request - [ ] Сделать удаление комментария для issue/pull request From ac6995cbfb9b704b88e2328f549d5f366606b473 Mon Sep 17 00:00:00 2001 From: aragami3070 Date: Wed, 16 Jul 2025 03:04:02 +0400 Subject: [PATCH 24/24] Feat: update package version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 129cab9..cdce842 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,7 +412,7 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "github-cli" -version = "1.9.2" +version = "1.10.0" dependencies = [ "clap", "octorust", diff --git a/Cargo.toml b/Cargo.toml index 2c1923e..d27a1fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "github-cli" -version = "1.9.2" +version = "1.10.0" edition = "2021" [dependencies]