1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ociunify
16
17 import (
18 "context"
19 "errors"
20 "sort"
21 "strings"
22
23 "cuelabs.dev/go/oci/ociregistry"
24 )
25
26 func (u unifier) Repositories(ctx context.Context, startAfter string) ociregistry.Seq[string] {
27 r0, r1 := both(u, func(r ociregistry.Interface, _ int) ociregistry.Seq[string] {
28 return r.Repositories(ctx, startAfter)
29 })
30 return mergeIter(r0, r1, strings.Compare)
31 }
32
33 func (u unifier) Tags(ctx context.Context, repo, startAfter string) ociregistry.Seq[string] {
34 r0, r1 := both(u, func(r ociregistry.Interface, _ int) ociregistry.Seq[string] {
35 return r.Tags(ctx, repo, startAfter)
36 })
37 return mergeIter(r0, r1, strings.Compare)
38 }
39
40 func (u unifier) Referrers(ctx context.Context, repo string, digest ociregistry.Digest, artifactType string) ociregistry.Seq[ociregistry.Descriptor] {
41 r0, r1 := both(u, func(r ociregistry.Interface, _ int) ociregistry.Seq[ociregistry.Descriptor] {
42 return r.Referrers(ctx, repo, digest, artifactType)
43 })
44 return mergeIter(r0, r1, compareDescriptor)
45 }
46
47 func compareDescriptor(d0, d1 ociregistry.Descriptor) int {
48 return strings.Compare(string(d0.Digest), string(d1.Digest))
49 }
50
51 func mergeIter[T any](it0, it1 ociregistry.Seq[T], cmp func(T, T) int) ociregistry.Seq[T] {
52
53 xs0, err0 := ociregistry.All(it0)
54 xs1, err1 := ociregistry.All(it1)
55 if err0 != nil || err1 != nil {
56 notFound0 := errors.Is(err0, ociregistry.ErrNameUnknown)
57 notFound1 := errors.Is(err1, ociregistry.ErrNameUnknown)
58 if notFound0 && notFound1 {
59 return ociregistry.ErrorIter[T](err0)
60 }
61 if notFound0 {
62 err0 = nil
63 }
64 if notFound1 {
65 err1 = nil
66 }
67 }
68 var xs []T
69 if len(xs0)+len(xs1) > 0 {
70 xs = make([]T, len(xs0)+len(xs1))
71 copy(xs, xs0)
72 copy(xs[len(xs0):], xs1)
73 sort.Slice(xs, func(i, j int) bool {
74 return cmp(xs[i], xs[j]) < 0
75 })
76 j := 0
77 for i := 1; i < len(xs); i++ {
78 if cmp(xs[i], xs[j]) != 0 {
79 j++
80 xs[j] = xs[i]
81 }
82 }
83 xs = xs[:j+1]
84 }
85 err := err0
86 if err == nil {
87 err = err1
88 }
89 if err == nil {
90 return ociregistry.SliceIter(xs)
91 }
92 return func(yield func(T, error) bool) {
93 for _, x := range xs {
94 if !yield(x, nil) {
95 return
96 }
97 }
98 yield(*new(T), err)
99 }
100 }
101
View as plain text