You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Explain unique replaces chain requirement in channel sort errors.
The "multiple channel head" error that can be returned from channel
sorting has been a source of confusion for users. The error message
now explains that a unique replacement chain is required in order to
define the relative order between channel entries, and it also
provides an abbreviated list of all replacement chains identified, in
the form "head...tail" or "singleton".
Signed-off-by: Ben Luddy <[email protected]>
// a bundle without a replacement is a channel head, but if we find more than one of those something is weird
666
+
// a bundle without a replacement is a channel head, but if we
667
+
// find more than one of those something is weird
664
668
headCandidates:= []*Operator{}
665
669
for_, b:=rangebundles {
666
670
if_, ok:=replacedBy[b]; !ok {
667
671
headCandidates=append(headCandidates, b)
668
672
}
669
673
}
674
+
iflen(headCandidates) ==0 {
675
+
returnnil, fmt.Errorf("no channel heads (entries not replaced by another entry) found in channel %q of package %q", channelName, packageName)
676
+
}
670
677
671
-
iflen(headCandidates) >1 {
672
-
varnames []string
673
-
for_, v:=rangeheadCandidates {
674
-
names=append(names, v.Identifier())
678
+
varchains [][]*Operator
679
+
for_, head:=rangeheadCandidates {
680
+
varchain []*Operator
681
+
visited:=make(map[*Operator]struct{})
682
+
current:=head
683
+
skip:=false
684
+
for {
685
+
visited[current] =struct{}{}
686
+
if!skip {
687
+
chain=append(chain, current)
688
+
}
689
+
next, ok:=replaces[current]
690
+
if!ok {
691
+
break
692
+
}
693
+
if_, ok:=visited[next]; ok {
694
+
returnnil, fmt.Errorf("a cycle exists in the chain of replacement beginning with %q in channel %q of package %q", head.Identifier(), channelName, packageName)
695
+
}
696
+
if_, ok:=skipped[current.Identifier()]; ok {
697
+
skip=true
698
+
}
699
+
current=next
675
700
}
676
-
returnnil, fmt.Errorf("found multiple channel heads: %v, please check the `replaces`/`skipRange` fields of the operator bundles", names)
677
-
678
-
} elseiflen(headCandidates) <1 {
679
-
returnnil, fmt.Errorf("head of channel not found")
returnnil, fmt.Errorf("a unique replacement chain within a channel is required to determine the relative order between channel entries, but %d replacement chains were found in channel %q of package %q: %s", len(schains), channelName, packageName, strings.Join(schains, ", "))
698
717
}
699
718
700
-
// TODO: do we care if the channel doesn't include every bundle in the input?
719
+
iflen(chains) ==0 {
720
+
// Bug?
721
+
returnnil, fmt.Errorf("found no replacement chains in channel %q of package %q", channelName, packageName)
722
+
}
701
723
702
-
returnchannel, nil
724
+
// TODO: do we care if the channel doesn't include every bundle in the input?
0 commit comments