From 7480a85ed8b84e0fe06ca5dda8719b77d6eb4e24 Mon Sep 17 00:00:00 2001
From: prozolic <42107886+prozolic@users.noreply.github.com>
Date: Sat, 23 May 2026 19:03:25 +0900
Subject: [PATCH] Fix RssFeedGenerator and refactor.
---
src/PRDigest.NET/Constants.cs | 9 +++++++++
src/PRDigest.NET/HtmlGenerator.cs | 18 +++++++++---------
src/PRDigest.NET/Program.cs | 22 +++++++---------------
src/PRDigest.NET/PullRequestAnalyzer.cs | 13 ++++++++-----
src/PRDigest.NET/RssFeedGenerator.cs | 4 ++++
5 files changed, 37 insertions(+), 29 deletions(-)
create mode 100644 src/PRDigest.NET/Constants.cs
diff --git a/src/PRDigest.NET/Constants.cs b/src/PRDigest.NET/Constants.cs
new file mode 100644
index 0000000..0dc1749
--- /dev/null
+++ b/src/PRDigest.NET/Constants.cs
@@ -0,0 +1,9 @@
+
+namespace PRDigest.NET;
+
+internal static class Constants
+{
+ public const string Owner = "dotnet";
+ public const string Repository = "runtime";
+ public const string FullRepository = $"{Owner}/{Repository}";
+}
\ No newline at end of file
diff --git a/src/PRDigest.NET/HtmlGenerator.cs b/src/PRDigest.NET/HtmlGenerator.cs
index b3c945f..a2f30bd 100644
--- a/src/PRDigest.NET/HtmlGenerator.cs
+++ b/src/PRDigest.NET/HtmlGenerator.cs
@@ -132,8 +132,8 @@ public static string GenerateHtmlFromMarkdown(string startTargetDate, string mar
// The TOC ends after , then a
separates it from PR details
var contentSpan = contentHtml.AsSpan();
var tocEndIndex = contentSpan.IndexOf("", StringComparison.Ordinal);
- string tocHtml;
- string prDetailsHtml;
+ ReadOnlySpan tocHtml;
+ ReadOnlySpan prDetailsHtml;
if (tocEndIndex >= 0)
{
@@ -141,13 +141,13 @@ public static string GenerateHtmlFromMarkdown(string startTargetDate, string mar
var hrIndex = contentSpan[tocEndIndex..].IndexOf("
= 0)
{
- tocHtml = contentSpan[..tocEndIndex].ToString();
- prDetailsHtml = contentSpan[(tocEndIndex + hrIndex)..].ToString();
+ tocHtml = contentSpan[..tocEndIndex];
+ prDetailsHtml = contentSpan[(tocEndIndex + hrIndex)..];
}
else
{
- tocHtml = contentSpan[..tocEndIndex].ToString();
- prDetailsHtml = contentSpan[tocEndIndex..].ToString();
+ tocHtml = contentSpan[..tocEndIndex];
+ prDetailsHtml = contentSpan[tocEndIndex..];
}
}
else
@@ -162,7 +162,7 @@ public static string GenerateHtmlFromMarkdown(string startTargetDate, string mar
var labelViewHtml = GenerateLabelViewHtml(analyzerResult);
// Extract part from tocHtml for floating TOC
- var floatingTocSpan = tocHtml.AsSpan();
+ var floatingTocSpan = tocHtml;
var olStart = floatingTocSpan.IndexOf("", StringComparison.Ordinal);
var floatingTocOlHtml = olStart >= 0 ? floatingTocSpan[olStart..].ToString() : "";
@@ -280,7 +280,7 @@ private static string GenerateCategorizedTocHtml(PullRequestAnalyzer.AnalysisRes
builder.AppendLiteral(Environment.NewLine);
// AI Agent PRs (collapsed)
- var aiAgentCount = analyzerResult.AiAgentPullRequestMetadataSpan.Length;
+ var aiAgentCount = analyzerResult.AgentPullRequestMetadataSpan.Length;
builder.AppendLiteral("");
builder.AppendLiteral(Environment.NewLine);
builder.AppendLiteral(" AI Agent PRs (");
@@ -289,7 +289,7 @@ private static string GenerateCategorizedTocHtml(PullRequestAnalyzer.AnalysisRes
builder.AppendLiteral(Environment.NewLine);
builder.AppendLiteral(" ");
builder.AppendLiteral(Environment.NewLine);
- foreach (var heading in analyzerResult.AiAgentPullRequestMetadataSpan)
+ foreach (var heading in analyzerResult.AgentPullRequestMetadataSpan)
{
AppendHeadingListItem(ref builder, heading);
}
diff --git a/src/PRDigest.NET/Program.cs b/src/PRDigest.NET/Program.cs
index 9224ead..0994ac1 100644
--- a/src/PRDigest.NET/Program.cs
+++ b/src/PRDigest.NET/Program.cs
@@ -33,10 +33,6 @@
async ValueTask SummarizeCurrentPullRequestAndCreate(string archivesDir, string outputsDir)
{
// Target dotnet/runtime.
- const string OWNER = "dotnet";
- const string REPO = "runtime";
- const string FullRepo = $"{OWNER}/{REPO}";
-
// 24-hour time range for the previous day.
var currentDate = TimeProvider.System.GetUtcNow();
var previousDate = currentDate.AddDays(-1);
@@ -63,10 +59,10 @@ async ValueTask SummarizeCurrentPullRequestAndCreate(string archivesDir, string
var pullRequestInfos = await GetAllPullRequestInfoAsync(startTargetDate, endTargetDate);
if (pullRequestInfos.Length == 0)
{
- Console.WriteLine($"There were no PRs merged into {FullRepo} between {startTargetDate:yyyy/MM/dd HH:mm:ss} and {endTargetDate:yyyy/MM/dd HH:mm:ss}.");
+ Console.WriteLine($"There were no PRs merged into {Constants.FullRepository} between {startTargetDate:yyyy/MM/dd HH:mm:ss} and {endTargetDate:yyyy/MM/dd HH:mm:ss}.");
return;
}
- Console.WriteLine($"{pullRequestInfos.Length} pull requests into {FullRepo} were merged between {startTargetDate:yyyy/MM/dd HH:mm:ss} and {endTargetDate:yyyy/MM/dd HH:mm:ss}.");
+ Console.WriteLine($"{pullRequestInfos.Length} pull requests into {Constants.FullRepository} were merged between {startTargetDate:yyyy/MM/dd HH:mm:ss} and {endTargetDate:yyyy/MM/dd HH:mm:ss}.");
// Generate HTML content for each pull request using Anthropic API.
var markdown = await SummarizePullRequestAsync(pullRequestInfos);
@@ -119,15 +115,11 @@ bool ExistSummaryForSpecifiedDate(string archivesDir, string year, string month,
async ValueTask GetAllPullRequestInfoAsync(DateTimeOffset startTargetDate, DateTimeOffset endTargetDate)
{
// Target dotnet/runtime.
- const string OWNER = "dotnet";
- const string REPO = "runtime";
- const string FullRepo = $"{OWNER}/{REPO}";
-
// Create search request for merged pull requests in the specified date range
var searchRequest = new SearchIssuesRequest()
{
Type = IssueTypeQualifier.PullRequest,
- Repos = [FullRepo],
+ Repos = [Constants.FullRepository],
State = ItemState.Closed,
Merged = DateRange.Between(startTargetDate, endTargetDate),
Is = [IssueIsQualifier.Merged]
@@ -154,10 +146,10 @@ async ValueTask GetAllPullRequestInfoAsync(DateTimeOffset sta
for (var i = 0; i < searchIssueResult.Items.Count; i++)
{
var pr = searchIssueResult.Items[i];
- var pullRequestTask = githubClient.PullRequest.Get(OWNER, REPO, pr.Number);
- var filesTask = githubClient.PullRequest.Files(OWNER, REPO, pr.Number);
- var issueCommentsTask = githubClient.Issue.Comment.GetAllForIssue(OWNER, REPO, pr.Number);
- var reviewsTask = githubClient.PullRequest.Review.GetAll(OWNER, REPO, pr.Number);
+ var pullRequestTask = githubClient.PullRequest.Get(Constants.Owner, Constants.Repository, pr.Number);
+ var filesTask = githubClient.PullRequest.Files(Constants.Owner, Constants.Repository, pr.Number);
+ var issueCommentsTask = githubClient.Issue.Comment.GetAllForIssue(Constants.Owner, Constants.Repository, pr.Number);
+ var reviewsTask = githubClient.PullRequest.Review.GetAll(Constants.Owner, Constants.Repository, pr.Number);
pullRequestInfos[i] = new PullRequestInfo
{
diff --git a/src/PRDigest.NET/PullRequestAnalyzer.cs b/src/PRDigest.NET/PullRequestAnalyzer.cs
index a2dae2d..7419d3c 100644
--- a/src/PRDigest.NET/PullRequestAnalyzer.cs
+++ b/src/PRDigest.NET/PullRequestAnalyzer.cs
@@ -257,10 +257,13 @@ private static Metadata GetMetadata(HeadingBlock heading, IEnumerable l.ToString()).ToImmutableArray() ?? ImmutableArray.Empty, mergedAt);
+ return new Metadata(
+ pullRequestNumber.TrimStart('#'),
+ displayText,
+ labels?.Select(l => l.ToString()).ToImmutableArray() ?? ImmutableArray.Empty,
+ mergedAt);
}
private static string GetOverview(ContainerInline? inline)
@@ -300,20 +303,20 @@ public sealed class AnalysisResults(
FrozenDictionary labelColorMap,
List botPullRequestMetadata,
List communityPullRequestMetadata,
- List aiAgentPullRequestMetadata,
+ List agentPullRequestMetadata,
FrozenDictionary summaryMap)
{
public int PullRequestTotalCount => pullRequestTotalCount;
public int PullRequestCountForCommunity => communityPullRequestMetadata.Count;
public int PullRequestCountForBot => botPullRequestMetadata.Count;
- public int PullRequestCountForAiAgent => aiAgentPullRequestMetadata.Count;
+ public int PullRequestCountForAiAgent => agentPullRequestMetadata.Count;
public FrozenDictionary> LabelMap => labelMap;
public FrozenDictionary LabelColorGroups => labelColorMap;
public int LabelCount => LabelMap.Count;
public ReadOnlySpan CommunityPullRequestMetadataSpan => CollectionsMarshal.AsSpan(communityPullRequestMetadata);
public ReadOnlySpan BotPullRequestMetadataSpan => CollectionsMarshal.AsSpan(botPullRequestMetadata);
- public ReadOnlySpan AiAgentPullRequestMetadataSpan => CollectionsMarshal.AsSpan(aiAgentPullRequestMetadata);
+ public ReadOnlySpan AgentPullRequestMetadataSpan => CollectionsMarshal.AsSpan(agentPullRequestMetadata);
public FrozenDictionary SummaryMap => summaryMap;
}
diff --git a/src/PRDigest.NET/RssFeedGenerator.cs b/src/PRDigest.NET/RssFeedGenerator.cs
index bacd9b9..d2a489e 100644
--- a/src/PRDigest.NET/RssFeedGenerator.cs
+++ b/src/PRDigest.NET/RssFeedGenerator.cs
@@ -53,6 +53,10 @@ private static void AppendItems(ref DefaultInterpolatedStringHandler itemBuilder
{
AppendItem(ref itemBuilder, target, analysisResult.SummaryMap, metadata);
}
+ foreach (var metadata in analysisResult.AgentPullRequestMetadataSpan)
+ {
+ AppendItem(ref itemBuilder, target, analysisResult.SummaryMap, metadata);
+ }
static void AppendItem(ref DefaultInterpolatedStringHandler builder, string target, FrozenDictionary summaryGroups, PullRequestAnalyzer.Metadata metadata)
{