Usability improvements for reference package
Various improvements motivated by early real-world use in engine code under development: - Make `WithDigest` return `Canonical`, since the return value always has a name and a digest. - Introduce a `NamedTagged` type, which can be used for strongly typing cases where something must have a name and a tag. - Rename `ParseNamed` to `WithName`, and create a `ParseNamed` that accepts tags and digests (returning a `Named` type). The new `ParseNamed` makes code using the reference package much less verbose, since typical use cases require a name, and this is an additional type assertion and error case after every `Parse` call. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
4c4112bdcf
commit
16eea0cc47
2 changed files with 31 additions and 9 deletions
|
@ -114,6 +114,12 @@ type Tagged interface {
|
|||
Tag() string
|
||||
}
|
||||
|
||||
// NamedTagged is an object including a name and tag.
|
||||
type NamedTagged interface {
|
||||
Named
|
||||
Tag() string
|
||||
}
|
||||
|
||||
// Digested is an object which has a digest
|
||||
// in which it can be referenced by
|
||||
type Digested interface {
|
||||
|
@ -178,10 +184,26 @@ func Parse(s string) (Reference, error) {
|
|||
return r, nil
|
||||
}
|
||||
|
||||
// ParseNamed parses the input string and returns a named
|
||||
// object representing the given string. If the input is
|
||||
// invalid ErrReferenceInvalidFormat will be returned.
|
||||
func ParseNamed(name string) (Named, error) {
|
||||
// ParseNamed parses s and returns a syntactically valid reference implementing
|
||||
// the Named interface. The reference must have a name, otherwise an error is
|
||||
// returned.
|
||||
// If an error was encountered it is returned, along with a nil Reference.
|
||||
// NOTE: ParseNamed will not handle short digests.
|
||||
func ParseNamed(s string) (Named, error) {
|
||||
ref, err := Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
named, isNamed := ref.(Named)
|
||||
if !isNamed {
|
||||
return nil, fmt.Errorf("reference %s has no name", ref.String())
|
||||
}
|
||||
return named, nil
|
||||
}
|
||||
|
||||
// WithName returns a named object representing the given string. If the input
|
||||
// is invalid ErrReferenceInvalidFormat will be returned.
|
||||
func WithName(name string) (Named, error) {
|
||||
if !anchoredNameRegexp.MatchString(name) {
|
||||
return nil, ErrReferenceInvalidFormat
|
||||
}
|
||||
|
@ -190,7 +212,7 @@ func ParseNamed(name string) (Named, error) {
|
|||
|
||||
// WithTag combines the name from "name" and the tag from "tag" to form a
|
||||
// reference incorporating both the name and the tag.
|
||||
func WithTag(name Named, tag string) (Tagged, error) {
|
||||
func WithTag(name Named, tag string) (NamedTagged, error) {
|
||||
if !anchoredNameRegexp.MatchString(tag) {
|
||||
return nil, ErrTagInvalidFormat
|
||||
}
|
||||
|
@ -202,7 +224,7 @@ func WithTag(name Named, tag string) (Tagged, error) {
|
|||
|
||||
// WithDigest combines the name from "name" and the digest from "digest" to form
|
||||
// a reference incorporating both the name and the digest.
|
||||
func WithDigest(name Named, digest digest.Digest) (Digested, error) {
|
||||
func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
|
||||
if !anchoredDigestRegexp.MatchString(digest.String()) {
|
||||
return nil, ErrDigestInvalidFormat
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ func TestSplitHostname(t *testing.T) {
|
|||
t.Fail()
|
||||
}
|
||||
|
||||
named, err := ParseNamed(testcase.input)
|
||||
named, err := WithName(testcase.input)
|
||||
if err != nil {
|
||||
failf("error parsing name: %s", err)
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ func TestWithTag(t *testing.T) {
|
|||
t.Fail()
|
||||
}
|
||||
|
||||
named, err := ParseNamed(testcase.name)
|
||||
named, err := WithName(testcase.name)
|
||||
if err != nil {
|
||||
failf("error parsing name: %s", err)
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ func TestWithDigest(t *testing.T) {
|
|||
t.Fail()
|
||||
}
|
||||
|
||||
named, err := ParseNamed(testcase.name)
|
||||
named, err := WithName(testcase.name)
|
||||
if err != nil {
|
||||
failf("error parsing name: %s", err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue