From b5c0cb7a11ba23e9625c4c1d26163e62275c14ce Mon Sep 17 00:00:00 2001 From: morganamilo Date: Tue, 20 Mar 2018 16:20:09 +0000 Subject: [PATCH 1/4] 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. --- upgrade.go | 143 ++++++++++++++++++++++------------------------------- 1 file changed, 58 insertions(+), 85 deletions(-) diff --git a/upgrade.go b/upgrade.go index cf5188f7..c3df730b 100644 --- a/upgrade.go +++ b/upgrade.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "os" + "strings" "sort" "sync" "unicode" @@ -83,52 +84,62 @@ func getVersionDiff(oldVersion, newversion string) (left, right string) { func upList(dt *depTree) (aurUp upSlice, repoUp upSlice, err error) { local, remote, _, remoteNames, err := filterPackages() if err != nil { - return + return nil, nil, err } - repoC := make(chan upSlice) - aurC := make(chan upSlice) - errC := make(chan error) + var wg sync.WaitGroup + var develUp upSlice + + var repoErr error + var aurErr error + var develErr error fmt.Println(bold(cyan("::") + " Searching databases for updates...")) + wg.Add(1) go func() { - repoUpList, err := upRepo(local) - errC <- err - repoC <- repoUpList + repoUp, repoErr = upRepo(local) + wg.Done() }() fmt.Println(bold(cyan("::") + " Searching AUR for updates...")) + wg.Add(1) go func() { - aurUpList, err := upAUR(remote, remoteNames, dt) - errC <- err - aurC <- aurUpList + aurUp, aurErr = upAUR(remote, remoteNames, dt) + wg.Done() }() - var i = 0 -loop: - for { - select { - case repoUp = <-repoC: - i++ - case aurUp = <-aurC: - i++ - case err := <-errC: - if err != nil { - fmt.Println(err) - } - default: - if i == 2 { - close(repoC) - close(aurC) - close(errC) - break loop - } + + if config.Devel { + fmt.Println(bold(cyan("::") + " Checking development packages...")) + wg.Add(1) + go func() { + develUp, develErr = upDevel(remote) + wg.Done() + }() + } + + + wg.Wait() + + errs := make([]string, 0) + for _, e := range []error{repoErr, aurErr, develErr} { + if e != nil { + errs = append(errs, e.Error()) } } - return + + 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, packageC chan upgrade, done chan bool) { +func upDevel(remote []alpm.Package) (toUpgrade upSlice, err error) { toUpdate := make([]alpm.Package, 0, 0) toRemove := make([]string, 0, 0) @@ -168,74 +179,36 @@ func upDevel(remote []alpm.Package, packageC chan upgrade, done chan bool) { fmt.Print(magenta("Warning: ")) fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right) } else { - packageC <- upgrade{pkg.Name(), "devel", pkg.Version(), "latest-commit"} + toUpgrade = append(toUpgrade, upgrade{pkg.Name(), "devel", pkg.Version(), "latest-commit"}) } } removeVCSPackage(toRemove) - done <- true + return } // upAUR gathers foreign packages and checks if they have new versions. // Output: Upgrade type package list. 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 { - aurPkg, ok := dt.Aur[pkg.Name()] - if !ok { - continue - } - - if (config.TimeUpdate && (int64(aurPkg.LastModified) > pkg.BuildDate().Unix())) || - (alpm.VerCmp(pkg.Version(), aurPkg.Version) < 0) { - if pkg.ShouldIgnore() { - left, right := getVersionDiff(pkg.Version(), aurPkg.Version) - fmt.Print(magenta("Warning: ")) - fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right) - } else { - packageC <- upgrade{aurPkg.Name, "aur", pkg.Version(), aurPkg.Version} - } - } + for _, pkg := range remote { + aurPkg, ok := dt.Aur[pkg.Name()] + if !ok { + continue } - done <- true - }(remote, remoteNames, dt) - - if routineDone == routines { - err = nil - 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 + if (config.TimeUpdate && (int64(aurPkg.LastModified) > pkg.BuildDate().Unix())) || + (alpm.VerCmp(pkg.Version(), aurPkg.Version) < 0) { + if pkg.ShouldIgnore() { + left, right := getVersionDiff(pkg.Version(), aurPkg.Version) + fmt.Print(magenta("Warning: ")) + fmt.Printf("%s ignoring package upgrade (%s => %s)\n", cyan(pkg.Name()), left, right) + } else { + toUpgrade = append(toUpgrade, upgrade{aurPkg.Name, "aur", pkg.Version(), aurPkg.Version}) } } } + + return } // upRepo gathers local packages and checks if they have new versions. From 624851b80b5fdca7bbdeff162488217caf3f08dc Mon Sep 17 00:00:00 2001 From: morganamilo Date: Tue, 20 Mar 2018 22:34:06 +0000 Subject: [PATCH 2/4] More sorting for upgrade menu Sort accending instead of decending Sort by package name as well as repo name Sort AUR packages as well as repo packages --- upgrade.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/upgrade.go b/upgrade.go index c3df730b..982ce477 100644 --- a/upgrade.go +++ b/upgrade.go @@ -28,9 +28,18 @@ func (u upSlice) Len() int { return len(u) } func (u upSlice) Swap(i, j int) { u[i], u[j] = u[j], u[i] } func (u upSlice) Less(i, j int) bool { - iRunes := []rune(u[i].Repository) - jRunes := []rune(u[j].Repository) + if u[i].Repository != u[j].Repository { + iRunes := []rune(u[i].Repository) + jRunes := []rune(u[j].Repository) + return lessRunes(iRunes, jRunes) + } else { + iRunes := []rune(u[i].Name) + jRunes := []rune(u[j].Name) + return lessRunes(iRunes, jRunes) + } +} +func lessRunes(iRunes, jRunes []rune) bool { max := len(iRunes) if max > len(jRunes) { max = len(jRunes) @@ -44,16 +53,16 @@ func (u upSlice) Less(i, j int) bool { ljr := unicode.ToLower(jr) if lir != ljr { - return lir > ljr + return lir < ljr } // the lowercase runes are the same, so compare the original if ir != jr { - return ir > jr + return ir < jr } } - return false + return len(iRunes) < len(jRunes) } func getVersionDiff(oldVersion, newversion string) (left, right string) { @@ -272,6 +281,7 @@ func upgradePkgs(dt *depTree) (stringSet, stringSet, error) { } sort.Sort(repoUp) + sort.Sort(aurUp) fmt.Println(bold(blue("::")), len(aurUp)+len(repoUp), bold("Packages to upgrade.")) repoUp.Print(len(aurUp) + 1) aurUp.Print(1) From bb211fdbf73d16cd27b1dba9f61b8b468d9406c9 Mon Sep 17 00:00:00 2001 From: morganamilo Date: Tue, 20 Mar 2018 23:04:28 +0000 Subject: [PATCH 3/4] Don't show package in aur/ if it is also in devel/ --- upgrade.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/upgrade.go b/upgrade.go index 982ce477..fdd07f0a 100644 --- a/upgrade.go +++ b/upgrade.go @@ -139,10 +139,21 @@ func upList(dt *depTree) (aurUp upSlice, repoUp upSlice, err error) { if len(errs) > 0 { err = fmt.Errorf("%s", strings.Join(errs, "\n")) + return nil, nil, err } if develUp != nil { - aurUp = append(aurUp, develUp...) + names := make(stringSet) + for _, up := range develUp { + names.set(up.Name) + } + for _, up := range aurUp { + if !names.get(up.Name) { + develUp = append(develUp, up) + } + } + + aurUp = develUp } return aurUp, repoUp, err From 98ea801004fc63b5a294f46392910e85286ffd98 Mon Sep 17 00:00:00 2001 From: morganamilo Date: Wed, 21 Mar 2018 16:30:00 +0000 Subject: [PATCH 4/4] Pass `-Su` to pacman during sysupgrade Previosly during `yay -Su` Yay would pass `pacman -S ` to pacman. Instead pass `pacman -Su --ignore ` This allows yay to handle replaces and package downgrades `-Suu` --- install.go | 10 +++------- upgrade.go | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/install.go b/install.go index 75ad7c02..3ce5d9d7 100644 --- a/install.go +++ b/install.go @@ -64,27 +64,23 @@ func install(parser *arguments) error { //create the arguments to pass for the repo install arguments := parser.copy() - arguments.delArg("u", "sysupgrade") arguments.delArg("y", "refresh") arguments.op = "S" arguments.targets = make(stringSet) if parser.existsArg("u", "sysupgrade") { - repoUp, aurUp, err := upgradePkgs(dt) + ignore, aurUp, err := upgradePkgs(dt) if err != nil { return err } + arguments.addParam("ignore", strings.Join(ignore.toSlice(), ",")) fmt.Println() for pkg := range aurUp { parser.addTarget(pkg) } - for pkg := range repoUp { - arguments.addTarget(pkg) - } - //discard stuff thats //not a target and //not an upgrade and @@ -184,7 +180,7 @@ func install(parser *arguments) error { } } - if !parser.existsArg("gendb") && len(arguments.targets) > 0 { + if !parser.existsArg("gendb") && (len(arguments.targets) > 0 || arguments.existsArg("u")) { err := passToPacman(arguments) if err != nil { return fmt.Errorf("Error installing repo packages") diff --git a/upgrade.go b/upgrade.go index fdd07f0a..c005524f 100644 --- a/upgrade.go +++ b/upgrade.go @@ -281,14 +281,14 @@ func removeIntListFromList(src, target []int) []int { // upgradePkgs handles updating the cache and installing updates. func upgradePkgs(dt *depTree) (stringSet, stringSet, error) { - repoNames := make(stringSet) + ignore := make(stringSet) aurNames := make(stringSet) aurUp, repoUp, err := upList(dt) if err != nil { - return repoNames, aurNames, err + return ignore, aurNames, err } else if len(aurUp)+len(repoUp) == 0 { - return repoNames, aurNames, err + return ignore, aurNames, err } sort.Sort(repoUp) @@ -298,13 +298,10 @@ func upgradePkgs(dt *depTree) (stringSet, stringSet, error) { aurUp.Print(1) if config.NoConfirm { - for _, up := range repoUp { - repoNames.set(up.Name) - } for _, up := range aurUp { aurNames.set(up.Name) } - return repoNames, aurNames, nil + return ignore, aurNames, nil } fmt.Println(bold(green(arrow + " Packages to not upgrade (eg: 1 2 3, 1-3, ^4 or repo name)"))) @@ -329,16 +326,18 @@ func upgradePkgs(dt *depTree) (stringSet, stringSet, error) { for i, pkg := range repoUp { if isInclude && otherInclude.get(pkg.Repository) { - continue + ignore.set(pkg.Name) } if isInclude && !include.get(len(repoUp)-i+len(aurUp)) { - repoNames.set(pkg.Name) + continue } if !isInclude && (exclude.get(len(repoUp)-i+len(aurUp)) || otherExclude.get(pkg.Repository)) { - repoNames.set(pkg.Name) + continue } + + ignore.set(pkg.Name) } for i, pkg := range aurUp { @@ -355,5 +354,5 @@ func upgradePkgs(dt *depTree) (stringSet, stringSet, error) { } } - return repoNames, aurNames, err + return ignore, aurNames, err }