1
0
mirror of https://github.com/Jguer/yay synced 2024-07-08 20:36:24 +00:00

fix(install): remove alpmHandle

This commit is contained in:
jguer 2020-08-01 01:20:00 +02:00
parent 9fd6917bc0
commit 005b29373d
No known key found for this signature in database
GPG Key ID: 6D6CC9BEA8556B35
15 changed files with 346 additions and 399 deletions

View File

@ -121,10 +121,7 @@ func cleanAUR(keepInstalled, keepCurrent, removeAll bool, alpmHandle *alpm.Handl
installedBases := make(stringset.StringSet)
inAURBases := make(stringset.StringSet)
remotePackages, _, err := query.GetRemotePackages(alpmHandle)
if err != nil {
return err
}
remotePackages, _ := query.GetRemotePackages(config.Runtime.DBExecutor)
files, err := ioutil.ReadDir(config.BuildDir)
if err != nil {

15
cmd.go
View File

@ -11,6 +11,7 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/completion"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/news"
"github.com/Jguer/yay/v10/pkg/query"
@ -169,7 +170,7 @@ func handleCmd(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error {
case "G", "getpkgbuild":
return handleGetpkgbuild(cmdArgs, alpmHandle)
case "P", "show":
return handlePrint(cmdArgs, alpmHandle)
return handlePrint(cmdArgs, alpmHandle, config.Runtime.DBExecutor)
case "Y", "--yay":
return handleYay(cmdArgs, alpmHandle)
}
@ -217,7 +218,7 @@ func lastBuildTime(alpmHandle *alpm.Handle) time.Time {
return lastTime
}
func handlePrint(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) (err error) {
func handlePrint(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, dbExecutor *db.AlpmExecutor) (err error) {
switch {
case cmdArgs.ExistsArg("d", "defaultconfig"):
tmpConfig := settings.MakeConfig()
@ -232,9 +233,9 @@ func handlePrint(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) (err erro
quiet := cmdArgs.ExistsArg("q", "quiet")
err = news.PrintNewsFeed(lastBuildTime(alpmHandle), config.SortMode, double, quiet)
case cmdArgs.ExistsDouble("c", "complete"):
err = completion.Show(alpmHandle, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, true)
err = completion.Show(dbExecutor, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, true)
case cmdArgs.ExistsArg("c", "complete"):
err = completion.Show(alpmHandle, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false)
err = completion.Show(dbExecutor, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false)
case cmdArgs.ExistsArg("s", "stats"):
err = localStatistics(alpmHandle)
default:
@ -295,10 +296,10 @@ func handleSync(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error {
return syncInfo(cmdArgs, targets, alpmHandle)
}
if cmdArgs.ExistsArg("u", "sysupgrade") {
return install(cmdArgs, alpmHandle, false)
return install(cmdArgs, config.Runtime.DBExecutor, false)
}
if len(cmdArgs.Targets) > 0 {
return install(cmdArgs, alpmHandle, false)
return install(cmdArgs, config.Runtime.DBExecutor, false)
}
if cmdArgs.ExistsArg("y", "refresh") {
return show(passToPacman(cmdArgs))
@ -426,7 +427,7 @@ func displayNumberMenu(pkgS []string, alpmHandle *alpm.Handle, cmdArgs *settings
sudoLoopBackground()
}
return install(arguments, alpmHandle, true)
return install(arguments, config.Runtime.DBExecutor, true)
}
func syncList(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error {

View File

@ -15,6 +15,7 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/completion"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/dep"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/multierror"
@ -23,6 +24,7 @@ import (
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/stringset"
"github.com/Jguer/yay/v10/pkg/text"
"github.com/Jguer/yay/v10/pkg/upgrade"
)
const gitEmptyTree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
@ -60,12 +62,12 @@ func asexp(cmdArgs *settings.Arguments, pkgs []string) error {
}
// Install handles package installs
func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProviders bool) (err error) {
func install(cmdArgs *settings.Arguments, dbExecutor *db.AlpmExecutor, ignoreProviders bool) (err error) {
var incompatible stringset.StringSet
var do *dep.Order
var aurUp upSlice
var repoUp upSlice
var aurUp upgrade.UpSlice
var repoUp upgrade.UpSlice
var srcinfos map[string]*gosrc.Srcinfo
@ -80,7 +82,7 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
}
}
} else if cmdArgs.ExistsArg("y", "refresh") || cmdArgs.ExistsArg("u", "sysupgrade") || len(cmdArgs.Targets) > 0 {
err = earlyPacmanCall(cmdArgs, alpmHandle)
err = earlyPacmanCall(cmdArgs, config.Runtime.DBExecutor)
if err != nil {
return err
}
@ -89,17 +91,12 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
// we may have done -Sy, our handle now has an old
// database.
alpmHandle, err = initAlpmHandle(config.Runtime.PacmanConf, alpmHandle)
if err != nil {
return err
}
config.Runtime.AlpmHandle = alpmHandle
err = config.Runtime.DBExecutor.RefreshHandle()
if err != nil {
return err
}
localNames, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
localNames, remoteNames, err := query.GetPackageNamesBySource(dbExecutor)
if err != nil {
return err
}
@ -122,7 +119,7 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
// if we are doing -u also request all packages needing update
if cmdArgs.ExistsArg("u", "sysupgrade") {
aurUp, repoUp, err = upList(warnings, alpmHandle, cmdArgs.ExistsDouble("u", "sysupgrade"))
aurUp, repoUp, err = upList(warnings, dbExecutor, cmdArgs.ExistsDouble("u", "sysupgrade"))
if err != nil {
return err
}
@ -324,7 +321,7 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
config.NoConfirm = oldValue
}
incompatible, err = getIncompatible(do.Aur, srcinfos, alpmHandle)
incompatible, err = getIncompatible(do.Aur, srcinfos, dbExecutor)
if err != nil {
return err
}
@ -369,14 +366,14 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
}
}
go exitOnError(completion.Update(alpmHandle, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false))
go exitOnError(completion.Update(dbExecutor, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false))
err = downloadPkgbuildsSources(do.Aur, incompatible)
if err != nil {
return err
}
err = buildInstallPkgbuilds(cmdArgs, alpmHandle, dp, do, srcinfos, incompatible, conflicts)
err = buildInstallPkgbuilds(cmdArgs, dbExecutor, dp, do, srcinfos, incompatible, conflicts)
if err != nil {
return err
}
@ -403,7 +400,7 @@ func removeMake(do *dep.Order) error {
return err
}
func inRepos(syncDB alpm.DBList, pkg string) bool {
func inRepos(dbExecutor *db.AlpmExecutor, pkg string) bool {
target := dep.ToTarget(pkg)
if target.DB == "aur" {
@ -414,33 +411,25 @@ func inRepos(syncDB alpm.DBList, pkg string) bool {
previousHideMenus := settings.HideMenus
settings.HideMenus = false
_, err := syncDB.FindSatisfier(target.DepString())
exists := dbExecutor.SyncSatisfierExists(target.DepString())
settings.HideMenus = previousHideMenus
if err == nil {
return true
}
return !syncDB.FindGroupPkgs(target.Name).Empty()
return exists || len(dbExecutor.PackagesFromGroup(target.Name)) > 0
}
func earlyPacmanCall(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error {
func earlyPacmanCall(cmdArgs *settings.Arguments, dbExecutor *db.AlpmExecutor) error {
arguments := cmdArgs.Copy()
arguments.Op = "S"
targets := cmdArgs.Targets
cmdArgs.ClearTargets()
arguments.ClearTargets()
syncDB, err := alpmHandle.SyncDBs()
if err != nil {
return err
}
if config.Runtime.Mode == settings.ModeRepo {
arguments.Targets = targets
} else {
// separate aur and repo targets
for _, target := range targets {
if inRepos(syncDB, target) {
if inRepos(dbExecutor, target) {
arguments.AddTarget(target)
} else {
cmdArgs.AddTarget(target)
@ -449,8 +438,7 @@ func earlyPacmanCall(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error
}
if cmdArgs.ExistsArg("y", "refresh") || cmdArgs.ExistsArg("u", "sysupgrade") || len(arguments.Targets) > 0 {
err = show(passToPacman(arguments))
if err != nil {
if err := show(passToPacman(arguments)); err != nil {
return errors.New(gotext.Get("error installing repo packages"))
}
}
@ -469,10 +457,10 @@ func earlyRefresh(cmdArgs *settings.Arguments) error {
return show(passToPacman(arguments))
}
func getIncompatible(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo, alpmHandle *alpm.Handle) (stringset.StringSet, error) {
func getIncompatible(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo, dbExecutor *db.AlpmExecutor) (stringset.StringSet, error) {
incompatible := make(stringset.StringSet)
basesMap := make(map[string]dep.Base)
alpmArch, err := alpmHandle.Arch()
alpmArch, err := dbExecutor.AlpmArch()
if err != nil {
return nil, err
}
@ -943,7 +931,7 @@ func downloadPkgbuildsSources(bases []dep.Base, incompatible stringset.StringSet
func buildInstallPkgbuilds(
cmdArgs *settings.Arguments,
alpmHandle *alpm.Handle,
dbExecutor *db.AlpmExecutor,
dp *dep.Pool,
do *dep.Order,
srcinfos map[string]*gosrc.Srcinfo,
@ -968,7 +956,7 @@ func buildInstallPkgbuilds(
config.NoConfirm = true
//remotenames: names of all non repo packages on the system
localNames, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
localNames, remoteNames, err := query.GetPackageNamesBySource(dbExecutor)
if err != nil {
return err
}

View File

@ -12,12 +12,12 @@ import (
"strings"
"time"
alpm "github.com/Jguer/go-alpm"
"github.com/Jguer/yay/v10/pkg/db"
)
// Show provides completion info for shells
func Show(alpmHandle *alpm.Handle, aurURL, completionPath string, interval int, force bool) error {
err := Update(alpmHandle, aurURL, completionPath, interval, force)
func Show(dbExecutor *db.AlpmExecutor, aurURL, completionPath string, interval int, force bool) error {
err := Update(dbExecutor, aurURL, completionPath, interval, force)
if err != nil {
return err
}
@ -33,7 +33,7 @@ func Show(alpmHandle *alpm.Handle, aurURL, completionPath string, interval int,
}
// Update updates completion cache to be used by Complete
func Update(alpmHandle *alpm.Handle, aurURL, completionPath string, interval int, force bool) error {
func Update(dbExecutor *db.AlpmExecutor, aurURL, completionPath string, interval int, force bool) error {
info, err := os.Stat(completionPath)
if os.IsNotExist(err) || (interval != -1 && time.Since(info.ModTime()).Hours() >= float64(interval*24)) || force {
@ -50,11 +50,7 @@ func Update(alpmHandle *alpm.Handle, aurURL, completionPath string, interval int
defer os.Remove(completionPath)
}
dbList, err := alpmHandle.SyncDBs()
if err != nil {
return err
}
erra := createRepoList(&dbList, out)
erra := createRepoList(dbExecutor, out)
out.Close()
return erra
@ -97,13 +93,12 @@ func createAURList(aurURL string, out io.Writer) error {
}
// CreatePackageList appends Repo packages to completion cache
func createRepoList(dbList *alpm.DBList, out io.Writer) error {
_ = dbList.ForEach(func(db alpm.DB) error {
_ = db.PkgCache().ForEach(func(pkg alpm.Package) error {
_, err := io.WriteString(out, pkg.Name()+"\t"+pkg.DB().Name()+"\n")
func createRepoList(dbExecutor *db.AlpmExecutor, out io.Writer) error {
for _, pkg := range dbExecutor.SyncPackages() {
_, err := io.WriteString(out, pkg.Name()+"\t"+pkg.DB().Name()+"\n")
if err != nil {
return err
})
return nil
})
}
}
return nil
}

View File

@ -8,6 +8,7 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/text"
"github.com/Jguer/yay/v10/pkg/upgrade"
)
type AlpmExecutor struct {
@ -176,6 +177,13 @@ func (ae *AlpmExecutor) LocalSatisfierExists(pkgName string) bool {
return true
}
func (ae *AlpmExecutor) SyncSatisfierExists(pkgName string) bool {
if _, err := ae.syncDB.FindSatisfier(pkgName); err != nil {
return false
}
return true
}
func (ae *AlpmExecutor) IsCorrectVersionInstalled(pkgName, versionRequired string) bool {
alpmPackage := ae.localDB.Pkg(pkgName)
if alpmPackage == nil {
@ -266,3 +274,49 @@ func (ae *AlpmExecutor) PackageGroups(pkg RepoPackage) []string {
alpmPackage := pkg.(*alpm.Package)
return alpmPackage.Groups().Slice()
}
// upRepo gathers local packages and checks if they have new versions.
// Output: Upgrade type package list.
func (ae *AlpmExecutor) RepoUpgrades(enableDowngrade bool) (upgrade.UpSlice, error) {
slice := upgrade.UpSlice{}
localDB, err := ae.handle.LocalDB()
if err != nil {
return slice, err
}
err = ae.handle.TransInit(alpm.TransFlagNoLock)
if err != nil {
return slice, err
}
defer func() {
err = ae.handle.TransRelease()
}()
err = ae.handle.SyncSysupgrade(enableDowngrade)
if err != nil {
return slice, err
}
_ = ae.handle.TransGetAdd().ForEach(func(pkg alpm.Package) error {
localVer := "-"
if localPkg := localDB.Pkg(pkg.Name()); localPkg != nil {
localVer = localPkg.Version()
}
slice = append(slice, upgrade.Upgrade{
Name: pkg.Name(),
Repository: pkg.DB().Name(),
LocalVersion: localVer,
RemoteVersion: pkg.Version(),
})
return nil
})
return slice, nil
}
func (ae *AlpmExecutor) AlpmArch() (string, error) {
return ae.handle.Arch()
}

View File

@ -1,13 +1,19 @@
package db
import alpm "github.com/Jguer/go-alpm"
import (
"time"
alpm "github.com/Jguer/go-alpm"
)
type RepoPackage interface {
Base() string
Name() string
Version() string
BuildDate() time.Time
DB() *alpm.DB
ISize() int64
Size() int64
Description() string
ISize() int64
Name() string
ShouldIgnore() bool
Size() int64
Version() string
}

View File

@ -1,83 +1,46 @@
package query
import (
alpm "github.com/Jguer/go-alpm"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
)
// GetPackageNamesBySource returns package names with and without correspondence in SyncDBS respectively
func GetPackageNamesBySource(alpmHandle *alpm.Handle) (local, remote []string, err error) {
localDB, err := alpmHandle.LocalDB()
if err != nil {
return nil, nil, err
}
dbList, err := alpmHandle.SyncDBs()
if err != nil {
return nil, nil, err
}
err = localDB.PkgCache().ForEach(func(k alpm.Package) error {
found := false
// For each DB search for our secret package.
_ = dbList.ForEach(func(d alpm.DB) error {
if found {
return nil
func GetPackageNamesBySource(dbExecutor *db.AlpmExecutor) (local, remote []string, err error) {
outer:
for _, localpkg := range dbExecutor.LocalPackages() {
for _, syncpkg := range dbExecutor.SyncPackages() {
if localpkg.Name() == syncpkg.Name() {
local = append(local, localpkg.Name())
continue outer
}
if d.Pkg(k.Name()) != nil {
found = true
local = append(local, k.Name())
}
return nil
})
if !found {
remote = append(remote, k.Name())
}
return nil
})
remote = append(remote, localpkg.Name())
}
return local, remote, err
}
// GetRemotePackages returns packages with no correspondence in SyncDBS.
func GetRemotePackages(alpmHandle *alpm.Handle) (
remote []alpm.Package,
remoteNames []string,
err error) {
localDB, err := alpmHandle.LocalDB()
if err != nil {
return
}
dbList, err := alpmHandle.SyncDBs()
if err != nil {
return
}
func GetRemotePackages(dbExecutor *db.AlpmExecutor) (
[]db.RepoPackage,
[]string) {
remoteNames := []string{}
remote := []db.RepoPackage{}
f := func(k alpm.Package) error {
found := false
// For each DB search for our secret package.
_ = dbList.ForEach(func(d alpm.DB) error {
if found {
return nil
outer:
for _, localpkg := range dbExecutor.LocalPackages() {
for _, syncpkg := range dbExecutor.SyncPackages() {
if localpkg.Name() == syncpkg.Name() {
continue outer
}
if d.Pkg(k.Name()) != nil {
found = true
}
return nil
})
if !found {
remote = append(remote, k)
remoteNames = append(remoteNames, k.Name())
}
return nil
remote = append(remote, localpkg)
remoteNames = append(remoteNames, localpkg.Name())
}
err = localDB.PkgCache().ForEach(f)
return remote, remoteNames, err
return remote, remoteNames
}
func RemoveInvalidTargets(targets []string, mode settings.TargetMode) []string {

View File

@ -29,7 +29,7 @@ func Red(in string) string {
return stylize(redCode, in)
}
func green(in string) string {
func Green(in string) string {
return stylize(greenCode, in)
}

View File

@ -28,11 +28,11 @@ func SprintOperationInfo(a ...interface{}) string {
}
func Info(a ...interface{}) {
fmt.Fprint(os.Stdout, append([]interface{}{Bold(green(arrow + " "))}, a...)...)
fmt.Fprint(os.Stdout, append([]interface{}{Bold(Green(arrow + " "))}, a...)...)
}
func Infoln(a ...interface{}) {
fmt.Fprintln(os.Stdout, append([]interface{}{Bold(green(arrow))}, a...)...)
fmt.Fprintln(os.Stdout, append([]interface{}{Bold(Green(arrow))}, a...)...)
}
func SprintWarn(a ...interface{}) string {

111
pkg/upgrade/upgrade.go Normal file
View File

@ -0,0 +1,111 @@
package upgrade
import (
"fmt"
"unicode"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/text"
)
// Upgrade type describes a system upgrade.
type Upgrade struct {
Name string
Repository string
LocalVersion string
RemoteVersion string
}
func (u *Upgrade) StylizedNameWithRepository() string {
return text.Bold(text.ColorHash(u.Repository)) + "/" + text.Bold(u.Name)
}
// upSlice is a slice of Upgrades
type UpSlice []Upgrade
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 {
if u[i].Repository == u[j].Repository {
iRunes := []rune(u[i].Name)
jRunes := []rune(u[j].Name)
return text.LessRunes(iRunes, jRunes)
}
iRunes := []rune(u[i].Repository)
jRunes := []rune(u[j].Repository)
return text.LessRunes(iRunes, jRunes)
}
func GetVersionDiff(oldVersion, newVersion string) (left, right string) {
if oldVersion == newVersion {
return oldVersion + text.Red(""), newVersion + text.Green("")
}
diffPosition := 0
checkWords := func(str string, index int, words ...string) bool {
for _, word := range words {
wordLength := len(word)
nextIndex := index + 1
if (index < len(str)-wordLength) &&
(str[nextIndex:(nextIndex+wordLength)] == word) {
return true
}
}
return false
}
for index, char := range oldVersion {
charIsSpecial := !(unicode.IsLetter(char) || unicode.IsNumber(char))
if (index >= len(newVersion)) || (char != rune(newVersion[index])) {
if charIsSpecial {
diffPosition = index
}
break
}
if charIsSpecial ||
(((index == len(oldVersion)-1) || (index == len(newVersion)-1)) &&
((len(oldVersion) != len(newVersion)) ||
(oldVersion[index] == newVersion[index]))) ||
checkWords(oldVersion, index, "rc", "pre", "alpha", "beta") {
diffPosition = index + 1
}
}
samePart := oldVersion[0:diffPosition]
left = samePart + text.Red(oldVersion[diffPosition:])
right = samePart + text.Green(newVersion[diffPosition:])
return left, right
}
// Print prints the details of the packages to upgrade.
func (u UpSlice) Print() {
longestName, longestVersion := 0, 0
for _, pack := range u {
packNameLen := len(pack.StylizedNameWithRepository())
packVersion, _ := GetVersionDiff(pack.LocalVersion, pack.RemoteVersion)
packVersionLen := len(packVersion)
longestName = intrange.Max(packNameLen, longestName)
longestVersion = intrange.Max(packVersionLen, longestVersion)
}
namePadding := fmt.Sprintf("%%-%ds ", longestName)
versionPadding := fmt.Sprintf("%%-%ds", longestVersion)
numberPadding := fmt.Sprintf("%%%dd ", len(fmt.Sprintf("%v", len(u))))
for k, i := range u {
left, right := GetVersionDiff(i.LocalVersion, i.RemoteVersion)
fmt.Print(text.Magenta(fmt.Sprintf(numberPadding, len(u)-k)))
fmt.Printf(namePadding, i.StylizedNameWithRepository())
fmt.Printf("%s -> %s\n", fmt.Sprintf(versionPadding, left), right)
}
}

View File

@ -0,0 +1,67 @@
package upgrade
import (
"testing"
"github.com/Jguer/yay/v10/pkg/text"
)
func TestGetVersionDiff(t *testing.T) {
text.UseColor = true
type versionPair struct {
Old string
New string
}
in := []versionPair{
{"1-1", "1-1"},
{"1-1", "2-1"},
{"2-1", "1-1"},
{"1-1", "1-2"},
{"1-2", "1-1"},
{"1.2.3-1", "1.2.4-1"},
{"1.8rc1+6+g0f377f94-1", "1.8rc1+1+g7e949283-1"},
{"1.8rc1+6+g0f377f94-1", "1.8rc2+1+g7e949283-1"},
{"1.8rc2", "1.9rc1"},
{"2.99.917+812+g75795523-1", "2.99.917+823+gd9bf46e4-1"},
{"1.2.9-1", "1.2.10-1"},
{"1.2.10-1", "1.2.9-1"},
{"1.2-1", "1.2.1-1"},
{"1.2.1-1", "1.2-1"},
{"0.7-4", "0.7+4+gd8d8c67-1"},
{"1.0.2_r0-1", "1.0.2_r0-2"},
{"1.0.2_r0-1", "1.0.2_r1-1"},
{"1.0.2_r0-1", "1.0.3_r0-1"},
}
out := []versionPair{
{"1-1" + text.Red(""), "1-1" + text.Green("")},
{text.Red("1-1"), text.Green("2-1")},
{text.Red("2-1"), text.Green("1-1")},
{"1-" + text.Red("1"), "1-" + text.Green("2")},
{"1-" + text.Red("2"), "1-" + text.Green("1")},
{"1.2." + text.Red("3-1"), "1.2." + text.Green("4-1")},
{"1.8rc1+" + text.Red("6+g0f377f94-1"), "1.8rc1+" + text.Green("1+g7e949283-1")},
{"1.8" + text.Red("rc1+6+g0f377f94-1"), "1.8" + text.Green("rc2+1+g7e949283-1")},
{"1." + text.Red("8rc2"), "1." + text.Green("9rc1")},
{"2.99.917+" + text.Red("812+g75795523-1"), "2.99.917+" + text.Green("823+gd9bf46e4-1")},
{"1.2." + text.Red("9-1"), "1.2." + text.Green("10-1")},
{"1.2." + text.Red("10-1"), "1.2." + text.Green("9-1")},
{"1.2" + text.Red("-1"), "1.2" + text.Green(".1-1")},
{"1.2" + text.Red(".1-1"), "1.2" + text.Green("-1")},
{"0.7" + text.Red("-4"), "0.7" + text.Green("+4+gd8d8c67-1")},
{"1.0.2_r0-" + text.Red("1"), "1.0.2_r0-" + text.Green("2")},
{"1.0.2_" + text.Red("r0-1"), "1.0.2_" + text.Green("r1-1")},
{"1.0." + text.Red("2_r0-1"), "1.0." + text.Green("3_r0-1")},
}
for i, pair := range in {
o, n := GetVersionDiff(pair.Old, pair.New)
if o != out[i].Old || n != out[i].New {
t.Errorf("Test %d failed for update: expected (%s => %s) got (%s => %s) %d %d %d %d",
i+1, in[i].Old, in[i].New, o, n, len(in[i].Old), len(in[i].New), len(o), len(n))
}
}
}

View File

@ -12,7 +12,6 @@ import (
"github.com/Jguer/go-alpm"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/stringset"
@ -105,36 +104,6 @@ func (s repoQuery) printSearch(dbExecutor *db.AlpmExecutor) {
// Pretty print a set of packages from the same package base.
func (u *upgrade) StylizedNameWithRepository() string {
return bold(text.ColorHash(u.Repository)) + "/" + bold(u.Name)
}
// Print prints the details of the packages to upgrade.
func (u upSlice) print() {
longestName, longestVersion := 0, 0
for _, pack := range u {
packNameLen := len(pack.StylizedNameWithRepository())
packVersion, _ := getVersionDiff(pack.LocalVersion, pack.RemoteVersion)
packVersionLen := len(packVersion)
longestName = intrange.Max(packNameLen, longestName)
longestVersion = intrange.Max(packVersionLen, longestVersion)
}
namePadding := fmt.Sprintf("%%-%ds ", longestName)
versionPadding := fmt.Sprintf("%%-%ds", longestVersion)
numberPadding := fmt.Sprintf("%%%dd ", len(fmt.Sprintf("%v", len(u))))
for k, i := range u {
left, right := getVersionDiff(i.LocalVersion, i.RemoteVersion)
fmt.Print(magenta(fmt.Sprintf(numberPadding, len(u)-k)))
fmt.Printf(namePadding, i.StylizedNameWithRepository())
fmt.Printf("%s -> %s\n", fmt.Sprintf(versionPadding, left), right)
}
}
// PrintInfo prints package info like pacman -Si.
func PrintInfo(a *rpc.Pkg, extendedInfo bool) {
text.PrintInfoValue(gotext.Get("Repository"), "aur")
@ -201,7 +170,7 @@ func localStatistics(alpmHandle *alpm.Handle) error {
return err
}
_, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
_, remoteNames, err := query.GetPackageNamesBySource(config.Runtime.DBExecutor)
if err != nil {
return err
}
@ -227,7 +196,7 @@ func printNumberOfUpdates(alpmHandle *alpm.Handle, enableDowngrade bool) error {
warnings := query.NewWarnings()
old := os.Stdout // keep backup of the real stdout
os.Stdout = nil
aurUp, repoUp, err := upList(warnings, alpmHandle, enableDowngrade)
aurUp, repoUp, err := upList(warnings, config.Runtime.DBExecutor, enableDowngrade)
os.Stdout = old // restoring the real stdout
if err != nil {
return err
@ -243,12 +212,12 @@ func printUpdateList(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, enabl
warnings := query.NewWarnings()
old := os.Stdout // keep backup of the real stdout
os.Stdout = nil
localNames, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
localNames, remoteNames, err := query.GetPackageNamesBySource(config.Runtime.DBExecutor)
if err != nil {
return err
}
aurUp, repoUp, err := upList(warnings, alpmHandle, enableDowngrade)
aurUp, repoUp, err := upList(warnings, config.Runtime.DBExecutor, enableDowngrade)
os.Stdout = old // restoring the real stdout
if err != nil {
return err

View File

@ -5,15 +5,16 @@ import (
"sort"
"strings"
"sync"
"unicode"
alpm "github.com/Jguer/go-alpm"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/query"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
"github.com/Jguer/yay/v10/pkg/upgrade"
rpc "github.com/mikkeloscar/aur"
@ -21,112 +22,12 @@ import (
"github.com/Jguer/yay/v10/pkg/stringset"
)
// upgrade type describes a system upgrade.
type upgrade struct {
Name string
Repository string
LocalVersion string
RemoteVersion string
}
// upSlice is a slice of Upgrades
type upSlice []upgrade
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 {
if u[i].Repository == u[j].Repository {
iRunes := []rune(u[i].Name)
jRunes := []rune(u[j].Name)
return text.LessRunes(iRunes, jRunes)
}
syncDB, err := config.Runtime.AlpmHandle.SyncDBs()
if err != nil {
iRunes := []rune(u[i].Repository)
jRunes := []rune(u[j].Repository)
return text.LessRunes(iRunes, jRunes)
}
less := false
found := syncDB.ForEach(func(db alpm.DB) error {
switch db.Name() {
case u[i].Repository:
less = true
case u[j].Repository:
less = false
default:
return nil
}
return fmt.Errorf("")
})
if found != nil {
return less
}
iRunes := []rune(u[i].Repository)
jRunes := []rune(u[j].Repository)
return text.LessRunes(iRunes, jRunes)
}
func getVersionDiff(oldVersion, newVersion string) (left, right string) {
if oldVersion == newVersion {
return oldVersion + red(""), newVersion + green("")
}
diffPosition := 0
checkWords := func(str string, index int, words ...string) bool {
for _, word := range words {
wordLength := len(word)
nextIndex := index + 1
if (index < len(str)-wordLength) &&
(str[nextIndex:(nextIndex+wordLength)] == word) {
return true
}
}
return false
}
for index, char := range oldVersion {
charIsSpecial := !(unicode.IsLetter(char) || unicode.IsNumber(char))
if (index >= len(newVersion)) || (char != rune(newVersion[index])) {
if charIsSpecial {
diffPosition = index
}
break
}
if charIsSpecial ||
(((index == len(oldVersion)-1) || (index == len(newVersion)-1)) &&
((len(oldVersion) != len(newVersion)) ||
(oldVersion[index] == newVersion[index]))) ||
checkWords(oldVersion, index, "rc", "pre", "alpha", "beta") {
diffPosition = index + 1
}
}
samePart := oldVersion[0:diffPosition]
left = samePart + red(oldVersion[diffPosition:])
right = samePart + green(newVersion[diffPosition:])
return left, right
}
// upList returns lists of packages to upgrade from each source.
func upList(warnings *query.AURWarnings, alpmHandle *alpm.Handle, enableDowngrade bool) (aurUp, repoUp upSlice, err error) {
remote, remoteNames, err := query.GetRemotePackages(alpmHandle)
if err != nil {
return nil, nil, err
}
func upList(warnings *query.AURWarnings, dbExecutor *db.AlpmExecutor, enableDowngrade bool) (aurUp, repoUp upgrade.UpSlice, err error) {
remote, remoteNames := query.GetRemotePackages(dbExecutor)
var wg sync.WaitGroup
var develUp upSlice
var develUp upgrade.UpSlice
var errs multierror.MultiError
aurdata := make(map[string]*rpc.Pkg)
@ -141,7 +42,7 @@ func upList(warnings *query.AURWarnings, alpmHandle *alpm.Handle, enableDowngrad
text.OperationInfoln(gotext.Get("Searching databases for updates..."))
wg.Add(1)
go func() {
repoUp, err = upRepo(alpmHandle, enableDowngrade)
repoUp, err = dbExecutor.RepoUpgrades(enableDowngrade)
errs.Add(err)
wg.Done()
}()
@ -196,8 +97,8 @@ func upList(warnings *query.AURWarnings, alpmHandle *alpm.Handle, enableDowngrad
return aurUp, repoUp, errs.Return()
}
func upDevel(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
toUpdate := make([]alpm.Package, 0)
func upDevel(remote []db.RepoPackage, aurdata map[string]*rpc.Pkg) upgrade.UpSlice {
toUpdate := make([]db.RepoPackage, 0)
toRemove := make([]string, 0)
var mux1 sync.Mutex
@ -232,12 +133,16 @@ func upDevel(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
wg.Wait()
toUpgrade := make(upSlice, 0, len(toUpdate))
toUpgrade := make(upgrade.UpSlice, 0, len(toUpdate))
for _, pkg := range toUpdate {
if pkg.ShouldIgnore() {
printIgnoringPackage(pkg, "latest-commit")
} else {
toUpgrade = append(toUpgrade, upgrade{pkg.Name(), "devel", pkg.Version(), "latest-commit"})
toUpgrade = append(toUpgrade,
upgrade.Upgrade{Name: pkg.Name(),
Repository: "devel",
LocalVersion: pkg.Version(),
RemoteVersion: "latest-commit"})
}
}
@ -245,10 +150,19 @@ func upDevel(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
return toUpgrade
}
func printIgnoringPackage(pkg db.RepoPackage, newPkgVersion string) {
left, right := upgrade.GetVersionDiff(pkg.Version(), newPkgVersion)
text.Warnln(gotext.Get("%s: ignoring package upgrade (%s => %s)",
cyan(pkg.Name()),
left, right,
))
}
// upAUR gathers foreign packages and checks if they have new versions.
// Output: Upgrade type package list.
func upAUR(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
toUpgrade := make(upSlice, 0)
func upAUR(remote []db.RepoPackage, aurdata map[string]*rpc.Pkg) upgrade.UpSlice {
toUpgrade := make(upgrade.UpSlice, 0)
for _, pkg := range remote {
aurPkg, ok := aurdata[pkg.Name()]
@ -261,7 +175,7 @@ func upAUR(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
if pkg.ShouldIgnore() {
printIgnoringPackage(pkg, aurPkg.Version)
} else {
toUpgrade = append(toUpgrade, upgrade{aurPkg.Name, "aur", pkg.Version(), aurPkg.Version})
toUpgrade = append(toUpgrade, upgrade.Upgrade{Name: aurPkg.Name, Repository: "aur", LocalVersion: pkg.Version(), RemoteVersion: aurPkg.Version})
}
}
}
@ -269,24 +183,15 @@ func upAUR(remote []alpm.Package, aurdata map[string]*rpc.Pkg) upSlice {
return toUpgrade
}
func printIgnoringPackage(pkg alpm.Package, newPkgVersion string) {
left, right := getVersionDiff(pkg.Version(), newPkgVersion)
text.Warnln(gotext.Get("%s: ignoring package upgrade (%s => %s)",
cyan(pkg.Name()),
left, right,
))
}
func printLocalNewerThanAUR(
remote []alpm.Package, aurdata map[string]*rpc.Pkg) {
remote []db.RepoPackage, aurdata map[string]*rpc.Pkg) {
for _, pkg := range remote {
aurPkg, ok := aurdata[pkg.Name()]
if !ok {
continue
}
left, right := getVersionDiff(pkg.Version(), aurPkg.Version)
left, right := upgrade.GetVersionDiff(pkg.Version(), aurPkg.Version)
if !isDevelPackage(pkg) && alpm.VerCmp(pkg.Version(), aurPkg.Version) > 0 {
text.Warnln(gotext.Get("%s: local (%s) is newer than AUR (%s)",
@ -307,54 +212,12 @@ func isDevelName(name string) bool {
return strings.Contains(name, "-always-")
}
func isDevelPackage(pkg alpm.Package) bool {
func isDevelPackage(pkg db.RepoPackage) bool {
return isDevelName(pkg.Name()) || isDevelName(pkg.Base())
}
// upRepo gathers local packages and checks if they have new versions.
// Output: Upgrade type package list.
func upRepo(alpmHandle *alpm.Handle, enableDowngrade bool) (upSlice, error) {
slice := upSlice{}
localDB, err := alpmHandle.LocalDB()
if err != nil {
return slice, err
}
err = alpmHandle.TransInit(alpm.TransFlagNoLock)
if err != nil {
return slice, err
}
defer func() {
err = alpmHandle.TransRelease()
}()
err = alpmHandle.SyncSysupgrade(enableDowngrade)
if err != nil {
return slice, err
}
_ = alpmHandle.TransGetAdd().ForEach(func(pkg alpm.Package) error {
localVer := "-"
if localPkg := localDB.Pkg(pkg.Name()); localPkg != nil {
localVer = localPkg.Version()
}
slice = append(slice, upgrade{
pkg.Name(),
pkg.DB().Name(),
localVer,
pkg.Version(),
})
return nil
})
return slice, nil
}
// upgradePkgs handles updating the cache and installing updates.
func upgradePkgs(aurUp, repoUp upSlice) (ignore, aurNames stringset.StringSet, err error) {
func upgradePkgs(aurUp, repoUp upgrade.UpSlice) (ignore, aurNames stringset.StringSet, err error) {
ignore = make(stringset.StringSet)
aurNames = make(stringset.StringSet)
@ -375,7 +238,7 @@ func upgradePkgs(aurUp, repoUp upSlice) (ignore, aurNames stringset.StringSet, e
sort.Sort(aurUp)
allUp := append(repoUp, aurUp...)
fmt.Printf("%s"+bold(" %d ")+"%s\n", bold(cyan("::")), allUpLen, bold(gotext.Get("Packages to upgrade.")))
allUp.print()
allUp.Print()
text.Infoln(gotext.Get("Packages to exclude: (eg: \"1 2 3\", \"1-3\", \"^4\" or repo name)"))

View File

@ -1,67 +0,0 @@
package main
import (
"testing"
"github.com/Jguer/yay/v10/pkg/text"
)
func TestGetVersionDiff(t *testing.T) {
text.UseColor = true
type versionPair struct {
Old string
New string
}
in := []versionPair{
{"1-1", "1-1"},
{"1-1", "2-1"},
{"2-1", "1-1"},
{"1-1", "1-2"},
{"1-2", "1-1"},
{"1.2.3-1", "1.2.4-1"},
{"1.8rc1+6+g0f377f94-1", "1.8rc1+1+g7e949283-1"},
{"1.8rc1+6+g0f377f94-1", "1.8rc2+1+g7e949283-1"},
{"1.8rc2", "1.9rc1"},
{"2.99.917+812+g75795523-1", "2.99.917+823+gd9bf46e4-1"},
{"1.2.9-1", "1.2.10-1"},
{"1.2.10-1", "1.2.9-1"},
{"1.2-1", "1.2.1-1"},
{"1.2.1-1", "1.2-1"},
{"0.7-4", "0.7+4+gd8d8c67-1"},
{"1.0.2_r0-1", "1.0.2_r0-2"},
{"1.0.2_r0-1", "1.0.2_r1-1"},
{"1.0.2_r0-1", "1.0.3_r0-1"},
}
out := []versionPair{
{"1-1" + red(""), "1-1" + green("")},
{red("1-1"), green("2-1")},
{red("2-1"), green("1-1")},
{"1-" + red("1"), "1-" + green("2")},
{"1-" + red("2"), "1-" + green("1")},
{"1.2." + red("3-1"), "1.2." + green("4-1")},
{"1.8rc1+" + red("6+g0f377f94-1"), "1.8rc1+" + green("1+g7e949283-1")},
{"1.8" + red("rc1+6+g0f377f94-1"), "1.8" + green("rc2+1+g7e949283-1")},
{"1." + red("8rc2"), "1." + green("9rc1")},
{"2.99.917+" + red("812+g75795523-1"), "2.99.917+" + green("823+gd9bf46e4-1")},
{"1.2." + red("9-1"), "1.2." + green("10-1")},
{"1.2." + red("10-1"), "1.2." + green("9-1")},
{"1.2" + red("-1"), "1.2" + green(".1-1")},
{"1.2" + red(".1-1"), "1.2" + green("-1")},
{"0.7" + red("-4"), "0.7" + green("+4+gd8d8c67-1")},
{"1.0.2_r0-" + red("1"), "1.0.2_r0-" + green("2")},
{"1.0.2_" + red("r0-1"), "1.0.2_" + green("r1-1")},
{"1.0." + red("2_r0-1"), "1.0." + green("3_r0-1")},
}
for i, pair := range in {
o, n := getVersionDiff(pair.Old, pair.New)
if o != out[i].Old || n != out[i].New {
t.Errorf("Test %d failed for update: expected (%s => %s) got (%s => %s) %d %d %d %d",
i+1, in[i].Old, in[i].New, o, n, len(in[i].Old), len(in[i].New), len(o), len(n))
}
}
}

2
vcs.go
View File

@ -36,7 +36,7 @@ func createDevelDB(vcsFilePath string, alpmHandle *alpm.Handle) error {
var mux sync.Mutex
var wg sync.WaitGroup
_, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
_, remoteNames, err := query.GetPackageNamesBySource(config.Runtime.DBExecutor)
if err != nil {
return err
}