bashbrew: account for namespaces when sorting repos

This commit is contained in:
Giuseppe Valente 2019-06-07 15:14:22 -07:00 committed by Tianon Gravi
parent 19e63bbaeb
commit bc4037dd68
4 changed files with 23 additions and 12 deletions

View File

@ -12,13 +12,13 @@ func cmdBuild(c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err) return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err)
} }
repos, err = sortRepos(repos, true) namespace := c.String("namespace")
repos, err = sortRepos(repos, true, namespace)
if err != nil { if err != nil {
return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err) return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err)
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := c.String("namespace")
pull := c.String("pull") pull := c.String("pull")
switch pull { switch pull {
case "always", "missing", "never": case "always", "missing", "never":
@ -34,7 +34,7 @@ func cmdBuild(c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err) return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
} }
entries, err := r.SortedEntries(true) entries, err := r.SortedEntries(true, namespace)
if err != nil { if err != nil {
return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err) return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err)
} }

View File

@ -14,13 +14,13 @@ func cmdList(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := "" namespace := c.String("namespace")
applyConstraints := c.Bool("apply-constraints") applyConstraints := c.Bool("apply-constraints")
onlyRepos := c.Bool("repos") onlyRepos := c.Bool("repos")
buildOrder := c.Bool("build-order") buildOrder := c.Bool("build-order")
if buildOrder { if buildOrder {
repos, err = sortRepos(repos, applyConstraints) repos, err = sortRepos(repos, applyConstraints, namespace)
if err != nil { if err != nil {
return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err) return cli.NewMultiError(fmt.Errorf(`failed sorting repo list`), err)
} }
@ -45,7 +45,7 @@ func cmdList(c *cli.Context) error {
var entries []*manifest.Manifest2822Entry var entries []*manifest.Manifest2822Entry
if buildOrder { if buildOrder {
entries, err = r.SortedEntries(applyConstraints) entries, err = r.SortedEntries(applyConstraints, namespace)
if err != nil { if err != nil {
return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err) return cli.NewMultiError(fmt.Errorf(`failed sorting entries list for %q`, repo), err)
} }

View File

@ -220,6 +220,7 @@ func main() {
Flags: []cli.Flag{ Flags: []cli.Flag{
commonFlags["all"], commonFlags["all"],
commonFlags["uniq"], commonFlags["uniq"],
commonFlags["namespace"],
commonFlags["apply-constraints"], commonFlags["apply-constraints"],
cli.BoolFlag{ cli.BoolFlag{
Name: "build-order", Name: "build-order",

View File

@ -5,7 +5,7 @@ import (
"pault.ag/go/topsort" "pault.ag/go/topsort"
) )
func sortRepos(repos []string, applyConstraints bool) ([]string, error) { func sortRepos(repos []string, applyConstraints bool, namespace string) ([]string, error) {
rs := []*Repo{} rs := []*Repo{}
rsMap := map[*Repo]string{} rsMap := map[*Repo]string{}
for _, repo := range repos { for _, repo := range repos {
@ -26,7 +26,7 @@ func sortRepos(repos []string, applyConstraints bool) ([]string, error) {
return repos, nil return repos, nil
} }
rs, err := sortRepoObjects(rs, applyConstraints) rs, err := sortRepoObjects(rs, applyConstraints, namespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -38,7 +38,7 @@ func sortRepos(repos []string, applyConstraints bool) ([]string, error) {
return ret, nil return ret, nil
} }
func (r Repo) SortedEntries(applyConstraints bool) ([]*manifest.Manifest2822Entry, error) { func (r Repo) SortedEntries(applyConstraints bool, namespace string) ([]*manifest.Manifest2822Entry, error) {
entries := r.Entries() entries := r.Entries()
// short circuit if we don't have to go further // short circuit if we don't have to go further
@ -52,7 +52,7 @@ func (r Repo) SortedEntries(applyConstraints bool) ([]*manifest.Manifest2822Entr
rs = append(rs, r.EntryRepo(entries[i])) rs = append(rs, r.EntryRepo(entries[i]))
} }
rs, err := sortRepoObjects(rs, applyConstraints) rs, err := sortRepoObjects(rs, applyConstraints, namespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -64,7 +64,14 @@ func (r Repo) SortedEntries(applyConstraints bool) ([]*manifest.Manifest2822Entr
return ret, nil return ret, nil
} }
func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) { func addNamespace(namespace, tag string) string {
if namespace != "" {
tag = namespace + "/" + tag
}
return tag
}
func sortRepoObjects(rs []*Repo, applyConstraints bool, namespace string) ([]*Repo, error) {
// short circuit if we don't have to go further // short circuit if we don't have to go further
if noSortFlag || len(rs) <= 1 { if noSortFlag || len(rs) <= 1 {
return rs, nil return rs, nil
@ -79,12 +86,13 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
for _, r := range rs { for _, r := range rs {
node := r.Identifier() node := r.Identifier()
for _, entry := range r.Entries() { for _, entry := range r.Entries() {
node = addNamespace(namespace, node)
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags("", false, entry) {
tag = addNamespace(namespace, tag)
if canonicalRepo, ok := canonicalRepos[tag]; ok && canonicalRepo.TagName != "" { if canonicalRepo, ok := canonicalRepos[tag]; ok && canonicalRepo.TagName != "" {
// if we run into a duplicate, we want to prefer a specific tag over a full repo // if we run into a duplicate, we want to prefer a specific tag over a full repo
continue continue
} }
canonicalNodes[tag] = node canonicalNodes[tag] = node
canonicalRepos[tag] = r canonicalRepos[tag] = r
} }
@ -115,6 +123,8 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
// TODO somehow reconcile/avoid "a:a -> b:b, b:b -> a:c" (which will exhibit here as cyclic) // TODO somehow reconcile/avoid "a:a -> b:b, b:b -> a:c" (which will exhibit here as cyclic)
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags("", false, entry) {
tag = addNamespace(namespace, tag)
if tagNode, ok := canonicalNodes[tag]; ok { if tagNode, ok := canonicalNodes[tag]; ok {
if tagNode == fromNode { if tagNode == fromNode {
// don't be cyclic // don't be cyclic