x/model: Registry -> Host, Nick -> Model
This commit is contained in:
parent
a4fd06d603
commit
d510a90214
@ -14,18 +14,18 @@ type NamePart int
|
|||||||
// Levels of concreteness
|
// Levels of concreteness
|
||||||
const (
|
const (
|
||||||
Invalid NamePart = iota
|
Invalid NamePart = iota
|
||||||
Registry
|
Host
|
||||||
Namespace
|
Namespace
|
||||||
Nick
|
Model
|
||||||
Tag
|
Tag
|
||||||
Build
|
Build
|
||||||
)
|
)
|
||||||
|
|
||||||
var kindNames = map[NamePart]string{
|
var kindNames = map[NamePart]string{
|
||||||
Invalid: "Invalid",
|
Invalid: "Invalid",
|
||||||
Registry: "Domain",
|
Host: "Host",
|
||||||
Namespace: "Namespace",
|
Namespace: "Namespace",
|
||||||
Nick: "Name",
|
Model: "Name",
|
||||||
Tag: "Tag",
|
Tag: "Tag",
|
||||||
Build: "Build",
|
Build: "Build",
|
||||||
}
|
}
|
||||||
@ -36,9 +36,9 @@ var kindNames = map[NamePart]string{
|
|||||||
//
|
//
|
||||||
// Users or Name must check Valid before using it.
|
// Users or Name must check Valid before using it.
|
||||||
type Name struct {
|
type Name struct {
|
||||||
domain string
|
host string
|
||||||
namespace string
|
namespace string
|
||||||
nick string
|
model string
|
||||||
tag string
|
tag string
|
||||||
build string
|
build string
|
||||||
}
|
}
|
||||||
@ -47,23 +47,23 @@ type Name struct {
|
|||||||
// concreteness. If a part is missing, it is replaced with a loud
|
// concreteness. If a part is missing, it is replaced with a loud
|
||||||
// placeholder.
|
// placeholder.
|
||||||
func (r Name) Full() string {
|
func (r Name) Full() string {
|
||||||
r.domain = cmp.Or(r.domain, "!(MISSING DOMAIN)")
|
r.host = cmp.Or(r.host, "!(MISSING DOMAIN)")
|
||||||
r.namespace = cmp.Or(r.namespace, "!(MISSING NAMESPACE)")
|
r.namespace = cmp.Or(r.namespace, "!(MISSING NAMESPACE)")
|
||||||
r.nick = cmp.Or(r.nick, "!(MISSING NAME)")
|
r.model = cmp.Or(r.model, "!(MISSING NAME)")
|
||||||
r.tag = cmp.Or(r.tag, "!(MISSING TAG)")
|
r.tag = cmp.Or(r.tag, "!(MISSING TAG)")
|
||||||
r.build = cmp.Or(r.build, "!(MISSING BUILD)")
|
r.build = cmp.Or(r.build, "!(MISSING BUILD)")
|
||||||
return r.String()
|
return r.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Name) NickAndTag() string {
|
func (r Name) ModelAndTag() string {
|
||||||
r.domain = ""
|
r.host = ""
|
||||||
r.namespace = ""
|
r.namespace = ""
|
||||||
r.build = ""
|
r.build = ""
|
||||||
return r.String()
|
return r.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Name) NickTagAndBuild() string {
|
func (r Name) ModelTagAndBuild() string {
|
||||||
r.domain = ""
|
r.host = ""
|
||||||
r.namespace = ""
|
r.namespace = ""
|
||||||
return r.String()
|
return r.String()
|
||||||
}
|
}
|
||||||
@ -71,15 +71,15 @@ func (r Name) NickTagAndBuild() string {
|
|||||||
// String returns the fully qualified ref string.
|
// String returns the fully qualified ref string.
|
||||||
func (r Name) String() string {
|
func (r Name) String() string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
if r.domain != "" {
|
if r.host != "" {
|
||||||
b.WriteString(r.domain)
|
b.WriteString(r.host)
|
||||||
b.WriteString("/")
|
b.WriteString("/")
|
||||||
}
|
}
|
||||||
if r.namespace != "" {
|
if r.namespace != "" {
|
||||||
b.WriteString(r.namespace)
|
b.WriteString(r.namespace)
|
||||||
b.WriteString("/")
|
b.WriteString("/")
|
||||||
}
|
}
|
||||||
b.WriteString(r.nick)
|
b.WriteString(r.model)
|
||||||
if r.tag != "" {
|
if r.tag != "" {
|
||||||
b.WriteString(":")
|
b.WriteString(":")
|
||||||
b.WriteString(r.tag)
|
b.WriteString(r.tag)
|
||||||
@ -121,17 +121,17 @@ func (r Name) Less(o Name) bool {
|
|||||||
// The length of the returned slice is always 5.
|
// The length of the returned slice is always 5.
|
||||||
func (r Name) Parts() []string {
|
func (r Name) Parts() []string {
|
||||||
return []string{
|
return []string{
|
||||||
r.domain,
|
r.host,
|
||||||
r.namespace,
|
r.namespace,
|
||||||
r.nick,
|
r.model,
|
||||||
r.tag,
|
r.tag,
|
||||||
r.build,
|
r.build,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Name) Domain() string { return r.namespace }
|
func (r Name) Host() string { return r.host }
|
||||||
func (r Name) Namespace() string { return r.namespace }
|
func (r Name) Namespace() string { return r.namespace }
|
||||||
func (r Name) Nick() string { return r.nick }
|
func (r Name) Model() string { return r.model }
|
||||||
func (r Name) Tag() string { return r.tag }
|
func (r Name) Tag() string { return r.tag }
|
||||||
func (r Name) Build() string { return r.build }
|
func (r Name) Build() string { return r.build }
|
||||||
|
|
||||||
@ -155,12 +155,12 @@ func ParseName(s string) Name {
|
|||||||
var r Name
|
var r Name
|
||||||
for kind, part := range NameParts(s) {
|
for kind, part := range NameParts(s) {
|
||||||
switch kind {
|
switch kind {
|
||||||
case Registry:
|
case Host:
|
||||||
r.domain = part
|
r.host = part
|
||||||
case Namespace:
|
case Namespace:
|
||||||
r.namespace = part
|
r.namespace = part
|
||||||
case Nick:
|
case Model:
|
||||||
r.nick = part
|
r.model = part
|
||||||
case Tag:
|
case Tag:
|
||||||
r.tag = part
|
r.tag = part
|
||||||
case Build:
|
case Build:
|
||||||
@ -186,9 +186,9 @@ func ParseName(s string) Name {
|
|||||||
func Merge(dst, src Name) Name {
|
func Merge(dst, src Name) Name {
|
||||||
return Name{
|
return Name{
|
||||||
// name is left untouched
|
// name is left untouched
|
||||||
nick: dst.nick,
|
model: dst.model,
|
||||||
|
|
||||||
domain: cmp.Or(dst.domain, src.domain),
|
host: cmp.Or(dst.host, src.host),
|
||||||
namespace: cmp.Or(dst.namespace, src.namespace),
|
namespace: cmp.Or(dst.namespace, src.namespace),
|
||||||
tag: cmp.Or(dst.tag, src.tag),
|
tag: cmp.Or(dst.tag, src.tag),
|
||||||
build: cmp.Or(dst.build, src.build),
|
build: cmp.Or(dst.build, src.build),
|
||||||
@ -250,15 +250,15 @@ func NameParts(s string) iter.Seq2[NamePart, string] {
|
|||||||
if !yieldValid(Tag, s[i+1:j]) {
|
if !yieldValid(Tag, s[i+1:j]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state, j = Nick, i
|
state, j = Model, i
|
||||||
default:
|
default:
|
||||||
yield(Invalid, "")
|
yield(Invalid, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
switch state {
|
switch state {
|
||||||
case Nick, Tag, Build:
|
case Model, Tag, Build:
|
||||||
if !yieldValid(Nick, s[i+1:j]) {
|
if !yieldValid(Model, s[i+1:j]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state, j = Namespace, i
|
state, j = Namespace, i
|
||||||
@ -266,7 +266,7 @@ func NameParts(s string) iter.Seq2[NamePart, string] {
|
|||||||
if !yieldValid(Namespace, s[i+1:j]) {
|
if !yieldValid(Namespace, s[i+1:j]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state, j = Registry, i
|
state, j = Host, i
|
||||||
default:
|
default:
|
||||||
yield(Invalid, "")
|
yield(Invalid, "")
|
||||||
return
|
return
|
||||||
@ -282,7 +282,7 @@ func NameParts(s string) iter.Seq2[NamePart, string] {
|
|||||||
if state <= Namespace {
|
if state <= Namespace {
|
||||||
yieldValid(state, s[:j])
|
yieldValid(state, s[:j])
|
||||||
} else {
|
} else {
|
||||||
yieldValid(Nick, s[:j])
|
yieldValid(Model, s[:j])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +292,7 @@ func NameParts(s string) iter.Seq2[NamePart, string] {
|
|||||||
func (r Name) Valid() bool {
|
func (r Name) Valid() bool {
|
||||||
// Parts ensures we only have valid parts, so no need to validate
|
// Parts ensures we only have valid parts, so no need to validate
|
||||||
// them here, only check if we have a name or not.
|
// them here, only check if we have a name or not.
|
||||||
return r.nick != ""
|
return r.model != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValidPart returns true if given part is valid ascii [a-zA-Z0-9_\.-]
|
// isValidPart returns true if given part is valid ascii [a-zA-Z0-9_\.-]
|
||||||
|
@ -7,15 +7,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var testNames = map[string]Name{
|
var testNames = map[string]Name{
|
||||||
"mistral:latest": {nick: "mistral", tag: "latest"},
|
"mistral:latest": {model: "mistral", tag: "latest"},
|
||||||
"mistral": {nick: "mistral"},
|
"mistral": {model: "mistral"},
|
||||||
"mistral:30B": {nick: "mistral", tag: "30B"},
|
"mistral:30B": {model: "mistral", tag: "30B"},
|
||||||
"mistral:7b": {nick: "mistral", tag: "7b"},
|
"mistral:7b": {model: "mistral", tag: "7b"},
|
||||||
"mistral:7b+Q4_0": {nick: "mistral", tag: "7b", build: "Q4_0"},
|
"mistral:7b+Q4_0": {model: "mistral", tag: "7b", build: "Q4_0"},
|
||||||
"mistral+KQED": {nick: "mistral", build: "KQED"},
|
"mistral+KQED": {model: "mistral", build: "KQED"},
|
||||||
"mistral.x-3:7b+Q4_0": {nick: "mistral.x-3", tag: "7b", build: "Q4_0"},
|
"mistral.x-3:7b+Q4_0": {model: "mistral.x-3", tag: "7b", build: "Q4_0"},
|
||||||
"mistral:7b+q4_0": {nick: "mistral", tag: "7b", build: "Q4_0"},
|
"mistral:7b+q4_0": {model: "mistral", tag: "7b", build: "Q4_0"},
|
||||||
"llama2": {nick: "llama2"},
|
"llama2": {model: "llama2"},
|
||||||
|
|
||||||
// invalid (includes fuzzing trophies)
|
// invalid (includes fuzzing trophies)
|
||||||
"+": {},
|
"+": {},
|
||||||
@ -36,7 +36,7 @@ var testNames = map[string]Name{
|
|||||||
"file:///etc/passwd:latest": {},
|
"file:///etc/passwd:latest": {},
|
||||||
"file:///etc/passwd:latest+u": {},
|
"file:///etc/passwd:latest+u": {},
|
||||||
|
|
||||||
strings.Repeat("a", MaxNameLength): {nick: strings.Repeat("a", MaxNameLength)},
|
strings.Repeat("a", MaxNameLength): {model: strings.Repeat("a", MaxNameLength)},
|
||||||
strings.Repeat("a", MaxNameLength+1): {},
|
strings.Repeat("a", MaxNameLength+1): {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,10 +66,10 @@ func TestParseName(t *testing.T) {
|
|||||||
t.Errorf("String() = %s; want %s", got.String(), s)
|
t.Errorf("String() = %s; want %s", got.String(), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if got.Valid() && got.Nick() == "" {
|
if got.Valid() && got.Model() == "" {
|
||||||
t.Errorf("Valid() = true; Nick() = %q; want non-empty name", got.Nick())
|
t.Errorf("Valid() = true; Model() = %q; want non-empty name", got.Model())
|
||||||
} else if !got.Valid() && got.Nick() != "" {
|
} else if !got.Valid() && got.Model() != "" {
|
||||||
t.Errorf("Valid() = false; Nick() = %q; want empty name", got.Nick())
|
t.Errorf("Valid() = false; Model() = %q; want empty name", got.Model())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -118,11 +118,11 @@ func TestNameStringVariants(t *testing.T) {
|
|||||||
t.Run(tt.in, func(t *testing.T) {
|
t.Run(tt.in, func(t *testing.T) {
|
||||||
p := ParseName(tt.in)
|
p := ParseName(tt.in)
|
||||||
t.Logf("ParseName(%q) = %#v", tt.in, p)
|
t.Logf("ParseName(%q) = %#v", tt.in, p)
|
||||||
if g := p.NickAndTag(); g != tt.nameAndTag {
|
if g := p.ModelAndTag(); g != tt.nameAndTag {
|
||||||
t.Errorf("NickAndTag(%q) = %q; want %q", tt.in, g, tt.nameAndTag)
|
t.Errorf("ModelAndTag(%q) = %q; want %q", tt.in, g, tt.nameAndTag)
|
||||||
}
|
}
|
||||||
if g := p.NickTagAndBuild(); g != tt.nameTagAndBuild {
|
if g := p.ModelTagAndBuild(); g != tt.nameTagAndBuild {
|
||||||
t.Errorf("NickTagAndBuild(%q) = %q; want %q", tt.in, g, tt.nameTagAndBuild)
|
t.Errorf("ModelTagAndBuild(%q) = %q; want %q", tt.in, g, tt.nameTagAndBuild)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user