From 353e3a4c9d4e25ce974782726092907f50fd6d44 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 9 Nov 2016 22:04:52 +0100 Subject: [PATCH] Add a new Match method to the reference package The Match method allows to see if a reference matches a specified patterns. Signed-off-by: Vincent Demeester --- reference/reference.go | 11 ++++++ reference/reference_test.go | 78 +++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/reference/reference.go b/reference/reference.go index dc3af1670..a6540b51f 100644 --- a/reference/reference.go +++ b/reference/reference.go @@ -24,6 +24,7 @@ package reference import ( "errors" "fmt" + "path" "strings" "github.com/docker/distribution/digest" @@ -236,6 +237,16 @@ func WithDigest(name Named, digest digest.Digest) (Canonical, error) { }, nil } +// Match reports whether ref matches the specified pattern. +// See https://godoc.org/path#Match for supported patterns. +func Match(pattern string, ref Reference) (bool, error) { + matched, err := path.Match(pattern, ref.String()) + if namedRef, isNamed := ref.(Named); isNamed && !matched { + matched, _ = path.Match(pattern, namedRef.Name()) + } + return matched, err +} + func getBestReferenceType(ref reference) Reference { if ref.name == "" { // Allow digest only references diff --git a/reference/reference_test.go b/reference/reference_test.go index f60cf093e..001054c0c 100644 --- a/reference/reference_test.go +++ b/reference/reference_test.go @@ -552,3 +552,81 @@ func TestWithDigest(t *testing.T) { } } } + +func TestMatchError(t *testing.T) { + named, err := Parse("foo") + if err != nil { + t.Fatal(err) + } + _, err = Match("[-x]", named) + if err == nil { + t.Fatalf("expected an error, got nothing") + } +} + +func TestMatch(t *testing.T) { + matchCases := []struct { + reference string + pattern string + expected bool + }{ + { + reference: "foo", + pattern: "foo/**/ba[rz]", + expected: false, + }, + { + reference: "foo/any/bat", + pattern: "foo/**/ba[rz]", + expected: false, + }, + { + reference: "foo/a/bar", + pattern: "foo/**/ba[rz]", + expected: true, + }, + { + reference: "foo/b/baz", + pattern: "foo/**/ba[rz]", + expected: true, + }, + { + reference: "foo/c/baz:tag", + pattern: "foo/**/ba[rz]", + expected: true, + }, + { + reference: "foo/c/baz:tag", + pattern: "foo/*/baz:tag", + expected: true, + }, + { + reference: "foo/c/baz:tag", + pattern: "foo/c/baz:tag", + expected: true, + }, + { + reference: "example.com/foo/c/baz:tag", + pattern: "*/foo/c/baz", + expected: true, + }, + { + reference: "example.com/foo/c/baz:tag", + pattern: "example.com/foo/c/baz", + expected: true, + }, + } + for _, c := range matchCases { + named, err := Parse(c.reference) + if err != nil { + t.Fatal(err) + } + actual, err := Match(c.pattern, named) + if err != nil { + t.Fatal(err) + } + if actual != c.expected { + t.Fatalf("expected %s match %s to be %v, was %v", c.reference, c.pattern, c.expected, actual) + } + } +}