diff --git a/go/src/bashbrew/cmd-build.go b/go/src/bashbrew/cmd-build.go index 9ef638a..aa8381c 100644 --- a/go/src/bashbrew/cmd-build.go +++ b/go/src/bashbrew/cmd-build.go @@ -44,7 +44,7 @@ func cmdBuild(c *cli.Context) error { continue } - from, err := r.DockerFrom(&entry) + from, err := r.DockerFrom(entry) if err != nil { return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err) } @@ -69,7 +69,7 @@ func cmdBuild(c *cli.Context) error { } } - cacheTag, err := r.DockerCacheName(&entry) + cacheTag, err := r.DockerCacheName(entry) if err != nil { return cli.NewMultiError(fmt.Errorf(`failed calculating "cache hash" for %q (tags %q)`, r.RepoName, entry.TagsString()), err) } @@ -79,7 +79,7 @@ func cmdBuild(c *cli.Context) error { if err != nil { fmt.Printf("Building %s (%s)\n", cacheTag, r.EntryIdentifier(entry)) if !dryRun { - commit, err := r.fetchGitRepo(arch, &entry) + commit, err := r.fetchGitRepo(arch, entry) if err != nil { return cli.NewMultiError(fmt.Errorf(`failed fetching git repo for %q (tags %q)`, r.RepoName, entry.TagsString()), err) } diff --git a/go/src/bashbrew/cmd-cat.go b/go/src/bashbrew/cmd-cat.go index cfd8055..3c67bfc 100644 --- a/go/src/bashbrew/cmd-cat.go +++ b/go/src/bashbrew/cmd-cat.go @@ -13,8 +13,17 @@ import ( ) var DefaultCatFormat = ` -{{- if i }}{{ "\n\n" }}{{ end -}} -{{- .TagName | ternary (.Manifest.GetTag .TagName) .Manifest -}} +{{- if i -}} + {{- "\n\n" -}} +{{- end -}} +{{- with .TagEntries -}} + {{- range $i, $e := . -}} + {{- if $i -}}{{- "\n\n" -}}{{- end -}} + {{- $e -}} + {{- end -}} +{{- else -}} + {{- .Manifest -}} +{{- end -}} ` func cmdCat(c *cli.Context) error { diff --git a/go/src/bashbrew/cmd-deps.go b/go/src/bashbrew/cmd-deps.go index e6df93a..5456c67 100644 --- a/go/src/bashbrew/cmd-deps.go +++ b/go/src/bashbrew/cmd-deps.go @@ -67,7 +67,7 @@ func cmdFamily(parents bool, c *cli.Context) error { continue } - from, err := r.DockerFrom(&entry) + from, err := r.DockerFrom(entry) if err != nil { return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err) } diff --git a/go/src/bashbrew/cmd-from.go b/go/src/bashbrew/cmd-from.go index 39f66ad..063d83c 100644 --- a/go/src/bashbrew/cmd-from.go +++ b/go/src/bashbrew/cmd-from.go @@ -27,7 +27,7 @@ func cmdFrom(c *cli.Context) error { continue } - from, err := r.DockerFrom(&entry) + from, err := r.DockerFrom(entry) if err != nil { return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q)`, r.RepoName, entry.TagsString()), err) } diff --git a/go/src/bashbrew/cmd-list.go b/go/src/bashbrew/cmd-list.go index 57c7116..13cf2fd 100644 --- a/go/src/bashbrew/cmd-list.go +++ b/go/src/bashbrew/cmd-list.go @@ -36,14 +36,14 @@ func cmdList(c *cli.Context) error { if r.TagEntry == nil { fmt.Printf("%s\n", r.RepoName) } else { - for _, tag := range r.Tags(namespace, uniq, *r.TagEntry) { + for _, tag := range r.Tags(namespace, uniq, r.TagEntry) { fmt.Printf("%s\n", tag) } } continue } - var entries []manifest.Manifest2822Entry + var entries []*manifest.Manifest2822Entry if buildOrder { entries, err = r.SortedEntries(applyConstraints) if err != nil { diff --git a/go/src/bashbrew/cmd-put-shared.go b/go/src/bashbrew/cmd-put-shared.go index c34013e..57aa6c2 100644 --- a/go/src/bashbrew/cmd-put-shared.go +++ b/go/src/bashbrew/cmd-put-shared.go @@ -19,7 +19,7 @@ func entriesToManifestToolYaml(singleArch bool, r Repo, entries ...*manifest.Man expectedNumber := 0 entryIdentifiers := []string{} for _, entry := range entries { - entryIdentifiers = append(entryIdentifiers, r.EntryIdentifier(*entry)) + entryIdentifiers = append(entryIdentifiers, r.EntryIdentifier(entry)) for _, entryArch := range entry.Architectures { if singleArch && entryArch != arch { @@ -36,7 +36,7 @@ func entriesToManifestToolYaml(singleArch bool, r Repo, entries ...*manifest.Man var archNamespace string if archNamespace, ok = archNamespaces[entryArch]; !ok || archNamespace == "" { - fmt.Fprintf(os.Stderr, "warning: no arch-namespace specified for %q; skipping (%q)\n", entryArch, r.EntryIdentifier(*entry)) + fmt.Fprintf(os.Stderr, "warning: no arch-namespace specified for %q; skipping (%q)\n", entryArch, r.EntryIdentifier(entry)) continue } @@ -106,7 +106,7 @@ func cmdPutShared(c *cli.Context) error { // handle all multi-architecture tags first (regardless of whether they have SharedTags) // turn them into SharedTagGroup objects so all manifest-tool invocations can be handled by a single process/loop for _, entry := range r.Entries() { - entryCopy := entry + entryCopy := *entry sharedTagGroups = append(sharedTagGroups, manifest.SharedTagGroup{ SharedTags: entry.Tags, Entries: []*manifest.Manifest2822Entry{&entryCopy}, diff --git a/go/src/bashbrew/repo.go b/go/src/bashbrew/repo.go index 12bc90c..ffd74c5 100644 --- a/go/src/bashbrew/repo.go +++ b/go/src/bashbrew/repo.go @@ -51,16 +51,19 @@ type Repo struct { TagName string Manifest *manifest.Manifest2822 TagEntry *manifest.Manifest2822Entry + + // if "TagName" refers to a SharedTag, "TagEntry" will be the first match, this will contain all matches (otherwise it will be just "TagEntry") + TagEntries []*manifest.Manifest2822Entry } func (r Repo) Identifier() string { if r.TagEntry != nil { - return r.EntryIdentifier(*r.TagEntry) + return r.EntryIdentifier(r.TagEntry) } return r.RepoName } -func (r Repo) EntryIdentifier(entry manifest.Manifest2822Entry) string { +func (r Repo) EntryIdentifier(entry *manifest.Manifest2822Entry) string { return r.RepoName + ":" + entry.Tags[0] } @@ -76,7 +79,7 @@ func (r Repo) EntryRepo(entry *manifest.Manifest2822Entry) *Repo { var haveOutputSkippedMessage = map[string]bool{} -func (r Repo) SkipConstraints(entry manifest.Manifest2822Entry) bool { +func (r Repo) SkipConstraints(entry *manifest.Manifest2822Entry) bool { repoTag := r.RepoName + ":" + entry.Tags[0] // TODO decide if "arch" and "constraints" should be handled separately (but probably not) @@ -135,16 +138,19 @@ NextConstraint: return false } -func (r Repo) Entries() []manifest.Manifest2822Entry { +func (r Repo) Entries() []*manifest.Manifest2822Entry { if r.TagName == "" { - return r.Manifest.Entries + ret := []*manifest.Manifest2822Entry{} + for i := range r.Manifest.Entries { + ret = append(ret, &r.Manifest.Entries[i]) + } + return ret } else { - // TODO what if r.TagName isn't a single entry, but is a SharedTag ? - return []manifest.Manifest2822Entry{*r.Manifest.GetTag(r.TagName)} + return r.TagEntries } } -func (r Repo) Tags(namespace string, uniq bool, entry manifest.Manifest2822Entry) []string { +func (r Repo) Tags(namespace string, uniq bool, entry *manifest.Manifest2822Entry) []string { tagRepo := path.Join(namespace, r.RepoName) ret := []string{} tags := append([]string{}, entry.Tags...) @@ -177,6 +183,14 @@ func fetch(repo string) (*Repo, error) { } if tagName != "" { r.TagEntry = man.GetTag(tagName) + if r.TagEntry == nil { + // must be a SharedTag + r.TagEntries = man.GetSharedTag(tagName) + r.TagEntry = r.TagEntries[0] + } else { + // not a SharedTag, backfill TagEntries + r.TagEntries = []*manifest.Manifest2822Entry{r.TagEntry} + } } repoCache[repo] = r return r, nil diff --git a/go/src/bashbrew/sort.go b/go/src/bashbrew/sort.go index 461374d..83cc0b6 100644 --- a/go/src/bashbrew/sort.go +++ b/go/src/bashbrew/sort.go @@ -38,7 +38,7 @@ func sortRepos(repos []string, applyConstraints bool) ([]string, error) { return ret, nil } -func (r Repo) SortedEntries(applyConstraints bool) ([]manifest.Manifest2822Entry, error) { +func (r Repo) SortedEntries(applyConstraints bool) ([]*manifest.Manifest2822Entry, error) { entries := r.Entries() // short circuit if we don't have to go further @@ -49,7 +49,7 @@ func (r Repo) SortedEntries(applyConstraints bool) ([]manifest.Manifest2822Entry // create individual "Repo" objects for each entry in "r" so they can be sorted by the same "sortRepoObjects" function rs := []*Repo{} for i := range entries { - rs = append(rs, r.EntryRepo(&entries[i])) + rs = append(rs, r.EntryRepo(entries[i])) } rs, err := sortRepoObjects(rs, applyConstraints) @@ -57,9 +57,9 @@ func (r Repo) SortedEntries(applyConstraints bool) ([]manifest.Manifest2822Entry return nil, err } - ret := []manifest.Manifest2822Entry{} + ret := []*manifest.Manifest2822Entry{} for _, entryR := range rs { - ret = append(ret, *entryR.TagEntry) + ret = append(ret, entryR.TagEntries...) } return ret, nil } @@ -101,7 +101,7 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) { continue } - from, err := r.DockerFrom(&entry) + from, err := r.DockerFrom(entry) if err != nil { return nil, err } diff --git a/go/vendor/manifest b/go/vendor/manifest index bceb1cb..3c343de 100644 --- a/go/vendor/manifest +++ b/go/vendor/manifest @@ -10,7 +10,7 @@ { "importpath": "github.com/docker-library/go-dockerlibrary", "repository": "https://github.com/docker-library/go-dockerlibrary", - "revision": "78186ac78fb8c1ce4e0f2f4847ae4d57a69cfcc3", + "revision": "7e50189a05d4ff8233197dc948cc8fb11a780e33", "branch": "master" }, { diff --git a/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/fetch.go b/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/fetch.go index 93b61f6..dc105ed 100644 --- a/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/fetch.go +++ b/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/fetch.go @@ -9,6 +9,13 @@ import ( "strings" ) +func validateTagName(man *Manifest2822, repoName, tagName string) error { + if tagName != "" && (man.GetTag(tagName) == nil && len(man.GetSharedTag(tagName)) == 0) { + return fmt.Errorf("tag not found in manifest for %q: %q", repoName, tagName) + } + return nil +} + // "library" is the default "library directory" // returns the parsed version of (in order): // if "repo" is a URL, the remote contents of that URL @@ -33,10 +40,10 @@ func Fetch(library, repo string) (string, string, *Manifest2822, error) { } defer resp.Body.Close() man, err := Parse(resp.Body) - if tagName != "" && man.GetTag(tagName) == nil { - return repoName, tagName, man, fmt.Errorf("tag not found in manifest for %q: %q", repoName, tagName) + if err != nil { + return repoName, tagName, man, err } - return repoName, tagName, man, err + return repoName, tagName, man, validateTagName(man, repoName, tagName) } // try file paths @@ -55,10 +62,10 @@ func Fetch(library, repo string) (string, string, *Manifest2822, error) { if err == nil { defer f.Close() man, err := Parse(f) - if tagName != "" && man.GetTag(tagName) == nil { - return repoName, tagName, man, fmt.Errorf("tag not found in manifest for %q: %q", repoName, tagName) + if err != nil { + return repoName, tagName, man, err } - return repoName, tagName, man, err + return repoName, tagName, man, validateTagName(man, repoName, tagName) } } diff --git a/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go b/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go index fe83a0f..4176029 100644 --- a/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go +++ b/go/vendor/src/github.com/docker-library/go-dockerlibrary/manifest/rfc2822.go @@ -308,20 +308,20 @@ func (entry Manifest2822Entry) HasArchitecture(arch string) bool { } func (manifest Manifest2822) GetTag(tag string) *Manifest2822Entry { - for _, entry := range manifest.Entries { + for i, entry := range manifest.Entries { if entry.HasTag(tag) { - return &entry + return &manifest.Entries[i] } } return nil } // GetSharedTag returns a list of entries with the given tag in entry.SharedTags (or the empty list if there are no entries with the given tag). -func (manifest Manifest2822) GetSharedTag(tag string) []Manifest2822Entry { - ret := []Manifest2822Entry{} - for _, entry := range manifest.Entries { +func (manifest Manifest2822) GetSharedTag(tag string) []*Manifest2822Entry { + ret := []*Manifest2822Entry{} + for i, entry := range manifest.Entries { if entry.HasSharedTag(tag) { - ret = append(ret, entry) + ret = append(ret, &manifest.Entries[i]) } } return ret