feat: add gh contributions to display contributions graph#13231
feat: add gh contributions to display contributions graph#13231maaslalani wants to merge 2 commits intocli:trunkfrom
gh contributions to display contributions graph#13231Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new gh contributions command to display a GitHub contributions “heatmap” graph in the terminal.
Changes:
- Registers the new
contributionscommand on the CLI root. - Implements GraphQL fetching and terminal rendering (plus JSON export support) for contribution calendar data.
- Adds unit tests covering flag parsing, date parsing, rendering output, JSON export, and user-not-found handling.
Show a summary per file
| File | Description |
|---|---|
| pkg/cmd/root/root.go | Wires gh contributions into the root command so it’s available to users. |
| pkg/cmd/contributions/http.go | Implements GraphQL requests to fetch viewer/user contribution calendar data. |
| pkg/cmd/contributions/contributions.go | Adds the command, flag handling, JSON export shaping, and terminal calendar rendering. |
| pkg/cmd/contributions/contributions_test.go | Adds tests for command parsing and core behaviors (rendering, JSON, errors). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
pkg/cmd/contributions/contributions.go:41
Now: time.Nowis assigned intoContributionsOptions, butopts.Nowis not used anywhere. IfNowis removed (recommended), this initialization should be removed too; otherwise wire it into the logic that needs current time.
opts := &ContributionsOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
Now: time.Now,
}
- Files reviewed: 4/4 changed files
- Comments generated: 3
| HttpClient func() (*http.Client, error) | ||
| HostConfig hostConfig | ||
| IO *iostreams.IOStreams | ||
| Now func() time.Time |
There was a problem hiding this comment.
ContributionsOptions.Now is set but never read anywhere in this package. This adds unused surface area and can confuse future maintainers; either remove the field entirely or use it for default range calculations so tests can control time.
This issue also appears on line 37 of the same file.
| // exportable shapes the result for JSON output, flattening days for | ||
| // easier consumption. | ||
| func exportable(r *ContributionsResult) map[string]any { | ||
| days := make([]ContributionDay, 0) |
There was a problem hiding this comment.
days := make([]ContributionDay, 0) will reallocate as weeks are appended. Since the total number of days is bounded and known-ish (len(weeks)*7), consider preallocating capacity to avoid repeated allocations when exporting JSON.
| days := make([]ContributionDay, 0) | |
| days := make([]ContributionDay, 0, len(r.Calendar.Weeks)*7) |
| assert.Contains(t, out, "M") | ||
| assert.Contains(t, out, "W") | ||
| assert.Contains(t, out, "F") |
There was a problem hiding this comment.
These assertions are very broad: "M" will match many parts of the output (e.g., "More", month names, ANSI sequences), so the test can pass even if day labels are missing. Consider asserting on something more specific (e.g., the expected day-label column pattern or a line prefix) to avoid false positives.
Adds
gh contributionsto display GitHub contributions graph on the terminal.