Improve bashbrew SharedTags handling (explicitly allowed for "bashbrew cat", etc)
This commit is contained in:
parent
1693d9a9e6
commit
a93f9f538f
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue