digest: Preserve tag and digest in With* functions

When WithDigest is called on a reference that has a tag, it should
preserve the tag.

When WithTag is called on a reference that has digest, it should
preserve the digest.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2016-11-08 14:47:33 -08:00
parent a2611c7520
commit bc1e7aa603
2 changed files with 43 additions and 0 deletions

View file

@ -218,6 +218,13 @@ func WithTag(name Named, tag string) (NamedTagged, error) {
if !anchoredTagRegexp.MatchString(tag) { if !anchoredTagRegexp.MatchString(tag) {
return nil, ErrTagInvalidFormat return nil, ErrTagInvalidFormat
} }
if canonical, ok := name.(Canonical); ok {
return reference{
name: name.Name(),
tag: tag,
digest: canonical.Digest(),
}, nil
}
return taggedReference{ return taggedReference{
name: name.Name(), name: name.Name(),
tag: tag, tag: tag,
@ -230,6 +237,13 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
if !anchoredDigestRegexp.MatchString(digest.String()) { if !anchoredDigestRegexp.MatchString(digest.String()) {
return nil, ErrDigestInvalidFormat return nil, ErrDigestInvalidFormat
} }
if tagged, ok := name.(Tagged); ok {
return reference{
name: name.Name(),
tag: tagged.Tag(),
digest: digest,
}, nil
}
return canonicalReference{ return canonicalReference{
name: name.Name(), name: name.Name(),
digest: digest, digest: digest,

View file

@ -467,6 +467,7 @@ func TestSerialization(t *testing.T) {
func TestWithTag(t *testing.T) { func TestWithTag(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
digest digest.Digest
tag string tag string
combined string combined string
}{ }{
@ -490,6 +491,12 @@ func TestWithTag(t *testing.T) {
tag: "TAG5", tag: "TAG5",
combined: "test.com:8000/foo:TAG5", combined: "test.com:8000/foo:TAG5",
}, },
{
name: "test.com:8000/foo",
digest: "sha256:1234567890098765432112345667890098765",
tag: "TAG5",
combined: "test.com:8000/foo:TAG5@sha256:1234567890098765432112345667890098765",
},
} }
for _, testcase := range testcases { for _, testcase := range testcases {
failf := func(format string, v ...interface{}) { failf := func(format string, v ...interface{}) {
@ -501,6 +508,14 @@ func TestWithTag(t *testing.T) {
if err != nil { if err != nil {
failf("error parsing name: %s", err) failf("error parsing name: %s", err)
} }
if testcase.digest != "" {
canonical, err := WithDigest(named, testcase.digest)
if err != nil {
failf("error adding digest")
}
named = canonical
}
tagged, err := WithTag(named, testcase.tag) tagged, err := WithTag(named, testcase.tag)
if err != nil { if err != nil {
failf("WithTag failed: %s", err) failf("WithTag failed: %s", err)
@ -515,6 +530,7 @@ func TestWithDigest(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
digest digest.Digest digest digest.Digest
tag string
combined string combined string
}{ }{
{ {
@ -532,6 +548,12 @@ func TestWithDigest(t *testing.T) {
digest: "sha256:1234567890098765432112345667890098765", digest: "sha256:1234567890098765432112345667890098765",
combined: "test.com:8000/foo@sha256:1234567890098765432112345667890098765", combined: "test.com:8000/foo@sha256:1234567890098765432112345667890098765",
}, },
{
name: "test.com:8000/foo",
digest: "sha256:1234567890098765432112345667890098765",
tag: "latest",
combined: "test.com:8000/foo:latest@sha256:1234567890098765432112345667890098765",
},
} }
for _, testcase := range testcases { for _, testcase := range testcases {
failf := func(format string, v ...interface{}) { failf := func(format string, v ...interface{}) {
@ -543,6 +565,13 @@ func TestWithDigest(t *testing.T) {
if err != nil { if err != nil {
failf("error parsing name: %s", err) failf("error parsing name: %s", err)
} }
if testcase.tag != "" {
tagged, err := WithTag(named, testcase.tag)
if err != nil {
failf("error adding tag")
}
named = tagged
}
digested, err := WithDigest(named, testcase.digest) digested, err := WithDigest(named, testcase.digest)
if err != nil { if err != nil {
failf("WithDigest failed: %s", err) failf("WithDigest failed: %s", err)