func NameSelector(name string) Selector {
	return nameSelector{
		sourced: sourced{name},
		name:    name,
	}
}
NameSelector returns a selector that matches all package versions of the given name
package manifest
import (
	"github.com/gobwas/glob"
	"github.com/pkg/errors"
	"strings"
	"unicode"
)
type Selector interface {
	Name() string
	String() string
	Matches(ref Reference) bool
	IsFullyQualified() bool
}
type sourced struct {
	source string
}
func (m sourced) String() string {
	return m.source
}
type qualified struct{}
func (m qualified) IsFullyQualified() bool {
	return true
}
type globSelector struct {
	sourced
	name    string
	channel string
	version glob.Glob
}
func (m globSelector) IsFullyQualified() bool {
	return m.name != "" && (m.version != nil || m.channel != "")
}
func (m globSelector) Matches(ref Reference) bool {
	if ref.Name != m.name {
		return false
	}
	if m.channel != "" && ref.Channel != m.channel {
		return false
	}
	if m.version != nil && !m.version.Match(ref.Version.String()) {
		return false
	}
	return true
}
func (m globSelector) Name() string {
	return m.name
}
func GlobSelector(from string) (Selector, error) {
	name, v, c := splitNameAndQualifier(from)
	var g glob.Glob
	if v != "" {
		compiled, err := glob.Compile(v)
		if err != nil {
			return globSelector{}, errors.WithStack(err)
		}
		g = compiled
	}
	return globSelector{sourced{from}, name, c, g}, nil
}
func splitNameAndQualifier(from string) (name string, version string, channel string) {
	for cursor := 0; cursor < len(from); cursor++ {
		rn := rune(from[cursor])
		if cursor > 0 && rune(from[cursor-1]) == '-' && (unicode.IsDigit(rn) || strings.ContainsRune("*[]{}", rn)) {
			return from[:cursor-1], from[cursor:], ""
		}
		if rn == '@' {
			return from[:cursor], "", from[cursor+1:]
		}
	}
	return from, "", ""
}
type nameSelector struct {
	sourced
	name string
}
func (m nameSelector) IsFullyQualified() bool {
	return false
}
func (m nameSelector) Matches(ref Reference) bool {
	return ref.Name == m.name
}
func (m nameSelector) Name() string {
	return m.name
}