diff --git a/registry/tags.go b/registry/tags.go index 8f2493eb1..3844f060a 100644 --- a/registry/tags.go +++ b/registry/tags.go @@ -1,20 +1,46 @@ package registry -import "context" +import ( + "context" + "net/url" + + "github.com/peterhellberg/link" +) type tagsResponse struct { Tags []string `json:"tags"` } -// Tags returns the tags for a specific repository. -func (r *Registry) Tags(ctx context.Context, repository string) ([]string, error) { - url := r.url("/v2/%s/tags/list", repository) - r.Logf("registry.tags url=%s repository=%s", url, repository) +func (r *Registry) tags(ctx context.Context, u string, repository string) ([]string, error) { + var uri string + if u == "" { + r.Logf("registry.tags url=%s repository=%s", u, repository) + uri = r.url("/v2/%s/tags/list", repository) + } else { + uri = r.url(u) + } var response tagsResponse - if _, err := r.getJSON(ctx, url, &response); err != nil { + h, err := r.getJSON(ctx, uri, &response) + if err != nil { return nil, err } + for _, l := range link.ParseHeader(h) { + if l.Rel == "next" { + unescaped, _ := url.QueryUnescape(l.URI) + tags, err := r.tags(ctx, unescaped, repository) + if err != nil { + return nil, err + } + response.Tags = append(response.Tags, tags...) + } + } + return response.Tags, nil } + +// Tags returns the tags for a specific repository. +func (r *Registry) Tags(ctx context.Context, repository string) ([]string, error) { + return r.tags(ctx, "", repository) +}