tools/bump: upgrade modules behind tool directives

x/tools is indirect, so never moved; v0.49.0 cannot read Go 1.27.2
export data and viewer emits invalid types, failing go generate.
This commit is contained in:
Kristoffer Dalby committed 2026-10-15 10:50:32 +02:00
1 parent bf63feb320
commit fd09dd86f2
2 files changed
+65 -2

No files matched your search

+24 -2
View File
@@ -166,7 +166,9 @@ func sqliteAtom(ctx context.Context, r *repo) (string, error) {
}
// directRequirements is every direct requirement not already owned by a
// lockstep atom.
// lockstep atom, plus the modules behind go.mod's tool lines. Those are marked
// indirect when nothing imports them, yet go generate runs them, and a stale
// golang.org/x/tools cannot read the export data a newer Go writes.
func directRequirements(r *repo) ([]string, error) {
f, err := parseGoMod(r)
if err != nil {
@@ -181,10 +183,15 @@ func directRequirements(r *repo) ([]string, error) {
modLibc: true,
}
tools := map[string]bool{}
for _, t := range f.Tool {
tools[toolModule(f, t.Path)] = true
}
var paths []string
for _, req := range f.Require {
if req.Indirect || owned[req.Mod.Path] {
if owned[req.Mod.Path] || (req.Indirect && !tools[req.Mod.Path]) {
continue
}
@@ -194,6 +201,21 @@ func directRequirements(r *repo) ([]string, error) {
return paths, nil
}
// toolModule finds the required module providing pkg. The longest match wins,
// since a nested module shadows its parent's tree.
func toolModule(f *modfile.File, pkg string) string {
var best string
for _, req := range f.Require {
p := req.Mod.Path
if (pkg == p || strings.HasPrefix(pkg, p+"/")) && len(p) > len(best) {
best = p
}
}
return best
}
// moduleAtom upgrades one direct requirement. One atom per module costs nothing
// on a good day, because the bisect tries every atom together first and only
// splits when that fails. It is what stops a single dependency deprecating an