浏览代码

fix(alpm): transfer handle initialization to executor

jguer 4 年之前
父节点
当前提交
9fd6917bc0
共有 8 个文件被更改,包括 233 次插入78 次删除
  1. 0 9
      callbacks.go
  2. 6 6
      cmd.go
  3. 4 0
      install.go
  4. 1 2
      main.go
  5. 186 11
      pkg/db/alpm.go
  6. 3 0
      pkg/db/executor.go
  7. 12 15
      print.go
  8. 21 35
      query.go

+ 0 - 9
callbacks.go

@@ -92,12 +92,3 @@ func questionCallback(question alpm.QuestionAny) {
 		break
 	}
 }
-
-func logCallback(level alpm.LogLevel, str string) {
-	switch level {
-	case alpm.LogWarning:
-		text.Warn(str)
-	case alpm.LogError:
-		text.Error(str)
-	}
-}

+ 6 - 6
cmd.go

@@ -277,7 +277,7 @@ func handleSync(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle) error {
 		} else {
 			config.SearchMode = detailed
 		}
-		return syncSearch(targets, alpmHandle)
+		return syncSearch(targets)
 	}
 	if cmdArgs.ExistsArg("p", "print", "print-format") {
 		return show(passToPacman(cmdArgs))
@@ -331,7 +331,7 @@ func displayNumberMenu(pkgS []string, alpmHandle *alpm.Handle, cmdArgs *settings
 		lenaq = len(aq)
 	}
 	if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-		pq, repoErr = queryRepo(pkgS, alpmHandle)
+		pq = queryRepo(pkgS, config.Runtime.DBExecutor)
 		lenpq = len(pq)
 		if repoErr != nil {
 			return repoErr
@@ -345,17 +345,17 @@ func displayNumberMenu(pkgS []string, alpmHandle *alpm.Handle, cmdArgs *settings
 	switch config.SortMode {
 	case settings.TopDown:
 		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-			pq.printSearch(alpmHandle)
+			pq.printSearch(config.Runtime.DBExecutor)
 		}
 		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
-			aq.printSearch(lenpq+1, alpmHandle)
+			aq.printSearch(lenpq+1, config.Runtime.DBExecutor)
 		}
 	case settings.BottomUp:
 		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
-			aq.printSearch(lenpq+1, alpmHandle)
+			aq.printSearch(lenpq+1, config.Runtime.DBExecutor)
 		}
 		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-			pq.printSearch(alpmHandle)
+			pq.printSearch(config.Runtime.DBExecutor)
 		}
 	default:
 		return fmt.Errorf(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))

+ 4 - 0
install.go

@@ -94,6 +94,10 @@ func install(cmdArgs *settings.Arguments, alpmHandle *alpm.Handle, ignoreProvide
 		return err
 	}
 	config.Runtime.AlpmHandle = alpmHandle
+	err = config.Runtime.DBExecutor.RefreshHandle()
+	if err != nil {
+		return err
+	}
 
 	localNames, remoteNames, err := query.GetPackageNamesBySource(alpmHandle)
 	if err != nil {

+ 1 - 2
main.go

@@ -145,7 +145,6 @@ func initAlpmHandle(pacmanConf *pacmanconf.Config, oldAlpmHandle *alpm.Handle) (
 	}
 
 	alpmHandle.SetQuestionCallback(questionCallback)
-	alpmHandle.SetLogCallback(logCallback)
 	return alpmHandle, nil
 }
 
@@ -194,7 +193,7 @@ func main() {
 	exitOnError(initVCS(runtime.VCSPath))
 	config.Runtime.AlpmHandle, config.Runtime.PacmanConf, err = initAlpm(cmdArgs, config.PacmanConf)
 	exitOnError(err)
-	config.Runtime.DBExecutor, err = db.NewExecutor(config.Runtime.AlpmHandle)
+	config.Runtime.DBExecutor, err = db.NewAlpmExecutor(config.Runtime.AlpmHandle, runtime.PacmanConf, questionCallback)
 	exitOnError(err)
 	exitOnError(handleCmd(cmdArgs, config.Runtime.AlpmHandle))
 	os.Exit(cleanup(config.Runtime.AlpmHandle))

+ 186 - 11
pkg/db/alpm.go

@@ -1,16 +1,26 @@
 package db
 
 import (
+	"errors"
+
 	alpm "github.com/Jguer/go-alpm"
+	"github.com/Morganamilo/go-pacmanconf"
+	"github.com/leonelquinteros/gotext"
+
+	"github.com/Jguer/yay/v10/pkg/text"
 )
 
 type AlpmExecutor struct {
-	Handle  *alpm.Handle
-	LocalDB *alpm.DB
-	SyncDB  alpm.DBList
+	handle           *alpm.Handle
+	localDB          *alpm.DB
+	syncDB           alpm.DBList
+	conf             *pacmanconf.Config
+	questionCallback func(question alpm.QuestionAny)
 }
 
-func NewExecutor(handle *alpm.Handle) (*AlpmExecutor, error) {
+func NewAlpmExecutor(handle *alpm.Handle,
+	pacamnConf *pacmanconf.Config,
+	questionCallback func(question alpm.QuestionAny)) (*AlpmExecutor, error) {
 	localDB, err := handle.LocalDB()
 	if err != nil {
 		return nil, err
@@ -20,18 +30,154 @@ func NewExecutor(handle *alpm.Handle) (*AlpmExecutor, error) {
 		return nil, err
 	}
 
-	return &AlpmExecutor{Handle: handle, LocalDB: localDB, SyncDB: syncDB}, nil
+	return &AlpmExecutor{handle: handle, localDB: localDB, syncDB: syncDB, conf: pacamnConf, questionCallback: questionCallback}, nil
+}
+
+func toUsage(usages []string) alpm.Usage {
+	if len(usages) == 0 {
+		return alpm.UsageAll
+	}
+
+	var ret alpm.Usage
+	for _, usage := range usages {
+		switch usage {
+		case "Sync":
+			ret |= alpm.UsageSync
+		case "Search":
+			ret |= alpm.UsageSearch
+		case "Install":
+			ret |= alpm.UsageInstall
+		case "Upgrade":
+			ret |= alpm.UsageUpgrade
+		case "All":
+			ret |= alpm.UsageAll
+		}
+	}
+
+	return ret
+}
+
+func configureAlpm(pacmanConf *pacmanconf.Config, alpmHandle *alpm.Handle) error {
+	// TODO: set SigLevel
+	// sigLevel := alpm.SigPackage | alpm.SigPackageOptional | alpm.SigDatabase | alpm.SigDatabaseOptional
+	// localFileSigLevel := alpm.SigUseDefault
+	// remoteFileSigLevel := alpm.SigUseDefault
+
+	for _, repo := range pacmanConf.Repos {
+		// TODO: set SigLevel
+		db, err := alpmHandle.RegisterSyncDB(repo.Name, 0)
+		if err != nil {
+			return err
+		}
+
+		db.SetServers(repo.Servers)
+		db.SetUsage(toUsage(repo.Usage))
+	}
+
+	if err := alpmHandle.SetCacheDirs(pacmanConf.CacheDir); err != nil {
+		return err
+	}
+
+	// add hook directories 1-by-1 to avoid overwriting the system directory
+	for _, dir := range pacmanConf.HookDir {
+		if err := alpmHandle.AddHookDir(dir); err != nil {
+			return err
+		}
+	}
+
+	if err := alpmHandle.SetGPGDir(pacmanConf.GPGDir); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetLogFile(pacmanConf.LogFile); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetIgnorePkgs(pacmanConf.IgnorePkg); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetIgnoreGroups(pacmanConf.IgnoreGroup); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetArch(pacmanConf.Architecture); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetNoUpgrades(pacmanConf.NoUpgrade); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetNoExtracts(pacmanConf.NoExtract); err != nil {
+		return err
+	}
+
+	/*if err := alpmHandle.SetDefaultSigLevel(sigLevel); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetLocalFileSigLevel(localFileSigLevel); err != nil {
+		return err
+	}
+
+	if err := alpmHandle.SetRemoteFileSigLevel(remoteFileSigLevel); err != nil {
+		return err
+	}*/
+
+	if err := alpmHandle.SetUseSyslog(pacmanConf.UseSyslog); err != nil {
+		return err
+	}
+
+	return alpmHandle.SetCheckSpace(pacmanConf.CheckSpace)
+}
+
+func logCallback(level alpm.LogLevel, str string) {
+	switch level {
+	case alpm.LogWarning:
+		text.Warn(str)
+	case alpm.LogError:
+		text.Error(str)
+	}
+}
+
+func (ae *AlpmExecutor) RefreshHandle() error {
+	if ae.handle != nil {
+		if errRelease := ae.handle.Release(); errRelease != nil {
+			return errRelease
+		}
+	}
+
+	alpmHandle, err := alpm.Initialize(ae.conf.RootDir, ae.conf.DBPath)
+	if err != nil {
+		return errors.New(gotext.Get("unable to CreateHandle: %s", err))
+	}
+
+	if errConf := configureAlpm(ae.conf, alpmHandle); errConf != nil {
+		return errConf
+	}
+
+	alpmHandle.SetQuestionCallback(ae.questionCallback)
+	alpmHandle.SetLogCallback(logCallback)
+	ae.handle = alpmHandle
+	ae.syncDB, err = alpmHandle.SyncDBs()
+	if err != nil {
+		return err
+	}
+
+	ae.localDB, err = alpmHandle.LocalDB()
+	return err
 }
 
 func (ae *AlpmExecutor) LocalSatisfierExists(pkgName string) bool {
-	if _, err := ae.LocalDB.PkgCache().FindSatisfier(pkgName); err != nil {
+	if _, err := ae.localDB.PkgCache().FindSatisfier(pkgName); err != nil {
 		return false
 	}
 	return true
 }
 
 func (ae *AlpmExecutor) IsCorrectVersionInstalled(pkgName, versionRequired string) bool {
-	alpmPackage := ae.LocalDB.Pkg(pkgName)
+	alpmPackage := ae.localDB.Pkg(pkgName)
 	if alpmPackage == nil {
 		return false
 	}
@@ -40,7 +186,7 @@ func (ae *AlpmExecutor) IsCorrectVersionInstalled(pkgName, versionRequired strin
 }
 
 func (ae *AlpmExecutor) SyncSatisfier(pkgName string) RepoPackage {
-	foundPkg, err := ae.SyncDB.FindSatisfier(pkgName)
+	foundPkg, err := ae.syncDB.FindSatisfier(pkgName)
 	if err != nil {
 		return nil
 	}
@@ -49,7 +195,7 @@ func (ae *AlpmExecutor) SyncSatisfier(pkgName string) RepoPackage {
 
 func (ae *AlpmExecutor) PackagesFromGroup(groupName string) []RepoPackage {
 	groupPackages := []RepoPackage{}
-	_ = ae.SyncDB.FindGroupPkgs(groupName).ForEach(func(pkg alpm.Package) error {
+	_ = ae.syncDB.FindGroupPkgs(groupName).ForEach(func(pkg alpm.Package) error {
 		groupPackages = append(groupPackages, &pkg)
 		return nil
 	})
@@ -58,15 +204,39 @@ func (ae *AlpmExecutor) PackagesFromGroup(groupName string) []RepoPackage {
 
 func (ae *AlpmExecutor) LocalPackages() []RepoPackage {
 	localPackages := []RepoPackage{}
-	_ = ae.LocalDB.PkgCache().ForEach(func(pkg alpm.Package) error {
+	_ = ae.localDB.PkgCache().ForEach(func(pkg alpm.Package) error {
 		localPackages = append(localPackages, RepoPackage(&pkg))
 		return nil
 	})
 	return localPackages
 }
 
+// SyncPackages searches SyncDB for packages or returns all packages if no search param is given
+func (ae *AlpmExecutor) SyncPackages(pkgNames ...string) []RepoPackage {
+	repoPackages := []RepoPackage{}
+	_ = ae.syncDB.ForEach(func(db alpm.DB) error {
+		if len(pkgNames) == 0 {
+			_ = db.PkgCache().ForEach(func(pkg alpm.Package) error {
+				repoPackages = append(repoPackages, RepoPackage(&pkg))
+				return nil
+			})
+		} else {
+			_ = db.Search(pkgNames).ForEach(func(pkg alpm.Package) error {
+				repoPackages = append(repoPackages, RepoPackage(&pkg))
+				return nil
+			})
+		}
+		return nil
+	})
+	return repoPackages
+}
+
+func (ae *AlpmExecutor) LocalPackage(pkgName string) RepoPackage {
+	return ae.localDB.Pkg(pkgName)
+}
+
 func (ae *AlpmExecutor) PackageFromDB(pkgName, dbName string) RepoPackage {
-	singleDB, err := ae.Handle.SyncDBByName(dbName)
+	singleDB, err := ae.handle.SyncDBByName(dbName)
 	if err != nil {
 		return nil
 	}
@@ -91,3 +261,8 @@ func (ae *AlpmExecutor) PackageConflicts(pkg RepoPackage) []alpm.Depend {
 	alpmPackage := pkg.(*alpm.Package)
 	return alpmPackage.Conflicts().Slice()
 }
+
+func (ae *AlpmExecutor) PackageGroups(pkg RepoPackage) []string {
+	alpmPackage := pkg.(*alpm.Package)
+	return alpmPackage.Groups().Slice()
+}

+ 3 - 0
pkg/db/executor.go

@@ -7,4 +7,7 @@ type RepoPackage interface {
 	Name() string
 	Version() string
 	DB() *alpm.DB
+	ISize() int64
+	Size() int64
+	Description() string
 }

+ 12 - 15
print.go

@@ -11,6 +11,7 @@ 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"
@@ -19,9 +20,7 @@ import (
 )
 
 // PrintSearch handles printing search results in a given format
-func (q aurQuery) printSearch(start int, alpmHandle *alpm.Handle) {
-	localDB, _ := alpmHandle.LocalDB()
-
+func (q aurQuery) printSearch(start int, dbExecutor *db.AlpmExecutor) {
 	for i := range q {
 		var toprint string
 		if config.SearchMode == numberMenu {
@@ -51,7 +50,7 @@ func (q aurQuery) printSearch(start int, alpmHandle *alpm.Handle) {
 			toprint += bold(red(gotext.Get("(Out-of-date: %s)", text.FormatTime(q[i].OutOfDate)))) + " "
 		}
 
-		if pkg := localDB.Pkg(q[i].Name); pkg != nil {
+		if pkg := dbExecutor.LocalPackage(q[i].Name); pkg != nil {
 			if pkg.Version() != q[i].Version {
 				toprint += bold(green(gotext.Get("(Installed: %s)", pkg.Version())))
 			} else {
@@ -64,7 +63,7 @@ func (q aurQuery) printSearch(start int, alpmHandle *alpm.Handle) {
 }
 
 // PrintSearch receives a RepoSearch type and outputs pretty text.
-func (s repoQuery) printSearch(alpmHandle *alpm.Handle) {
+func (s repoQuery) printSearch(dbExecutor *db.AlpmExecutor) {
 	for i, res := range s {
 		var toprint string
 		if config.SearchMode == numberMenu {
@@ -86,18 +85,16 @@ func (s repoQuery) printSearch(alpmHandle *alpm.Handle) {
 			bold(" ("+text.Human(res.Size())+
 				" "+text.Human(res.ISize())+") ")
 
-		if len(res.Groups().Slice()) != 0 {
-			toprint += fmt.Sprint(res.Groups().Slice(), " ")
+		packageGroups := dbExecutor.PackageGroups(res)
+		if len(packageGroups) != 0 {
+			toprint += fmt.Sprint(packageGroups, " ")
 		}
 
-		localDB, err := alpmHandle.LocalDB()
-		if err == nil {
-			if pkg := localDB.Pkg(res.Name()); pkg != nil {
-				if pkg.Version() != res.Version() {
-					toprint += bold(green(gotext.Get("(Installed: %s)", pkg.Version())))
-				} else {
-					toprint += bold(green(gotext.Get("(Installed)")))
-				}
+		if pkg := dbExecutor.LocalPackage(res.Name()); pkg != nil {
+			if pkg.Version() != res.Version() {
+				toprint += bold(green(gotext.Get("(Installed: %s)", pkg.Version())))
+			} else {
+				toprint += bold(green(gotext.Get("(Installed)")))
 			}
 		}
 

+ 21 - 35
query.go

@@ -11,6 +11,7 @@ import (
 	"github.com/leonelquinteros/gotext"
 	rpc "github.com/mikkeloscar/aur"
 
+	"github.com/Jguer/yay/v10/pkg/db"
 	"github.com/Jguer/yay/v10/pkg/query"
 	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
@@ -21,7 +22,13 @@ import (
 type aurQuery []rpc.Pkg
 
 // Query holds the results of a repository search.
-type repoQuery []alpm.Package
+type repoQuery []db.RepoPackage
+
+func (s repoQuery) Reverse() {
+	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+		s[i], s[j] = s[j], s[i]
+	}
+}
 
 func (q aurQuery) Len() int {
 	return len(q)
@@ -140,10 +147,9 @@ func narrowSearch(pkgS []string, sortS bool) (aurQuery, error) {
 }
 
 // SyncSearch presents a query to the local repos and to the AUR.
-func syncSearch(pkgS []string, alpmHandle *alpm.Handle) (err error) {
+func syncSearch(pkgS []string) (err error) {
 	pkgS = query.RemoveInvalidTargets(pkgS, config.Runtime.Mode)
 	var aurErr error
-	var repoErr error
 	var aq aurQuery
 	var pq repoQuery
 
@@ -151,26 +157,23 @@ func syncSearch(pkgS []string, alpmHandle *alpm.Handle) (err error) {
 		aq, aurErr = narrowSearch(pkgS, true)
 	}
 	if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-		pq, repoErr = queryRepo(pkgS, alpmHandle)
-		if repoErr != nil {
-			return err
-		}
+		pq = queryRepo(pkgS, config.Runtime.DBExecutor)
 	}
 
 	switch config.SortMode {
 	case settings.TopDown:
 		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-			pq.printSearch(alpmHandle)
+			pq.printSearch(config.Runtime.DBExecutor)
 		}
 		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
-			aq.printSearch(1, alpmHandle)
+			aq.printSearch(1, config.Runtime.DBExecutor)
 		}
 	case settings.BottomUp:
 		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
-			aq.printSearch(1, alpmHandle)
+			aq.printSearch(1, config.Runtime.DBExecutor)
 		}
 		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
-			pq.printSearch(alpmHandle)
+			pq.printSearch(config.Runtime.DBExecutor)
 		}
 	default:
 		return errors.New(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
@@ -239,30 +242,13 @@ func syncInfo(cmdArgs *settings.Arguments, pkgS []string, alpmHandle *alpm.Handl
 }
 
 // Search handles repo searches. Creates a RepoSearch struct.
-func queryRepo(pkgInputN []string, alpmHandle *alpm.Handle) (s repoQuery, err error) {
-	dbList, err := alpmHandle.SyncDBs()
-	if err != nil {
-		return
-	}
-
-	_ = dbList.ForEach(func(db alpm.DB) error {
-		if len(pkgInputN) == 0 {
-			pkgs := db.PkgCache()
-			s = append(s, pkgs.Slice()...)
-		} else {
-			pkgs := db.Search(pkgInputN)
-			s = append(s, pkgs.Slice()...)
-		}
-		return nil
-	})
+func queryRepo(pkgInputN []string, dbExecutor *db.AlpmExecutor) repoQuery {
+	s := repoQuery(dbExecutor.SyncPackages(pkgInputN...))
 
 	if config.SortMode == settings.BottomUp {
-		for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
-			s[i], s[j] = s[j], s[i]
-		}
+		s.Reverse()
 	}
-
-	return
+	return s
 }
 
 // PackageSlices separates an input slice into aur and repo slices
@@ -273,13 +259,13 @@ func packageSlices(toCheck []string, alpmHandle *alpm.Handle) (aur, repo []strin
 	}
 
 	for _, _pkg := range toCheck {
-		db, name := text.SplitDBFromName(_pkg)
+		dbName, name := text.SplitDBFromName(_pkg)
 		found := false
 
-		if db == "aur" || config.Runtime.Mode == settings.ModeAUR {
+		if dbName == "aur" || config.Runtime.Mode == settings.ModeAUR {
 			aur = append(aur, _pkg)
 			continue
-		} else if db != "" || config.Runtime.Mode == settings.ModeRepo {
+		} else if dbName != "" || config.Runtime.Mode == settings.ModeRepo {
 			repo = append(repo, _pkg)
 			continue
 		}