-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat: Add native Go 1.23 Iterator support #3916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: Add native Go 1.23 Iterator support #3916
Conversation
- Create tools/gen-iterators to generate type-safe iterators for all List methods. - Generate github/iterators.go containing generic iter.Seq2 wrappers. - Update tools/metadata to ignore generated iterators (avoiding metadata duplication). - Add tests verifying pagination logic.
- Create tools/gen-iterators to generate type-safe iterators for all List methods. - Generate github/iterators.go containing generic iter.Seq2 wrappers. - Update tools/metadata to ignore generated iterators (avoiding metadata duplication). - Add table-driven tests verifying pagination and safety (copying opts). - Add benchmark comparing iterators to manual pagination. - Add Godoc example.
|
Review when you can guys. Hoping this feature closes the gap between GO and AWS/Azure. Happy to help :) - Let me know of any changes, hiccups or additions you want. Let's keep the momentum up. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3916 +/- ##
==========================================
- Coverage 92.45% 85.47% -6.99%
==========================================
Files 203 204 +1
Lines 14954 17565 +2611
==========================================
+ Hits 13826 15014 +1188
- Misses 926 1917 +991
- Partials 202 634 +432 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@alexandear - @gmlewis = Thanks for the review! I've addressed all the feedback:
@Not-Dhananjay-Mishra - Thanks for catching that! It looks like an accidental regression occurred where DependencySBOMCategory (and its RateLimits field) was dropped, likely due to a merge/rebase issue with my local branch. I have restored the DependencySBOMCategory constant, the GetRateLimitCategory case, and the DependencySBOM field in the RateLimits struct. Tests now pass. I will update the PR shortly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just Jules being annoying. Got stuck adding them to the wrong branch despite explicit instructions to keep it separate. - One branch for the stringify performance upgrade & one for this. Probably should start new sessions for each branch instead of sticking to one jules task for both.
Anyway I reverted them & I'm applying them to the correct branch now. Sorry for the mix up. Google Labs got some amazing products but they're still working out the kinks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@merchantmoh-debug - it appears that those changes are still leaking through to this PR.
Please take a look at this PR in the GitHub user interface and you will see what we are seeing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmlewis - Yeah; It's a mess. Still learning the Github UI myself. That's why I let Jules handle it.
Boy oh boy did he give me a lot of work to do. That's AI for you. Helpful 90% of the time then it crashes your entire project lol! I'll fix it as soon as I wake up. Need to sleep - I'm on "owl" mode right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just remember that AI usage can be thought of as another tool in the code developer's toolbox and still needs to be used carefully... and the results must be reviewed by the developer. I find the experience very similar to having a coworker that you delegate the job to... sometimes there are communication challenges or the other coworker simply doesn't have the same understanding or mental picture that you assume they do, and so the results don't always turn out like you expected. Thus, we as developers must still review everything.
gmlewis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @merchantmoh-debug - this is looking very promising.
| @@ -0,0 +1,29 @@ | |||
| // Copyright 2025 The go-github AUTHORS. All rights reserved. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All new source files created in 2026 should have // Copyright 2026 ....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes >.<; good catch.
| @@ -0,0 +1,455 @@ | |||
| // Copyright 2025 The go-github AUTHORS. All rights reserved. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto for this file and all NEW files. If a file already existed, please do not change its copyright year.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha.
| // Use of this source code is governed by a BSD-style | ||
| // license that can be found in the LICENSE file. | ||
| // Code generated by gen-iterators; DO NOT EDIT. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this the first line. See suggestion above.
| // Use of this source code is governed by a BSD-style | ||
| // license that can be found in the LICENSE file. | ||
| // Code generated by gen-iterators; DO NOT EDIT. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this the first line. See suggestion above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@merchantmoh-debug - it appears that those changes are still leaking through to this PR.
Please take a look at this PR in the GitHub user interface and you will see what we are seeing.
| # golangci-lint -v custom generates the following local file: | ||
| custom-gcl | ||
| custom-gcl.exe | ||
| gen-iterators |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the addition of //go:generate, this executable should never have to be built, and therefore this line is unnecessary. Please remove.
Co-authored-by: Glenn Lewis <[email protected]>
Co-authored-by: Glenn Lewis <[email protected]>
Co-authored-by: Glenn Lewis <[email protected]>
Co-authored-by: Glenn Lewis <[email protected]>
|
You can completely ignore this suggestion from the email, as it will be taken care of by one of the other suggestions: |
This comment was marked as outdated.
This comment was marked as outdated.
|
I know it's not ideal to discuss this inside a PR, but we don’t have an issue for this feature, so this is the only place to do it. Do we really need to generate iterators at all? Maybe we could provide helper functions similar to what we have in the GitLab API client: Scan, Scan2, ScanAndCollect? The benefits would be:
|
That is an intriguing suggestion, @alexandear! There have been many attempts to discuss adding automated pagination to this repo in the past, including:
If you are willing, it might be nice to put together a PR that demonstrates this alternative mechanism and we can compare the two approaches. Would you be willing to work on that, @alexandear? |
This PR introduces native Go 1.23 iterator support to the entire library via a new code generator.
The Problem
Pagination in go-github currently requires verbose boilerplate:
The Solution: With this PR, users can simply write:
Implementation Details
github/gen-iterators.go: A new AST-based tool (similar to gen-accessors) that scans all List* methods, identifies their pagination patterns (Page/Cursor), and generates a corresponding *Iter method returning iter.Seq2.
It handles methods using standard ListOptions embedding and explicit Page fields.
It copies the opts struct to avoid mutating the caller's options during iteration.
github/iterators.go: The generated file containing hundreds of type-safe iterators.
Metadata Handling: Updated tools/metadata to exclude the generated iterators from API operation mapping validation, as they wrap existing operations.
Testing & Benchmarks
github/iterators_benchmark_test.go confirms that the iterator abstraction introduces negligible overhead compared to manual looping.
github/iterators_test.go verifies single-page, multi-page, and error handling scenarios.
Tests explicitly verify that the user's opts struct is NOT mutated by the iterator.
Documentation
Added github/example_iterators_test.go to provide a clear example in the Godoc.
This modernizes the library to leverage the latest Go features, significantly improving Developer Experience (DX) by eliminating error-prone pagination boilerplate.