Skip to content

Commit c464906

Browse files
committed
use component resolvers for completion
1 parent a6f1f3b commit c464906

File tree

3 files changed

+105
-17
lines changed

3 files changed

+105
-17
lines changed

api/ocm/resolvers/forward.go

+70
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package resolvers
22

33
import (
4+
"github.com/mandelsoft/goutils/errors"
5+
"golang.org/x/exp/maps"
6+
47
"ocm.software/ocm/api/ocm/internal"
8+
common "ocm.software/ocm/api/utils/misc"
59
)
610

711
type (
@@ -25,3 +29,69 @@ const (
2529
func NewResolverRule(prefix string, spec RepositorySpec, prio ...int) ResolverRule {
2630
return internal.NewResolverRule(prefix, spec, prio...)
2731
}
32+
33+
// VersionResolver is able to resolve component versions.
34+
type VersionResolver interface {
35+
ListVersions() ([]string, error)
36+
LookupVersion(version string) (ComponentVersionAccess, error)
37+
HasVersion(vers string) (bool, error)
38+
}
39+
40+
// VersionResolverForComponent provides a VersionResolver for a component resolver.
41+
// It resolves all versions provided by a component known to a ComponentResolver.
42+
// The version set may be composed by versions of the component found in
43+
// multiple repositories according to the result of the ComponentResolver.
44+
func VersionResolverForComponent(name string, resolver ComponentResolver) (VersionResolver, error) {
45+
crs := resolver.LookupComponentProviders(name)
46+
if len(crs) == 0 {
47+
return nil, errors.ErrNotFound(KIND_COMPONENT, name)
48+
}
49+
50+
versions := map[string]ResolvedComponentProvider{}
51+
for _, cr := range crs {
52+
c, err := cr.LookupComponent(name)
53+
if err != nil {
54+
return nil, err
55+
}
56+
vers, err := c.ListVersions()
57+
if err != nil {
58+
return nil, err
59+
}
60+
for _, v := range vers {
61+
if _, ok := versions[v]; !ok {
62+
versions[v] = cr
63+
}
64+
}
65+
}
66+
return &versionResolver{name, versions}, nil
67+
}
68+
69+
type versionResolver struct {
70+
comp string
71+
versions map[string]ResolvedComponentProvider
72+
}
73+
74+
func (v *versionResolver) ListVersions() ([]string, error) {
75+
return maps.Keys(v.versions), nil
76+
}
77+
78+
func (v *versionResolver) LookupVersion(version string) (ComponentVersionAccess, error) {
79+
p := v.versions[version]
80+
if p == nil {
81+
return nil, errors.ErrNotFound(KIND_COMPONENTVERSION, common.NewNameVersion(v.comp, version).String())
82+
}
83+
vp, err := p.LookupComponent(v.comp)
84+
if err != nil {
85+
return nil, err
86+
}
87+
return vp.LookupVersion(version)
88+
}
89+
90+
func (v *versionResolver) HasVersion(vers string) (bool, error) {
91+
cv, err := v.LookupVersion(vers)
92+
if err != nil {
93+
return false, err
94+
}
95+
defer cv.Close()
96+
return cv != nil, nil
97+
}

api/ocm/resolvers/resolver_test.go

+19-15
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,29 @@ var _ = Describe("resolver", func() {
4242
env.Cleanup()
4343
})
4444

45-
It("lookup cv per standard resolver", func() {
46-
// ocmlog.Context().AddRule(logging.NewConditionRule(logging.TraceLevel, accessio.ALLOC_REALM))
45+
Context("resolver", func() {
46+
var ctx ocm.Context
4747

48-
ctx := ocm.New()
48+
BeforeEach(func() {
49+
ctx = ocm.New()
50+
spec := Must(ctf.NewRepositorySpec(accessobj.ACC_READONLY, ARCH, env))
51+
ctx.AddResolverRule("ocm.software", spec, 10)
52+
})
4953

50-
spec := Must(ctf.NewRepositorySpec(accessobj.ACC_READONLY, ARCH, env))
51-
ctx.AddResolverRule("ocm.software", spec, 10)
54+
It("lookup cv per standard resolver", func() {
55+
cv := Must(ctx.GetResolver().LookupComponentVersion(COMPONENT, VERSION))
56+
Close(cv)
57+
Expect(ctx.Finalize()).To(Succeed())
58+
})
5259

53-
cv := Must(ctx.GetResolver().LookupComponentVersion(COMPONENT, VERSION))
60+
It("lookup cv per version resolver", func() {
61+
vr := Must(resolvers.VersionResolverForComponent(COMPONENT, ctx.GetResolver().(resolvers.ComponentResolver)))
62+
Expect(vr.ListVersions()).To(ContainElements(VERSION))
5463

55-
/*
56-
err := cv.Repository().Close()
57-
if err != nil {
58-
defer cv.Close()
59-
Expect(err).To(Succeed())
60-
}
61-
*/
62-
Close(cv)
63-
Expect(ctx.Finalize()).To(Succeed())
64+
cv := Must(vr.LookupVersion(VERSION))
65+
Close(cv)
66+
Expect(ctx.Finalize()).To(Succeed())
67+
})
6468
})
6569

6670
It("orders resolver rules", func() {

cmds/ocm/commands/ocmcmds/common/handlers/comphdlr/typehandler.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"ocm.software/ocm/api/ocm"
1313
"ocm.software/ocm/api/ocm/compdesc"
1414
metav1 "ocm.software/ocm/api/ocm/compdesc/meta/v1"
15+
"ocm.software/ocm/api/ocm/resolvers"
1516
common "ocm.software/ocm/api/utils/misc"
1617
"ocm.software/ocm/api/utils/semverutils"
1718
"ocm.software/ocm/cmds/ocm/common/output"
@@ -148,7 +149,7 @@ func (h *TypeHandler) filterVersions(vers []string) ([]string, error) {
148149
}
149150

150151
func (h *TypeHandler) get(repo ocm.Repository, elemspec utils.ElemSpec) ([]output.Object, error) {
151-
var component ocm.ComponentAccess
152+
var component resolvers.VersionResolver
152153
var result []output.Object
153154
var err error
154155

@@ -176,11 +177,25 @@ func (h *TypeHandler) get(repo ocm.Repository, elemspec utils.ElemSpec) ([]outpu
176177
evaluated.Repository = cv.Repository()
177178
h.session.Closer(cv)
178179
}
180+
} else {
181+
// if the resolver is a component resolver, we can use it to list all available version
182+
// cross all repositories found for the given component.
183+
if cr, ok := h.resolver.(resolvers.ComponentResolver); ok {
184+
cvr, err := resolvers.VersionResolverForComponent(comp.Component, cr)
185+
if err != nil {
186+
return nil, err
187+
}
188+
component = cvr
189+
evaluated = &ocm.EvaluationResult{}
190+
evaluated.Ref.CompSpec = comp
191+
}
179192
}
180193
}
181194
if evaluated == nil {
182195
return nil, errors.Wrapf(err, "%s: invalid component version reference", name)
183196
}
197+
} else {
198+
component = evaluated.Component
184199
}
185200
if evaluated.Version != nil {
186201
result = append(result, &Object{
@@ -192,7 +207,6 @@ func (h *TypeHandler) get(repo ocm.Repository, elemspec utils.ElemSpec) ([]outpu
192207
return result, nil
193208
}
194209
spec = evaluated.Ref
195-
component = evaluated.Component
196210
repo = evaluated.Repository
197211
} else {
198212
comp := ocm.CompSpec{Component: ""}

0 commit comments

Comments
 (0)