diff --git a/types/model/name.go b/types/model/name.go index 1a820c4f..7f037b61 100644 --- a/types/model/name.go +++ b/types/model/name.go @@ -185,8 +185,8 @@ func parseMask(s string) Name { return r } -func MustParseName(s, defaults string) Name { - r := ParseName(s, "") +func MustParseName(s, fill string) Name { + r := ParseName(s, fill) if !r.IsValid() { panic("invalid Name: " + s) } @@ -643,6 +643,15 @@ func (r Name) Filepath() string { return filepath.Join(r.parts[:]...) } +// FilepathNoBuild returns a complete, canonicalized, relative file path using +// the parts of a complete Name, but without the build part. +func (r Name) FilepathNoBuild() string { + for i := range PartBuild { + r.parts[i] = strings.ToLower(r.parts[i]) + } + return filepath.Join(r.parts[:PartBuild]...) +} + // isValidPart reports if s contains all valid characters for the given // part kind. func isValidPart(kind PartKind, s string) bool { diff --git a/types/model/name_test.go b/types/model/name_test.go index 166e0a57..b45dadaf 100644 --- a/types/model/name_test.go +++ b/types/model/name_test.go @@ -318,6 +318,13 @@ func TestNameGoString(t *testing.T) { } } +func TestDisplayLongest(t *testing.T) { + g := ParseName("example.com/library/mistral:latest+Q4_0", FillNothing).DisplayLongest() + if g != "example.com/library/mistral:latest" { + t.Errorf("got = %q; want %q", g, "example.com/library/mistral:latest") + } +} + func TestDisplayShortest(t *testing.T) { cases := []struct { in string @@ -478,30 +485,36 @@ func TestNamePath(t *testing.T) { } } -func TestNameFromFilepath(t *testing.T) { +func TestNameFilepath(t *testing.T) { cases := []struct { - in string - want string + in string + want string + wantNoBuild string }{ { - in: "example.com/library/mistral:latest+Q4_0", - want: "example.com/library/mistral/latest/Q4_0", + in: "example.com/library/mistral:latest+Q4_0", + want: "example.com/library/mistral/latest/Q4_0", + wantNoBuild: "example.com/library/mistral/latest", }, { - in: "Example.Com/Library/Mistral:Latest+Q4_0", - want: "example.com/library/mistral/latest/Q4_0", + in: "Example.Com/Library/Mistral:Latest+Q4_0", + want: "example.com/library/mistral/latest/Q4_0", + wantNoBuild: "example.com/library/mistral/latest", }, { - in: "Example.Com/Library/Mistral:Latest+Q4_0", - want: "example.com/library/mistral/latest/Q4_0", + in: "Example.Com/Library/Mistral:Latest+Q4_0", + want: "example.com/library/mistral/latest/Q4_0", + wantNoBuild: "example.com/library/mistral/latest", }, { - in: "example.com/library/mistral:latest", - want: "example.com/library/mistral/latest", + in: "example.com/library/mistral:latest", + want: "example.com/library/mistral/latest", + wantNoBuild: "example.com/library/mistral/latest", }, { - in: "", - want: "", + in: "", + want: "", + wantNoBuild: "", }, } for _, tt := range cases { @@ -513,6 +526,11 @@ func TestNameFromFilepath(t *testing.T) { if g != tt.want { t.Errorf("got = %q; want %q", g, tt.want) } + g = p.FilepathNoBuild() + g = filepath.ToSlash(g) + if g != tt.wantNoBuild { + t.Errorf("got = %q; want %q", g, tt.wantNoBuild) + } }) } }