Improve bashbrew SharedTags handling (explicitly allowed for "bashbrew cat", etc)

This commit is contained in:
Tianon Gravi 2019-01-28 16:16:50 -08:00
parent 1693d9a9e6
commit a93f9f538f
11 changed files with 68 additions and 38 deletions

View File

@ -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)
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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 {

View File

@ -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},

View File

@ -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

View File

@ -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
}

2
go/vendor/manifest vendored
View File

@ -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"
},
{

View File

@ -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)
}
}

View File

@ -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