From 56f436592dc84c8afcd1a23cac800a3879543ab0 Mon Sep 17 00:00:00 2001 From: Origami404 Date: Wed, 8 Apr 2026 23:44:43 +0800 Subject: [PATCH] fix: align comment numbering with review sequence --- README.en.md | 4 ++-- README.md | 4 ++-- src/model.rs | 1 + src/normalize.rs | 1 + src/render/markdown.rs | 32 ++++++++++++++++++++++++++++---- tests/render_json_tests.rs | 1 + tests/render_markdown_tests.rs | 11 +++++++++-- 7 files changed, 44 insertions(+), 10 deletions(-) diff --git a/README.en.md b/README.en.md index e01f423..d6cb915 100644 --- a/README.en.md +++ b/README.en.md @@ -71,14 +71,14 @@ total: files, +, - ## Review 1 () > -### Comment . +### Comment .. : : ```md ``` -### Reply .. +### Reply ... : : ```md diff --git a/README.md b/README.md index 68e534f..f26fb34 100644 --- a/README.md +++ b/README.md @@ -71,14 +71,14 @@ total: files, +, - ## Review 1 () > -### Comment . +### Comment .. : : ```md <原始评论正文> ``` -### Reply .. +### Reply ... : : ```md diff --git a/src/model.rs b/src/model.rs index 4daabf3..ad42280 100644 --- a/src/model.rs +++ b/src/model.rs @@ -67,6 +67,7 @@ pub struct CommentThread { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CommentItem { pub id: i64, + pub review_id: Option, pub user: String, pub created_at: String, pub path: Option, diff --git a/src/normalize.rs b/src/normalize.rs index 445c420..0aaa028 100644 --- a/src/normalize.rs +++ b/src/normalize.rs @@ -214,6 +214,7 @@ fn to_comment_item(comment: ReviewCommentDto) -> CommentItem { CommentItem { id: comment.id, + review_id: comment.pull_request_review_id, user: comment.user.login, created_at: comment.created_at, path: comment.path, diff --git a/src/render/markdown.rs b/src/render/markdown.rs index 2eefdd1..65dda56 100644 --- a/src/render/markdown.rs +++ b/src/render/markdown.rs @@ -29,9 +29,8 @@ fn render_comment_location(path: Option<&str>, line: Option) -> Option String { +fn render_thread(comment_number: &str, thread: &CommentThread) -> String { let mut out = String::new(); - let comment_number = format!("{pr_index}.{comment_seq}"); out.push_str(&format!("### Comment {comment_number}\n")); let root_location = render_comment_location(thread.root_comment.path.as_deref(), thread.root_comment.line) @@ -57,6 +56,7 @@ fn render_thread(pr_index: i64, comment_seq: usize, thread: &CommentThread) -> S pub fn render_markdown(doc: &PrReviewDocument) -> String { let mut out = String::new(); + let mut rendered = vec![false; doc.threads.len()]; out.push_str(&format!( "# {} `#{}` {}\n\n", @@ -108,11 +108,35 @@ pub fn render_markdown(doc: &PrReviewDocument) -> String { if let Some(submitted_at) = &review.submitted_at { out.push_str(&format!("- submitted at: {}\n\n", submitted_at)); } + + let mut review_comment_seq = 1usize; + for (thread_index, thread) in doc.threads.iter().enumerate() { + if thread.root_comment.review_id == Some(review.id) { + let comment_number = + format!("{}.{}.{}", doc.meta.pr_index, review_index + 1, review_comment_seq); + out.push_str(&render_thread(&comment_number, thread)); + out.push('\n'); + rendered[thread_index] = true; + review_comment_seq += 1; + } + } + + out.push('\n'); } + let mut has_unassigned = false; + let mut unassigned_seq = 1usize; for (thread_index, thread) in doc.threads.iter().enumerate() { - out.push_str(&render_thread(doc.meta.pr_index, thread_index + 1, thread)); - out.push('\n'); + if !rendered[thread_index] { + if !has_unassigned { + out.push_str("## Comments (No Review)\n\n"); + has_unassigned = true; + } + let comment_number = format!("{}.0.{}", doc.meta.pr_index, unassigned_seq); + out.push_str(&render_thread(&comment_number, thread)); + out.push('\n'); + unassigned_seq += 1; + } } out.trim_end().to_string() diff --git a/tests/render_json_tests.rs b/tests/render_json_tests.rs index 66d0311..62fa126 100644 --- a/tests/render_json_tests.rs +++ b/tests/render_json_tests.rs @@ -35,6 +35,7 @@ fn model_json_roundtrip() { line: Some(10), root_comment: CommentItem { id: 100, + review_id: Some(1), user: "reviewer".into(), created_at: "2026-04-08T12:00:00Z".into(), path: Some("src/main.rs".into()), diff --git a/tests/render_markdown_tests.rs b/tests/render_markdown_tests.rs index af81c5a..7f1123d 100644 --- a/tests/render_markdown_tests.rs +++ b/tests/render_markdown_tests.rs @@ -48,6 +48,7 @@ fn render_markdown_includes_expected_sections_and_preserves_comment_markdown() { line: Some(9), root_comment: CommentItem { id: 11, + review_id: Some(1), user: "bob".into(), created_at: "2026-04-08T11:01:00Z".into(), path: Some("src/main.rs".into()), @@ -56,6 +57,7 @@ fn render_markdown_includes_expected_sections_and_preserves_comment_markdown() { }, replies: vec![CommentItem { id: 12, + review_id: Some(1), user: "alice".into(), created_at: "2026-04-08T11:02:00Z".into(), path: Some("src/main.rs".into()), @@ -72,10 +74,14 @@ fn render_markdown_includes_expected_sections_and_preserves_comment_markdown() { assert!(md.contains("## Commits")); assert!(md.contains("## Diff Stat")); assert!(md.contains("## Review 1 (COMMENT)")); - assert!(md.contains("### Comment 7.1")); + assert!(md.contains("### Comment 7.1.1")); assert!(md.contains("src/main.rs:9")); - assert!(md.contains("### Reply 7.1.1")); + assert!(md.contains("### Reply 7.1.1.1")); assert!(md.contains("src/main.rs:12")); + let review_pos = md.find("## Review 1 (COMMENT)").unwrap(); + let comment_pos = md.find("### Comment 7.1.1").unwrap(); + assert!(comment_pos > review_pos); + assert!(!md.contains("## Comments (No Review)")); assert!(md.contains("````md")); assert!(md.contains("```rs\nlet x = 1;\n```")); assert!(md.contains("looks good")); @@ -111,6 +117,7 @@ fn render_markdown_uses_minimal_fence_for_plain_text() { line: None, root_comment: CommentItem { id: 1, + review_id: None, user: "bob".into(), created_at: "2026-04-08T11:00:00Z".into(), path: None,