Simplify upList()

Before the goroutines in upList() were layed out like:
	upLists()
	|- - - 	upRepo()
	|- - - 	pAur()
		| - - -	upDevel()

Simplified by moving upDevel() from upAur() to upList():
	upList()
	|- - - 	upRepo()
	|- - - 	upAur()
	|- - - 	upDevel()

With the simpler layout it was easy to then remove some un need channel
useage entirely and use WaitGroups in other places.

Now if any of the three inner functions error, upList() will return
a combined error instead of just printing the error and carrying on.
This commit is contained in:
morganamilo 2018-03-20 16:20:09 +00:00
parent bb35f202b8
commit b5c0cb7a11
No known key found for this signature in database
GPG key ID: 6FE9E7996B0B082E

View file

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
"strings"
"sort" "sort"
"sync" "sync"
"unicode" "unicode"
@ -83,52 +84,62 @@ func getVersionDiff(oldVersion, newversion string) (left, right string) {
func upList(dt *depTree) (aurUp upSlice, repoUp upSlice, err error) { func upList(dt *depTree) (aurUp upSlice, repoUp upSlice, err error) {
local, remote, _, remoteNames, err := filterPackages() local, remote, _, remoteNames, err := filterPackages()
if err != nil { if err != nil {
return return nil, nil, err
} }
repoC := make(chan upSlice) var wg sync.WaitGroup
aurC := make(chan upSlice) var develUp upSlice
errC := make(chan error)
var repoErr error
var aurErr error
var develErr error
fmt.Println(bold(cyan("::") + " Searching databases for updates...")) fmt.Println(bold(cyan("::") + " Searching databases for updates..."))
wg.Add(1)
go func() { go func() {
repoUpList, err := upRepo(local) repoUp, repoErr = upRepo(local)
errC <- err wg.Done()
repoC <- repoUpList
}() }()
fmt.Println(bold(cyan("::") + " Searching AUR for updates...")) fmt.Println(bold(cyan("::") + " Searching AUR for updates..."))
wg.Add(1)
go func() { go func() {
aurUpList, err := upAUR(remote, remoteNames, dt) aurUp, aurErr = upAUR(remote, remoteNames, dt)
errC <- err wg.Done()
aurC <- aurUpList
}() }()
var i = 0
loop: if config.Devel {
for { fmt.Println(bold(cyan("::") + " Checking development packages..."))
select { wg.Add(1)
case repoUp = <-repoC: go func() {
i++ develUp, develErr = upDevel(remote)
case aurUp = <-aurC: wg.Done()
i++ }()
case err := <-errC:
if err != nil {
fmt.Println(err)
}
default:
if i == 2 {
close(repoC)
close(aurC)
close(errC)
break loop
}
}
}
return
} }
func upDevel(remote []alpm.Package, packageC chan upgrade, done chan bool) {
wg.Wait()
errs := make([]string, 0)
for _, e := range []error{repoErr, aurErr, develErr} {
if e != nil {
errs = append(errs, e.Error())
}
}
if len(errs) > 0 {
err = fmt.Errorf("%s", strings.Join(errs, "\n"))
}
if develUp != nil {
aurUp = append(aurUp, develUp...)
}
return aurUp, repoUp, err
}
func upDevel(remote []alpm.Package) (toUpgrade upSlice, err error) {
toUpdate := make([]alpm.Package, 0, 0) toUpdate := make([]alpm.Package, 0, 0)
toRemove := make([]string, 0, 0) toRemove := make([]string, 0, 0)
@ -168,31 +179,17 @@ func upDevel(remote []alpm.Package, packageC chan upgrade, done chan bool) {
fmt.Print(magenta("Warning: ")) fmt.Print(magenta("Warning: "))
fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right) fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right)
} else { } else {
packageC <- upgrade{pkg.Name(), "devel", pkg.Version(), "latest-commit"} toUpgrade = append(toUpgrade, upgrade{pkg.Name(), "devel", pkg.Version(), "latest-commit"})
} }
} }
removeVCSPackage(toRemove) removeVCSPackage(toRemove)
done <- true return
} }
// upAUR gathers foreign packages and checks if they have new versions. // upAUR gathers foreign packages and checks if they have new versions.
// Output: Upgrade type package list. // Output: Upgrade type package list.
func upAUR(remote []alpm.Package, remoteNames []string, dt *depTree) (toUpgrade upSlice, err error) { func upAUR(remote []alpm.Package, remoteNames []string, dt *depTree) (toUpgrade upSlice, err error) {
var routines int
var routineDone int
packageC := make(chan upgrade)
done := make(chan bool)
if config.Devel {
routines++
go upDevel(remote, packageC, done)
fmt.Println(bold(cyan("::") + " Checking development packages..."))
}
routines++
go func(remote []alpm.Package, remoteNames []string, dt *depTree) {
for _, pkg := range remote { for _, pkg := range remote {
aurPkg, ok := dt.Aur[pkg.Name()] aurPkg, ok := dt.Aur[pkg.Name()]
if !ok { if !ok {
@ -206,38 +203,14 @@ func upAUR(remote []alpm.Package, remoteNames []string, dt *depTree) (toUpgrade
fmt.Print(magenta("Warning: ")) fmt.Print(magenta("Warning: "))
fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right) fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right)
} else { } else {
packageC <- upgrade{aurPkg.Name, "aur", pkg.Version(), aurPkg.Version} toUpgrade = append(toUpgrade, upgrade{aurPkg.Name, "aur", pkg.Version(), aurPkg.Version})
} }
} }
} }
done <- true
}(remote, remoteNames, dt)
if routineDone == routines {
err = nil
return return
} }
for {
select {
case pkg := <-packageC:
for _, w := range toUpgrade {
if w.Name == pkg.Name {
continue
}
}
toUpgrade = append(toUpgrade, pkg)
case <-done:
routineDone++
if routineDone == routines {
err = nil
return
}
}
}
}
// upRepo gathers local packages and checks if they have new versions. // upRepo gathers local packages and checks if they have new versions.
// Output: Upgrade type package list. // Output: Upgrade type package list.
func upRepo(local []alpm.Package) (upSlice, error) { func upRepo(local []alpm.Package) (upSlice, error) {