yay/depOrder.go
morganamilo 43feb12c85
Merge handles.Aur and depOrder.Bases
depOrder.Aur contains the order in which AUR packages are to be
installed. While depOrder.bases contains the actual package data
organized by pkgbase.

deoOrder.AUR is kind of counterintuitive, as it only contains one
package from each package base.

For example if you were to install libc++{,abi,experimental},
depOrder.Aur would only contain one of those packages, which one
actually being quite random. depOrder.Bases[pkg.Pkgbase] will then be
looked up and everything under that slice would be installed.

This means that the only real use depOrder.Aur has, is to give the
pkgbase. So to cut out the middleman, lets merge .Aur and .Bases into
a single field.

Doing this has also heped to spot som subtle bugs:

Fix subtle split package errors.

The number menus now correctly list and respect (installed) for bases
that have atleast one of their packages installed.

Entering package names in number menus now always expects the pkgbase
name instead of the random package which happened to make it into .Aur.

--rebuild and --redownload correctly handles split packages.

formatPkgbase is also used more.
2018-08-18 17:05:12 +01:00

134 lines
2.6 KiB
Go

package main
import (
alpm "github.com/jguer/go-alpm"
rpc "github.com/mikkeloscar/aur"
)
type Base []*rpc.Pkg
func (b Base) Pkgbase() string {
return b[0].PackageBase
}
func (b Base) Version() string {
return b[0].Version
}
func (b Base) URLPath() string {
return b[0].URLPath
}
type depOrder struct {
Aur []Base
Repo []*alpm.Package
Runtime stringSet
}
func makeDepOrder() *depOrder {
return &depOrder{
make([]Base, 0),
make([]*alpm.Package, 0),
make(stringSet),
}
}
func getDepOrder(dp *depPool) *depOrder {
do := makeDepOrder()
basesMap := make(map[string]Base)
for _, target := range dp.Targets {
dep := target.DepString()
aurPkg := dp.Aur[dep]
if aurPkg != nil && pkgSatisfies(aurPkg.Name, aurPkg.Version, dep) {
do.orderPkgAur(aurPkg, dp, basesMap, true)
}
aurPkg = dp.findSatisfierAur(dep)
if aurPkg != nil {
do.orderPkgAur(aurPkg, dp, basesMap, true)
}
repoPkg := dp.findSatisfierRepo(dep)
if repoPkg != nil {
do.orderPkgRepo(repoPkg, dp, true)
}
}
for _, base := range basesMap {
do.Aur = append(do.Aur, base)
}
return do
}
func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, basesMap map[string]Base, runtime bool) {
if runtime {
do.Runtime.set(pkg.Name)
}
delete(dp.Aur, pkg.Name)
for i, deps := range [3][]string{pkg.Depends, pkg.MakeDepends, pkg.CheckDepends} {
for _, dep := range deps {
aurPkg := dp.findSatisfierAur(dep)
if aurPkg != nil {
do.orderPkgAur(aurPkg, dp, basesMap, runtime && i == 0)
}
repoPkg := dp.findSatisfierRepo(dep)
if repoPkg != nil {
do.orderPkgRepo(repoPkg, dp, runtime && i == 0)
}
}
}
basesMap[pkg.PackageBase] = append(basesMap[pkg.PackageBase], pkg)
}
func (do *depOrder) orderPkgRepo(pkg *alpm.Package, dp *depPool, runtime bool) {
if runtime {
do.Runtime.set(pkg.Name())
}
delete(dp.Repo, pkg.Name())
pkg.Depends().ForEach(func(dep alpm.Depend) (err error) {
repoPkg := dp.findSatisfierRepo(dep.String())
if repoPkg != nil {
do.orderPkgRepo(repoPkg, dp, runtime)
}
return nil
})
do.Repo = append(do.Repo, pkg)
}
func (do *depOrder) HasMake() bool {
lenAur := 0
for _, base := range do.Aur {
lenAur += len(base)
}
return len(do.Runtime) != lenAur+len(do.Repo)
}
func (do *depOrder) getMake() []string {
makeOnly := make([]string, 0, len(do.Aur)+len(do.Repo)-len(do.Runtime))
for _, base := range do.Aur {
for _, pkg := range base {
if !do.Runtime.get(pkg.Name) {
makeOnly = append(makeOnly, pkg.Name)
}
}
}
for _, pkg := range do.Repo {
if !do.Runtime.get(pkg.Name()) {
makeOnly = append(makeOnly, pkg.Name())
}
}
return makeOnly
}