Skip to content

Commit

Permalink
feat(v12): add group install (Jguer#1835)
Browse files Browse the repository at this point in the history
v12engine: add group install
  • Loading branch information
Jguer authored Nov 20, 2022
1 parent 6ad63ca commit 9f67d10
Show file tree
Hide file tree
Showing 18 changed files with 230 additions and 153 deletions.
32 changes: 28 additions & 4 deletions aur_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"os"
"sync"

"github.com/Jguer/yay/v11/pkg/db"
"github.com/Jguer/yay/v11/pkg/dep"
Expand All @@ -12,6 +13,7 @@ import (
"github.com/Jguer/yay/v11/pkg/settings/parser"
"github.com/Jguer/yay/v11/pkg/text"

gosrc "github.com/Morganamilo/go-srcinfo"
mapset "github.com/deckarep/golang-set/v2"
"github.com/leonelquinteros/gotext"
)
Expand Down Expand Up @@ -48,10 +50,11 @@ func (installer *Installer) Install(ctx context.Context,
cmdArgs *parser.Arguments,
targets []map[string]*dep.InstallInfo,
pkgBuildDirs map[string]string,
srcinfos map[string]*gosrc.Srcinfo,
) error {
// Reorganize targets into layers of dependencies
for i := len(targets) - 1; i >= 0; i-- {
err := installer.handleLayer(ctx, cmdArgs, targets[i], pkgBuildDirs)
err := installer.handleLayer(ctx, cmdArgs, targets[i], pkgBuildDirs, srcinfos)
if err != nil {
// rollback
return err
Expand All @@ -62,7 +65,10 @@ func (installer *Installer) Install(ctx context.Context,
}

func (installer *Installer) handleLayer(ctx context.Context,
cmdArgs *parser.Arguments, layer map[string]*dep.InstallInfo, pkgBuildDirs map[string]string,
cmdArgs *parser.Arguments,
layer map[string]*dep.InstallInfo,
pkgBuildDirs map[string]string,
srcinfos map[string]*gosrc.Srcinfo,
) error {
// Install layer
nameToBaseMap := make(map[string]string, 0)
Expand Down Expand Up @@ -107,7 +113,8 @@ func (installer *Installer) handleLayer(ctx context.Context,
return ErrInstallRepoPkgs
}

errAur := installer.installAURPackages(ctx, cmdArgs, aurDeps, aurExp, nameToBaseMap, pkgBuildDirs, false)
errAur := installer.installAURPackages(ctx, cmdArgs, aurDeps, aurExp,
nameToBaseMap, pkgBuildDirs, true, srcinfos)

return errAur
}
Expand All @@ -117,11 +124,22 @@ func (installer *Installer) installAURPackages(ctx context.Context,
aurDepNames, aurExpNames mapset.Set[string],
nameToBase, pkgBuildDirsByBase map[string]string,
installIncompatible bool,
srcinfos map[string]*gosrc.Srcinfo,
) error {
all := aurDepNames.Union(aurExpNames).ToSlice()
if len(all) == 0 {
return nil
}

deps, exps := make([]string, 0, aurDepNames.Cardinality()), make([]string, 0, aurExpNames.Cardinality())
pkgArchives := make([]string, 0, len(exps)+len(deps))

for _, name := range aurDepNames.Union(aurExpNames).ToSlice() {
var (
mux sync.Mutex
wg sync.WaitGroup
)

for _, name := range all {
base := nameToBase[name]
dir := pkgBuildDirsByBase[base]
args := []string{"--nobuild", "-fC"}
Expand Down Expand Up @@ -169,8 +187,14 @@ func (installer *Installer) installAURPackages(ctx context.Context,
if hasDebug {
deps = append(deps, name+"-debug")
}

srcinfo := srcinfos[base]
wg.Add(1)
go config.Runtime.VCSStore.Update(ctx, name, srcinfo.Source, &mux, &wg)
}

wg.Wait()

if err := installPkgArchive(ctx, cmdArgs, pkgArchives); err != nil {
return fmt.Errorf("%s - %w", fmt.Sprintf(gotext.Get("error installing:")+" %v", pkgArchives), err)
}
Expand Down
85 changes: 37 additions & 48 deletions install.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ func asexp(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string) error
// Install handles package installs.
func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders bool) error {
var (
incompatible stringset.StringSet
do *dep.Order
srcinfos map[string]*gosrc.Srcinfo
noDeps = cmdArgs.ExistsDouble("d", "nodeps")
Expand Down Expand Up @@ -270,11 +269,11 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu
text.Errorln(errDiffMenu)
}

if errM := mergePkgbuilds(ctx, do.Aur); errM != nil {
if errM := mergePkgbuilds(ctx, pkgbuildDirs); errM != nil {
return errM
}

srcinfos, err = parseSrcinfoFiles(do.Aur, true)
srcinfos, err = parseSrcinfoFiles(pkgbuildDirs, true)
if err != nil {
return err
}
Expand All @@ -289,13 +288,12 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu
text.Errorln(errEditMenu)
}

incompatible, err = getIncompatible(do.Aur, srcinfos, dbExecutor)
if err != nil {
return err
if errI := confirmIncompatibleInstall(srcinfos, dbExecutor); errI != nil {
return errI
}

if config.PGPFetch {
if errCPK := pgp.CheckPgpKeys(do.Aur, srcinfos, config.GpgBin, config.GpgFlags, settings.NoConfirm); errCPK != nil {
if _, errCPK := pgp.CheckPgpKeys(pkgbuildDirs, srcinfos, config.GpgBin, config.GpgFlags, settings.NoConfirm); errCPK != nil {
return errCPK
}
}
Expand Down Expand Up @@ -341,19 +339,14 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu
config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false)
}()

pkgBuildDirs := make(map[string]string, len(do.Aur))
for _, base := range do.Aur {
pkgBuildDirs[base.Pkgbase()] = filepath.Join(config.BuildDir, base.Pkgbase())
}

if errP := downloadPKGBUILDSourceFanout(ctx,
config.Runtime.CmdBuilder,
pkgBuildDirs,
len(incompatible) > 0, config.MaxConcurrentDownloads); errP != nil {
pkgbuildDirs,
true, config.MaxConcurrentDownloads); errP != nil {
text.Errorln(errP)
}

if errB := buildInstallPkgbuilds(ctx, cmdArgs, dbExecutor, dp, do, srcinfos, incompatible, conflicts, noDeps, noCheck); errB != nil {
if errB := buildInstallPkgbuilds(ctx, cmdArgs, dbExecutor, dp, do, srcinfos, true, conflicts, noDeps, noCheck); errB != nil {
return errB
}

Expand Down Expand Up @@ -461,42 +454,39 @@ func earlyRefresh(ctx context.Context, cmdArgs *parser.Arguments) error {
arguments, config.Runtime.Mode, settings.NoConfirm))
}

func getIncompatible(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo, dbExecutor db.Executor) (stringset.StringSet, error) {
incompatible := make(stringset.StringSet)
basesMap := make(map[string]dep.Base)
func confirmIncompatibleInstall(srcinfos map[string]*gosrc.Srcinfo, dbExecutor db.Executor) error {
incompatible := []string{}

alpmArch, err := dbExecutor.AlpmArchitectures()
if err != nil {
return nil, err
return err
}

nextpkg:
for _, base := range bases {
for _, arch := range srcinfos[base.Pkgbase()].Arch {
for base, srcinfo := range srcinfos {
for _, arch := range srcinfo.Arch {
if db.ArchIsSupported(alpmArch, arch) {
continue nextpkg
}
}

incompatible.Set(base.Pkgbase())
basesMap[base.Pkgbase()] = base
incompatible = append(incompatible, base)
}

if len(incompatible) > 0 {
text.Warnln(gotext.Get("The following packages are not compatible with your architecture:"))

for pkg := range incompatible {
fmt.Print(" " + text.Cyan(basesMap[pkg].String()))
for _, pkg := range incompatible {
fmt.Print(" " + text.Cyan(pkg))
}

fmt.Println()

if !text.ContinueTask(os.Stdin, gotext.Get("Try to build them anyway?"), true, settings.NoConfirm) {
return nil, &settings.ErrUserAbort{}
return &settings.ErrUserAbort{}
}
}

return incompatible, nil
return nil
}

func parsePackageList(ctx context.Context, dir string) (pkgdests map[string]string, pkgVersion string, err error) {
Expand Down Expand Up @@ -532,26 +522,25 @@ func parsePackageList(ctx context.Context, dir string) (pkgdests map[string]stri
return pkgdests, pkgVersion, nil
}

func parseSrcinfoFiles(bases []dep.Base, errIsFatal bool) (map[string]*gosrc.Srcinfo, error) {
func parseSrcinfoFiles(pkgBuildDirs map[string]string, 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)

text.OperationInfoln(gotext.Get("(%d/%d) Parsing SRCINFO: %s", k+1, len(bases), text.Cyan(base.String())))
k := 0
for base, dir := range pkgBuildDirs {
text.OperationInfoln(gotext.Get("(%d/%d) Parsing SRCINFO: %s", k+1, len(pkgBuildDirs), text.Cyan(base)))

pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
if err != nil {
if !errIsFatal {
text.Warnln(gotext.Get("failed to parse %s -- skipping: %s", base.String(), err))
text.Warnln(gotext.Get("failed to parse %s -- skipping: %s", base, err))
continue
}

return nil, errors.New(gotext.Get("failed to parse %s: %s", base.String(), err))
return nil, errors.New(gotext.Get("failed to parse %s: %s", base, err))
}

srcinfos[pkg] = pkgbuild
srcinfos[base] = pkgbuild
k++
}

return srcinfos, nil
Expand Down Expand Up @@ -583,27 +572,27 @@ func pkgbuildsToSkip(bases []dep.Base, targets stringset.StringSet) stringset.St
return toSkip
}

func gitMerge(ctx context.Context, path, name string) error {
func gitMerge(ctx context.Context, dir string) error {
_, stderr, err := config.Runtime.CmdBuilder.Capture(
config.Runtime.CmdBuilder.BuildGitCmd(ctx,
filepath.Join(path, name), "reset", "--hard", "HEAD"))
dir, "reset", "--hard", "HEAD"))
if err != nil {
return errors.New(gotext.Get("error resetting %s: %s", name, stderr))
return errors.New(gotext.Get("error resetting %s: %s", dir, stderr))
}

_, stderr, err = config.Runtime.CmdBuilder.Capture(
config.Runtime.CmdBuilder.BuildGitCmd(ctx,
filepath.Join(path, name), "merge", "--no-edit", "--ff"))
dir, "merge", "--no-edit", "--ff"))
if err != nil {
return errors.New(gotext.Get("error merging %s: %s", name, stderr))
return errors.New(gotext.Get("error merging %s: %s", dir, stderr))
}

return nil
}

func mergePkgbuilds(ctx context.Context, bases []dep.Base) error {
for _, base := range bases {
err := gitMerge(ctx, config.BuildDir, base.Pkgbase())
func mergePkgbuilds(ctx context.Context, pkgbuildDirs map[string]string) error {
for _, dir := range pkgbuildDirs {
err := gitMerge(ctx, dir)
if err != nil {
return err
}
Expand All @@ -619,7 +608,7 @@ func buildInstallPkgbuilds(
dp *dep.Pool,
do *dep.Order,
srcinfos map[string]*gosrc.Srcinfo,
incompatible stringset.StringSet,
incompatible bool,
conflicts stringset.MapStringSet, noDeps, noCheck bool,
) error {
deps := make([]string, 0)
Expand Down Expand Up @@ -680,7 +669,7 @@ func buildInstallPkgbuilds(

args := []string{"--nobuild", "-fC"}

if incompatible.Get(pkg) {
if incompatible {
args = append(args, "--ignorearch")
}

Expand Down Expand Up @@ -749,7 +738,7 @@ func buildInstallPkgbuilds(
} else {
args := []string{"-cf", "--noconfirm", "--noextract", "--noprepare", "--holdver"}

if incompatible.Get(pkg) {
if incompatible {
args = append(args, "--ignorearch")
}

Expand Down
19 changes: 11 additions & 8 deletions local_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,27 @@ func installLocalPKGBUILD(
}
installer := &Installer{dbExecutor: dbExecutor}

if errP := preparer.Present(os.Stdout, topoSorted); errP != nil {
return errP
pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, topoSorted)
if err != nil {
return err
}

if cleanFunc := preparer.ShouldCleanMakeDeps(); cleanFunc != nil {
installer.AddPostInstallHook(cleanFunc)
}

pkgBuildDirs, err := preparer.PrepareWorkspace(ctx, topoSorted)
if err != nil {
return err
}

if cleanAURDirsFunc := preparer.ShouldCleanAURDirs(pkgBuildDirs); cleanAURDirsFunc != nil {
installer.AddPostInstallHook(cleanAURDirsFunc)
}

if err = installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs); err != nil {
srcinfoOp := srcinfoOperator{dbExecutor: dbExecutor}

srcinfos, err := srcinfoOp.Run(pkgBuildDirs)
if err != nil {
return err
}

if err = installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs, srcinfos); err != nil {
if errHook := installer.RunPostInstallHooks(ctx); errHook != nil {
text.Errorln(errHook)
}
Expand Down
20 changes: 19 additions & 1 deletion pkg/dep/depGraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (g *Grapher) GraphFromTargets(ctx context.Context,
if pkg := g.dbExecutor.SyncPackage(target.Name); pkg != nil {
dbName := pkg.DB().Name()
graph.AddNode(pkg.Name())
g.ValidateAndSetNodeInfo(graph, target.Name, &topo.NodeInfo[*InstallInfo]{
g.ValidateAndSetNodeInfo(graph, pkg.Name(), &topo.NodeInfo[*InstallInfo]{
Color: colorMap[Explicit],
Background: bgColorMap[Sync],
Value: &InstallInfo{
Expand All @@ -144,6 +144,24 @@ func (g *Grapher) GraphFromTargets(ctx context.Context,
continue
}

groupPackages := g.dbExecutor.PackagesFromGroup(target.Name)
if len(groupPackages) > 0 {
dbName := groupPackages[0].DB().Name()
graph.AddNode(target.Name)
g.ValidateAndSetNodeInfo(graph, target.Name, &topo.NodeInfo[*InstallInfo]{
Color: colorMap[Explicit],
Background: bgColorMap[Sync],
Value: &InstallInfo{
Source: Sync,
Reason: Explicit,
Version: "",
SyncDBName: &dbName,
},
})

continue
}

fallthrough
case "aur":
graph, err = g.GraphFromAURCache(ctx, graph, []string{target.Name})
Expand Down
4 changes: 4 additions & 0 deletions pkg/menus/clean_menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func anyExistInCache(pkgbuildDirs map[string]string) bool {
}

func CleanFn(ctx context.Context, config *settings.Configuration, w io.Writer, pkgbuildDirsByBase map[string]string) error {
if len(pkgbuildDirsByBase) == 0 {
return nil // no work to do
}

if !anyExistInCache(pkgbuildDirsByBase) {
return nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/menus/diff_menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ func Diff(ctx context.Context, cmdBuilder exe.ICmdBuilder, w io.Writer,
}

func DiffFn(ctx context.Context, config *settings.Configuration, w io.Writer, pkgbuildDirsByBase map[string]string) error {
if len(pkgbuildDirsByBase) == 0 {
return nil // no work to do
}

bases := make([]string, 0, len(pkgbuildDirsByBase))
for base := range pkgbuildDirsByBase {
bases = append(bases, base)
Expand Down
Loading

0 comments on commit 9f67d10

Please sign in to comment.