Skip to content
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
9 changes: 9 additions & 0 deletions src/PRDigest.NET/Constants.cs
Original file line number Diff line number Diff line change
@@ -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}";
}
18 changes: 9 additions & 9 deletions src/PRDigest.NET/HtmlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,22 @@ public static string GenerateHtmlFromMarkdown(string startTargetDate, string mar
// The TOC ends after </ol>, then a <hr /> separates it from PR details
var contentSpan = contentHtml.AsSpan();
var tocEndIndex = contentSpan.IndexOf("</ol>", StringComparison.Ordinal);
string tocHtml;
string prDetailsHtml;
ReadOnlySpan<char> tocHtml;
ReadOnlySpan<char> prDetailsHtml;

if (tocEndIndex >= 0)
{
tocEndIndex += "</ol>".Length;
var hrIndex = contentSpan[tocEndIndex..].IndexOf("<hr", StringComparison.Ordinal);
if (hrIndex >= 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
Expand All @@ -162,7 +162,7 @@ public static string GenerateHtmlFromMarkdown(string startTargetDate, string mar
var labelViewHtml = GenerateLabelViewHtml(analyzerResult);

// Extract <ol> part from tocHtml for floating TOC
var floatingTocSpan = tocHtml.AsSpan();
var floatingTocSpan = tocHtml;
var olStart = floatingTocSpan.IndexOf("<ol>", StringComparison.Ordinal);
var floatingTocOlHtml = olStart >= 0 ? floatingTocSpan[olStart..].ToString() : "";

Expand Down Expand Up @@ -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("<details class=\"label-group\">");
builder.AppendLiteral(Environment.NewLine);
builder.AppendLiteral(" <summary class=\"label-group-summary\">AI Agent PRs <span class=\"label-pr-count\">(");
Expand All @@ -289,7 +289,7 @@ private static string GenerateCategorizedTocHtml(PullRequestAnalyzer.AnalysisRes
builder.AppendLiteral(Environment.NewLine);
builder.AppendLiteral(" <ol class=\"label-pr-list\">");
builder.AppendLiteral(Environment.NewLine);
foreach (var heading in analyzerResult.AiAgentPullRequestMetadataSpan)
foreach (var heading in analyzerResult.AgentPullRequestMetadataSpan)
{
AppendHeadingListItem(ref builder, heading);
}
Expand Down
22 changes: 7 additions & 15 deletions src/PRDigest.NET/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -119,15 +115,11 @@ bool ExistSummaryForSpecifiedDate(string archivesDir, string year, string month,
async ValueTask<PullRequestInfo[]> 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]
Expand All @@ -154,10 +146,10 @@ async ValueTask<PullRequestInfo[]> 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
{
Expand Down
13 changes: 8 additions & 5 deletions src/PRDigest.NET/PullRequestAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,13 @@ private static Metadata GetMetadata(HeadingBlock heading, IEnumerable<LiteralInl
inline = inline.NextSibling;
}

var anchorId = pullRequestNumber.TrimStart('#');
var displayText = $"{pullRequestNumber} {titleText.Trim()}";

return new Metadata(anchorId, displayText, labels?.Select(l => l.ToString()).ToImmutableArray() ?? ImmutableArray<string>.Empty, mergedAt);
return new Metadata(
pullRequestNumber.TrimStart('#'),
displayText,
labels?.Select(l => l.ToString()).ToImmutableArray() ?? ImmutableArray<string>.Empty,
mergedAt);
}

private static string GetOverview(ContainerInline? inline)
Expand Down Expand Up @@ -300,20 +303,20 @@ public sealed class AnalysisResults(
FrozenDictionary<string, string> labelColorMap,
List<Metadata> botPullRequestMetadata,
List<Metadata> communityPullRequestMetadata,
List<Metadata> aiAgentPullRequestMetadata,
List<Metadata> agentPullRequestMetadata,
FrozenDictionary<string, Summary> 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<string, ImmutableArray<Metadata>> LabelMap => labelMap;
public FrozenDictionary<string, string> LabelColorGroups => labelColorMap;
public int LabelCount => LabelMap.Count;
public ReadOnlySpan<Metadata> CommunityPullRequestMetadataSpan => CollectionsMarshal.AsSpan(communityPullRequestMetadata);
public ReadOnlySpan<Metadata> BotPullRequestMetadataSpan => CollectionsMarshal.AsSpan(botPullRequestMetadata);
public ReadOnlySpan<Metadata> AiAgentPullRequestMetadataSpan => CollectionsMarshal.AsSpan(aiAgentPullRequestMetadata);
public ReadOnlySpan<Metadata> AgentPullRequestMetadataSpan => CollectionsMarshal.AsSpan(agentPullRequestMetadata);
Comment thread
prozolic marked this conversation as resolved.
public FrozenDictionary<string, Summary> SummaryMap => summaryMap;
}

Expand Down
4 changes: 4 additions & 0 deletions src/PRDigest.NET/RssFeedGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, PullRequestAnalyzer.Summary> summaryGroups, PullRequestAnalyzer.Metadata metadata)
{
Expand Down