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>master
							parent
							
								
									4c4112bdcf
								
							
						
					
					
						commit
						16eea0cc47
					
				|  | @ -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 New Issue