aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-13 00:14:15 +0900
committerOphestra <cat@gensokyo.uk>2026-05-13 00:18:27 +0900
commit487a03b5a3ed9a354ea4f5572c5d509b01951566 (patch)
treefa020b369f6ef766ca2b5436162d30e53431e97e /internal/pkg
parent8f3c22896adc06b6c5f646540924dc3a39170e45 (diff)
internal/pkg: deduplicate DCE by ident
This eliminates edge cases where target artifacts do not compare equal. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg')
-rw-r--r--internal/pkg/pkg.go47
-rw-r--r--internal/pkg/pkg_test.go2
2 files changed, 31 insertions, 18 deletions
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 378d0166..96289c9b 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -1499,41 +1499,52 @@ func (e *CureError) Error() string { return e.Err.Error() }
type DependencyCureError []*CureError
// unwrapM recursively expands underlying errors into a caller-supplied map.
-func (e *DependencyCureError) unwrapM(me map[Artifact]*CureError) {
+func (e *DependencyCureError) unwrapM(
+ ir *IRCache,
+ me map[unique.Handle[ID]]*CureError,
+) {
for _, err := range *e {
- if _, ok := me[err.A]; ok {
+ id := ir.Ident(err.A)
+ if _, ok := me[id]; ok {
continue
}
if _e, ok := err.Err.(*DependencyCureError); ok {
- _e.unwrapM(me)
+ _e.unwrapM(ir, me)
continue
}
- me[err.A] = err
+ me[id] = err
}
}
// unwrap recursively expands and deduplicates underlying errors.
-func (e *DependencyCureError) unwrap() DependencyCureError {
- me := make(map[Artifact]*CureError)
- e.unwrapM(me)
- errs := slices.AppendSeq(
- make(DependencyCureError, 0, len(me)),
- maps.Values(me),
- )
+func (e *DependencyCureError) unwrap(ir *IRCache) DependencyCureError {
+ me := make(map[unique.Handle[ID]]*CureError)
+ e.unwrapM(ir, me)
+ type ent struct {
+ id unique.Handle[ID]
+ err *CureError
+ }
+ errs := make([]*ent, 0, len(me))
+ for id, err := range me {
+ errs = append(errs, &ent{id, err})
+ }
var identBuf [2]ID
- ir := NewIR()
- slices.SortFunc(errs, func(a, b *CureError) int {
- identBuf[0], identBuf[1] = ir.Ident(a.A).Value(), ir.Ident(b.A).Value()
+ slices.SortFunc(errs, func(a, b *ent) int {
+ identBuf[0], identBuf[1] = a.id.Value(), b.id.Value()
return slices.Compare(identBuf[0][:], identBuf[1][:])
})
- return errs
+ _errs := make(DependencyCureError, len(errs))
+ for i, v := range errs {
+ _errs[i] = v.err
+ }
+ return _errs
}
// Unwrap returns a deduplicated slice of underlying errors.
func (e *DependencyCureError) Unwrap() []error {
- errs := e.unwrap()
+ errs := e.unwrap(NewIR())
_errs := make([]error, len(errs))
for i, err := range errs {
_errs[i] = err
@@ -1543,13 +1554,13 @@ func (e *DependencyCureError) Unwrap() []error {
// Error returns a user-facing multiline error message.
func (e *DependencyCureError) Error() string {
- errs := e.unwrap()
+ ir := NewIR()
+ errs := e.unwrap(ir)
if len(errs) == 0 {
return "invalid dependency cure outcome"
}
var buf strings.Builder
buf.WriteString("errors curing dependencies:")
- ir := NewIR()
for _, err := range errs {
buf.WriteString("\n\t" +
reportName(err.A, ir.Ident(err.A)) + ": " +
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
index 4ce4ba6a..9d6757c7 100644
--- a/internal/pkg/pkg_test.go
+++ b/internal/pkg/pkg_test.go
@@ -1515,6 +1515,8 @@ func TestDependencyCureError(t *testing.T) {
makeIdent := func(ident ...byte) pkg.Artifact {
var a overrideIdent
copy(a.id[:], ident)
+ // does not compare equal
+ a.TrivialArtifact = new(stubArtifact)
return a
}