diff --git a/docs/api/v2/names.go b/docs/api/v2/names.go index 19cb72a0..14b7ea60 100644 --- a/docs/api/v2/names.go +++ b/docs/api/v2/names.go @@ -6,19 +6,10 @@ import ( "strings" ) -// TODO(stevvooe): Move these definitions back to an exported package. While -// they are used with v2 definitions, their relevance expands beyond. -// "distribution/names" is a candidate package. +// TODO(stevvooe): Move these definitions to the future "reference" package. +// While they are used with v2 definitions, their relevance expands beyond. const ( - // RepositoryNameComponentMinLength is the minimum number of characters in a - // single repository name slash-delimited component - RepositoryNameComponentMinLength = 2 - - // RepositoryNameMinComponents is the minimum number of slash-delimited - // components that a repository name must have - RepositoryNameMinComponents = 1 - // RepositoryNameTotalLengthMax is the maximum total number of characters in // a repository name RepositoryNameTotalLengthMax = 255 @@ -40,17 +31,13 @@ var RepositoryNameRegexp = regexp.MustCompile(`(?:` + RepositoryNameComponentReg // TagNameRegexp matches valid tag names. From docker/docker:graph/tags.go. var TagNameRegexp = regexp.MustCompile(`[\w][\w.-]{0,127}`) -// TODO(stevvooe): Contribute these exports back to core, so they are shared. +// TagNameAnchoredRegexp matches valid tag names, anchored at the start and +// end of the matched string. +var TagNameAnchoredRegexp = regexp.MustCompile("^" + TagNameRegexp.String() + "$") var ( - // ErrRepositoryNameComponentShort is returned when a repository name - // contains a component which is shorter than - // RepositoryNameComponentMinLength - ErrRepositoryNameComponentShort = fmt.Errorf("repository name component must be %v or more characters", RepositoryNameComponentMinLength) - - // ErrRepositoryNameMissingComponents is returned when a repository name - // contains fewer than RepositoryNameMinComponents components - ErrRepositoryNameMissingComponents = fmt.Errorf("repository name must have at least %v components", RepositoryNameMinComponents) + // ErrRepositoryNameEmpty is returned for empty, invalid repository names. + ErrRepositoryNameEmpty = fmt.Errorf("repository name must have at least one component") // ErrRepositoryNameLong is returned when a repository name is longer than // RepositoryNameTotalLengthMax @@ -76,21 +63,17 @@ var ( // The result of the production, known as the "namespace", should be limited // to 255 characters. func ValidateRepositoryName(name string) error { + if name == "" { + return ErrRepositoryNameEmpty + } + if len(name) > RepositoryNameTotalLengthMax { return ErrRepositoryNameLong } components := strings.Split(name, "/") - if len(components) < RepositoryNameMinComponents { - return ErrRepositoryNameMissingComponents - } - for _, component := range components { - if len(component) < RepositoryNameComponentMinLength { - return ErrRepositoryNameComponentShort - } - if !RepositoryNameComponentAnchoredRegexp.MatchString(component) { return ErrRepositoryNameComponentInvalid } diff --git a/docs/api/v2/names_test.go b/docs/api/v2/names_test.go index 0975fb7c..51e0ba8b 100644 --- a/docs/api/v2/names_test.go +++ b/docs/api/v2/names_test.go @@ -1,6 +1,7 @@ package v2 import ( + "strconv" "strings" "testing" ) @@ -10,6 +11,10 @@ func TestRepositoryNameRegexp(t *testing.T) { input string err error }{ + { + input: "", + err: ErrRepositoryNameEmpty, + }, { input: "short", }, @@ -30,11 +35,26 @@ func TestRepositoryNameRegexp(t *testing.T) { }, { input: "a/a/a/b/b", - err: ErrRepositoryNameComponentShort, }, { input: "a/a/a/a/", - err: ErrRepositoryNameComponentShort, + err: ErrRepositoryNameComponentInvalid, + }, + { + input: "a//a/a", + err: ErrRepositoryNameComponentInvalid, + }, + { + input: "a", + }, + { + input: "a/aa", + }, + { + input: "aa/a", + }, + { + input: "a/aa/a", }, { input: "foo.com/bar/baz", @@ -58,10 +78,6 @@ func TestRepositoryNameRegexp(t *testing.T) { { input: "a-a/a-a", }, - { - input: "a", - err: ErrRepositoryNameComponentShort, - }, { input: "a-/a/a/a", err: ErrRepositoryNameComponentInvalid, @@ -110,9 +126,8 @@ func TestRepositoryNameRegexp(t *testing.T) { err: ErrRepositoryNameComponentInvalid, }, } { - failf := func(format string, v ...interface{}) { - t.Logf(testcase.input+": "+format, v...) + t.Logf(strconv.Quote(testcase.input)+": "+format, v...) t.Fail() } diff --git a/docs/api/v2/routes_test.go b/docs/api/v2/routes_test.go index fb268336..9fd29a4f 100644 --- a/docs/api/v2/routes_test.go +++ b/docs/api/v2/routes_test.go @@ -263,6 +263,7 @@ func checkTestRouter(t *testing.T, testCases []routeTestCase, prefix string, dee } if testcase.StatusCode != http.StatusOK { + resp.Body.Close() // We don't care about json response. continue } @@ -291,6 +292,8 @@ func checkTestRouter(t *testing.T, testCases []routeTestCase, prefix string, dee if deeplyEqual && !reflect.DeepEqual(actualRouteInfo, testcase) { t.Fatalf("actual does not equal expected: %#v != %#v", actualRouteInfo, testcase) } + + resp.Body.Close() } }