Skip to content

Latest commit

 

History

History
185 lines (146 loc) · 12.3 KB

File metadata and controls

185 lines (146 loc) · 12.3 KB

Implementation Plan

This document outlines the steps to implement the GitHub PR Reporter application.

Phase 1: Project Setup and Core Structure

  • 1. Initialize a new Dart console application.
  • 2. Add dependencies to pubspec.yaml:
    • args for command-line argument parsing.
    • github for interacting with the GitHub API.
    • google_cloud_ai_generativelanguage_v1beta for the Gemini API.
    • test and mocktail for unit testing (as dev dependencies).
  • 3. Create the initial directory and file structure:
    • bin/github_reporter.dart (main entry point)
    • lib/github_reporter.dart (for ReportGenerator class)
    • lib/src/services/github_service.dart
    • lib/src/services/gemini_service.dart
    • test/ directory for unit tests.

Phase 2: Service Layer Implementation

  • 1. Implement GitHubService:
    • Create the class structure in github_service.dart.
    • Implement a method to fetch merged pull requests for a given repository and date range.
  • 2. Implement GeminiService:
    • Create the class structure in gemini_service.dart.
    • Implement a method to generate a text summary from a given input string (the PR details).

Phase 3: Core Logic and Report Generation

  • 1. Implement ReportGenerator:
    • Create the class structure in github_reporter.dart.
    • Implement the generateReport method to orchestrate calls to the service classes.
    • Implement the logic to format the collected data into the final Markdown report string.

Phase 4: Command-Line Interface (CLI)

  • 1. Implement the entry point in bin/github_reporter.dart:
    • Set up command-line argument parsing using the args package.
    • Implement logic to handle API keys from both arguments and environment variables.
    • Implement the default date range logic.
    • Instantiate and run the ReportGenerator.
    • Print the final report to stdout.
    • Implement error handling to print messages to stderr and exit.

Phase 5: Testing

  • 1. Write unit tests for ReportGenerator using mocked services.
  • 2. Write unit tests for the service classes (GitHubService) using mocktail.

Phase 6: Finalization

  • 1. Add dartdoc comments to all public APIs.
  • 2. Run dart format on the entire codebase.
  • 3. Review and update all documentation (USAGE.md, DESIGN.md, IMPLEMENTATION.md).

Phase 7: Gemini Summarization Enhancement

  • 1. Implement a system instruction for Gemini to guide summary creation.
  • 2. Include the pull request diff in the data sent to Gemini for summarization.

Phase 8: Verbose mode

  • 1. Add a --verbose flag to the CLI in bin/github_reporter.dart.
  • 2. Pass the verbose flag to the ReportGenerator.
  • 3. In ReportGenerator, if verbose mode is enabled:
    • Log a message when the GitHubService is called to fetch pull requests.
    • Log the number of pull requests returned by the GitHubService.
    • For each pull request, log a message before calling the GeminiService to generate the summary.
    • Log a message after the summary is generated.
  • 4. Update USAGE.md to document the new --verbose flag.

Phase 9: File Output

  • 1. Add an --output-file option to the CLI in bin/github_reporter.dart.
  • 2. In bin/github_reporter.dart, if the --output-file option is provided, write the report to the specified file.
  • 3. If the --output-file option is not provided, print the report to the console.
  • 4. Update USAGE.md to document the new --output-file option.
  • 5. Update DESIGN.md to reflect the new file output functionality.

Phase 10: Gemini API Retry Logic

  • 1. Implement a retry loop in GeminiService.getSummary to handle transient errors from the Gemini API.
  • 2. The loop should attempt to generate a summary up to three times.
  • 3. Implement exponential backoff for the delay between retries.
  • 4. If all retries fail, throw an exception.
  • 5. Update DESIGN.md to reflect the new retry logic.

Phase 11: Filter by Author

  • 1. Add a --exclude-author option to the CLI in bin/github_reporter.dart.
  • 2. Modify ReportGenerator.generateReport to accept a list of authors to exclude.
  • 3. Modify GitHubService.getMergedPullRequests to filter out pull requests from the specified authors using the GitHub search query.
  • 4. Update USAGE.md to document the new --exclude-author option.
  • 5. Update DESIGN.md to reflect the new filtering functionality.

Phase 12: Report Formatting Enhancements

  • 1. Make the pull request ID in the Markdown report a clickable link to the pull request on GitHub.
  • 2. Format the Merged At time in the report to Pacific Time, 12-hour clock, with only hours and minutes listed.
  • 3. Update USAGE.md to reflect these formatting changes.
  • 4. Update DESIGN.md to reflect these formatting changes.

Phase 13: GitHub API Rate Limit Handling

  • 1. Create a custom exception class RateLimitException in github_service.dart.
  • 2. In GitHubService, catch the RateLimitHit exception from the github package and re-throw it as a RateLimitException.
  • 3. In bin/github_reporter.dart, add a try-catch block to handle the RateLimitException.
  • 4. When a RateLimitException is caught, log a user-friendly error message to stderr and exit with a non-zero status code.
  • 5. Ensure that no report is written to a file if a RateLimitException occurs.
  • 6. Update DESIGN.md to document the new rate limit handling mechanism.
  • 7. Write a unit test to verify that RateLimitHit is correctly caught and re-thrown as RateLimitException.

Phase 14: Closed Issue Reporting

  • 1. Create a new Issue model in lib/src/models/issue.dart.
  • 2. Add a getClosedIssues method to GitHubService to fetch closed issues within the specified date range.
  • 3. In ReportGenerator, call getClosedIssues and add a new "Closed Issues" section to the report.
  • 4. Write unit tests for the new getClosedIssues method in GitHubService.

Phase 15: Issue Reaction Reporting

  • 1. Update the Issue model in lib/src/models/issue.dart to include reaction data.
  • 2. Update the getClosedIssues method in GitHubService to fetch reaction data for each issue.
  • 3. In ReportGenerator, format and display the reaction data in the "Closed Issues" section of the report.
  • 4. Update the unit tests for getClosedIssues to include reaction data.

Phase 16: Overall Report Summary

  • 1. Create a new prompt for the Gemini service to generate an overall summary.
  • 2. Create a new method in GeminiService to generate the overall summary.
  • 3. In ReportGenerator, call the new method and add the overall summary to the top of the report.
  • 4. Update DESIGN.md and USAGE.md to reflect the new overall summary feature.
  • 5. Update the unit tests to include the overall summary.

Phase 17: Hacker News Service

  • 1. Create new data models for Hacker News stories and comments in lib/src/models/.
  • 2. Create a new HackerNewsService class in lib/src/services/hacker_news_service.dart.
  • 3. Implement a method in HackerNewsService to get the top stories from the Hacker News API.
  • 4. Implement a method in HackerNewsService to get the details of a story, including its comments.
  • 5. Add unit tests for the HackerNewsService.
  • 6. Integrate the HackerNewsService into the ReportGenerator to include a new "Hacker News" section in the report.
  • 7. Update DESIGN.md and USAGE.md to reflect the new Hacker News integration.

Phase 18: Multi-Report Summarization

  • 1. Create a new prompt for the Gemini service to generate a summary of summaries from multiple reports.
  • 2. Create a new method in GeminiService to generate the multi-report summary.
  • 3. In ReportGenerator, call the new method and add the multi-report summary to the top of the combined report.
  • 4. Update DESIGN.md and USAGE.md to reflect the new multi-report summary feature.
  • 5. Update the unit tests to include the multi-report summary.

Implementation Notes

  • 2025-11-03: Initialized a new Dart console application using dart create. Added args, github, and google_generative_ai as dependencies, and test and mocktail as dev dependencies. Created the initial directory and file structure for the services.
  • 2025-11-03: Implemented the initial GitHubService and GeminiService classes. GitHubService includes a method to fetch merged pull requests within a date range, and GeminiService includes a method to generate a summary from text.
  • 2025-11-03: Implemented the ReportGenerator class. This class orchestrates calls to the GitHubService and GeminiService and formats the collected data into a Markdown report.
  • 2025-11-03: Implemented the command-line interface in bin/github_reporter.dart. This includes argument parsing, API key handling from both arguments and environment variables, default date logic, and error handling.
  • 2025-11-03: Wrote unit tests for the ReportGenerator using mocked GitHubService and GeminiService instances. This ensures the report generation logic is working correctly. Despite verification that the mock is being called, a persistent type 'Null' is not a subtype of type 'Future<String>' error is occurring, which is currently unresolved.
  • 2025-11-03: Wrote unit tests for the GitHubService. The GeminiService could not be tested as the GenerativeModel class is final and cannot be mocked. This will be revisited.
  • 2025-11-03: The CLI tests were removed as they were not a reliable way to test the CLI. Manual testing will be performed.
  • 2025-11-03: Added dartdoc comments to all public APIs, formatted the entire codebase using dart format, and reviewed all documentation.
  • 2025-11-03: Added a system instruction to the GeminiService to guide the model in creating better summaries.
  • 2025-11-04: Modified the --help flag output in bin/github_reporter.dart to include a brief description and a sample invocation before the options list.
  • 2025-11-04: Updated USAGE.md to reflect the new --help message format and the default date behavior.
  • 2025-11-04: Fixed the stderr not defined error in lib/github_reporter.dart by importing dart:io.
  • 2025-11-04: Added logging for the start and end dates in ReportGenerator.generateReport when verbose mode is enabled.
  • 2025-11-04: Added logging for GitHub API requests in GitHubService when verbose mode is enabled.
  • 2025-11-04: Switched from using PullRequestsService to SearchService in GitHubService to fetch merged pull requests more efficiently. Updated tests to reflect this change.
  • 2025-11-04: Switched from using a text file to a Dart file with a const string for the Gemini system instruction. This provides compile-time validation and better performance.
  • 2025-11-04: Added an --output-file option to the CLI to allow writing the report to a file instead of printing it to the console.
  • 2025-11-04: Clarified in USAGE.md that the --output-file option will overwrite existing files.
  • 2025-11-04: Implemented a retry mechanism with exponential backoff in GeminiService to handle transient API errors.
  • 2025-11-04: Refactored maxRetries in GeminiService to be a top-level constant for better maintainability.
  • 2025-11-06: Modified the default end date to be yesterday's date instead of the current date.
  • 2025-11-06: Implemented filtering of pull requests by author using the --exclude-author CLI option.
  • 2025-11-06: Implemented clickable pull request IDs and Pacific Time formatting for Merged At times in the report.
  • 2025-11-06: Made the author's name in the report a clickable link to their GitHub profile.
  • 2025-11-11: Added the summarizeMultiReport method to GeminiService and the createMultiReportSummaryPrompt to prompts.dart to support summarizing summaries from multiple reports.
  • 2026-01-22: Fixed an issue where the application would hang after execution by properly disposing of http.Client instances in GitHubService and HackerNewsService.