Feature Request: Read PR Comments (#31)#32
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new bb pr show command to display pull request comments (general + inline) and improves local repo detection to support git worktrees.
Changes:
- Added
bb pr showentry point and implemented fetching/formatting/display of general and inline PR comments. - Added git worktree-compatible repo detection by using
git rev-parse --git-dirinstead of checking for a.git/directory. - Documented the new command in
CHANGELOG.md.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/Actions/Pr.php | Introduces the show command and supporting helpers to fetch/filter/format PR comments. |
| bin/bb | Updates git-repo detection to work with worktrees. |
| CHANGELOG.md | Notes the new bb pr show command and its usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/Actions/Pr.php
Outdated
| $comments = $this->fetchComments($prId, $limit); | ||
| $inlineComments = $this->fetchInlineComments($prId, $limit); | ||
|
|
There was a problem hiding this comment.
displayComments() calls both fetchComments() and fetchInlineComments(), but both methods hit the same /pullrequests/{id}/comments endpoint. This doubles the API calls and also means the pagelen limit applies to the combined stream, so one section can show fewer than limit items even when more exist. Consider fetching once and partitioning into general vs inline in-memory (and/or paginating until each bucket reaches the requested limit).
There was a problem hiding this comment.
Smart, will look into this
src/Actions/Pr.php
Outdated
| if ($diff->d > 7) { | ||
| return $date->format('M d, Y'); | ||
| } elseif ($diff->d > 0) { | ||
| return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago'; | ||
| } elseif ($diff->h > 0) { | ||
| return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago'; | ||
| } else { | ||
| return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago'; |
There was a problem hiding this comment.
formatTimestamp() uses $diff->d for thresholds, but DateInterval::d is the day component (0–31), not the total number of days. For timestamps older than a month this can produce incorrect relative output (e.g., 40 days ago may look like only a few days). Use $diff->days (total days) for these comparisons, and also consider $diff->invert to avoid reporting future timestamps as "... ago".
| if ($diff->d > 7) { | |
| return $date->format('M d, Y'); | |
| } elseif ($diff->d > 0) { | |
| return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago'; | |
| } elseif ($diff->h > 0) { | |
| return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago'; | |
| } else { | |
| return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago'; | |
| // If the timestamp is in the future, avoid showing a misleading "ago" string. | |
| if ($diff->invert === 0 && $diff->days > 7) { | |
| return $date->format('M d, Y'); | |
| } elseif ($diff->invert === 0 && $diff->days > 0) { | |
| return $diff->days . ' day' . ($diff->days > 1 ? 's' : '') . ' ago'; | |
| } elseif ($diff->invert === 0 && $diff->h > 0) { | |
| return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago'; | |
| } elseif ($diff->invert === 0) { | |
| return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago'; | |
| } else { | |
| // For future timestamps, fall back to an absolute date. | |
| return $date->format('M d, Y'); |
src/Actions/Pr.php
Outdated
| if (array_get($comment, 'type') === 'pullrequest_comment' && | ||
| !empty(array_get($comment, 'inline.path')) && | ||
| !empty(array_get($comment, 'content.raw', ''))) { | ||
| $inlineComments[] = $comment; |
There was a problem hiding this comment.
fetchInlineComments() filters out entries with empty content.raw. This will also drop deleted inline comments (which are still relevant context and are handled explicitly for general comments). Consider including deleted inline comments and letting the formatter render a placeholder (similar to formatGeneralComment()), rather than silently omitting them.
|
To be honest, |
|
Hi, File-by-File Review1.
|
| # | Severity | File | Issue |
|---|---|---|---|
| 1 | High | Pr.php |
Class too large — extract into PrDetails or similar |
| 2 | High | Pr.php |
Move formatTimestamp (and optionally extractCommitHash) to helpers.php |
| 3 | Medium | Pr.php |
formatTimestamp invert logic is backwards (past vs future) |
| 4 | Medium | Pr.php |
Filter-then-slice order bug (unresolved filter applied after limit) |
| 5 | Low | Pr.php |
resolved field path may not match Bitbucket API schema |
| 6 | Low | Pr.php |
No pagination support for comments endpoint |
Recommended Next Steps
- Create a new
PrDetails(orPrShow) action class to house the show/comments functionality. - Move
formatTimestamptohelpers.phpas a standalone function. - Fix the
formatTimestampinvert logic. - Fix filter-before-slice ordering for the unresolved flag.
- Verify the
resolvedfield path against actual Bitbucket API responses. - Squash your commits please.
Thanks again for the PR! Please address the above points before merging.
@dinncer Once these issues are addressed, I’m okay with merging.
Add PR comment viewing with detailed display and optimizations - Create new PrDetails class for fetching and displaying PR comments - Support both general comments and inline code comments with file paths - Optimize API calls by fetching all comments once and partitioning in-memory - Add format_relative_timestamp helper for human-readable time display - Fix timestamp calculation bug for dates older than 1 month - Handle future timestamps and missing data gracefully - Register 'show' command in AVAILABLE_COMMANDS - Update CHANGELOG with new feature
Also, removed the limit parameter. This makes it more Up next after this (possibly in another PR), nicer viewing of the output (possibly render markdown like how |
|
Thanks for addressing the review comments and updating the PR. The changes look good now and I appreciate you taking the time to go through the feedback and adjust the implementation. Thanks for the contribution! We'll include this in the upcoming 1.4.0 release @semiherdogan |
I am writing this PR to address this issue I raised. I added support for inline and general comments. The way it is formatted is in markdown, maybe a bit too fancy but I think it looks good. That can be changed easily, let me know if you'd like it to be simpler (though I do think .md comments with a --json flag would be the best solution). I also added a drive by fix for git worktree support (use git rev-parse instead of assuming .git is a directory [not the case for worktrees]). Anyways, that's what I had to say, here's an additional AI summary of the important points:
AI SUMMARY
What changed
bb pr showas a new PR command entry point insrc/Actions/Pr.phpsrc/Actions/Pr.php, including:show()displayComments()fetchComments()fetchInlineComments()formatGeneralComment()formatInlineComment()formatTimestamp()bin/bb: switched git-repo detection togit rev-parse --git-dirso worktrees are supported (instead of assuming.gitis a directory)CHANGELOG.mdUsage
bb pr show <pr_id> [limit] [unresolved]
Example output: