diff --git a/cmds/ocm/commands/ocmcmds/pubsub/get/cmd.go b/cmds/ocm/commands/ocmcmds/pubsub/get/cmd.go
index 4f6d2e17b7..c314bb6084 100644
--- a/cmds/ocm/commands/ocmcmds/pubsub/get/cmd.go
+++ b/cmds/ocm/commands/ocmcmds/pubsub/get/cmd.go
@@ -41,7 +41,7 @@ func (o *Command) ForName(name string) *cobra.Command {
Short: "Get the pubsub spec for an ocm repository",
Long: `
A repository may be able to store a publish/subscribe specification
-to propagate the creation or update of component version.
+to propagate the creation or update of component versions.
If such an implementation is available and a specification is
assigned to the repository, it is shown. The specification
can be set with the ocm set pubsub.
diff --git a/cmds/ocm/commands/ocmcmds/pubsub/set/cmd.go b/cmds/ocm/commands/ocmcmds/pubsub/set/cmd.go
index fbc815a15e..ae958e84ac 100644
--- a/cmds/ocm/commands/ocmcmds/pubsub/set/cmd.go
+++ b/cmds/ocm/commands/ocmcmds/pubsub/set/cmd.go
@@ -44,7 +44,7 @@ func (o *Command) ForName(name string) *cobra.Command {
Short: "Set the pubsub spec for an ocm repository",
Long: `
A repository may be able to store a publish/subscribe specification
-to propagate the creation or update of component version.
+to propagate the creation or update of component versions.
If such an implementation is available this command can be used
to set the pub/sub specification for a repository.
If no specification is given an existing specification
diff --git a/docs/reference/ocm_get_pubsub.md b/docs/reference/ocm_get_pubsub.md
index 8df9aee94a..153e4ca317 100644
--- a/docs/reference/ocm_get_pubsub.md
+++ b/docs/reference/ocm_get_pubsub.md
@@ -24,7 +24,7 @@ pubsub, ps
A repository may be able to store a publish/subscribe specification
-to propagate the creation or update of component version.
+to propagate the creation or update of component versions.
If such an implementation is available and a specification is
assigned to the repository, it is shown. The specification
can be set with the [ocm set pubsub](ocm_set_pubsub.md).
diff --git a/go.mod b/go.mod
index 77a6eed5a6..4221763d66 100644
--- a/go.mod
+++ b/go.mod
@@ -32,6 +32,7 @@ require (
github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/swag v0.23.0
github.com/go-test/deep v1.1.0
+ github.com/gobwas/glob v0.2.3
github.com/golang/mock v1.6.0
github.com/google/go-github/v45 v45.2.0
github.com/hashicorp/vault-client-go v0.4.3
@@ -193,7 +194,6 @@ require (
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
- github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/goccy/go-yaml v1.11.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
diff --git a/pkg/contexts/ocm/compdesc/accessors.go b/pkg/contexts/ocm/compdesc/accessors.go
new file mode 100644
index 0000000000..51215f722f
--- /dev/null
+++ b/pkg/contexts/ocm/compdesc/accessors.go
@@ -0,0 +1,84 @@
+package compdesc
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/equivalent"
+ metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+// NameAccessor describes a accessor for a named object.
+type NameAccessor interface {
+ // GetName returns the name of the object.
+ GetName() string
+ // SetName sets the name of the object.
+ SetName(name string)
+}
+
+// VersionAccessor describes a accessor for a versioned object.
+type VersionAccessor interface {
+ // GetVersion returns the version of the object.
+ GetVersion() string
+ // SetVersion sets the version of the object.
+ SetVersion(version string)
+}
+
+// LabelsAccessor describes a accessor for a labeled object.
+type LabelsAccessor interface {
+ // GetLabels returns the labels of the object.
+ GetLabels() metav1.Labels
+ // SetLabels sets the labels of the object.
+ SetLabels(labels []metav1.Label)
+}
+
+// ObjectMetaAccessor describes a accessor for named and versioned object.
+type ObjectMetaAccessor interface {
+ NameAccessor
+ VersionAccessor
+ LabelsAccessor
+}
+
+// ElementMetaAccessor provides generic access an elements meta information.
+type ElementMetaAccessor interface {
+ ElementMetaProvider
+ Equivalent(ElementMetaAccessor) equivalent.EqualState
+}
+
+// ElementAccessor provides generic access to list of elements.
+type ElementAccessor interface {
+ Len() int
+ Get(i int) ElementMetaAccessor
+}
+
+type ElementMetaProvider interface {
+ GetMeta() *ElementMeta
+}
+
+// ElementArtifactAccessor provides access to generic artifact information of an element.
+type ElementArtifactAccessor interface {
+ ElementMetaAccessor
+ GetType() string
+ GetAccess() AccessSpec
+ SetAccess(a AccessSpec)
+}
+
+type ElementDigestAccessor interface {
+ GetDigest() *metav1.DigestSpec
+ SetDigest(*metav1.DigestSpec)
+}
+
+// ArtifactAccessor provides generic access to list of artifacts.
+// There are resources or sources.
+type ArtifactAccessor interface {
+ ElementAccessor
+ GetArtifact(i int) ElementArtifactAccessor
+}
+
+// AccessSpec is an abstract specification of an access method
+// The outbound object is typicall a runtime.UnstructuredTypedObject.
+// Inbound any serializable AccessSpec implementation is possible.
+type AccessSpec = accessors.AccessSpec
+
+// AccessProvider provides access to an access specification of elements.
+type AccessProvider interface {
+ GetAccess() AccessSpec
+}
diff --git a/pkg/contexts/ocm/compdesc/componentdescriptor.go b/pkg/contexts/ocm/compdesc/componentdescriptor.go
index 56da53aace..e4b1d592f4 100644
--- a/pkg/contexts/ocm/compdesc/componentdescriptor.go
+++ b/pkg/contexts/ocm/compdesc/componentdescriptor.go
@@ -9,6 +9,7 @@ import (
"github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/equivalent"
metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
"github.com/open-component-model/ocm/pkg/runtime"
"github.com/open-component-model/ocm/pkg/semverutils"
)
@@ -112,8 +113,8 @@ type ComponentSpec struct {
}
const (
- SystemIdentityName = "name"
- SystemIdentityVersion = "version"
+ SystemIdentityName = metav1.SystemIdentityName
+ SystemIdentityVersion = metav1.SystemIdentityVersion
)
type ElementMetaAccess interface {
@@ -247,6 +248,31 @@ func (o *ElementMeta) GetIdentity(accessor ElementAccessor) metav1.Identity {
return identity
}
+// GetIdentityForContext returns the identity of the object.
+func (o *ElementMeta) GetIdentityForContext(accessor accessors.ElementListAccessor) metav1.Identity {
+ identity := o.ExtraIdentity.Copy()
+ if identity == nil {
+ identity = metav1.Identity{}
+ }
+ identity[SystemIdentityName] = o.Name
+ if accessor != nil {
+ found := false
+ l := accessor.Len()
+ for i := 0; i < l; i++ {
+ m := accessor.Get(i).GetMeta()
+ if m.GetName() == o.GetName() && m.GetExtraIdentity().Equals(o.ExtraIdentity) {
+ if found {
+ identity[SystemIdentityVersion] = o.Version
+
+ break
+ }
+ found = true
+ }
+ }
+ }
+ return identity
+}
+
// GetRawIdentity returns the identity plus version.
func (o *ElementMeta) GetRawIdentity() metav1.Identity {
identity := o.ExtraIdentity.Copy()
@@ -304,43 +330,6 @@ func (o *ElementMeta) Equivalent(a *ElementMeta) equivalent.EqualState {
return state.Apply(o.Labels.Equivalent(a.Labels))
}
-// NameAccessor describes a accessor for a named object.
-type NameAccessor interface {
- // GetName returns the name of the object.
- GetName() string
- // SetName sets the name of the object.
- SetName(name string)
-}
-
-// VersionAccessor describes a accessor for a versioned object.
-type VersionAccessor interface {
- // GetVersion returns the version of the object.
- GetVersion() string
- // SetVersion sets the version of the object.
- SetVersion(version string)
-}
-
-// LabelsAccessor describes a accessor for a labeled object.
-type LabelsAccessor interface {
- // GetLabels returns the labels of the object.
- GetLabels() metav1.Labels
- // SetLabels sets the labels of the object.
- SetLabels(labels []metav1.Label)
-}
-
-// ObjectMetaAccessor describes a accessor for named and versioned object.
-type ObjectMetaAccessor interface {
- NameAccessor
- VersionAccessor
- LabelsAccessor
-}
-
-// ElementMetaAccessor provides generic access an elements meta information.
-type ElementMetaAccessor interface {
- ElementMetaProvider
- Equivalent(ElementMetaAccessor) equivalent.EqualState
-}
-
func GetByIdentity(a ElementAccessor, id metav1.Identity) ElementMetaAccessor {
l := a.Len()
for i := 0; i < l; i++ {
@@ -363,47 +352,10 @@ func GetIndexByIdentity(a ElementAccessor, id metav1.Identity) int {
return -1
}
-// ElementAccessor provides generic access to list of elements.
-type ElementAccessor interface {
- Len() int
- Get(i int) ElementMetaAccessor
-}
-
-type ElementMetaProvider interface {
- GetMeta() *ElementMeta
-}
-
-// ElementArtifactAccessor provides access to generic artifact information of an element.
-type ElementArtifactAccessor interface {
- ElementMetaAccessor
- GetType() string
- GetAccess() AccessSpec
- SetAccess(a AccessSpec)
-}
-
-type ElementDigestAccessor interface {
- GetDigest() *metav1.DigestSpec
- SetDigest(*metav1.DigestSpec)
-}
-
-// ArtifactAccessor provides generic access to list of artifacts.
-// There are resources or sources.
-type ArtifactAccessor interface {
- ElementAccessor
- GetArtifact(i int) ElementArtifactAccessor
-}
-
// ArtifactAccess provides access to a dedicated kind of artifact set
// in the component descriptor (resources or sources).
type ArtifactAccess func(cd *ComponentDescriptor) ArtifactAccessor
-// AccessSpec is an abstract specification of an access method
-// The outbound object is typicall a runtime.UnstructuredTypedObject.
-// Inbound any serializable AccessSpec implementation is possible.
-type AccessSpec interface {
- runtime.VersionedTypedObject
-}
-
// GenericAccessSpec returns a generic AccessSpec implementation for an unstructured object.
// It can always be used instead of a dedicated access spec implementation. The core
// methods will map these spec into effective ones before an access is returned to the caller.
@@ -413,11 +365,6 @@ func GenericAccessSpec(un *runtime.UnstructuredTypedObject) AccessSpec {
}
}
-// AccessProvider provides access to an access specification of elements.
-type AccessProvider interface {
- GetAccess() AccessSpec
-}
-
// Sources describes a set of source specifications.
type Sources []Source
@@ -652,6 +599,10 @@ func (r *Resource) SetDigest(d *metav1.DigestSpec) {
r.Digest = d
}
+func (r *Resource) GetRelation() metav1.ResourceRelation {
+ return r.Relation
+}
+
func (r *Resource) Equivalent(e ElementMetaAccessor) equivalent.EqualState {
if o, ok := e.(*Resource); !ok {
state := equivalent.StateNotLocalHashEqual()
diff --git a/pkg/contexts/ocm/compdesc/deprecated.go b/pkg/contexts/ocm/compdesc/deprecated.go
new file mode 100644
index 0000000000..669150bb90
--- /dev/null
+++ b/pkg/contexts/ocm/compdesc/deprecated.go
@@ -0,0 +1,287 @@
+package compdesc
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/mandelsoft/goutils/sliceutils"
+
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/utils/selector"
+)
+
+// GetResourceAccessByIdentity returns a pointer to the resource that matches the given identity.
+//
+// Deprecated: use GetResourceByIdentity.
+func (cd *ComponentDescriptor) GetResourceAccessByIdentity(id v1.Identity) *Resource {
+ dig := id.Digest()
+ for i, res := range cd.Resources {
+ if bytes.Equal(res.GetIdentityDigest(cd.Resources), dig) {
+ return &cd.Resources[i]
+ }
+ }
+ return nil
+}
+
+// GetResourceByRegexSelector returns resources that match the given selectors.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourceByRegexSelector(sel interface{}) (Resources, error) {
+ identitySelector, err := selector.ParseRegexSelector(sel)
+ if err != nil {
+ return nil, fmt.Errorf("unable to parse selector: %w", err)
+ }
+ return cd.GetResourcesByIdentitySelectors(identitySelector)
+}
+
+// GetResourcesByIdentitySelectors returns resources that match the given identity selectors.
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourcesByIdentitySelectors(selectors ...IdentitySelector) (Resources, error) {
+ return cd.GetResourcesBySelectors(selectors, nil)
+}
+
+// GetResourcesByResourceSelectors returns resources that match the given resource selectors.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourcesByResourceSelectors(selectors ...ResourceSelector) (Resources, error) {
+ return cd.GetResourcesBySelectors(nil, selectors)
+}
+
+// GetResourcesBySelectors returns resources that match the given selector.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourcesBySelectors(selectors []IdentitySelector, resourceSelectors []ResourceSelector) (Resources, error) {
+ resources := make(Resources, 0)
+ for i := range cd.Resources {
+ selctx := NewResourceSelectionContext(i, cd.Resources)
+ if len(selectors) > 0 {
+ ok, err := selector.MatchSelectors(selctx.Identity(), selectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
+ }
+ if !ok {
+ continue
+ }
+ }
+ ok, err := MatchResourceByResourceSelector(selctx, resourceSelectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
+ }
+ if !ok {
+ continue
+ }
+ resources = append(resources, *selctx.Resource)
+ }
+ if len(resources) == 0 {
+ return resources, NotFound
+ }
+ return resources, nil
+}
+
+// GetExternalResources returns external resource with the given type, name and version.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetExternalResources(rtype, name, version string) (Resources, error) {
+ return cd.GetResourcesBySelectors(
+ []selector.Interface{
+ ByName(name),
+ ByVersion(version),
+ },
+ []ResourceSelector{
+ ByResourceType(rtype),
+ ByRelation(v1.ExternalRelation),
+ })
+}
+
+// GetExternalResource returns external resource with the given type, name and version.
+//
+// If multiple resources match, the first one is returned.
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetExternalResource(rtype, name, version string) (Resource, error) {
+ resources, err := cd.GetExternalResources(rtype, name, version)
+ if err != nil {
+ return Resource{}, err
+ }
+ // at least one resource must be defined, otherwise the getResourceBySelectors functions returns a NotFound err.
+ return resources[0], nil
+}
+
+// GetLocalResources returns all local resources with the given type, name and version.
+func (cd *ComponentDescriptor) GetLocalResources(rtype, name, version string) (Resources, error) {
+ return cd.GetResourcesBySelectors(
+ []selector.Interface{
+ ByName(name),
+ ByVersion(version),
+ },
+ []ResourceSelector{
+ ByResourceType(rtype),
+ ByRelation(v1.LocalRelation),
+ })
+}
+
+// GetLocalResource returns a local resource with the given type, name and version.
+//
+// If multiple resources match, the first one is returned.
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetLocalResource(rtype, name, version string) (Resource, error) {
+ resources, err := cd.GetLocalResources(rtype, name, version)
+ if err != nil {
+ return Resource{}, err
+ }
+ // at least one resource must be defined, otherwise the getResourceBySelectors functions returns a NotFound err.
+ return resources[0], nil
+}
+
+// GetResourcesByType returns all resources that match the given type and selectors.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourcesByType(rtype string, selectors ...IdentitySelector) (Resources, error) {
+ return cd.GetResourcesBySelectors(
+ selectors,
+ []ResourceSelector{
+ ByResourceType(rtype),
+ })
+}
+
+// GetResourcesByName returns all local and external resources with a name.
+//
+// Deprecated: use GetResources with appropriate selectors.
+func (cd *ComponentDescriptor) GetResourcesByName(name string, selectors ...IdentitySelector) (Resources, error) {
+ return cd.GetResourcesBySelectors(
+ sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name)),
+ nil)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// GetSourceAccessByIdentity returns a pointer to the source that matches the given identity.
+//
+// Deprecated: use GetSourceByIdentity.
+func (cd *ComponentDescriptor) GetSourceAccessByIdentity(id v1.Identity) *Source {
+ dig := id.Digest()
+ for i, res := range cd.Sources {
+ if bytes.Equal(res.GetIdentityDigest(cd.Sources), dig) {
+ return &cd.Sources[i]
+ }
+ }
+ return nil
+}
+
+// GetSourcesByIdentitySelectors returns references that match the given selector.
+//
+// Deprecated: use GetSources with appropriate selectors.
+func (cd *ComponentDescriptor) GetSourcesByIdentitySelectors(selectors ...IdentitySelector) (Sources, error) {
+ srcs := make(Sources, 0)
+ for _, src := range cd.Sources {
+ ok, err := selector.MatchSelectors(src.GetIdentity(cd.Sources), selectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for source %s: %w", src.Name, err)
+ }
+ if ok {
+ srcs = append(srcs, src)
+ }
+ }
+ if len(srcs) == 0 {
+ return srcs, NotFound
+ }
+ return srcs, nil
+}
+
+// GetSourcesByName returns all sources with a name.
+//
+// Deprecated: use GetSources with appropriate selectors.
+func (cd *ComponentDescriptor) GetSourcesByName(name string, selectors ...IdentitySelector) (Sources, error) {
+ return cd.GetSourcesByIdentitySelectors(
+ sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name))...)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// GetComponentReferences returns all component references that matches the given selectors.
+//
+// Deprectated: use GetReferences with appropriate selectors.
+func (cd *ComponentDescriptor) GetComponentReferences(selectors ...IdentitySelector) ([]ComponentReference, error) {
+ refs := make([]ComponentReference, 0)
+ for _, ref := range cd.References {
+ ok, err := selector.MatchSelectors(ref.GetIdentity(cd.References), selectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for resource %s: %w", ref.Name, err)
+ }
+ if ok {
+ refs = append(refs, ref)
+ }
+ }
+ if len(refs) == 0 {
+ return refs, NotFound
+ }
+ return refs, nil
+}
+
+// GetComponentReferenceIndex returns the index of a given component reference.
+// If the index is not found -1 is returned.
+// Deprecated: use GetReferenceIndex.
+func (cd *ComponentDescriptor) GetComponentReferenceIndex(ref ComponentReference) int {
+ return cd.GetReferenceIndex(ref.GetMeta())
+}
+
+// GetReferenceAccessByIdentity returns a pointer to the reference that matches the given identity.
+// Deprectated: use GetReferenceByIdentity.
+func (cd *ComponentDescriptor) GetReferenceAccessByIdentity(id v1.Identity) *ComponentReference {
+ dig := id.Digest()
+ for i, ref := range cd.References {
+ if bytes.Equal(ref.GetIdentityDigest(cd.Resources), dig) {
+ return &cd.References[i]
+ }
+ }
+ return nil
+}
+
+// GetReferencesByIdentitySelectors returns resources that match the given identity selectors.
+// Deprectated: use GetReferences with appropriate selectors.
+func (cd *ComponentDescriptor) GetReferencesByIdentitySelectors(selectors ...IdentitySelector) (References, error) {
+ return cd.GetReferencesBySelectors(selectors, nil)
+}
+
+// GetReferencesByReferenceSelectors returns resources that match the given resource selectors.
+// Deprectated: use GetReferences with appropriate selectors.
+func (cd *ComponentDescriptor) GetReferencesByReferenceSelectors(selectors ...ReferenceSelector) (References, error) {
+ return cd.GetReferencesBySelectors(nil, selectors)
+}
+
+// GetReferencesBySelectors returns resources that match the given selector.
+// Deprectated: use GetReferences with appropriate selectors.
+func (cd *ComponentDescriptor) GetReferencesBySelectors(selectors []IdentitySelector, referenceSelectors []ReferenceSelector) (References, error) {
+ references := make(References, 0)
+ for i := range cd.References {
+ selctx := NewReferenceSelectionContext(i, cd.References)
+ if len(selectors) > 0 {
+ ok, err := selector.MatchSelectors(selctx.Identity(), selectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
+ }
+ if !ok {
+ continue
+ }
+ }
+ ok, err := MatchReferencesByReferenceSelector(selctx, referenceSelectors...)
+ if err != nil {
+ return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
+ }
+ if !ok {
+ continue
+ }
+ references = append(references, *selctx.ComponentReference)
+ }
+ if len(references) == 0 {
+ return references, NotFound
+ }
+ return references, nil
+}
+
+// GetReferencesByName returns references that match the given name.
+// Deprectated: use GetReferences with appropriate selectors.
+func (cd *ComponentDescriptor) GetReferencesByName(name string, selectors ...IdentitySelector) (References, error) {
+ return cd.GetReferencesBySelectors(
+ sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name)),
+ nil)
+}
diff --git a/pkg/contexts/ocm/compdesc/helper.go b/pkg/contexts/ocm/compdesc/helper.go
index 8d50b892ab..f394b098f3 100644
--- a/pkg/contexts/ocm/compdesc/helper.go
+++ b/pkg/contexts/ocm/compdesc/helper.go
@@ -5,9 +5,12 @@ import (
"fmt"
"github.com/mandelsoft/goutils/errors"
- "github.com/mandelsoft/goutils/sliceutils"
v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/refsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/rscsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/srcsel"
"github.com/open-component-model/ocm/pkg/runtime"
"github.com/open-component-model/ocm/pkg/utils/selector"
)
@@ -37,22 +40,34 @@ func (cd *ComponentDescriptor) AddRepositoryContext(repoCtx runtime.TypedObject)
return nil
}
-// GetComponentReferences returns all component references that matches the given selectors.
-func (cd *ComponentDescriptor) GetComponentReferences(selectors ...IdentitySelector) ([]ComponentReference, error) {
- refs := make([]ComponentReference, 0)
- for _, ref := range cd.References {
- ok, err := selector.MatchSelectors(ref.GetIdentity(cd.References), selectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for resource %s: %w", ref.Name, err)
- }
- if ok {
- refs = append(refs, ref)
+func (cd *ComponentDescriptor) SelectResources(sel ...rscsel.Selector) ([]Resource, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+
+ list := MapToSelectorElementList(cd.Resources)
+ result := []Resource{}
+ for _, r := range cd.Resources {
+ if len(sel) > 0 {
+ mr := MapToSelectorResource(&r)
+ for _, s := range sel {
+ if !s.MatchResource(list, mr) {
+ continue
+ }
+ }
}
+ result = append(result, r)
}
- if len(refs) == 0 {
- return refs, NotFound
+ return result, nil
+}
+
+func (cd *ComponentDescriptor) GetResources() []Resource {
+ result := []Resource{}
+ for _, r := range cd.Resources {
+ result = append(result, r)
}
- return refs, nil
+ return result
}
// GetResourceByIdentity returns resource that matches the given identity.
@@ -66,17 +81,6 @@ func (cd *ComponentDescriptor) GetResourceByIdentity(id v1.Identity) (Resource,
return Resource{}, NotFound
}
-// GetResourceAccessByIdentity returns a pointer to the resource that matches the given identity.
-func (cd *ComponentDescriptor) GetResourceAccessByIdentity(id v1.Identity) *Resource {
- dig := id.Digest()
- for i, res := range cd.Resources {
- if bytes.Equal(res.GetIdentityDigest(cd.Resources), dig) {
- return &cd.Resources[i]
- }
- }
- return nil
-}
-
// GetResourceIndexByIdentity returns the index of the resource that matches the given identity.
func (cd *ComponentDescriptor) GetResourceIndexByIdentity(id v1.Identity) int {
dig := id.Digest()
@@ -106,129 +110,40 @@ func (cd *ComponentDescriptor) GetResourceByDefaultSelector(sel interface{}) (Re
return cd.GetResourcesByIdentitySelectors(identitySelector)
}
-// GetResourceByRegexSelector returns resources that match the given selectors.
-func (cd *ComponentDescriptor) GetResourceByRegexSelector(sel interface{}) (Resources, error) {
- identitySelector, err := selector.ParseRegexSelector(sel)
- if err != nil {
- return nil, fmt.Errorf("unable to parse selector: %w", err)
- }
- return cd.GetResourcesByIdentitySelectors(identitySelector)
-}
-
-// GetResourcesByIdentitySelectors returns resources that match the given identity selectors.
-func (cd *ComponentDescriptor) GetResourcesByIdentitySelectors(selectors ...IdentitySelector) (Resources, error) {
- return cd.GetResourcesBySelectors(selectors, nil)
+// GetResourceIndex returns the index of a given resource.
+// If the index is not found -1 is returned.
+func (cd *ComponentDescriptor) GetResourceIndex(res *ResourceMeta) int {
+ return ElementIndex(cd.Resources, res)
}
-// GetResourcesByResourceSelectors returns resources that match the given resource selectors.
-func (cd *ComponentDescriptor) GetResourcesByResourceSelectors(selectors ...ResourceSelector) (Resources, error) {
- return cd.GetResourcesBySelectors(nil, selectors)
-}
+func (cd *ComponentDescriptor) SelectSources(sel ...srcsel.Selector) ([]Source, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
-// GetResourcesBySelectors returns resources that match the given selector.
-func (cd *ComponentDescriptor) GetResourcesBySelectors(selectors []IdentitySelector, resourceSelectors []ResourceSelector) (Resources, error) {
- resources := make(Resources, 0)
- for i := range cd.Resources {
- selctx := NewResourceSelectionContext(i, cd.Resources)
- if len(selectors) > 0 {
- ok, err := selector.MatchSelectors(selctx.Identity(), selectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
- }
- if !ok {
- continue
+ list := MapToSelectorElementList(cd.Sources)
+ result := []Source{}
+ for _, r := range cd.Sources {
+ if len(sel) > 0 {
+ mr := MapToSelectorSource(&r)
+ for _, s := range sel {
+ if !s.MatchSource(list, mr) {
+ continue
+ }
}
}
- ok, err := MatchResourceByResourceSelector(selctx, resourceSelectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
- }
- if !ok {
- continue
- }
- resources = append(resources, *selctx.Resource)
- }
- if len(resources) == 0 {
- return resources, NotFound
+ result = append(result, r)
}
- return resources, nil
+ return result, nil
}
-// GetExternalResources returns external resource with the given type, name and version.
-func (cd *ComponentDescriptor) GetExternalResources(rtype, name, version string) (Resources, error) {
- return cd.GetResourcesBySelectors(
- []selector.Interface{
- ByName(name),
- ByVersion(version),
- },
- []ResourceSelector{
- ByResourceType(rtype),
- ByRelation(v1.ExternalRelation),
- })
-}
-
-// GetExternalResource returns external resource with the given type, name and version.
-// If multiple resources match, the first one is returned.
-func (cd *ComponentDescriptor) GetExternalResource(rtype, name, version string) (Resource, error) {
- resources, err := cd.GetExternalResources(rtype, name, version)
- if err != nil {
- return Resource{}, err
+func (cd *ComponentDescriptor) GetSources() []Source {
+ result := []Source{}
+ for _, r := range cd.Sources {
+ result = append(result, r)
}
- // at least one resource must be defined, otherwise the getResourceBySelectors functions returns a NotFound err.
- return resources[0], nil
-}
-
-// GetLocalResources returns all local resources with the given type, name and version.
-func (cd *ComponentDescriptor) GetLocalResources(rtype, name, version string) (Resources, error) {
- return cd.GetResourcesBySelectors(
- []selector.Interface{
- ByName(name),
- ByVersion(version),
- },
- []ResourceSelector{
- ByResourceType(rtype),
- ByRelation(v1.LocalRelation),
- })
-}
-
-// GetLocalResource returns a local resource with the given type, name and version.
-// If multiple resources match, the first one is returned.
-func (cd *ComponentDescriptor) GetLocalResource(rtype, name, version string) (Resource, error) {
- resources, err := cd.GetLocalResources(rtype, name, version)
- if err != nil {
- return Resource{}, err
- }
- // at least one resource must be defined, otherwise the getResourceBySelectors functions returns a NotFound err.
- return resources[0], nil
-}
-
-// GetResourcesByType returns all resources that match the given type and selectors.
-func (cd *ComponentDescriptor) GetResourcesByType(rtype string, selectors ...IdentitySelector) (Resources, error) {
- return cd.GetResourcesBySelectors(
- selectors,
- []ResourceSelector{
- ByResourceType(rtype),
- })
-}
-
-// GetResourcesByName returns all local and external resources with a name.
-func (cd *ComponentDescriptor) GetResourcesByName(name string, selectors ...IdentitySelector) (Resources, error) {
- return cd.GetResourcesBySelectors(
- sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name)),
- nil)
-}
-
-// GetResourceIndex returns the index of a given resource.
-// If the index is not found -1 is returned.
-func (cd *ComponentDescriptor) GetResourceIndex(res *ResourceMeta) int {
- return ElementIndex(cd.Resources, res)
-}
-
-// GetComponentReferenceIndex returns the index of a given component reference.
-// If the index is not found -1 is returned.
-// Deprecated: use GetReferenceIndex.
-func (cd *ComponentDescriptor) GetComponentReferenceIndex(ref ComponentReference) int {
- return cd.GetReferenceIndex(ref.GetMeta())
+ return result
}
// GetSourceByIdentity returns source that match the given identity.
@@ -242,17 +157,6 @@ func (cd *ComponentDescriptor) GetSourceByIdentity(id v1.Identity) (Source, erro
return Source{}, NotFound
}
-// GetSourceByIdentity returns a pointer to the source that matches the given identity.
-func (cd *ComponentDescriptor) GetSourceAccessByIdentity(id v1.Identity) *Source {
- dig := id.Digest()
- for i, res := range cd.Sources {
- if bytes.Equal(res.GetIdentityDigest(cd.Sources), dig) {
- return &cd.Sources[i]
- }
- }
- return nil
-}
-
// GetSourceIndexByIdentity returns the index of the source that matches the given identity.
func (cd *ComponentDescriptor) GetSourceIndexByIdentity(id v1.Identity) int {
dig := id.Digest()
@@ -264,36 +168,12 @@ func (cd *ComponentDescriptor) GetSourceIndexByIdentity(id v1.Identity) int {
return -1
}
-// GetSourcesByIdentitySelectors returns references that match the given selector.
-func (cd *ComponentDescriptor) GetSourcesByIdentitySelectors(selectors ...IdentitySelector) (Sources, error) {
- srcs := make(Sources, 0)
- for _, src := range cd.Sources {
- ok, err := selector.MatchSelectors(src.GetIdentity(cd.Sources), selectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for source %s: %w", src.Name, err)
- }
- if ok {
- srcs = append(srcs, src)
- }
- }
- if len(srcs) == 0 {
- return srcs, NotFound
- }
- return srcs, nil
-}
-
// GetSourceIndex returns the index of a given source.
// If the index is not found -1 is returned.
func (cd *ComponentDescriptor) GetSourceIndex(src *SourceMeta) int {
return ElementIndex(cd.Sources, src)
}
-// GetSourcesByName returns all sources with a name.
-func (cd *ComponentDescriptor) GetSourcesByName(name string, selectors ...IdentitySelector) (Sources, error) {
- return cd.GetSourcesByIdentitySelectors(
- sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name))...)
-}
-
// GetReferenceByIdentity returns reference that matches the given identity.
func (cd *ComponentDescriptor) GetReferenceByIdentity(id v1.Identity) (ComponentReference, error) {
dig := id.Digest()
@@ -305,15 +185,34 @@ func (cd *ComponentDescriptor) GetReferenceByIdentity(id v1.Identity) (Component
return ComponentReference{}, errors.ErrNotFound(KIND_REFERENCE, id.String())
}
-// GetReferenceAccessByIdentity returns a pointer to the reference that matches the given identity.
-func (cd *ComponentDescriptor) GetReferenceAccessByIdentity(id v1.Identity) *ComponentReference {
- dig := id.Digest()
- for i, ref := range cd.References {
- if bytes.Equal(ref.GetIdentityDigest(cd.Resources), dig) {
- return &cd.References[i]
+func (cd *ComponentDescriptor) SelectReferences(sel ...refsel.Selector) ([]ComponentReference, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+
+ list := MapToSelectorElementList(cd.References)
+ result := []ComponentReference{}
+ for _, r := range cd.References {
+ if len(sel) > 0 {
+ mr := MapToSelectorReference(&r)
+ for _, s := range sel {
+ if !s.MatchReference(list, mr) {
+ continue
+ }
+ }
}
+ result = append(result, r)
}
- return nil
+ return result, nil
+}
+
+func (cd *ComponentDescriptor) GetReferences() []ComponentReference {
+ result := []ComponentReference{}
+ for _, r := range cd.References {
+ result = append(result, r)
+ }
+ return result
}
// GetReferenceIndexByIdentity returns the index of the reference that matches the given identity.
@@ -327,52 +226,6 @@ func (cd *ComponentDescriptor) GetReferenceIndexByIdentity(id v1.Identity) int {
return -1
}
-// GetReferencesByName returns references that match the given name.
-func (cd *ComponentDescriptor) GetReferencesByName(name string, selectors ...IdentitySelector) (References, error) {
- return cd.GetReferencesBySelectors(
- sliceutils.CopyAppend[IdentitySelector](selectors, ByName(name)),
- nil)
-}
-
-// GetReferencesByIdentitySelectors returns resources that match the given identity selectors.
-func (cd *ComponentDescriptor) GetReferencesByIdentitySelectors(selectors ...IdentitySelector) (References, error) {
- return cd.GetReferencesBySelectors(selectors, nil)
-}
-
-// GetReferencesByReferenceSelectors returns resources that match the given resource selectors.
-func (cd *ComponentDescriptor) GetReferencesByReferenceSelectors(selectors ...ReferenceSelector) (References, error) {
- return cd.GetReferencesBySelectors(nil, selectors)
-}
-
-// GetReferencesBySelectors returns resources that match the given selector.
-func (cd *ComponentDescriptor) GetReferencesBySelectors(selectors []IdentitySelector, referenceSelectors []ReferenceSelector) (References, error) {
- references := make(References, 0)
- for i := range cd.References {
- selctx := NewReferenceSelectionContext(i, cd.References)
- if len(selectors) > 0 {
- ok, err := selector.MatchSelectors(selctx.Identity(), selectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
- }
- if !ok {
- continue
- }
- }
- ok, err := MatchReferencesByReferenceSelector(selctx, referenceSelectors...)
- if err != nil {
- return nil, fmt.Errorf("unable to match selector for resource %s: %w", selctx.Name, err)
- }
- if !ok {
- continue
- }
- references = append(references, *selctx.ComponentReference)
- }
- if len(references) == 0 {
- return references, NotFound
- }
- return references, nil
-}
-
// GetReferenceIndex returns the index of a given source.
// If the index is not found -1 is returned.
func (cd *ComponentDescriptor) GetReferenceIndex(src ElementMetaProvider) int {
diff --git a/pkg/contexts/ocm/compdesc/selector.go b/pkg/contexts/ocm/compdesc/selector.go
new file mode 100644
index 0000000000..578ccde40b
--- /dev/null
+++ b/pkg/contexts/ocm/compdesc/selector.go
@@ -0,0 +1,61 @@
+package compdesc
+
+import (
+ "github.com/mandelsoft/goutils/generics"
+
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+type elemList struct {
+ ElementAccessor
+}
+
+func (e *elemList) Get(i int) accessors.ElementMetaAccessor {
+ return generics.Cast[accessors.ElementMetaAccessor](e.ElementAccessor.Get(i))
+}
+
+func MapToSelectorElementList(accessor ElementAccessor) accessors.ElementListAccessor {
+ return &elemList{accessor}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type rscAcc struct {
+ *Resource
+}
+
+func (a rscAcc) GetMeta() accessors.ElementMeta {
+ return a.Resource.GetMeta()
+}
+
+func MapToSelectorResource(r *Resource) accessors.ResourceAccessor {
+ return rscAcc{r}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type srcAcc struct {
+ *Source
+}
+
+func (a srcAcc) GetMeta() accessors.ElementMeta {
+ return a.Source.GetMeta()
+}
+
+func MapToSelectorSource(r *Source) accessors.SourceAccessor {
+ return srcAcc{r}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type refAcc struct {
+ *ComponentReference
+}
+
+func (a refAcc) GetMeta() accessors.ElementMeta {
+ return a.ComponentReference.GetMeta()
+}
+
+func MapToSelectorReference(r *ComponentReference) accessors.ReferenceAccessor {
+ return refAcc{r}
+}
diff --git a/pkg/contexts/ocm/compdesc/selectors.go b/pkg/contexts/ocm/compdesc/selectors.go
index 81c6f60988..c3a96438f5 100644
--- a/pkg/contexts/ocm/compdesc/selectors.go
+++ b/pkg/contexts/ocm/compdesc/selectors.go
@@ -12,6 +12,7 @@ import (
"github.com/open-component-model/ocm/pkg/utils/selector"
)
+// Deprecated: use package selectors and its sub packages.
type IdentityBasedSelector interface {
IdentitySelector
ElementSelector
@@ -19,12 +20,14 @@ type IdentityBasedSelector interface {
ReferenceSelector
}
+// Deprecated: use package selectors and its sub packages.
type ElementBasedSelector interface {
ElementSelector
ResourceSelector
ReferenceSelector
}
+// Deprecated: use package selectors and its sub packages.
type LabelBasedSelector interface {
LabelSelector
ElementSelector
@@ -34,6 +37,7 @@ type LabelBasedSelector interface {
////////////////////////////////////////////////////////////////////////////////
+// Deprecated: use package selectors and its sub packages.
type IdentitySelector = selector.Interface
type byVersion struct {
@@ -60,6 +64,8 @@ func (b *byVersion) MatchReference(obj ReferenceSelectionContext) (bool, error)
// ByVersion creates a new selector that
// selects an element based on its version.
+//
+// Deprecated: use package selectors and its sub packages.
func ByVersion(version string) IdentityBasedSelector {
return &byVersion{version: version}
}
@@ -88,6 +94,8 @@ func (b *byName) MatchReference(obj ReferenceSelectionContext) (bool, error) {
// ByName creates a new selector that
// selects an element based on its name.
+//
+// Deprecated: use package selectors and its sub packages.
func ByName(name string) IdentityBasedSelector {
return &byName{name: name}
}
@@ -126,6 +134,8 @@ func (b *byIdentity) MatchReference(obj ReferenceSelectionContext) (bool, error)
// ByIdentity creates a new resource and identity selector that
// selects a resource based on its identity.
+//
+// Deprecated: use package selectors and its sub packages.
func ByIdentity(name string, extras ...string) IdentityBasedSelector {
id := v1.NewIdentity(name, extras...)
return &byIdentity{id: id}
@@ -135,6 +145,8 @@ func ByIdentity(name string, extras ...string) IdentityBasedSelector {
// selects a resource based on its partial identity.
// All given attributes must match, but potential additional attributes
// of a resource identity are ignored.
+//
+// Deprecated: use package selectors and its sub packages.
func ByPartialIdentity(name string, extras ...string) IdentityBasedSelector {
id := v1.NewIdentity(name, extras...)
return &byIdentity{id: id, partial: true}
@@ -172,6 +184,8 @@ func (b *withExtraId) MatchReference(obj ReferenceSelectionContext) (bool, error
// WithExtraIdentity creates a new selector that
// selects an element based on extra identities.
+//
+// Deprecated: use package selectors and its sub packages.
func WithExtraIdentity(args ...string) IdentityBasedSelector {
ids := v1.Identity{}
for i := 0; i < len(args); i += 2 {
@@ -185,6 +199,8 @@ func WithExtraIdentity(args ...string) IdentityBasedSelector {
////////////////////////////////////////////////////////////////////////////////
// ResourceSelectorFunc defines a function to filter a resource.
+//
+// Deprecated: use package selectors and its sub packages.
type ResourceSelectorFunc func(obj ResourceSelectionContext) (bool, error)
var _ ResourceSelector = ResourceSelectorFunc(nil)
@@ -198,6 +214,7 @@ type resourceSelectionContext struct {
identity
}
+// Deprecated: use package selectors and its sub packages.
func NewResourceSelectionContext(index int, rscs Resources) ResourceSelectionContext {
return &resourceSelectionContext{
Resource: &rscs[index],
@@ -211,14 +228,20 @@ func NewResourceSelectionContext(index int, rscs Resources) ResourceSelectionCon
// ResourceSelectionContext describes the selction context for a resource
// selector. It contains the resource and provides access to its
// identity in the context of its component descriptor.
+//
+// Deprecated: use package selectors and its sub packages.
type ResourceSelectionContext = *resourceSelectionContext
// ResourceSelector defines a selector based on resource attributes.
+//
+// Deprecated: use package selectors and its sub packages.
type ResourceSelector interface {
MatchResource(obj ResourceSelectionContext) (bool, error)
}
// MatchResourceByResourceSelector applies all resource selector against the given resource object.
+//
+// Deprecated: use package selectors and its sub packages.
func MatchResourceByResourceSelector(obj ResourceSelectionContext, resourceSelectors ...ResourceSelector) (bool, error) {
for _, sel := range resourceSelectors {
ok, err := sel.MatchResource(obj)
@@ -233,6 +256,8 @@ func MatchResourceByResourceSelector(obj ResourceSelectionContext, resourceSelec
}
// AndR is an AND resource selector.
+//
+// Deprecated: use package labelsel.
func AndR(sel ...ResourceSelector) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
for _, s := range sel {
@@ -246,6 +271,8 @@ func AndR(sel ...ResourceSelector) ResourceSelector {
}
// OrR is an OR resource selector.
+//
+// Deprecated: use package labelsel.
func OrR(sel ...ResourceSelector) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
for _, s := range sel {
@@ -259,6 +286,8 @@ func OrR(sel ...ResourceSelector) ResourceSelector {
}
// NotR is a negated resource selector.
+//
+// Deprecated: use package labelsel.
func NotR(sel ResourceSelector) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
ok, err := sel.MatchResource(obj)
@@ -271,6 +300,8 @@ func NotR(sel ResourceSelector) ResourceSelector {
// ByResourceType creates a new resource selector that
// selects a resource based on its type.
+//
+// Deprecated: use package selectors and its sub packages.
func ByResourceType(ttype string) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
return ttype == "" || obj.GetType() == ttype, nil
@@ -279,6 +310,8 @@ func ByResourceType(ttype string) ResourceSelector {
// ByRelation creates a new resource selector that
// selects a resource based on its relation type.
+//
+// Deprecated: use package selectors and its sub packages.
func ByRelation(relation v1.ResourceRelation) ResourceSelectorFunc {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
return obj.Relation == relation, nil
@@ -286,6 +319,8 @@ func ByRelation(relation v1.ResourceRelation) ResourceSelectorFunc {
}
// ByAccessMethod creates a new selector that matches a resource access method type.
+//
+// Deprecated: use package selectors and its sub packages.
func ByAccessMethod(name string) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
if obj.Access == nil {
@@ -296,6 +331,8 @@ func ByAccessMethod(name string) ResourceSelector {
}
// ForExecutable creates a new selector that matches a resource for an executable.
+//
+// Deprecated: use package selectors and its sub packages.
func ForExecutable(name string) ResourceSelector {
return ResourceSelectorFunc(func(obj ResourceSelectionContext) (bool, error) {
return obj.Name == name && obj.Type == resourcetypes.EXECUTABLE && obj.ExtraIdentity != nil &&
@@ -307,11 +344,15 @@ func ForExecutable(name string) ResourceSelector {
////////////////////////////////////////////////////////////////////////////////
// LabelSelector is used to match a label in a label set.
+//
+// Deprecated: use package selectors and its sub packages.
type LabelSelector interface {
MatchLabel(l v1.Label) (bool, error)
}
// LabelSelectorFunc is a function used as LabelSelector.
+//
+// Deprecated: use package selectors and its sub packages.
type LabelSelectorFunc func(l v1.Label) (bool, error)
func (l LabelSelectorFunc) MatchLabel(label v1.Label) (bool, error) {
@@ -319,6 +360,8 @@ func (l LabelSelectorFunc) MatchLabel(label v1.Label) (bool, error) {
}
// AndL is an AND label selector.
+//
+// Deprecated: use package selectors and its sub packages.
func AndL(sel ...LabelSelector) LabelSelector {
return LabelSelectorFunc(func(obj v1.Label) (bool, error) {
for _, s := range sel {
@@ -332,6 +375,8 @@ func AndL(sel ...LabelSelector) LabelSelector {
}
// OrL is an OR label selector.
+//
+// Deprecated: use package selectors and its sub packages.
func OrL(sel ...LabelSelector) LabelSelector {
return LabelSelectorFunc(func(obj v1.Label) (bool, error) {
for _, s := range sel {
@@ -345,6 +390,8 @@ func OrL(sel ...LabelSelector) LabelSelector {
}
// NotL is a negated label selector.
+//
+// Deprecated: use package selectors and its sub packages.
func NotL(sel LabelSelector) LabelSelector {
return LabelSelectorFunc(func(obj v1.Label) (bool, error) {
ok, err := sel.MatchLabel(obj)
@@ -392,6 +439,8 @@ func (b *byLabel) MatchLabel(l v1.Label) (bool, error) {
// be grouped into a single label selector to be applied in
// combination. Otherwise, a resource might match if the label
// selectors all match, but different labels.
+//
+// Deprecated: use package selectors and its sub packages.
func ByLabel(sel ...LabelSelector) LabelBasedSelector {
return &byLabel{selector: LabelSelectorFunc(func(l v1.Label) (bool, error) {
return MatchLabels(v1.Labels{l}, sel...)
@@ -399,12 +448,16 @@ func ByLabel(sel ...LabelSelector) LabelBasedSelector {
}
// ByLabelName matches an element by a label name.
+//
+// Deprecated: use package selectors and its sub packages.
func ByLabelName(name string) LabelBasedSelector {
return &byLabel{selector: LabelSelectorFunc(func(l v1.Label) (bool, error) { return l.Name == name, nil })}
}
// ByLabelValue matches a resource or label by a label value.
// This selector should typically be combined with ByLabelName.
+//
+// Deprecated: use package selectors and its sub packages.
func ByLabelValue(value interface{}) LabelBasedSelector {
return &byLabel{selector: LabelSelectorFunc(func(l v1.Label) (bool, error) {
var data interface{}
@@ -417,18 +470,24 @@ func ByLabelValue(value interface{}) LabelBasedSelector {
// ByLabelVersion matches a resource or label by a label version.
// This selector should typically be combined with ByLabelName.
+//
+// Deprecated: use package selectors and its sub packages.
func ByLabelVersion(version string) LabelBasedSelector {
return &byLabel{selector: LabelSelectorFunc(func(l v1.Label) (bool, error) { return l.Version == version, nil })}
}
// BySignedLabel matches a resource or label by a label indicated to be signed.
// This selector should typically be combined with ByLabelName.
+//
+// Deprecated: use package selectors and its sub packages.
func BySignedLabel(flags ...bool) LabelBasedSelector {
flag := utils.OptionalDefaultedBool(true, flags...)
return &byLabel{selector: LabelSelectorFunc(func(l v1.Label) (bool, error) { return l.Signing == flag, nil })}
}
// MatchLabels checks whether a set of labels matches the given label selectors.
+//
+// Deprecated: use package selectors and its sub packages.
func MatchLabels(labels v1.Labels, sel ...LabelSelector) (bool, error) {
if len(labels) == 0 && len(sel) == 0 {
return true, nil
@@ -453,6 +512,8 @@ outer:
}
// SelectLabels returns labels matching the given label selectors.
+//
+// Deprecated: use package selectors and its sub packages.
func SelectLabels(labels v1.Labels, sel ...LabelSelector) (v1.Labels, error) {
list := make(v1.Labels, 0)
outer:
@@ -473,6 +534,8 @@ outer:
}
// MatchReferencesByReferenceSelector applies all resource selector against the given resource object.
+//
+// Deprecated: use package selectors and its sub packages.
func MatchReferencesByReferenceSelector(obj ReferenceSelectionContext, resourceSelectors ...ReferenceSelector) (bool, error) {
for _, sel := range resourceSelectors {
ok, err := sel.MatchReference(obj)
@@ -493,8 +556,10 @@ type elementSelectionContext struct {
identity
}
+// Deprecated: not supported anymore.
type ElementSelectionContext = *elementSelectionContext
+// Deprecated: not supported anymore.
func NewElementSelectionContext(index int, elems ElementAccessor) ElementSelectionContext {
return &elementSelectionContext{
ElementMeta: elems.Get(index).GetMeta(),
@@ -505,6 +570,7 @@ func NewElementSelectionContext(index int, elems ElementAccessor) ElementSelecti
}
}
+// Deprecated: use package selectors and its sub packages.
type ElementSelector interface {
MatchElement(obj ElementSelectionContext) (bool, error)
}
@@ -512,6 +578,8 @@ type ElementSelector interface {
////////////////////////////////////////////////////////////////////////////////
// ReferenceSelectorFunc defines a function to filter a resource.
+//
+// Deprecated: use package selectors and its sub packages.
type ReferenceSelectorFunc func(obj ReferenceSelectionContext) (bool, error)
var _ ReferenceSelector = ReferenceSelectorFunc(nil)
@@ -525,6 +593,7 @@ type referenceSelectionContext struct {
identity
}
+// Deprecated: use package selectors and its sub packages.
func NewReferenceSelectionContext(index int, refs References) ReferenceSelectionContext {
return &referenceSelectionContext{
ComponentReference: &refs[index],
@@ -538,14 +607,20 @@ func NewReferenceSelectionContext(index int, refs References) ReferenceSelection
// ReferenceSelectionContext describes the selection context for a reference
// selector. It contains the reference and provides access to its
// identity in the context of its component descriptor.
+//
+// Deprecated: use package selectors and its sub packages.
type ReferenceSelectionContext = *referenceSelectionContext
// ReferenceSelector defines a selector based on reference attributes.
+//
+// Deprecated: use package selectors and its sub packages.
type ReferenceSelector interface {
MatchReference(obj ReferenceSelectionContext) (bool, error)
}
// AndC is an AND reference selector.
+//
+// Deprecated: use package selectors and its sub packages.
func AndC(sel ...ReferenceSelector) ReferenceSelector {
return ReferenceSelectorFunc(func(obj ReferenceSelectionContext) (bool, error) {
for _, s := range sel {
@@ -559,6 +634,8 @@ func AndC(sel ...ReferenceSelector) ReferenceSelector {
}
// OrC is an OR resource selector.
+//
+// Deprecated: use package selectors and its sub packages.
func OrC(sel ...ReferenceSelector) ReferenceSelector {
return ReferenceSelectorFunc(func(obj ReferenceSelectionContext) (bool, error) {
for _, s := range sel {
@@ -572,6 +649,8 @@ func OrC(sel ...ReferenceSelector) ReferenceSelector {
}
// NotC is a negated resource selector.
+//
+// Deprecated: use package selectors and its sub packages.
func NotC(sel ReferenceSelector) ReferenceSelector {
return ReferenceSelectorFunc(func(obj ReferenceSelectionContext) (bool, error) {
ok, err := sel.MatchReference(obj)
@@ -582,6 +661,7 @@ func NotC(sel ReferenceSelector) ReferenceSelector {
})
}
+// Deprecated: use package selectors and its sub packages.
func ByComponent(name string) ReferenceSelector {
return ReferenceSelectorFunc(func(obj ReferenceSelectionContext) (bool, error) {
return obj.ComponentName == name, nil
diff --git a/pkg/contexts/ocm/cpi/dummy.go b/pkg/contexts/ocm/cpi/dummy.go
index 4111edbe0a..0ea31bc101 100644
--- a/pkg/contexts/ocm/cpi/dummy.go
+++ b/pkg/contexts/ocm/cpi/dummy.go
@@ -8,6 +8,9 @@ import (
"github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc"
metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
"github.com/open-component-model/ocm/pkg/contexts/ocm/internal"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/refsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/rscsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/srcsel"
)
type DummyComponentVersionAccess struct {
@@ -67,6 +70,10 @@ func (d *DummyComponentVersionAccess) GetDescriptor() *compdesc.ComponentDescrip
return nil
}
+func (d *DummyComponentVersionAccess) SelectResources(sel ...rscsel.Selector) ([]ResourceAccess, error) {
+ return nil, nil
+}
+
func (d *DummyComponentVersionAccess) GetResources() []ResourceAccess {
return nil
}
@@ -83,10 +90,15 @@ func (d *DummyComponentVersionAccess) GetResourceByIndex(i int) (ResourceAccess,
return nil, errors.ErrInvalid("resource index", strconv.Itoa(i))
}
+// Deprecated: use GetResources.
func (d *DummyComponentVersionAccess) GetResourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]ResourceAccess, error) {
return nil, errors.ErrInvalid("resource", name)
}
+func (d *DummyComponentVersionAccess) SelectSources(sel ...srcsel.Selector) ([]SourceAccess, error) {
+ return nil, nil
+}
+
func (d *DummyComponentVersionAccess) GetSources() []SourceAccess {
return nil
}
@@ -107,6 +119,14 @@ func (d *DummyComponentVersionAccess) GetReference(meta metav1.Identity) (Compon
return ComponentReference{}, errors.ErrNotFound("reference", meta.String())
}
+func (d *DummyComponentVersionAccess) SelectReferences(sel ...refsel.Selector) ([]ComponentReference, error) {
+ return nil, nil
+}
+
+func (d *DummyComponentVersionAccess) GetReferences() []ComponentReference {
+ return nil
+}
+
func (d *DummyComponentVersionAccess) GetReferenceIndex(metav1.Identity) int {
return -1
}
@@ -115,6 +135,7 @@ func (d *DummyComponentVersionAccess) GetReferenceByIndex(i int) (ComponentRefer
return ComponentReference{}, errors.ErrInvalid("reference index", strconv.Itoa(i))
}
+// Deprecated: use GetSources.
func (d *DummyComponentVersionAccess) GetSourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]SourceAccess, error) {
return nil, errors.ErrInvalid("source", name)
}
@@ -137,6 +158,10 @@ func (d *DummyComponentVersionAccess) Update() error {
return errors.ErrNotSupported("update")
}
+func (d *DummyComponentVersionAccess) Execute(f func() error) error {
+ return f()
+}
+
func (d *DummyComponentVersionAccess) AddBlob(blob BlobAccess, arttype, refName string, global AccessSpec, opts ...BlobUploadOption) (AccessSpec, error) {
return nil, errors.ErrNotSupported("adding blobs")
}
@@ -184,22 +209,27 @@ func (d *DummyComponentVersionAccess) UseDirectAccess() bool {
return true
}
+// Deprecated: use GetResources.
func (d *DummyComponentVersionAccess) GetResourcesByIdentitySelectors(selectors ...compdesc.IdentitySelector) ([]internal.ResourceAccess, error) {
return nil, nil
}
+// Deprecated: use GetResources.
func (d *DummyComponentVersionAccess) GetResourcesByResourceSelectors(selectors ...compdesc.ResourceSelector) ([]internal.ResourceAccess, error) {
return nil, nil
}
+// Deprecated: use GetReferences.
func (d *DummyComponentVersionAccess) GetReferencesByName(name string, selectors ...compdesc.IdentitySelector) (compdesc.References, error) {
return nil, nil
}
+// Deprecated: use GetReferences.
func (d *DummyComponentVersionAccess) GetReferencesByIdentitySelectors(selectors ...compdesc.IdentitySelector) (compdesc.References, error) {
return nil, nil
}
+// Deprecated: use GetReferences.
func (d *DummyComponentVersionAccess) GetReferencesByReferenceSelectors(selectors ...compdesc.ReferenceSelector) (compdesc.References, error) {
return nil, nil
}
diff --git a/pkg/contexts/ocm/cpi/repocpi/view_cv.go b/pkg/contexts/ocm/cpi/repocpi/view_cv.go
index 6586e58f4b..ec0cc6db0c 100644
--- a/pkg/contexts/ocm/cpi/repocpi/view_cv.go
+++ b/pkg/contexts/ocm/cpi/repocpi/view_cv.go
@@ -17,6 +17,10 @@ import (
"github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi"
"github.com/open-component-model/ocm/pkg/contexts/ocm/internal"
"github.com/open-component-model/ocm/pkg/contexts/ocm/plugin/descriptor"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/refsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/rscsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/srcsel"
"github.com/open-component-model/ocm/pkg/refmgmt"
"github.com/open-component-model/ocm/pkg/refmgmt/resource"
"github.com/open-component-model/ocm/pkg/utils"
@@ -643,6 +647,7 @@ func (c *componentVersionAccessView) GetResourceByIndex(i int) (cpi.ResourceAcce
return cpi.NewResourceAccess(c, r.Access, r.ResourceMeta), nil
}
+// Deprecated: use GetResources with appropriate selectors.
func (c *componentVersionAccessView) GetResourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]cpi.ResourceAccess, error) {
resources, err := c.GetDescriptor().GetResourcesByName(name, selectors...)
if err != nil {
@@ -656,6 +661,28 @@ func (c *componentVersionAccessView) GetResourcesByName(name string, selectors .
return result, nil
}
+func (c *componentVersionAccessView) SelectResources(sel ...rscsel.Selector) ([]cpi.ResourceAccess, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+
+ list := compdesc.MapToSelectorElementList(c.GetDescriptor().Resources)
+ result := []cpi.ResourceAccess{}
+ for _, r := range c.GetDescriptor().Resources {
+ if len(sel) > 0 {
+ mr := compdesc.MapToSelectorResource(&r)
+ for _, s := range sel {
+ if !s.MatchResource(list, mr) {
+ continue
+ }
+ }
+ }
+ result = append(result, cpi.NewResourceAccess(c, r.Access, r.ResourceMeta))
+ }
+ return result, nil
+}
+
func (c *componentVersionAccessView) GetResources() []cpi.ResourceAccess {
result := []cpi.ResourceAccess{}
for _, r := range c.GetDescriptor().Resources {
@@ -665,16 +692,22 @@ func (c *componentVersionAccessView) GetResources() []cpi.ResourceAccess {
}
// GetResourcesByIdentitySelectors returns resources that match the given identity selectors.
+//
+// Deprecated: use GetReferences.
func (c *componentVersionAccessView) GetResourcesByIdentitySelectors(selectors ...compdesc.IdentitySelector) ([]cpi.ResourceAccess, error) {
return c.GetResourcesBySelectors(selectors, nil)
}
// GetResourcesByResourceSelectors returns resources that match the given resource selectors.
+//
+// Deprecated: use GetResources.
func (c *componentVersionAccessView) GetResourcesByResourceSelectors(selectors ...compdesc.ResourceSelector) ([]cpi.ResourceAccess, error) {
return c.GetResourcesBySelectors(nil, selectors)
}
// GetResourcesBySelectors returns resources that match the given selector.
+//
+// Deprecated: use GetResources.
func (c *componentVersionAccessView) GetResourcesBySelectors(selectors []compdesc.IdentitySelector, resourceSelectors []compdesc.ResourceSelector) ([]cpi.ResourceAccess, error) {
resources := make([]cpi.ResourceAccess, 0)
rscs := c.GetDescriptor().Resources
@@ -728,6 +761,7 @@ func (c *componentVersionAccessView) GetSourceByIndex(i int) (cpi.SourceAccess,
return cpi.NewSourceAccess(c, r.Access, r.SourceMeta), nil
}
+// Deprecated: use GetSources with appropriate selectors.
func (c *componentVersionAccessView) GetSourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]cpi.SourceAccess, error) {
sources, err := c.GetDescriptor().GetSourcesByName(name, selectors...)
if err != nil {
@@ -741,6 +775,28 @@ func (c *componentVersionAccessView) GetSourcesByName(name string, selectors ...
return result, nil
}
+func (c *componentVersionAccessView) SelectSources(sel ...srcsel.Selector) ([]cpi.SourceAccess, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+
+ list := compdesc.MapToSelectorElementList(c.GetDescriptor().Sources)
+ result := []cpi.SourceAccess{}
+ for _, r := range c.GetDescriptor().Sources {
+ if len(sel) > 0 {
+ mr := compdesc.MapToSelectorSource(&r)
+ for _, s := range sel {
+ if !s.MatchSource(list, mr) {
+ continue
+ }
+ }
+ }
+ result = append(result, cpi.NewSourceAccess(c, r.Access, r.SourceMeta))
+ }
+ return result, nil
+}
+
func (c *componentVersionAccessView) GetSources() []cpi.SourceAccess {
result := []cpi.SourceAccess{}
for _, r := range c.GetDescriptor().Sources {
@@ -749,8 +805,16 @@ func (c *componentVersionAccessView) GetSources() []cpi.SourceAccess {
return result
}
-func (c *componentVersionAccessView) GetReferences() compdesc.References {
- return c.GetDescriptor().References
+func (c *componentVersionAccessView) SelectReferences(sel ...refsel.Selector) ([]compdesc.ComponentReference, error) {
+ err := selectors.ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+ return c.GetDescriptor().SelectReferences(sel...)
+}
+
+func (c *componentVersionAccessView) GetReferences() []compdesc.ComponentReference {
+ return c.GetDescriptor().GetReferences()
}
func (c *componentVersionAccessView) GetReference(id metav1.Identity) (cpi.ComponentReference, error) {
@@ -768,21 +832,28 @@ func (c *componentVersionAccessView) GetReferenceByIndex(i int) (cpi.ComponentRe
return c.GetDescriptor().References[i], nil
}
+// Deprecated: use GetReferences.
func (c *componentVersionAccessView) GetReferencesByName(name string, selectors ...compdesc.IdentitySelector) (compdesc.References, error) {
return c.GetDescriptor().GetReferencesByName(name, selectors...)
}
// GetReferencesByIdentitySelectors returns references that match the given identity selectors.
+//
+// Deprecated: use GetReferences.
func (c *componentVersionAccessView) GetReferencesByIdentitySelectors(selectors ...compdesc.IdentitySelector) (compdesc.References, error) {
return c.GetReferencesBySelectors(selectors, nil)
}
// GetReferencesByReferenceSelectors returns references that match the given resource selectors.
+//
+// Deprecated: use GetReferences.
func (c *componentVersionAccessView) GetReferencesByReferenceSelectors(selectors ...compdesc.ReferenceSelector) (compdesc.References, error) {
return c.GetReferencesBySelectors(nil, selectors)
}
// GetReferencesBySelectors returns references that match the given selector.
+//
+// Deprecated: use GetReferences.
func (c *componentVersionAccessView) GetReferencesBySelectors(selectors []compdesc.IdentitySelector, referenceSelectors []compdesc.ReferenceSelector) (compdesc.References, error) {
references := make(compdesc.References, 0)
refs := c.GetDescriptor().References
diff --git a/pkg/contexts/ocm/internal/repository.go b/pkg/contexts/ocm/internal/repository.go
index 2ef145b159..6c0c67e863 100644
--- a/pkg/contexts/ocm/internal/repository.go
+++ b/pkg/contexts/ocm/internal/repository.go
@@ -8,6 +8,9 @@ import (
"github.com/open-component-model/ocm/pkg/contexts/credentials"
"github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc"
metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/refsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/rscsel"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/srcsel"
"github.com/open-component-model/ocm/pkg/refmgmt/resource"
)
@@ -128,20 +131,37 @@ type ComponentVersionAccess interface {
GetProvider() *compdesc.Provider
SetProvider(provider *compdesc.Provider) error
- GetResources() []ResourceAccess
GetResource(meta metav1.Identity) (ResourceAccess, error)
GetResourceIndex(meta metav1.Identity) int
GetResourceByIndex(i int) (ResourceAccess, error)
+ GetResources() []ResourceAccess
+ SelectResources(sel ...rscsel.Selector) ([]ResourceAccess, error)
+
+ //
+ // Deprecated: use GetResources with selector arguments.
+ //nolint: staticcheck // deprecated
GetResourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]ResourceAccess, error)
+
+ //
+ // Deprecated: use GetResources with selector arguments.
+ //nolint: staticcheck // deprecated
GetResourcesByIdentitySelectors(selectors ...compdesc.IdentitySelector) ([]ResourceAccess, error)
+
+ //
+ // Deprecated: use GetResources with selector arguments.
+ //nolint: staticcheck // deprecated
GetResourcesByResourceSelectors(selectors ...compdesc.ResourceSelector) ([]ResourceAccess, error)
SetResource(*ResourceMeta, compdesc.AccessSpec, ...ModificationOption) error
SetResourceByAccess(art ResourceAccess, modopts ...BlobModificationOption) error
- GetSources() []SourceAccess
GetSource(meta metav1.Identity) (SourceAccess, error)
GetSourceIndex(meta metav1.Identity) int
GetSourceByIndex(i int) (SourceAccess, error)
+ GetSources() []SourceAccess
+ SelectSources(sel ...srcsel.Selector) ([]SourceAccess, error)
+
+ // Deprecated: use GetResources with appropriate selectors.
+ //nolint: staticcheck // deprecated
GetSourcesByName(name string, selectors ...compdesc.IdentitySelector) ([]SourceAccess, error)
// SetSource updates or sets anew source. The options only use the
// target options. All other options are ignored.
@@ -153,8 +173,19 @@ type ComponentVersionAccess interface {
GetReference(meta metav1.Identity) (ComponentReference, error)
GetReferenceIndex(meta metav1.Identity) int
GetReferenceByIndex(i int) (ComponentReference, error)
+ GetReferences() []ComponentReference
+ SelectReferences(sel ...refsel.Selector) ([]ComponentReference, error)
+
+ // Deprecated: use GetReferences with appropriate selectors.
+ //nolint: staticcheck // deprecated
GetReferencesByName(name string, selectors ...compdesc.IdentitySelector) (compdesc.References, error)
+
+ // Deprecated: use GetReferences with appropriate selectors.
+ //nolint: staticcheck // deprecated
GetReferencesByIdentitySelectors(selectors ...compdesc.IdentitySelector) (compdesc.References, error)
+
+ // Deprecated: use GetReferences with appropriate selectors.
+ //nolint: staticcheck // deprecated
GetReferencesByReferenceSelectors(selectors ...compdesc.ReferenceSelector) (compdesc.References, error)
SetReference(ref *ComponentReference, opts ...TargetOption) error
@@ -188,6 +219,10 @@ type ComponentVersionAccess interface {
// Update adds the version with all changes to the component instance it has been created for.
Update() error
+
+ // Execute executes a function on a valid and locked component version reference.
+ // If it returns an error this error is forwarded.
+ Execute(func() error) error
}
// ComponentLister provides the optional repository list functionality of
diff --git a/pkg/contexts/ocm/pubsub/types/compound/type.go b/pkg/contexts/ocm/pubsub/types/compound/type.go
index 31df9279f4..29f132cd4c 100644
--- a/pkg/contexts/ocm/pubsub/types/compound/type.go
+++ b/pkg/contexts/ocm/pubsub/types/compound/type.go
@@ -19,9 +19,9 @@ const (
func init() {
pubsub.RegisterType(pubsub.NewPubSubType[*Spec](Type,
- pubsub.WithDesciption("a pub/sub system forwarding events to described sub-level systems.")))
+ pubsub.WithDesciption("A pub/sub system forwarding events to described sub-level systems.")))
pubsub.RegisterType(pubsub.NewPubSubType[*Spec](TypeV1,
- pubsub.WithFormatSpec(`It is describe by the following field:
+ pubsub.WithFormatSpec(`It is described by the following field:
- **specifications
** *list of pubsub specs*
diff --git a/pkg/contexts/ocm/selectors/accessors/accessors.go b/pkg/contexts/ocm/selectors/accessors/accessors.go
new file mode 100644
index 0000000000..1559f89d22
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/accessors/accessors.go
@@ -0,0 +1,56 @@
+package accessors
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/runtime"
+)
+
+// ElementListAccessor provides generic access to list of elements.
+type ElementListAccessor interface {
+ Len() int
+ Get(i int) ElementMetaAccessor
+}
+
+// ElementMeta describes the access to common element meta data attributes.
+type ElementMeta interface {
+ GetName() string
+ GetVersion() string
+ GetExtraIdentity() v1.Identity
+ GetLabels() v1.Labels
+ GetIdentityForContext(accessor ElementListAccessor) v1.Identity
+}
+
+// ElementMetaAccessor provides generic access an elements meta information.
+type ElementMetaAccessor interface {
+ GetMeta() ElementMeta
+}
+
+// AccessSpec is the minimal interface for access spec attributes.
+type AccessSpec interface {
+ runtime.VersionedTypedObject
+}
+
+// ArtifactAccessor provides access to generic artifact information of an element.
+type ArtifactAccessor interface {
+ ElementMetaAccessor
+ GetType() string
+ GetAccess() AccessSpec
+}
+
+// ResourceAccessor provides access to resource attribute.
+type ResourceAccessor interface {
+ ArtifactAccessor
+ GetRelation() v1.ResourceRelation
+ GetDigest() *v1.DigestSpec
+}
+
+// SourceAccessor provides access to source attribute.
+type SourceAccessor interface {
+ ArtifactAccessor
+}
+
+// ReferenceAccessor provides access to source attribute.
+type ReferenceAccessor interface {
+ ElementMetaAccessor
+ GetComponentName() string
+}
diff --git a/pkg/contexts/ocm/selectors/artifacts.go b/pkg/contexts/ocm/selectors/artifacts.go
new file mode 100644
index 0000000000..c6dd782baf
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/artifacts.go
@@ -0,0 +1,54 @@
+package selectors
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+type ArtifactSelector interface {
+ MatchArtifact(a accessors.ArtifactAccessor) bool
+}
+
+type ArtifactSelectorImpl struct {
+ ArtifactSelector
+}
+
+func (i *ArtifactSelectorImpl) MatchResource(list accessors.ElementListAccessor, a accessors.ResourceAccessor) bool {
+ return i.MatchArtifact(a)
+}
+
+func (i *ArtifactSelectorImpl) MatchSource(list accessors.ElementListAccessor, a accessors.SourceAccessor) bool {
+ return i.MatchArtifact(a)
+}
+
+type ArtifactErrorSelectorImpl struct {
+ ErrorSelectorBase
+ ArtifactSelectorImpl
+}
+
+func NewArtifactErrorSelectorImpl(s ArtifactSelector, err error) *ArtifactErrorSelectorImpl {
+ return &ArtifactErrorSelectorImpl{NewErrorSelectorBase(err), ArtifactSelectorImpl{s}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type artType string
+
+func (n artType) MatchArtifact(a accessors.ArtifactAccessor) bool {
+ return string(n) == a.GetType()
+}
+
+func ArtifactType(n string) *ArtifactSelectorImpl {
+ return &ArtifactSelectorImpl{artType(n)}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type accessKind string
+
+func (n accessKind) MatchArtifact(a accessors.ArtifactAccessor) bool {
+ return string(n) == a.GetAccess().GetKind()
+}
+
+func AccessKind(n string) *ArtifactSelectorImpl {
+ return &ArtifactSelectorImpl{accessKind(n)}
+}
diff --git a/pkg/contexts/ocm/selectors/identity.go b/pkg/contexts/ocm/selectors/identity.go
new file mode 100644
index 0000000000..0ba701b847
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/identity.go
@@ -0,0 +1,195 @@
+package selectors
+
+import (
+ "regexp"
+
+ "github.com/Masterminds/semver/v3"
+
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+type IdentitySelector interface {
+ MatchIdentity(identity v1.Identity) bool
+}
+
+type IdentitySelectorImpl struct {
+ IdentitySelector
+}
+
+func (i *IdentitySelectorImpl) MatchResource(list accessors.ElementListAccessor, a accessors.ResourceAccessor) bool {
+ return i.MatchIdentity(a.GetMeta().GetIdentityForContext(list))
+}
+
+func (i *IdentitySelectorImpl) MatchSource(list accessors.ElementListAccessor, a accessors.SourceAccessor) bool {
+ return i.MatchIdentity(a.GetMeta().GetIdentityForContext(list))
+}
+
+func (i *IdentitySelectorImpl) MatchReference(list accessors.ElementListAccessor, a accessors.ReferenceAccessor) bool {
+ return i.MatchIdentity(a.GetMeta().GetIdentityForContext(list))
+}
+
+type IdentityErrorSelectorImpl struct {
+ ErrorSelectorBase
+ IdentitySelectorImpl
+}
+
+func NewIdentityErrorSelectorImpl(s IdentitySelector, err error) *IdentityErrorSelectorImpl {
+ return &IdentityErrorSelectorImpl{NewErrorSelectorBase(err), IdentitySelectorImpl{s}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type idattrs struct {
+ v1.Identity
+}
+
+func (i *idattrs) MatchIdentity(identity v1.Identity) bool {
+ for n, v := range i.Identity {
+ if identity[n] != v {
+ return false
+ }
+ }
+ return true
+}
+
+func IdentityAttributesByKeyPairs(extra ...string) *IdentitySelectorImpl {
+ return &IdentitySelectorImpl{&idattrs{v1.NewExtraIdentity(extra...)}}
+}
+
+func IdentityAttributes(identity v1.Identity) *IdentitySelectorImpl {
+ return &IdentitySelectorImpl{&idattrs{identity}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type id struct {
+ v1.Identity
+}
+
+func (i *id) MatchIdentity(identity v1.Identity) bool {
+ if len(i.Identity) != len(identity) {
+ return false
+ }
+ for n, v := range i.Identity {
+ if identity[n] != v {
+ return false
+ }
+ }
+ return true
+}
+
+func IdentityByKeyPairs(extra ...string) *IdentitySelectorImpl {
+ return &IdentitySelectorImpl{&id{v1.NewExtraIdentity(extra...)}}
+}
+
+func Identity(identity v1.Identity) *IdentitySelectorImpl {
+ return &IdentitySelectorImpl{&id{identity}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type num int
+
+func (i num) MatchIdentity(identity v1.Identity) bool {
+ return len(identity) == int(i)
+}
+
+func NumberOfIdentityAttributes(n int) *IdentitySelectorImpl {
+ return &IdentitySelectorImpl{num(n)}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type idRegEx struct {
+ attr string
+ *regexp.Regexp
+}
+
+func (c *idRegEx) MatchIdentity(identity v1.Identity) bool {
+ v, ok := identity[c.attr]
+ if !ok {
+ return false
+ }
+ return c.Regexp.MatchString(v)
+}
+
+func IdentityAttrRegex(name, ex string) *IdentitySelectorImpl {
+ c, _ := regexp.Compile(ex)
+ return &IdentitySelectorImpl{&idRegEx{name, c}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type Name string
+
+func (n Name) MatchIdentity(identity v1.Identity) bool {
+ return string(n) == identity[v1.SystemIdentityName]
+}
+
+func (n Name) MatchResource(list accessors.ElementListAccessor, r accessors.ResourceAccessor) bool {
+ return string(n) == r.GetMeta().GetName()
+}
+
+func (n Name) MatchSource(list accessors.ElementListAccessor, r accessors.SourceAccessor) bool {
+ return string(n) == r.GetMeta().GetName()
+}
+
+func (n Name) MatchReference(list accessors.ElementListAccessor, r accessors.ReferenceAccessor) bool {
+ return string(n) == r.GetMeta().GetName()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type Version string
+
+func (v Version) MatchIdentity(identity v1.Identity) bool {
+ return string(v) == identity[v1.SystemIdentityVersion]
+}
+
+func (v Version) MatchResource(list accessors.ElementListAccessor, r accessors.ResourceAccessor) bool {
+ return string(v) == r.GetMeta().GetVersion()
+}
+
+func (v Version) MatchSource(list accessors.ElementListAccessor, r accessors.SourceAccessor) bool {
+ return string(v) == r.GetMeta().GetVersion()
+}
+
+func (v Version) MatchReference(list accessors.ElementListAccessor, r accessors.ReferenceAccessor) bool {
+ return string(v) == r.GetMeta().GetVersion()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type semverConstraint struct {
+ *semver.Constraints
+}
+
+func VersionConstraint(expr string) *semverConstraint {
+ c, _ := semver.NewConstraint(expr)
+ return &semverConstraint{c}
+}
+
+func (v *semverConstraint) check(vers string) bool {
+ sv, _ := semver.NewVersion(vers)
+ if sv == nil {
+ return false
+ }
+ return v.Constraints.Check(sv)
+}
+
+func (v *semverConstraint) MatchIdentity(identity v1.Identity) bool {
+ return v.check(identity[v1.SystemIdentityVersion])
+}
+
+func (v *semverConstraint) MatchResource(list accessors.ElementListAccessor, r accessors.ResourceAccessor) bool {
+ return v.check(r.GetMeta().GetVersion())
+}
+
+func (v *semverConstraint) MatchSource(list accessors.ElementListAccessor, r accessors.SourceAccessor) bool {
+ return v.check(r.GetMeta().GetVersion())
+}
+
+func (v *semverConstraint) MatchReference(list accessors.ElementListAccessor, r accessors.ReferenceAccessor) bool {
+ return v.check(r.GetMeta().GetVersion())
+}
diff --git a/pkg/contexts/ocm/selectors/label.go b/pkg/contexts/ocm/selectors/label.go
new file mode 100644
index 0000000000..dd3a7cbd58
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/label.go
@@ -0,0 +1,86 @@
+package selectors
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+func SelectLabels(labels v1.Labels, sel ...LabelSelector) ([]v1.Label, error) {
+ err := ValidateSelectors(sel...)
+ if err != nil {
+ return nil, err
+ }
+ return GetLabels(labels, sel...), nil
+}
+
+func GetLabels(labels v1.Labels, sel ...LabelSelector) []v1.Label {
+ var result []v1.Label
+ for _, l := range labels {
+ for _, s := range sel {
+ if !s.MatchLabel(&l) {
+ continue
+ }
+ }
+ result = append(result, l)
+ }
+ return result
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type LabelSelectorImpl struct {
+ LabelSelector
+}
+
+func (i *LabelSelectorImpl) MatchResource(list accessors.ElementListAccessor, a accessors.ResourceAccessor) bool {
+ return len(GetLabels(a.GetMeta().GetLabels(), i)) > 0
+}
+
+func (i *LabelSelectorImpl) MatchSource(list accessors.ElementListAccessor, a accessors.SourceAccessor) bool {
+ return len(GetLabels(a.GetMeta().GetLabels(), i)) > 0
+}
+
+func (i *LabelSelectorImpl) MatchReference(list accessors.ElementListAccessor, a accessors.ReferenceAccessor) bool {
+ return len(GetLabels(a.GetMeta().GetLabels(), i)) > 0
+}
+
+type LabelErrPropSelectorImpl struct {
+ LabelSelectorImpl
+}
+
+func (l *LabelErrPropSelectorImpl) GetError() error {
+ if e, ok := l.LabelSelector.(ErrorProvider); ok {
+ return e.GetError()
+ }
+ return nil
+}
+
+type LabelErrorSelectorImpl struct {
+ ErrorSelectorBase
+ LabelSelectorImpl
+}
+
+func NewLabelErrorSelectorImpl(s LabelSelector, err error) *LabelErrorSelectorImpl {
+ return &LabelErrorSelectorImpl{NewErrorSelectorBase(err), LabelSelectorImpl{s}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type label []LabelSelector
+
+func (s label) MatchLabel(l *v1.Label) bool {
+ for _, n := range s {
+ if !n.MatchLabel(l) {
+ return false
+ }
+ }
+ return true
+}
+
+func (s label) GetError() error {
+ return ValidateSubSelectors("and", []LabelSelector(s)...)
+}
+
+func Label(sel ...LabelSelector) *LabelErrPropSelectorImpl {
+ return &LabelErrPropSelectorImpl{LabelSelectorImpl{label(sel)}}
+}
diff --git a/pkg/contexts/ocm/selectors/labelsel/interface.go b/pkg/contexts/ocm/selectors/labelsel/interface.go
new file mode 100644
index 0000000000..fe1b4103fd
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/labelsel/interface.go
@@ -0,0 +1,178 @@
+package labelsel
+
+import (
+ "bytes"
+ "container/list"
+ "encoding/json"
+ "reflect"
+
+ "github.com/mandelsoft/goutils/errors"
+ "github.com/mikefarah/yq/v4/pkg/yqlib"
+ "gopkg.in/op/go-logging.v1"
+
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/runtime"
+ "github.com/open-component-model/ocm/pkg/utils"
+)
+
+func init() {
+ logging.SetLevel(logging.ERROR, "yq-lib")
+ yqlib.InitExpressionParser()
+}
+
+type Selector = selectors.LabelSelector
+
+func Select(labels v1.Labels, sel ...Selector) ([]v1.Label, error) {
+ return selectors.SelectLabels(labels, sel...)
+}
+
+func Get(labels v1.Labels, sel ...Selector) []v1.Label {
+ return selectors.GetLabels(labels, sel...)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type name string
+
+func (n name) MatchLabel(l *v1.Label) bool {
+ return string(n) == l.Name
+}
+
+func Name(n string) *selectors.LabelSelectorImpl {
+ return &selectors.LabelSelectorImpl{name(n)}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type version string
+
+func (n version) MatchLabel(l *v1.Label) bool {
+ return string(n) == l.Version
+}
+
+func Version(n string) *selectors.LabelSelectorImpl {
+ return &selectors.LabelSelectorImpl{version(n)}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+type signed bool
+
+func (n signed) MatchLabel(l *v1.Label) bool {
+ return bool(n) == l.Signing
+}
+
+func Signed(b ...bool) *selectors.LabelSelectorImpl {
+ return &selectors.LabelSelectorImpl{signed(utils.OptionalDefaultedBool(true, b...))}
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+type mergealgo string
+
+func (n mergealgo) MatchLabel(l *v1.Label) bool {
+ a := string(n)
+ if l.Merge == nil {
+ return a == ""
+ }
+ return a == l.Merge.Algorithm
+}
+
+func MergeAlgo(algo string) *selectors.LabelSelectorImpl {
+ return &selectors.LabelSelectorImpl{mergealgo(algo)}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+func AsStructure(value interface{}) (interface{}, error) {
+ var err error
+
+ data, ok := value.([]byte)
+ if !ok {
+ data, err = json.Marshal(value)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var v interface{}
+ err = runtime.DefaultYAMLEncoding.Unmarshal(data, &v)
+ if err != nil {
+ return nil, err
+ }
+ return v, nil
+}
+
+// Value matches a label by a label value.
+// This selector should typically be combined with Name.
+func Value(value interface{}) *selectors.LabelErrorSelectorImpl {
+ data, err := AsStructure(value)
+ return selectors.NewLabelErrorSelectorImpl(selectors.LabelSelectorFunc(func(l *v1.Label) bool {
+ var value interface{}
+ err := json.Unmarshal(l.Value, &value)
+ if err != nil {
+ return false
+ }
+ return reflect.DeepEqual(value, data)
+ }), err)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+func YQParse(data []byte) (*yqlib.CandidateNode, error) {
+ decoder := yqlib.NewYamlDecoder(yqlib.YamlPreferences{})
+ err := decoder.Init(bytes.NewReader(data))
+ if err != nil {
+ return nil, err
+ }
+ return decoder.Decode()
+}
+
+type yqeval struct {
+ expr *yqlib.ExpressionNode
+ value interface{}
+}
+
+func (v *yqeval) MatchLabel(l *v1.Label) bool {
+ if v.expr == nil {
+ return false
+ }
+ in, err := YQParse(l.Value)
+ if err != nil {
+ return false
+ }
+ t := yqlib.NewDataTreeNavigator()
+ docs := list.New()
+ docs.PushBack(in)
+ context, err := t.GetMatchingNodes(yqlib.Context{MatchingNodes: docs}, v.expr)
+ if err != nil {
+ return false
+ }
+ if context.MatchingNodes.Len() != 1 {
+ return false
+ }
+ data, err := context.MatchingNodes.Front().Value.(*yqlib.CandidateNode).MarshalJSON()
+ if err != nil {
+ return false
+ }
+ var out interface{}
+ err = json.Unmarshal(data, &out)
+ if err != nil {
+ return false
+ }
+ return reflect.DeepEqual(v.value, out)
+}
+
+// YQExpression matches a part of a label values described by a YQ expression.
+// If value is a []byte, it is interpreted as JSON data, otherwise the value
+// marshalled as JSON.
+func YQExpression(expr string, value interface{}) *selectors.LabelErrorSelectorImpl {
+ var data interface{}
+
+ node, err := yqlib.ExpressionParser.ParseExpression(expr)
+ if err == nil {
+ data, err = AsStructure(value)
+ }
+ return selectors.NewLabelErrorSelectorImpl(&yqeval{node, data}, errors.Wrapf(err, "YQExpression selector"))
+}
diff --git a/pkg/contexts/ocm/selectors/labelsel/label_test.go b/pkg/contexts/ocm/selectors/labelsel/label_test.go
new file mode 100644
index 0000000000..1e0dc22dcd
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/labelsel/label_test.go
@@ -0,0 +1,88 @@
+package labelsel_test
+
+import (
+ "bytes"
+
+ . "github.com/mandelsoft/goutils/testutils"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/labelsel"
+ "sigs.k8s.io/yaml"
+
+ "github.com/mikefarah/yq/v4/pkg/yqlib"
+)
+
+func Parse(data []byte) (*yqlib.CandidateNode, error) {
+ decoder := yqlib.NewYamlDecoder(yqlib.YamlPreferences{})
+ err := decoder.Init(bytes.NewReader(data))
+ if err != nil {
+ return nil, err
+ }
+ return decoder.Decode()
+}
+
+var _ = Describe("yq label values", func() {
+ data := `
+people:
+- name: alice
+ age: 25
+- name: bob
+ age: 26
+data:
+ attr: value
+`
+ Context("yq", func() {
+ It("", func() {
+ doc := Must(Parse([]byte(data)))
+ eval := yqlib.NewAllAtOnceEvaluator()
+ r := Must(eval.EvaluateNodes(".people[0].name", doc))
+ Expect(r.Len()).To(Equal(1))
+ e := r.Front()
+ v := e.Value.(*yqlib.CandidateNode)
+ data := Must(v.MarshalJSON())
+ Expect(data).To(YAMLEqual("alice"))
+ })
+ })
+
+ Context("labels", func() {
+ var datav map[string]interface{}
+ labels := v1.Labels{}
+ MustBeSuccessful(yaml.Unmarshal([]byte(data), &datav))
+ MustBeSuccessful(labels.SetValue("data", datav))
+ MustBeSuccessful(labels.SetValue("string", "some data"))
+
+ It("check complex data", func() {
+ m := labelsel.YQExpression(".data", datav["data"])
+ Expect(m).NotTo(BeNil())
+ Expect(selectors.ValidateSelectors(m)).NotTo(HaveOccurred())
+
+ Expect(m.MatchLabel(&labels[0])).To(BeTrue())
+ Expect(m.MatchLabel(&labels[1])).To(BeFalse())
+ })
+
+ It("check complex expression", func() {
+ m := labelsel.YQExpression(".people[0].name", "alice")
+ Expect(m).NotTo(BeNil())
+ Expect(selectors.ValidateSelectors(m)).NotTo(HaveOccurred())
+
+ Expect(m.MatchLabel(&labels[0])).To(BeTrue())
+ Expect(m.MatchLabel(&labels[1])).To(BeFalse())
+ })
+
+ It("detects error", func() {
+ m := labelsel.YQExpression(".people[0]].name", "alice")
+ Expect(m).NotTo(BeNil())
+ Expect(selectors.ValidateSelectors(m)).To(MatchError("error in selector list: YQExpression selector: bad expression, could not find matching `)`"))
+ })
+
+ It("detects error in expressions", func() {
+ m := labelsel.YQExpression(".people[0]].name", "alice")
+ Expect(m).NotTo(BeNil())
+ Expect(selectors.ValidateSelectors(labelsel.Or(m))).To(MatchError("error in selector list: or: YQExpression selector: bad expression, could not find matching `)`"))
+ Expect(selectors.ValidateSelectors(labelsel.And(m))).To(MatchError("error in selector list: and: YQExpression selector: bad expression, could not find matching `)`"))
+ Expect(selectors.ValidateSelectors(labelsel.Not(m))).To(MatchError("error in selector list: not: YQExpression selector: bad expression, could not find matching `)`"))
+ })
+ })
+})
diff --git a/pkg/contexts/ocm/selectors/labelsel/operators.go b/pkg/contexts/ocm/selectors/labelsel/operators.go
new file mode 100644
index 0000000000..7b628ca381
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/labelsel/operators.go
@@ -0,0 +1,56 @@
+package labelsel
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+)
+
+var (
+ _ selectors.ErrorProvider = (or)(nil)
+ _ selectors.ErrorProvider = (*not)(nil)
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+func And(sel ...Selector) *selectors.LabelErrPropSelectorImpl {
+ return selectors.Label(sel...)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type or []Selector
+
+func (a or) MatchLabel(l *v1.Label) bool {
+ for _, o := range a {
+ if o.MatchLabel(l) {
+ return true
+ }
+ }
+ return false
+}
+
+func (a or) GetError() error {
+ return selectors.ValidateSubSelectors("or", []Selector(a)...)
+}
+
+func Or(operands ...Selector) Selector {
+ return or(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type not struct {
+ sel Selector
+}
+
+func (a *not) MatchLabel(l *v1.Label) bool {
+ return !a.sel.MatchLabel(l)
+}
+
+func (a *not) GetError() error {
+ return selectors.ValidateSubSelectors("not", a.sel)
+}
+
+func Not(operand Selector) Selector {
+ return ¬{operand}
+}
diff --git a/pkg/contexts/ocm/selectors/labelsel/suite_test.go b/pkg/contexts/ocm/selectors/labelsel/suite_test.go
new file mode 100644
index 0000000000..a73a112c6a
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/labelsel/suite_test.go
@@ -0,0 +1,13 @@
+package labelsel_test
+
+import (
+ "testing"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+)
+
+func TestConfig(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "label selectorTest Suite")
+}
diff --git a/pkg/contexts/ocm/selectors/refsel/element.go b/pkg/contexts/ocm/selectors/refsel/element.go
new file mode 100644
index 0000000000..1aa9964744
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/refsel/element.go
@@ -0,0 +1,35 @@
+package refsel
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/labelsel"
+)
+
+// Identity selectors
+
+func IdentityByKeyPairs(extras ...string) Selector {
+ return selectors.IdentityByKeyPairs(extras...)
+}
+
+func Identity(id v1.Identity) Selector {
+ return selectors.Identity(id)
+}
+
+func Name(n string) Selector {
+ return selectors.Name(n)
+}
+
+func Version(n string) Selector {
+ return selectors.Version(n)
+}
+
+// Label selectors
+
+func Label(sel ...selectors.LabelSelector) Selector {
+ return selectors.Label(sel...)
+}
+
+func LabelName(n string) Selector {
+ return labelsel.Name(n)
+}
diff --git a/pkg/contexts/ocm/selectors/refsel/interface.go b/pkg/contexts/ocm/selectors/refsel/interface.go
new file mode 100644
index 0000000000..872222c5f4
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/refsel/interface.go
@@ -0,0 +1,59 @@
+package refsel
+
+import (
+ "regexp"
+
+ "github.com/gobwas/glob"
+
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+type (
+ Selector = selectors.ReferenceSelector
+ SelectorFunc = selectors.ReferenceSelectorFunc
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+type Component string
+
+func (c Component) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ return string(c) == ref.GetComponentName()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type compGlob struct {
+ glob.Glob
+}
+
+func (c *compGlob) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ if c.Glob == nil {
+ return false
+ }
+ return c.Glob.Match(ref.GetComponentName())
+}
+
+func ComponentGlob(g string) Selector {
+ c, err := glob.Compile(g, '/')
+ return selectors.NewReferenceErrorSelectorImpl(&compGlob{c}, err)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type compRegEx struct {
+ *regexp.Regexp
+}
+
+func (c *compRegEx) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ if c.Regexp == nil {
+ return false
+ }
+ return c.Regexp.MatchString(ref.GetComponentName())
+}
+
+func ComponentRegex(g string) selectors.ReferenceSelector {
+ c, err := regexp.Compile(g)
+ return selectors.NewReferenceErrorSelectorImpl(&compRegEx{c}, err)
+}
diff --git a/pkg/contexts/ocm/selectors/refsel/operators.go b/pkg/contexts/ocm/selectors/refsel/operators.go
new file mode 100644
index 0000000000..08ce913202
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/refsel/operators.go
@@ -0,0 +1,72 @@
+package refsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+var (
+ _ selectors.ErrorProvider = (and)(nil)
+ _ selectors.ErrorProvider = (or)(nil)
+ _ selectors.ErrorProvider = (*not)(nil)
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+type and []Selector
+
+func (a and) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ for _, o := range a {
+ if !o.MatchReference(list, ref) {
+ return false
+ }
+ }
+ return true
+}
+
+func (a and) GetError() error {
+ return selectors.ValidateSubSelectors("and", []Selector(a)...)
+}
+
+func And(operands ...Selector) Selector {
+ return and(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type or []Selector
+
+func (a or) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ for _, o := range a {
+ if o.MatchReference(list, ref) {
+ return true
+ }
+ }
+ return false
+}
+
+func (a or) GetError() error {
+ return selectors.ValidateSubSelectors("or", []Selector(a)...)
+}
+
+func Or(operands ...Selector) Selector {
+ return or(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type not struct {
+ Selector
+}
+
+func (a *not) MatchReference(list accessors.ElementListAccessor, ref accessors.ReferenceAccessor) bool {
+ return !a.Selector.MatchReference(list, ref)
+}
+
+func (a *not) GetError() error {
+ return selectors.ValidateSubSelectors("not", a.Selector)
+}
+
+func Not(operand Selector) Selector {
+ return ¬{operand}
+}
diff --git a/pkg/contexts/ocm/selectors/rscsel/artifact.go b/pkg/contexts/ocm/selectors/rscsel/artifact.go
new file mode 100644
index 0000000000..68107f4ead
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/rscsel/artifact.go
@@ -0,0 +1,15 @@
+package rscsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+)
+
+// Artifact selectors
+
+func ArtifactType(n string) Selector {
+ return selectors.ArtifactType(n)
+}
+
+func AccessKind(n string) Selector {
+ return selectors.AccessKind(n)
+}
diff --git a/pkg/contexts/ocm/selectors/rscsel/element.go b/pkg/contexts/ocm/selectors/rscsel/element.go
new file mode 100644
index 0000000000..b2383ced8e
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/rscsel/element.go
@@ -0,0 +1,39 @@
+package rscsel
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/labelsel"
+)
+
+// Identity selectors
+
+func IdentityByKeyPairs(extras ...string) Selector {
+ return selectors.IdentityByKeyPairs(extras...)
+}
+
+func Identity(id v1.Identity) Selector {
+ return selectors.Identity(id)
+}
+
+func Name(n string) Selector {
+ return selectors.Name(n)
+}
+
+func Version(n string) Selector {
+ return selectors.Version(n)
+}
+
+func VersionConstraint(expr string) Selector {
+ return selectors.VersionConstraint(expr)
+}
+
+// Label selectors
+
+func Label(sel ...selectors.LabelSelector) Selector {
+ return selectors.Label(sel...)
+}
+
+func LabelName(n string) Selector {
+ return labelsel.Name(n)
+}
diff --git a/pkg/contexts/ocm/selectors/rscsel/interface.go b/pkg/contexts/ocm/selectors/rscsel/interface.go
new file mode 100644
index 0000000000..c783de7d16
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/rscsel/interface.go
@@ -0,0 +1,40 @@
+package rscsel
+
+import (
+ "runtime"
+
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/extraid"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+type (
+ Selector = selectors.ResourceSelector
+ SelectorFunc = selectors.ResourceSelectorFunc
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+type Relation v1.ResourceRelation
+
+func (r Relation) MatchResource(list accessors.ElementListAccessor, res accessors.ResourceAccessor) bool {
+ return v1.ResourceRelation(r) == res.GetRelation()
+}
+
+var (
+ Local = Relation(v1.LocalRelation)
+ External = Relation(v1.ExternalRelation)
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+func Executable(name string) Selector {
+ return SelectorFunc(func(list accessors.ElementListAccessor, a accessors.ResourceAccessor) bool {
+ extra := a.GetMeta().GetExtraIdentity()
+ return a.GetMeta().GetName() == name && a.GetType() == resourcetypes.EXECUTABLE && extra != nil &&
+ extra[extraid.ExecutableOperatingSystem] == runtime.GOOS &&
+ extra[extraid.ExecutableArchitecture] == runtime.GOARCH
+ })
+}
diff --git a/pkg/contexts/ocm/selectors/rscsel/operators.go b/pkg/contexts/ocm/selectors/rscsel/operators.go
new file mode 100644
index 0000000000..c69120170b
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/rscsel/operators.go
@@ -0,0 +1,72 @@
+package rscsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+var (
+ _ selectors.ErrorProvider = (and)(nil)
+ _ selectors.ErrorProvider = (or)(nil)
+ _ selectors.ErrorProvider = (*not)(nil)
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+type and []Selector
+
+func (a and) MatchResource(list accessors.ElementListAccessor, e accessors.ResourceAccessor) bool {
+ for _, o := range a {
+ if !o.MatchResource(list, e) {
+ return false
+ }
+ }
+ return true
+}
+
+func (a and) GetError() error {
+ return selectors.ValidateSubSelectors("and", []Selector(a)...)
+}
+
+func And(operands ...Selector) Selector {
+ return and(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type or []Selector
+
+func (a or) MatchResource(list accessors.ElementListAccessor, e accessors.ResourceAccessor) bool {
+ for _, o := range a {
+ if o.MatchResource(list, e) {
+ return true
+ }
+ }
+ return false
+}
+
+func (a or) GetError() error {
+ return selectors.ValidateSubSelectors("or", []Selector(a)...)
+}
+
+func Or(operands ...Selector) Selector {
+ return or(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type not struct {
+ Selector
+}
+
+func (a *not) MatchResource(list accessors.ElementListAccessor, e accessors.ResourceAccessor) bool {
+ return !a.Selector.MatchResource(list, e)
+}
+
+func (a *not) GetError() error {
+ return selectors.ValidateSubSelectors("not", a.Selector)
+}
+
+func Not(operand Selector) Selector {
+ return ¬{operand}
+}
diff --git a/pkg/contexts/ocm/selectors/select.go b/pkg/contexts/ocm/selectors/select.go
new file mode 100644
index 0000000000..352530d1e8
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/select.go
@@ -0,0 +1,170 @@
+package selectors
+
+import (
+ "github.com/mandelsoft/goutils/errors"
+ "github.com/mandelsoft/goutils/generics"
+
+ metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+// ErrorProvider is an optional interface a Selector can offer
+// to propagate an error determined setting up the selector.
+// Such an error cannot be returned directly by the function
+// creating the selector, because this would prohibit to
+// compose selector sets as variadic arguments.
+type ErrorProvider interface {
+ GetError() error
+}
+
+type ErrorSelectorBase struct {
+ err error
+}
+
+func NewErrorSelectorBase(err error) ErrorSelectorBase {
+ return ErrorSelectorBase{err}
+}
+
+func (s *ErrorSelectorBase) GetError() error {
+ return s.err
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type ResourceSelector interface {
+ MatchResource(accessors.ElementListAccessor, accessors.ResourceAccessor) bool
+}
+
+type ResourceSelectorFunc func(accessors.ElementListAccessor, accessors.ResourceAccessor) bool
+
+func (f ResourceSelectorFunc) MatchResource(list accessors.ElementListAccessor, a accessors.ResourceAccessor) bool {
+ return f(list, a)
+}
+
+type ResourceErrorSelectorImpl struct {
+ ErrorSelectorBase
+ ResourceSelector
+}
+
+func NewResourceErrorSelectorImpl(s ResourceSelector, err error) *ResourceErrorSelectorImpl {
+ return &ResourceErrorSelectorImpl{NewErrorSelectorBase(err), s}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type SourceSelector interface {
+ MatchSource(accessors.ElementListAccessor, accessors.SourceAccessor) bool
+}
+
+type SourceSelectorFunc func(accessors.ElementListAccessor, accessors.SourceAccessor) bool
+
+func (f SourceSelectorFunc) MatchSource(list accessors.ElementListAccessor, a accessors.SourceAccessor) bool {
+ return f(list, a)
+}
+
+type SourceErrorSelectorImpl struct {
+ ErrorSelectorBase
+ SourceSelector
+}
+
+func NewSourceErrorSelectorImpl(s SourceSelector, err error) *SourceErrorSelectorImpl {
+ return &SourceErrorSelectorImpl{NewErrorSelectorBase(err), s}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type ReferenceSelector interface {
+ MatchReference(accessors.ElementListAccessor, accessors.ReferenceAccessor) bool
+}
+
+type ReferenceSelectorFunc func(accessors.ElementListAccessor, accessors.ReferenceAccessor) bool
+
+func (f ReferenceSelectorFunc) MatchReference(list accessors.ElementListAccessor, a accessors.ReferenceAccessor) bool {
+ return f(list, a)
+}
+
+type ReferenceErrorSelectorImpl struct {
+ ErrorSelectorBase
+ ReferenceSelector
+}
+
+func NewReferenceErrorSelectorImpl(s ReferenceSelector, err error) *ReferenceErrorSelectorImpl {
+ return &ReferenceErrorSelectorImpl{NewErrorSelectorBase(err), s}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type LabelSelector interface {
+ MatchLabel(label *metav1.Label) bool
+}
+
+type LabelSelectorFunc func(label *metav1.Label) bool
+
+func (f LabelSelectorFunc) MatchLabel(l *metav1.Label) bool {
+ return f(l)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+func ValidateSelectors[T any](sel ...T) error {
+ list := errors.ErrListf("error in selector list")
+ return validateSelectors(list, sel...)
+}
+
+func ValidateSubSelectors[T any](msg string, sel ...T) error {
+ list := errors.ErrList(msg)
+ return validateSelectors(list, sel...)
+}
+
+func validateSelectors[T any](list *errors.ErrorList, sel ...T) error {
+ for _, s := range sel {
+ if p, ok := generics.TryCast[ErrorProvider](s); ok {
+ list.Add(p.GetError())
+ }
+ }
+ return list.Result()
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+func _select[S, E any](list accessors.ElementListAccessor, m func(S, E) bool, sel ...S) []E {
+ var result []E
+ for i := 0; i < list.Len(); i++ {
+ e := list.Get(i).(E)
+ for _, s := range sel {
+ if !m(s, e) {
+ continue
+ }
+ }
+ result = append(result, e)
+ }
+ return result
+}
+
+// SelectResources select resources by a set of selectors.
+// It requires to be called with a compdesc.Resources list.
+func SelectResources(list accessors.ElementListAccessor, sel ...ResourceSelector) []accessors.ResourceAccessor {
+ return _select(list,
+ func(s ResourceSelector, e accessors.ResourceAccessor) bool {
+ return s.MatchResource(list, e)
+ },
+ sel...)
+}
+
+// SelectSources select sources by a set of selectors.
+// It requires to be called with a compdesc.Sources list.
+func SelectSources(list accessors.ElementListAccessor, sel ...SourceSelector) []accessors.SourceAccessor {
+ return _select(list,
+ func(s SourceSelector, e accessors.SourceAccessor) bool {
+ return s.MatchSource(list, e)
+ }, sel...)
+}
+
+// SelectReferences select resources by a set of selectors.
+// It requires to be called with a compdesc.References list.
+func SelectReferences(list accessors.ElementListAccessor, sel ...ReferenceSelector) []accessors.ReferenceAccessor {
+ return _select(list,
+ func(s ReferenceSelector, e accessors.ReferenceAccessor) bool {
+ return s.MatchReference(list, e)
+ }, sel...)
+}
diff --git a/pkg/contexts/ocm/selectors/srcsel/artifact.go b/pkg/contexts/ocm/selectors/srcsel/artifact.go
new file mode 100644
index 0000000000..ebb2d7023f
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/srcsel/artifact.go
@@ -0,0 +1,15 @@
+package srcsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+)
+
+// Artifact selectors
+
+func ArtifactType(n string) Selector {
+ return selectors.ArtifactType(n)
+}
+
+func AccessKind(n string) Selector {
+ return selectors.AccessKind(n)
+}
diff --git a/pkg/contexts/ocm/selectors/srcsel/element.go b/pkg/contexts/ocm/selectors/srcsel/element.go
new file mode 100644
index 0000000000..e0e26a7991
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/srcsel/element.go
@@ -0,0 +1,39 @@
+package srcsel
+
+import (
+ v1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/labelsel"
+)
+
+// Identity selectors
+
+func IdentityByKeyPairs(extras ...string) Selector {
+ return selectors.IdentityByKeyPairs(extras...)
+}
+
+func Identity(id v1.Identity) Selector {
+ return selectors.Identity(id)
+}
+
+func Name(n string) Selector {
+ return selectors.Name(n)
+}
+
+func Version(n string) Selector {
+ return selectors.Version(n)
+}
+
+func VersionConstraint(expr string) Selector {
+ return selectors.VersionConstraint(expr)
+}
+
+// Label selectors
+
+func Label(sel ...selectors.LabelSelector) Selector {
+ return selectors.Label(sel...)
+}
+
+func LabelName(n string) Selector {
+ return labelsel.Name(n)
+}
diff --git a/pkg/contexts/ocm/selectors/srcsel/interface.go b/pkg/contexts/ocm/selectors/srcsel/interface.go
new file mode 100644
index 0000000000..063d723834
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/srcsel/interface.go
@@ -0,0 +1,10 @@
+package srcsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+)
+
+type (
+ Selector = selectors.SourceSelector
+ SelectorFunc = selectors.SourceSelectorFunc
+)
diff --git a/pkg/contexts/ocm/selectors/srcsel/operators.go b/pkg/contexts/ocm/selectors/srcsel/operators.go
new file mode 100644
index 0000000000..5adc213909
--- /dev/null
+++ b/pkg/contexts/ocm/selectors/srcsel/operators.go
@@ -0,0 +1,72 @@
+package srcsel
+
+import (
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors"
+ "github.com/open-component-model/ocm/pkg/contexts/ocm/selectors/accessors"
+)
+
+var (
+ _ selectors.ErrorProvider = (and)(nil)
+ _ selectors.ErrorProvider = (or)(nil)
+ _ selectors.ErrorProvider = (*not)(nil)
+)
+
+////////////////////////////////////////////////////////////////////////////////
+
+type and []Selector
+
+func (a and) MatchSource(list accessors.ElementListAccessor, e accessors.SourceAccessor) bool {
+ for _, o := range a {
+ if !o.MatchSource(list, e) {
+ return false
+ }
+ }
+ return true
+}
+
+func (a and) GetError() error {
+ return selectors.ValidateSubSelectors("and", []Selector(a)...)
+}
+
+func And(operands ...Selector) Selector {
+ return and(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type or []Selector
+
+func (a or) MatchSource(list accessors.ElementListAccessor, e accessors.SourceAccessor) bool {
+ for _, o := range a {
+ if o.MatchSource(list, e) {
+ return true
+ }
+ }
+ return false
+}
+
+func (a or) GetError() error {
+ return selectors.ValidateSubSelectors("or", []Selector(a)...)
+}
+
+func Or(operands ...Selector) Selector {
+ return or(operands)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+type not struct {
+ Selector
+}
+
+func (a *not) MatchReference(list accessors.ElementListAccessor, e accessors.SourceAccessor) bool {
+ return !a.Selector.MatchSource(list, e)
+}
+
+func (a *not) GetError() error {
+ return selectors.ValidateSubSelectors("not", a.Selector)
+}
+
+func Not(operand Selector) Selector {
+ return ¬{operand}
+}