Background: the x/tools/go/packages.Load
function returns a set of packages that are nodes in a DAG, the import graph over packages. To enumerate them, one calls Visit
, passing a pair of (pre, post) functions to be called before and after the node is visited in dependencies-first order. The pre feature is almost unused: only one of the two dozen calls to Visit in x/tools uses it; I suspect the ratio is even lower in the broader ecosystem.
Proposal: As a convenience, we propose to add a Postorder
function that returns a go1.23 iterator over the sequence of packages in the import graph, in dependencies first order.
package packages // golang.org/x/tools/go/packages
// Postorder returns an iterator over the the packages in
// the import graph whose roots are pkg.
// Packages are enumerated in dependencies-first order.
func Postorder(pkgs []*Package) iter.Seq[*Package]
Example before:
pkgs, err := packages.Load(...)
if err != nil { ... }
packages.Visit(pkgs, nil, func(pkg *Package) {
log.Println(pkg)
})
Example after:
for pkg := range packages.Postorder(pkgs) {
log.Println(pkg)
}