Merge pull request #637 from Morganamilo/refactorinstall2

Refactor install
This commit is contained in:
Anna 2018-08-18 17:08:34 +01:00 committed by GitHub
commit a37bbd851e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 230 additions and 214 deletions

16
dep.go
View file

@ -149,15 +149,15 @@ func splitDbFromName(pkg string) (string, string) {
return "", split[0]
}
func getBases(pkgs map[string]*rpc.Pkg) map[string][]*rpc.Pkg {
bases := make(map[string][]*rpc.Pkg)
func getBases(pkgs []*rpc.Pkg) []Base {
basesMap := make(map[string]Base)
for _, pkg := range pkgs {
_, ok := bases[pkg.PackageBase]
if !ok {
bases[pkg.PackageBase] = make([]*rpc.Pkg, 0)
}
bases[pkg.PackageBase] = append(bases[pkg.PackageBase], pkg)
basesMap[pkg.PackageBase] = append(basesMap[pkg.PackageBase], pkg)
}
bases := make([]Base, 0, len(basesMap))
for _, base := range basesMap {
bases = append(bases, base)
}
return bases

View file

@ -5,35 +5,48 @@ import (
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 []*rpc.Pkg
Aur []Base
Repo []*alpm.Package
Runtime stringSet
Bases map[string][]*rpc.Pkg
}
func makeDepOrder() *depOrder {
return &depOrder{
make([]*rpc.Pkg, 0),
make([]Base, 0),
make([]*alpm.Package, 0),
make(stringSet),
make(map[string][]*rpc.Pkg),
}
}
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, true)
do.orderPkgAur(aurPkg, dp, basesMap, true)
}
aurPkg = dp.findSatisfierAur(dep)
if aurPkg != nil {
do.orderPkgAur(aurPkg, dp, true)
do.orderPkgAur(aurPkg, dp, basesMap, true)
}
repoPkg := dp.findSatisfierRepo(dep)
@ -42,10 +55,14 @@ func getDepOrder(dp *depPool) *depOrder {
}
}
for _, base := range basesMap {
do.Aur = append(do.Aur, base)
}
return do
}
func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, runtime bool) {
func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, basesMap map[string]Base, runtime bool) {
if runtime {
do.Runtime.set(pkg.Name)
}
@ -55,7 +72,7 @@ func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, runtime bool) {
for _, dep := range deps {
aurPkg := dp.findSatisfierAur(dep)
if aurPkg != nil {
do.orderPkgAur(aurPkg, dp, runtime && i == 0)
do.orderPkgAur(aurPkg, dp, basesMap, runtime && i == 0)
}
repoPkg := dp.findSatisfierRepo(dep)
@ -65,11 +82,7 @@ func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, runtime bool) {
}
}
if _, ok := do.Bases[pkg.PackageBase]; !ok {
do.Aur = append(do.Aur, pkg)
do.Bases[pkg.PackageBase] = make([]*rpc.Pkg, 0)
}
do.Bases[pkg.PackageBase] = append(do.Bases[pkg.PackageBase], pkg)
basesMap[pkg.PackageBase] = append(basesMap[pkg.PackageBase], pkg)
}
func (do *depOrder) orderPkgRepo(pkg *alpm.Package, dp *depPool, runtime bool) {
@ -92,7 +105,7 @@ func (do *depOrder) orderPkgRepo(pkg *alpm.Package, dp *depPool, runtime bool) {
func (do *depOrder) HasMake() bool {
lenAur := 0
for _, base := range do.Bases {
for _, base := range do.Aur {
lenAur += len(base)
}
@ -102,7 +115,7 @@ func (do *depOrder) HasMake() bool {
func (do *depOrder) getMake() []string {
makeOnly := make([]string, 0, len(do.Aur)+len(do.Repo)-len(do.Runtime))
for _, base := range do.Bases {
for _, base := range do.Aur {
for _, pkg := range base {
if !do.Runtime.get(pkg.Name) {
makeOnly = append(makeOnly, pkg.Name)

View file

@ -11,7 +11,6 @@ import (
gosrc "github.com/Morganamilo/go-srcinfo"
alpm "github.com/jguer/go-alpm"
rpc "github.com/mikkeloscar/aur"
)
// Install handles package installs
@ -23,10 +22,10 @@ func install(parser *arguments) error {
var aurUp upSlice
var repoUp upSlice
warnings := &aurWarnings{}
var srcinfos map[string]*gosrc.Srcinfo
warnings := &aurWarnings{}
removeMake := false
srcinfosStale := make(map[string]*gosrc.Srcinfo)
if mode == ModeAny || mode == ModeRepo {
if config.CombinedUpgrade {
@ -94,7 +93,7 @@ func install(parser *arguments) error {
}
for up := range aurUp {
requestTargets = append(requestTargets, "aur/" + up)
requestTargets = append(requestTargets, "aur/"+up)
parser.addTarget("aur/" + up)
}
@ -176,7 +175,7 @@ func install(parser *arguments) error {
}
if config.CleanMenu {
askClean := pkgbuildNumberMenu(do.Aur, do.Bases, remoteNamesCache)
askClean := pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toClean, err := cleanNumberMenu(do.Aur, remoteNamesCache, askClean)
if err != nil {
return err
@ -185,24 +184,24 @@ func install(parser *arguments) error {
cleanBuilds(toClean)
}
toSkip := pkgBuildsToSkip(do.Aur, targets)
cloned, err := downloadPkgBuilds(do.Aur, do.Bases, toSkip)
toSkip := pkgbuildsToSkip(do.Aur, targets)
cloned, err := downloadPkgbuilds(do.Aur, toSkip)
if err != nil {
return err
}
var toDiff []*rpc.Pkg
var toEdit []*rpc.Pkg
var toDiff []Base
var toEdit []Base
if config.DiffMenu {
pkgbuildNumberMenu(do.Aur, do.Bases, remoteNamesCache)
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toDiff, err = diffNumberMenu(do.Aur, remoteNamesCache)
if err != nil {
return err
}
if len(toDiff) > 0 {
err = showPkgBuildDiffs(toDiff, do.Bases, cloned)
err = showPkgbuildDiffs(toDiff, cloned)
if err != nil {
return err
}
@ -219,26 +218,25 @@ func install(parser *arguments) error {
config.NoConfirm = oldValue
}
err = mergePkgBuilds(do.Aur)
err = mergePkgbuilds(do.Aur)
if err != nil {
return err
}
//initial srcinfo parse before pkgver() bump
err = parseSRCINFOFiles(do.Aur, srcinfosStale, do.Bases)
srcinfos, err = parseSrcinfoFiles(do.Aur, true)
if err != nil {
return err
}
if config.EditMenu {
pkgbuildNumberMenu(do.Aur, do.Bases, remoteNamesCache)
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toEdit, err = editNumberMenu(do.Aur, remoteNamesCache)
if err != nil {
return err
}
if len(toEdit) > 0 {
err = editPkgBuilds(toEdit, srcinfosStale)
err = editPkgbuilds(toEdit, srcinfos)
if err != nil {
return err
}
@ -255,13 +253,13 @@ func install(parser *arguments) error {
config.NoConfirm = oldValue
}
incompatible, err = getIncompatible(do.Aur, srcinfosStale)
incompatible, err = getIncompatible(do.Aur, srcinfos)
if err != nil {
return err
}
if config.PGPFetch {
err = checkPgpKeys(do.Aur, do.Bases, srcinfosStale)
err = checkPgpKeys(do.Aur, srcinfos)
if err != nil {
return err
}
@ -312,12 +310,12 @@ func install(parser *arguments) error {
go updateCompletion(false)
err = downloadPkgBuildsSources(do.Aur, do.Bases, incompatible)
err = downloadPkgbuildsSources(do.Aur, incompatible)
if err != nil {
return err
}
err = buildInstallPkgBuilds(dp, do, srcinfosStale, parser, incompatible, conflicts)
err = buildInstallPkgbuilds(dp, do, srcinfos, parser, incompatible, conflicts)
if err != nil {
return err
}
@ -341,7 +339,7 @@ func install(parser *arguments) error {
}
if config.CleanAfter {
clean(do.Aur)
cleanBuilds(do.Aur)
}
return nil
@ -416,29 +414,31 @@ func earlyRefresh(parser *arguments) error {
return show(passToPacman(arguments))
}
func getIncompatible(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo) (stringSet, error) {
func getIncompatible(bases []Base, srcinfos map[string]*gosrc.Srcinfo) (stringSet, error) {
incompatible := make(stringSet)
basesMap := make(map[string]Base)
alpmArch, err := alpmHandle.Arch()
if err != nil {
return nil, err
}
nextpkg:
for _, pkg := range pkgs {
for _, arch := range srcinfos[pkg.PackageBase].Arch {
for _, base := range bases {
for _, arch := range srcinfos[base.Pkgbase()].Arch {
if arch == "any" || arch == alpmArch {
continue nextpkg
}
}
incompatible.set(pkg.PackageBase)
incompatible.set(base.Pkgbase())
basesMap[base.Pkgbase()] = base
}
if len(incompatible) > 0 {
fmt.Println()
fmt.Print(bold(yellow(arrow)) + " The following packages are not compatible with your architecture:")
for pkg := range incompatible {
fmt.Print(" " + cyan(pkg))
fmt.Print(" " + cyan((basesMap[pkg].String())))
}
fmt.Println()
@ -485,16 +485,23 @@ func parsePackageList(dir string) (map[string]string, string, error) {
return pkgdests, version, nil
}
func pkgbuildNumberMenu(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, installed stringSet) bool {
func pkgbuildNumberMenu(bases []Base, installed stringSet) bool {
toPrint := ""
askClean := false
for n, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
for n, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
toPrint += fmt.Sprintf(magenta("%3d")+" %-40s", len(pkgs)-n,
bold(formatPkgbase(pkg, bases)))
if installed.get(pkg.Name) {
toPrint += fmt.Sprintf(magenta("%3d")+" %-40s", len(bases)-n,
bold(base.String()))
anyInstalled := false
for _, b := range base {
anyInstalled = anyInstalled || installed.get(b.Name)
}
if anyInstalled {
toPrint += bold(green(" (Installed)"))
}
@ -511,8 +518,8 @@ func pkgbuildNumberMenu(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, installed
return askClean
}
func cleanNumberMenu(pkgs []*rpc.Pkg, installed stringSet, hasClean bool) ([]*rpc.Pkg, error) {
toClean := make([]*rpc.Pkg, 0)
func cleanNumberMenu(bases []Base, installed stringSet, hasClean bool) ([]Base, error) {
toClean := make([]Base, 0)
if !hasClean {
return toClean, nil
@ -534,38 +541,44 @@ func cleanNumberMenu(pkgs []*rpc.Pkg, installed stringSet, hasClean bool) ([]*rp
}
if !cOtherInclude.get("n") && !cOtherInclude.get("none") {
for i, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
for i, base := range bases {
pkg := base.Pkgbase()
anyInstalled := false
for _, b := range base {
anyInstalled = anyInstalled || installed.get(b.Name)
}
dir := filepath.Join(config.BuildDir, pkg)
if _, err := os.Stat(dir); os.IsNotExist(err) {
continue
}
if !cIsInclude && cExclude.get(len(pkgs)-i) {
if !cIsInclude && cExclude.get(len(bases)-i) {
continue
}
if installed.get(pkg.Name) && (cOtherInclude.get("i") || cOtherInclude.get("installed")) {
toClean = append(toClean, pkg)
if anyInstalled && (cOtherInclude.get("i") || cOtherInclude.get("installed")) {
toClean = append(toClean, base)
continue
}
if !installed.get(pkg.Name) && (cOtherInclude.get("no") || cOtherInclude.get("notinstalled")) {
toClean = append(toClean, pkg)
if !anyInstalled && (cOtherInclude.get("no") || cOtherInclude.get("notinstalled")) {
toClean = append(toClean, base)
continue
}
if cOtherInclude.get("a") || cOtherInclude.get("all") {
toClean = append(toClean, pkg)
toClean = append(toClean, base)
continue
}
if cIsInclude && (cInclude.get(len(pkgs)-i) || cOtherInclude.get(pkg.PackageBase)) {
toClean = append(toClean, pkg)
if cIsInclude && (cInclude.get(len(bases)-i) || cOtherInclude.get(pkg)) {
toClean = append(toClean, base)
continue
}
if !cIsInclude && (!cExclude.get(len(pkgs)-i) && !cOtherExclude.get(pkg.PackageBase)) {
toClean = append(toClean, pkg)
if !cIsInclude && (!cExclude.get(len(bases)-i) && !cOtherExclude.get(pkg)) {
toClean = append(toClean, base)
continue
}
}
@ -574,16 +587,16 @@ func cleanNumberMenu(pkgs []*rpc.Pkg, installed stringSet, hasClean bool) ([]*rp
return toClean, nil
}
func editNumberMenu(pkgs []*rpc.Pkg, installed stringSet) ([]*rpc.Pkg, error) {
return editDiffNumberMenu(pkgs, installed, false)
func editNumberMenu(bases []Base, installed stringSet) ([]Base, error) {
return editDiffNumberMenu(bases, installed, false)
}
func diffNumberMenu(pkgs []*rpc.Pkg, installed stringSet) ([]*rpc.Pkg, error) {
return editDiffNumberMenu(pkgs, installed, true)
func diffNumberMenu(bases []Base, installed stringSet) ([]Base, error) {
return editDiffNumberMenu(bases, installed, true)
}
func editDiffNumberMenu(pkgs []*rpc.Pkg, installed stringSet, diff bool) ([]*rpc.Pkg, error) {
toEdit := make([]*rpc.Pkg, 0)
func editDiffNumberMenu(bases []Base, installed stringSet, diff bool) ([]Base, error) {
toEdit := make([]Base, 0)
var editInput string
var err error
@ -613,32 +626,38 @@ func editDiffNumberMenu(pkgs []*rpc.Pkg, installed stringSet, diff bool) ([]*rpc
}
if !eOtherInclude.get("n") && !eOtherInclude.get("none") {
for i, pkg := range pkgs {
if !eIsInclude && eExclude.get(len(pkgs)-i) {
for i, base := range bases {
pkg := base.Pkgbase()
anyInstalled := false
for _, b := range base {
anyInstalled = anyInstalled || installed.get(b.Name)
}
if !eIsInclude && eExclude.get(len(bases)-i) {
continue
}
if installed.get(pkg.Name) && (eOtherInclude.get("i") || eOtherInclude.get("installed")) {
toEdit = append(toEdit, pkg)
if anyInstalled && (eOtherInclude.get("i") || eOtherInclude.get("installed")) {
toEdit = append(toEdit, base)
continue
}
if !installed.get(pkg.Name) && (eOtherInclude.get("no") || eOtherInclude.get("notinstalled")) {
toEdit = append(toEdit, pkg)
if !anyInstalled && (eOtherInclude.get("no") || eOtherInclude.get("notinstalled")) {
toEdit = append(toEdit, base)
continue
}
if eOtherInclude.get("a") || eOtherInclude.get("all") {
toEdit = append(toEdit, pkg)
toEdit = append(toEdit, base)
continue
}
if eIsInclude && (eInclude.get(len(pkgs)-i) || eOtherInclude.get(pkg.PackageBase)) {
toEdit = append(toEdit, pkg)
if eIsInclude && (eInclude.get(len(bases)-i) || eOtherInclude.get(pkg)) {
toEdit = append(toEdit, base)
}
if !eIsInclude && (!eExclude.get(len(pkgs)-i) && !eOtherExclude.get(pkg.PackageBase)) {
toEdit = append(toEdit, pkg)
if !eIsInclude && (!eExclude.get(len(bases)-i) && !eOtherExclude.get(pkg)) {
toEdit = append(toEdit, base)
}
}
}
@ -646,30 +665,31 @@ func editDiffNumberMenu(pkgs []*rpc.Pkg, installed stringSet, diff bool) ([]*rpc
return toEdit, nil
}
func cleanBuilds(pkgs []*rpc.Pkg) {
for i, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
fmt.Printf(bold(cyan("::")+" Deleting (%d/%d): %s\n"), i+1, len(pkgs), cyan(dir))
func cleanBuilds(bases []Base) {
for i, base := range bases {
dir := filepath.Join(config.BuildDir, base.Pkgbase())
fmt.Printf(bold(cyan("::")+" Deleting (%d/%d): %s\n"), i+1, len(bases), cyan(dir))
os.RemoveAll(dir)
}
}
func showPkgBuildDiffs(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, cloned stringSet) error {
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
func showPkgbuildDiffs(bases []Base, cloned stringSet) error {
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
if shouldUseGit(dir) {
start := "HEAD"
if cloned.get(pkg.PackageBase) {
if cloned.get(pkg) {
start = gitEmptyTree
} else {
hasDiff, err := gitHasDiff(config.BuildDir, pkg.PackageBase)
hasDiff, err := gitHasDiff(config.BuildDir, pkg)
if err != nil {
return err
}
if !hasDiff {
fmt.Printf("%s %s: %s\n", bold(yellow(arrow)), cyan(formatPkgbase(pkg, bases)), bold("No changes -- skipping"))
fmt.Printf("%s %s: %s\n", bold(yellow(arrow)), cyan(base.String()), bold("No changes -- skipping"))
continue
}
}
@ -700,13 +720,14 @@ func showPkgBuildDiffs(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, cloned stri
return nil
}
func editPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo) error {
pkgbuilds := make([]string, 0, len(pkgs))
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
func editPkgbuilds(bases []Base, srcinfos map[string]*gosrc.Srcinfo) error {
pkgbuilds := make([]string, 0, len(bases))
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
pkgbuilds = append(pkgbuilds, filepath.Join(dir, "PKGBUILD"))
for _, splitPkg := range srcinfos[pkg.PackageBase].SplitPackages() {
for _, splitPkg := range srcinfos[pkg].SplitPackages() {
if splitPkg.Install != "" {
pkgbuilds = append(pkgbuilds, filepath.Join(dir, splitPkg.Install))
}
@ -727,52 +748,46 @@ func editPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo) error {
return nil
}
func parseSRCINFOFiles(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo, bases map[string][]*rpc.Pkg) error {
for k, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
func parseSrcinfoFiles(bases []Base, errIsFatal bool) (map[string]*gosrc.Srcinfo, error) {
srcinfos := make(map[string]*gosrc.Srcinfo)
for k, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
fmt.Printf(str, k+1, len(bases), cyan(base.String()))
pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
if err != nil {
return fmt.Errorf("%s: %s", pkg.Name, err)
if !errIsFatal {
fmt.Printf("failed to parse %s -- skipping: %s\n", base.String(), err)
continue
}
return nil, fmt.Errorf("failed to parse %s: %s", base.String(), err)
}
srcinfos[pkg.PackageBase] = pkgbuild
srcinfos[pkg] = pkgbuild
}
return nil
return srcinfos, nil
}
func tryParsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo, bases map[string][]*rpc.Pkg) {
for k, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
if err != nil {
fmt.Printf("cannot parse %s skipping: %s\n", pkg.Name, err)
continue
}
srcinfos[pkg.PackageBase] = pkgbuild
}
}
func pkgBuildsToSkip(pkgs []*rpc.Pkg, targets stringSet) stringSet {
func pkgbuildsToSkip(bases []Base, targets stringSet) stringSet {
toSkip := make(stringSet)
for _, pkg := range pkgs {
if config.ReDownload == "no" || (config.ReDownload == "yes" && !targets.get(pkg.Name)) {
dir := filepath.Join(config.BuildDir, pkg.PackageBase, ".SRCINFO")
for _, base := range bases {
isTarget := false
for _, pkg := range base {
isTarget = isTarget || targets.get(pkg.Name)
}
if config.ReDownload == "no" || (config.ReDownload == "yes" && isTarget) {
dir := filepath.Join(config.BuildDir, base.Pkgbase(), ".SRCINFO")
pkgbuild, err := gosrc.ParseFile(dir)
if err == nil {
if alpm.VerCmp(pkgbuild.Version(), pkg.Version) >= 0 {
toSkip.set(pkg.PackageBase)
if alpm.VerCmp(pkgbuild.Version(), base.Version()) >= 0 {
toSkip.set(base.Pkgbase())
}
}
}
@ -781,10 +796,10 @@ func pkgBuildsToSkip(pkgs []*rpc.Pkg, targets stringSet) stringSet {
return toSkip
}
func mergePkgBuilds(pkgs []*rpc.Pkg) error {
for _, pkg := range pkgs {
if shouldUseGit(filepath.Join(config.BuildDir, pkg.PackageBase)) {
err := gitMerge(config.BuildDir, pkg.PackageBase)
func mergePkgbuilds(bases []Base) error {
for _, base := range bases {
if shouldUseGit(filepath.Join(config.BuildDir, base.Pkgbase())) {
err := gitMerge(config.BuildDir, base.Pkgbase())
if err != nil {
return err
}
@ -794,38 +809,39 @@ func mergePkgBuilds(pkgs []*rpc.Pkg) error {
return nil
}
func downloadPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, toSkip stringSet) (stringSet, error) {
func downloadPkgbuilds(bases []Base, toSkip stringSet) (stringSet, error) {
cloned := make(stringSet)
downloaded := 0
var wg sync.WaitGroup
var mux sync.Mutex
var errs MultiError
download := func(k int, pkg *rpc.Pkg) {
download := func(k int, base Base) {
defer wg.Done()
pkg := base.Pkgbase()
if toSkip.get(pkg.PackageBase) {
if toSkip.get(pkg) {
mux.Lock()
downloaded++
str := bold(cyan("::") + " PKGBUILD up to date, Skipping (%d/%d): %s\n")
fmt.Printf(str, downloaded, len(pkgs), cyan(formatPkgbase(pkg, bases)))
fmt.Printf(str, downloaded, len(bases), cyan(base.String()))
mux.Unlock()
return
}
if shouldUseGit(filepath.Join(config.BuildDir, pkg.PackageBase)) {
clone, err := gitDownload(baseURL+"/"+pkg.PackageBase+".git", config.BuildDir, pkg.PackageBase)
if shouldUseGit(filepath.Join(config.BuildDir, pkg)) {
clone, err := gitDownload(baseURL+"/"+pkg+".git", config.BuildDir, pkg)
if err != nil {
errs.Add(err)
return
}
if clone {
mux.Lock()
cloned.set(pkg.PackageBase)
cloned.set(pkg)
mux.Unlock()
}
} else {
err := downloadAndUnpack(baseURL+pkg.URLPath, config.BuildDir)
err := downloadAndUnpack(baseURL+base.URLPath(), config.BuildDir)
if err != nil {
errs.Add(err)
return
@ -835,13 +851,13 @@ func downloadPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, toSkip stri
mux.Lock()
downloaded++
str := bold(cyan("::") + " Downloaded PKGBUILD (%d/%d): %s\n")
fmt.Printf(str, downloaded, len(pkgs), cyan(formatPkgbase(pkg, bases)))
fmt.Printf(str, downloaded, len(bases), cyan(base.String()))
mux.Unlock()
}
for k, pkg := range pkgs {
for k, base := range bases {
wg.Add(1)
go download(k, pkg)
go download(k, base)
}
wg.Wait()
@ -849,41 +865,43 @@ func downloadPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, toSkip stri
return cloned, errs.Return()
}
func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, incompatible stringSet) (err error) {
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
func downloadPkgbuildsSources(bases []Base, incompatible stringSet) (err error) {
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
args := []string{"--verifysource", "-Ccf"}
if incompatible.get(pkg.PackageBase) {
if incompatible.get(pkg) {
args = append(args, "--ignorearch")
}
err = show(passToMakepkg(dir, args...))
if err != nil {
return fmt.Errorf("Error downloading sources: %s", cyan(formatPkgbase(pkg, bases)))
return fmt.Errorf("Error downloading sources: %s", cyan(base.String()))
}
}
return
}
func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
for _, pkg := range do.Aur {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
for _, base := range do.Aur {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
built := true
srcinfo := srcinfos[pkg.PackageBase]
srcinfo := srcinfos[pkg]
args := []string{"--nobuild", "-fC"}
if incompatible.get(pkg.PackageBase) {
if incompatible.get(pkg) {
args = append(args, "--ignorearch")
}
//pkgver bump
err := show(passToMakepkg(dir, args...))
if err != nil {
return fmt.Errorf("Error making: %s", pkg.Name)
return fmt.Errorf("Error making: %s", base.String())
}
pkgdests, version, err := parsePackageList(dir)
@ -891,8 +909,12 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
return err
}
if config.ReBuild == "no" || (config.ReBuild == "yes" && !dp.Explicit.get(pkg.Name)) {
for _, split := range do.Bases[pkg.PackageBase] {
isExplicit := false
for _, b := range base {
isExplicit = isExplicit || dp.Explicit.get(b.Name)
}
if config.ReBuild == "no" || (config.ReBuild == "yes" && isExplicit) {
for _, split := range base {
pkgdest, ok := pkgdests[split.Name]
if !ok {
return fmt.Errorf("Could not find PKGDEST for: %s", split.Name)
@ -911,17 +933,17 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
if built {
fmt.Println(bold(yellow(arrow)),
cyan(pkg.Name+"-"+version)+bold(" Already made -- skipping build"))
cyan(pkg+"-"+version)+bold(" Already made -- skipping build"))
} else {
args := []string{"-cf", "--noconfirm", "--noextract", "--noprepare", "--holdver"}
if incompatible.get(pkg.PackageBase) {
if incompatible.get(pkg) {
args = append(args, "--ignorearch")
}
err := show(passToMakepkg(dir, args...))
if err != nil {
return fmt.Errorf("Error making: %s", pkg.Name)
return fmt.Errorf("Error making: %s", base.String())
}
}
@ -946,7 +968,7 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
cmdArgs.globals["ask"] = fmt.Sprint(uask)
} else {
conflict := false
for _, split := range do.Bases[pkg.PackageBase] {
for _, split := range base {
if _, ok := conflicts[split.Name]; ok {
conflict = true
}
@ -973,7 +995,7 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
remoteNamesCache := sliceToStringSet(remoteNames)
localNamesCache := sliceToStringSet(localNames)
for _, split := range do.Bases[pkg.PackageBase] {
for _, split := range base {
pkgdest, ok := pkgdests[split.Name]
if !ok {
return fmt.Errorf("Could not find PKGDEST for: %s", split.Name)
@ -1000,7 +1022,7 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
var mux sync.Mutex
var wg sync.WaitGroup
for _, pkg := range do.Bases[pkg.PackageBase] {
for _, pkg := range base {
wg.Add(1)
go updateVCSData(pkg.Name, srcinfo.Source, &mux, &wg)
}
@ -1023,13 +1045,3 @@ func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
return nil
}
func clean(pkgs []*rpc.Pkg) {
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
fmt.Println(bold(green(arrow +
" CleanAfter enabled. Deleting " + pkg.Name + " source folder.")))
os.RemoveAll(dir)
}
}

33
keys.go
View file

@ -8,12 +8,11 @@ import (
"strings"
gosrc "github.com/Morganamilo/go-srcinfo"
rpc "github.com/mikkeloscar/aur"
)
// pgpKeySet maps a PGP key with a list of PKGBUILDs that require it.
// This is similar to stringSet, used throughout the code.
type pgpKeySet map[string][]*rpc.Pkg
type pgpKeySet map[string][]Base
func (set pgpKeySet) toSlice() []string {
slice := make([]string, 0, len(set))
@ -23,14 +22,11 @@ func (set pgpKeySet) toSlice() []string {
return slice
}
func (set pgpKeySet) set(key string, p *rpc.Pkg) {
func (set pgpKeySet) set(key string, p Base) {
// Using ToUpper to make sure keys with a different case will be
// considered the same.
upperKey := strings.ToUpper(key)
if _, exists := set[upperKey]; !exists {
set[upperKey] = []*rpc.Pkg{}
}
set[key] = append(set[key], p)
set[key] = append(set[upperKey], p)
}
func (set pgpKeySet) get(key string) bool {
@ -41,28 +37,29 @@ func (set pgpKeySet) get(key string) bool {
// checkPgpKeys iterates through the keys listed in the PKGBUILDs and if needed,
// asks the user whether yay should try to import them.
func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo) error {
func checkPgpKeys(bases []Base, srcinfos map[string]*gosrc.Srcinfo) error {
// Let's check the keys individually, and then we can offer to import
// the problematic ones.
problematic := make(pgpKeySet)
args := append(strings.Fields(config.GpgFlags), "--list-keys")
// Mapping all the keys.
for _, pkg := range pkgs {
srcinfo := srcinfos[pkg.PackageBase]
for _, base := range bases {
pkg := base.Pkgbase()
srcinfo := srcinfos[pkg]
for _, key := range srcinfo.ValidPGPKeys {
// If key already marked as problematic, indicate the current
// PKGBUILD requires it.
if problematic.get(key) {
problematic.set(key, pkg)
problematic.set(key, base)
continue
}
cmd := exec.Command(config.GpgBin, append(args, key)...)
err := cmd.Run()
if err != nil {
problematic.set(key, pkg)
problematic.set(key, base)
}
}
}
@ -72,7 +69,7 @@ func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[str
return nil
}
str, err := formatKeysToImport(problematic, bases)
str, err := formatKeysToImport(problematic)
if err != nil {
return err
}
@ -104,7 +101,7 @@ func importKeys(keys []string) error {
// formatKeysToImport receives a set of keys and returns a string containing the
// question asking the user wants to import the problematic keys.
func formatKeysToImport(keys pgpKeySet, bases map[string][]*rpc.Pkg) (string, error) {
func formatKeysToImport(keys pgpKeySet) (string, error) {
if len(keys) == 0 {
return "", fmt.Errorf("%s No keys to import", bold(red(arrow+" Error:")))
}
@ -112,12 +109,12 @@ func formatKeysToImport(keys pgpKeySet, bases map[string][]*rpc.Pkg) (string, er
var buffer bytes.Buffer
buffer.WriteString(bold(green(arrow)))
buffer.WriteString(bold(green(" PGP keys need importing:")))
for key, pkgs := range keys {
for key, bases := range keys {
pkglist := ""
for _, pkg := range pkgs {
pkglist += formatPkgbase(pkg, bases) + " "
for _, base := range bases {
pkglist += base.String() + " "
}
pkglist = strings.TrimRight(pkglist, " ")
pkglist = strings.TrimRight(pkglist, " ")
buffer.WriteString(fmt.Sprintf("\n%s %s, required by: %s", yellow(bold(smallArrow)), cyan(key), cyan(pkglist)))
}
return buffer.String(), nil

View file

@ -143,11 +143,12 @@ func (s repoQuery) printSearch() {
// Pretty print a set of packages from the same package base.
// Packages foo and bar from a pkgbase named base would print like so:
// base (foo bar)
func formatPkgbase(pkg *rpc.Pkg, bases map[string][]*rpc.Pkg) string {
func (base Base) String() string {
pkg := base[0]
str := pkg.PackageBase
if len(bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name {
if len(base) > 1 || pkg.PackageBase != pkg.Name {
str2 := " ("
for _, split := range bases[pkg.PackageBase] {
for _, split := range base {
str2 += split.Name + " "
}
str2 = str2[:len(str2)-1] + ")"
@ -210,18 +211,19 @@ func (do *depOrder) Print() {
}
}
for _, pkg := range do.Aur {
pkgStr := " " + pkg.PackageBase + "-" + pkg.Version
for _, base := range do.Aur {
pkg := base.Pkgbase()
pkgStr := " " + pkg + "-" + base[0].Version
pkgStrMake := pkgStr
push := false
pushMake := false
if len(do.Bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name {
if len(base) > 1 || pkg != base[0].Name {
pkgStr += " ("
pkgStrMake += " ("
for _, split := range do.Bases[pkg.PackageBase] {
for _, split := range base {
if do.Runtime.get(split.Name) {
pkgStr += split.Name + " "
aurLen++
@ -235,7 +237,7 @@ func (do *depOrder) Print() {
pkgStr = pkgStr[:len(pkgStr)-1] + ")"
pkgStrMake = pkgStrMake[:len(pkgStrMake)-1] + ")"
} else if do.Runtime.get(pkg.Name) {
} else if do.Runtime.get(base[0].Name) {
aurLen++
push = true
} else {

18
vcs.go
View file

@ -10,7 +10,6 @@ import (
"time"
gosrc "github.com/Morganamilo/go-srcinfo"
rpc "github.com/mikkeloscar/aur"
)
// Info contains the last commit sha of a repo
@ -26,8 +25,6 @@ type shaInfo struct {
func createDevelDB() error {
var mux sync.Mutex
var wg sync.WaitGroup
infoMap := make(map[string]*rpc.Pkg)
srcinfosStale := make(map[string]*gosrc.Srcinfo)
_, _, _, remoteNames, err := filterPackages()
if err != nil {
@ -39,17 +36,12 @@ func createDevelDB() error {
return err
}
for _, pkg := range info {
infoMap[pkg.Name] = pkg
}
bases := getBases(info)
toSkip := pkgbuildsToSkip(bases, sliceToStringSet(remoteNames))
downloadPkgbuilds(bases, toSkip)
srcinfos, _ := parseSrcinfoFiles(bases, false)
bases := getBases(infoMap)
toSkip := pkgBuildsToSkip(info, sliceToStringSet(remoteNames))
downloadPkgBuilds(info, bases, toSkip)
tryParsesrcinfosFile(info, srcinfosStale, bases)
for _, pkgbuild := range srcinfosStale {
for _, pkgbuild := range srcinfos {
for _, pkg := range pkgbuild.Packages {
wg.Add(1)
go updateVCSData(pkg.Pkgname, pkgbuild.Source, &mux, &wg)