Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separated the relevant-reviewers comment from the DiffGraph comment. #183

Merged
merged 4 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions vibi-dpu/src/core/diff_graph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use crate::graph::mermaid_elements::generate_mermaid_flowchart;
use crate::utils::user::ProviderEnum;
use crate::utils::review::Review;
use crate::core::github;
use crate::utils::gitops::StatItem;

pub async fn send_diff_graph(review: &Review, excluded_files: &Vec<StatItem>, small_files: &Vec<StatItem>, access_token: &str) {
let comment = diff_graph_comment_text(excluded_files, small_files, review).await;
// add comment for GitHub
if review.provider().to_string() == ProviderEnum::Github.to_string() {
log::info!("Inserting comment on repo {}...", review.repo_name());
github::comment::add_comment(&comment, review, &access_token).await;
}

// TODO: add comment for Bitbucket
}

async fn diff_graph_comment_text(excluded_files: &Vec<StatItem>, small_files: &Vec<StatItem>, review: &Review) -> String {
let mut comment = "Relevant users for this PR:\n\n".to_string();

let all_diff_files: Vec<StatItem> = excluded_files
.iter()
.chain(small_files.iter())
.cloned() // Clone the StatItem instances since `iter` returns references
.collect(); // Collect into a new vector
if let Some(mermaid_text) = mermaid_comment(&all_diff_files, review).await {
comment += mermaid_text.as_str();
}
comment += "To modify DiffGraph settings, go to [your Vibinex settings page.](https://vibinex.com/settings)\n";
return comment;
}

async fn mermaid_comment(diff_files: &Vec<StatItem>, review: &Review) -> Option<String> {
let flowchart_str_opt = generate_mermaid_flowchart(diff_files, review).await;
if flowchart_str_opt.is_none() {
log::error!("[mermaid_comment] Unable to generate flowchart for review: {}", review.id());
return None;
}
let flowchart_str = flowchart_str_opt.expect("Empty flowchart_str_opt");
let mermaid_comment = format!(
"### Call Stack Diff\n```mermaid\n{}\n```",
flowchart_str,
);
return Some(mermaid_comment);
}

3 changes: 2 additions & 1 deletion vibi-dpu/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ pub mod utils;
pub mod approval;
pub mod bitbucket;
pub mod github;
pub mod trigger;
pub mod trigger;
pub mod diff_graph;
34 changes: 5 additions & 29 deletions vibi-dpu/src/core/relevance.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::{HashMap, HashSet};

use crate::{bitbucket::{self, user::author_from_commit}, core::github, db::review::save_review_to_db, graph::mermaid_elements::generate_mermaid_flowchart, utils::{aliases::get_login_handles, gitops::StatItem, hunk::{HunkMap, PrHunkItem}, relevance::Relevance, user::ProviderEnum}};
use crate::{bitbucket::{self, user::author_from_commit}, core::github, db::review::save_review_to_db, utils::{aliases::get_login_handles, gitops::StatItem, hunk::{HunkMap, PrHunkItem}, relevance::Relevance, user::ProviderEnum}};
use crate::utils::review::Review;
use crate::utils::repo_config::RepoConfig;

pub async fn process_relevance(hunkmap: &HunkMap, excluded_files: &Vec<StatItem>, small_files: &Vec<StatItem>, review: &Review,
pub async fn process_relevance(hunkmap: &HunkMap, excluded_files: &Vec<StatItem>, review: &Review,
repo_config: &mut RepoConfig, access_token: &str, old_review_opt: &Option<Review>,
) {
log::info!("Processing relevance of code authors...");
Expand All @@ -22,8 +22,7 @@ pub async fn process_relevance(hunkmap: &HunkMap, excluded_files: &Vec<StatItem>
let relevance_vec = relevance_vec_opt.expect("Empty coverage_obj_opt");
if repo_config.comment() {
// create comment text
let comment = comment_text(&relevance_vec, repo_config.auto_assign(),
excluded_files, small_files, review).await;
let comment = relevant_reviewers_comment_text(&relevance_vec, repo_config.auto_assign(), excluded_files).await;
// add comment
if review.provider().to_string() == ProviderEnum::Bitbucket.to_string() {
// TODO - add feature flag check
Expand Down Expand Up @@ -185,8 +184,8 @@ async fn calculate_relevance(prhunk: &PrHunkItem, review: &mut Review) -> Option
return Some(relevance_vec);
}

async fn comment_text(relevance_vec: &Vec<Relevance>, auto_assign: bool,
excluded_files: &Vec<StatItem>, small_files: &Vec<StatItem>, review: &Review) -> String {
async fn relevant_reviewers_comment_text(relevance_vec: &Vec<Relevance>, auto_assign: bool,
excluded_files: &Vec<StatItem>) -> String {
let mut comment = "Relevant users for this PR:\n\n".to_string(); // Added two newlines
comment += "| Contributor Name/Alias | Relevance |\n"; // Added a newline at the end
comment += "| -------------- | --------------- |\n"; // Added a newline at the end
Expand Down Expand Up @@ -226,32 +225,9 @@ async fn comment_text(relevance_vec: &Vec<Relevance>, auto_assign: bool,
comment += "If you are a relevant reviewer, you can use the [Vibinex browser extension](https://chromewebstore.google.com/detail/vibinex-code-review/jafgelpkkkopeaefadkdjcmnicgpcncc) to see parts of the PR relevant to you\n"; // Added a newline at the end
comment += "Relevance of the reviewer is calculated based on the git blame information of the PR. To know more, hit us up at contact@vibinex.com.\n\n"; // Added two newlines
comment += "To change comment and auto-assign settings, go to [your Vibinex settings page.](https://vibinex.com/u)\n"; // Added a newline at the end
let all_diff_files: Vec<StatItem> = excluded_files
.iter()
.chain(small_files.iter())
.cloned() // Clone the StatItem instances since `iter` returns references
.collect(); // Collect into a new vector
if let Some(mermaid_text) = mermaid_comment(&all_diff_files, review).await {
comment += mermaid_text.as_str();
}

return comment;
}

pub async fn mermaid_comment(diff_files: &Vec<StatItem>, review: &Review) -> Option<String> {
let flowchart_str_opt = generate_mermaid_flowchart(diff_files, review).await;
if flowchart_str_opt.is_none() {
log::error!("[mermaid_comment] Unable to generate flowchart for review: {}", review.id());
return None;
}
let flowchart_str = flowchart_str_opt.expect("Empty flowchart_str_opt");
let mermaid_comment = format!(
"### Call Stack Diff\n```mermaid\n{}\n```",
flowchart_str,
);
return Some(mermaid_comment);
}

pub fn deduplicated_relevance_vec_for_comment(relevance_vec: &Vec<Relevance>) -> (HashMap<Vec<String>, f32>, Vec<String>) {
let mut combined_relevance_map: HashMap<Vec<String>, f32> = HashMap::new();
let mut unmapped_aliases = Vec::new();
Expand Down
37 changes: 27 additions & 10 deletions vibi-dpu/src/core/review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{env, thread, time::Duration};
use serde_json::Value;

use crate::{
core::{relevance::process_relevance, utils::get_access_token},
core::{relevance::process_relevance, diff_graph::send_diff_graph, utils::get_access_token},
db::{
hunk::{get_hunk_from_db, store_hunkmap_to_db},
repo::get_clone_url_clone_dir,
Expand Down Expand Up @@ -41,24 +41,37 @@ pub async fn process_review(message_data: &Vec<u8>) {
}
let access_token = access_token_opt.expect("Empty access_token_opt");
commit_check(&review, &access_token).await;
let hunkmap_opt = process_review_changes(&review).await;
send_hunkmap(&hunkmap_opt, &review, &repo_config, &access_token, &old_review_opt).await;
process_review_changes(&review, &repo_config, &access_token, &old_review_opt).await;
}

pub async fn send_hunkmap(hunkmap_opt: &Option<(HunkMap, Vec<StatItem>, Vec<StatItem>)>, review: &Review,
pub async fn process_review_changes(review: &Review, repo_config: &RepoConfig, access_token: &str, old_review_opt: &Option<Review>) {
log::info!("Processing changes in code...");
if let Some((excluded_files, smallfiles)) = get_included_and_excluded_files(review) {
let hunkmap_opt = calculate_hunkmap(review, &smallfiles).await;
send_hunkmap(&hunkmap_opt, &excluded_files, review, repo_config, access_token, old_review_opt).await;

if repo_config.diff_graph() {
send_diff_graph(review, &excluded_files, &smallfiles, access_token).await;
}
} else {
log::error!("Failed to get included and excluded files");
}
}

pub async fn send_hunkmap(hunkmap_opt: &Option<HunkMap>, excluded_files: &Vec<StatItem>, review: &Review,
repo_config: &RepoConfig, access_token: &str, old_review_opt: &Option<Review>) {
if hunkmap_opt.is_none() {
log::error!("[send_hunkmap] Empty hunkmap in send_hunkmap");
return;
}
let (hunkmap, excluded_files, small_files) = hunkmap_opt.as_ref().expect("empty hunkmap_opt");
let hunkmap = hunkmap_opt.to_owned().expect("empty hunkmap_opt");
log::debug!("HunkMap = {:?}", &hunkmap);
store_hunkmap_to_db(&hunkmap, review);
publish_hunkmap(&hunkmap);
let hunkmap_async = hunkmap.clone();
let review_async = review.clone();
let mut repo_config_clone = repo_config.clone();
process_relevance(&hunkmap_async, excluded_files, small_files, &review_async,
process_relevance(&hunkmap_async, &excluded_files, &review_async,
&mut repo_config_clone, access_token, old_review_opt).await;
}

Expand All @@ -73,16 +86,20 @@ fn hunk_already_exists(review: &Review) -> bool {
log::debug!("[hunk_already_exists] Hunk already in db!");
return true;
}
pub async fn process_review_changes(review: &Review) -> Option<(HunkMap, Vec<StatItem>, Vec<StatItem>)>{
log::info!("Processing changes in code...");
let mut prvec = Vec::<PrHunkItem>::new();

fn get_included_and_excluded_files(review: &Review) -> Option<(Vec<StatItem>, Vec<StatItem>)> {
let fileopt = get_excluded_files(&review);
log::debug!("[process_review_changes] fileopt = {:?}", &fileopt);
if fileopt.is_none() {
log::error!("[process_review_changes] No files to review for PR {}", review.id());
return None;
}
let (excluded_files, smallfiles) = fileopt.expect("fileopt is empty");
return Some(( excluded_files, smallfiles));
}

async fn calculate_hunkmap(review: &Review, smallfiles: &Vec<StatItem>) -> Option<HunkMap> {
let mut prvec = Vec::<PrHunkItem>::new();
let diffmap = generate_diff(&review, &smallfiles);
log::debug!("[process_review_changes] diffmap = {:?}", &diffmap);
let linemap = process_diffmap(&diffmap);
Expand All @@ -102,7 +119,7 @@ pub async fn process_review_changes(review: &Review) -> Option<(HunkMap, Vec<Sta
format!("{}/hunkmap", review.db_key()),
);
log::debug!("[process_review_changes] hunkmap: {:?}", hunkmap);
return Some((hunkmap, excluded_files, smallfiles));
return Some(hunkmap);
}

pub async fn commit_check(review: &Review, access_token: &str) {
Expand Down
4 changes: 1 addition & 3 deletions vibi-dpu/src/core/trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ pub async fn process_trigger(message_data: &Vec<u8>) {
// commit_check
commit_check(&review, &access_token).await;
// process_review_changes
let hunkmap_opt = process_review_changes(&review).await;
// send_hunkmap
send_hunkmap(&hunkmap_opt, &review, &repo_config, &access_token, &None).await;
process_review_changes(&review, &repo_config, &access_token, &None).await;
}

fn parse_message_fields(msg: &Value) -> Option<TriggerReview> {
Expand Down
10 changes: 8 additions & 2 deletions vibi-dpu/src/utils/repo_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RepoConfig {
comment: bool,
auto_assign: bool
auto_assign: bool,
diff_graph: bool
}

impl RepoConfig {
Expand All @@ -16,11 +17,16 @@ impl RepoConfig {
self.auto_assign
}

pub fn diff_graph(&self) -> bool {
self.diff_graph
}

// Function to create a default RepoConfig
pub fn default() -> Self {
RepoConfig {
comment: true,
auto_assign: true
auto_assign: true,
diff_graph: false
}
}
}