mirror of
https://github.com/ollama/ollama.git
synced 2025-05-11 18:36:41 +02:00
Merge pull request #3715 from ollama/mxyng/modelname-2
update list handler to use model.Name
This commit is contained in:
commit
ffbd3d173f
6 changed files with 216 additions and 88 deletions
|
@ -35,6 +35,12 @@ func Unqualified(n Name) error {
|
|||
// spot in logs.
|
||||
const MissingPart = "!MISSING!"
|
||||
|
||||
const (
|
||||
defaultHost = "registry.ollama.ai"
|
||||
defaultNamespace = "library"
|
||||
defaultTag = "latest"
|
||||
)
|
||||
|
||||
// DefaultName returns a name with the default values for the host, namespace,
|
||||
// and tag parts. The model and digest parts are empty.
|
||||
//
|
||||
|
@ -43,9 +49,9 @@ const MissingPart = "!MISSING!"
|
|||
// - The default tag is ("latest")
|
||||
func DefaultName() Name {
|
||||
return Name{
|
||||
Host: "registry.ollama.ai",
|
||||
Namespace: "library",
|
||||
Tag: "latest",
|
||||
Host: defaultHost,
|
||||
Namespace: defaultNamespace,
|
||||
Tag: defaultTag,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +175,27 @@ func ParseNameBare(s string) Name {
|
|||
return n
|
||||
}
|
||||
|
||||
// ParseNameFromFilepath parses a 4-part filepath as a Name. The parts are
|
||||
// expected to be in the form:
|
||||
//
|
||||
// { host } "/" { namespace } "/" { model } "/" { tag }
|
||||
func ParseNameFromFilepath(s string) (n Name) {
|
||||
parts := strings.Split(s, string(filepath.Separator))
|
||||
if len(parts) != 4 {
|
||||
return Name{}
|
||||
}
|
||||
|
||||
n.Host = parts[0]
|
||||
n.Namespace = parts[1]
|
||||
n.Model = parts[2]
|
||||
n.Tag = parts[3]
|
||||
if !n.IsFullyQualified() {
|
||||
return Name{}
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// Merge merges the host, namespace, and tag parts of the two names,
|
||||
// preferring the non-empty parts of a.
|
||||
func Merge(a, b Name) Name {
|
||||
|
@ -203,6 +230,27 @@ func (n Name) String() string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
// DisplayShort returns a short string version of the name.
|
||||
func (n Name) DisplayShortest() string {
|
||||
var sb strings.Builder
|
||||
|
||||
if n.Host != defaultHost {
|
||||
sb.WriteString(n.Host)
|
||||
sb.WriteByte('/')
|
||||
sb.WriteString(n.Namespace)
|
||||
sb.WriteByte('/')
|
||||
} else if n.Namespace != defaultNamespace {
|
||||
sb.WriteString(n.Namespace)
|
||||
sb.WriteByte('/')
|
||||
}
|
||||
|
||||
// always include model and tag
|
||||
sb.WriteString(n.Model)
|
||||
sb.WriteString(":")
|
||||
sb.WriteString(n.Tag)
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// IsValid reports whether all parts of the name are present and valid. The
|
||||
// digest is a special case, and is checked for validity only if present.
|
||||
func (n Name) IsValid() bool {
|
||||
|
|
|
@ -309,6 +309,49 @@ func TestParseDigest(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestParseNameFromFilepath(t *testing.T) {
|
||||
cases := map[string]Name{
|
||||
filepath.Join("host", "namespace", "model", "tag"): {Host: "host", Namespace: "namespace", Model: "model", Tag: "tag"},
|
||||
filepath.Join("host:port", "namespace", "model", "tag"): {Host: "host:port", Namespace: "namespace", Model: "model", Tag: "tag"},
|
||||
filepath.Join("namespace", "model", "tag"): {},
|
||||
filepath.Join("model", "tag"): {},
|
||||
filepath.Join("model"): {},
|
||||
filepath.Join("..", "..", "model", "tag"): {},
|
||||
filepath.Join("", "namespace", ".", "tag"): {},
|
||||
filepath.Join(".", ".", ".", "."): {},
|
||||
filepath.Join("/", "path", "to", "random", "file"): {},
|
||||
}
|
||||
|
||||
for in, want := range cases {
|
||||
t.Run(in, func(t *testing.T) {
|
||||
got := ParseNameFromFilepath(in)
|
||||
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("parseNameFromFilepath(%q) = %v; want %v", in, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisplayShortest(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"registry.ollama.ai/library/model:latest": "model:latest",
|
||||
"registry.ollama.ai/library/model:tag": "model:tag",
|
||||
"registry.ollama.ai/namespace/model:tag": "namespace/model:tag",
|
||||
"host/namespace/model:tag": "host/namespace/model:tag",
|
||||
"host/library/model:tag": "host/library/model:tag",
|
||||
}
|
||||
|
||||
for in, want := range cases {
|
||||
t.Run(in, func(t *testing.T) {
|
||||
got := ParseNameBare(in).DisplayShortest()
|
||||
if got != want {
|
||||
t.Errorf("parseName(%q).DisplayShortest() = %q; want %q", in, got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzName(f *testing.F) {
|
||||
for s := range testCases {
|
||||
f.Add(s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue