A merge of a base rebuilds what stands on it
The controller knew which modules were built against which base artifacts and used it only when asked (build --on). A merge that rebuilt the runtime image left forty-two modules on the old image until somebody asked, twice, by hand (hq issue 186). The merge now takes every module standing on what moved, through every layer, into the same rebuild, in base order — the same rebuild the flag does, asked by the merge that made it necessary.
This commit is contained in:
@@ -299,6 +299,20 @@ func (f following) SourceMoved(ctx context.Context, m link.SourceMoved) error {
|
||||
if err != nil {
|
||||
return notNow(err)
|
||||
}
|
||||
// And whatever stands on what moved. A base rebuilt without its dependents is a mesh half on
|
||||
// the old image until somebody remembers to ask — on 2026-10-01 forty-two modules, twice, by
|
||||
// hand (novox/hq issue 186). The relation is the one `build --on` reads; this is the same
|
||||
// rebuild, asked by the merge that made it necessary, in base order.
|
||||
standing := dependentsOf(moved, entries, against)
|
||||
if len(standing) > 0 {
|
||||
var on []string
|
||||
for _, e := range standing {
|
||||
on = append(on, e.Manifest.Module)
|
||||
}
|
||||
fmt.Printf(" %d module(s) stand on what moved and are rebuilt with it: %s\n",
|
||||
len(standing), strings.Join(on, ", "))
|
||||
moved = append(moved, standing...)
|
||||
}
|
||||
ordered := orderByBases(moved, against)
|
||||
names := make([]string, 0, len(ordered))
|
||||
for _, e := range ordered {
|
||||
@@ -522,3 +536,37 @@ func isHistory(mergedAt string, seen time.Time) bool {
|
||||
}
|
||||
return at.Before(seen)
|
||||
}
|
||||
|
||||
// dependentsOf is every catalogued module that stands on one of the moved modules, directly or
|
||||
// through another dependent, and is not itself among them — in the catalogue's order, so the
|
||||
// answer is the same each time. A module standing on nothing that moved is left alone: a merge
|
||||
// rebuilds what it changed and what is built on top of that, not the catalogue.
|
||||
func dependentsOf(moved, entries []inventory.Entry, against map[string][]string) []inventory.Entry {
|
||||
bases := map[string]bool{}
|
||||
for _, e := range moved {
|
||||
bases[e.Manifest.Module] = true
|
||||
}
|
||||
var out []inventory.Entry
|
||||
taken := map[string]bool{}
|
||||
for grew := true; grew; {
|
||||
grew = false
|
||||
for _, e := range entries {
|
||||
name := e.Manifest.Module
|
||||
if bases[name] || taken[name] {
|
||||
continue
|
||||
}
|
||||
for base := range bases {
|
||||
if standsOnModule(e, base, against) {
|
||||
taken[name] = true
|
||||
out = append(out, e)
|
||||
grew = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, e := range out {
|
||||
bases[e.Manifest.Module] = true
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user