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) {