From 4f1f539217e628b1ac8ab4c512b07f43aaaf8def Mon Sep 17 00:00:00 2001 From: Jo Date: Tue, 29 Nov 2022 12:25:36 +0000 Subject: [PATCH] Ignore last layer fails and keep building (#1841) * fix: do not instantiate cleaning hooks if there's no AUR pkg * chore: squash local and sync install * still update completions in local mode * allow failures on the last install layer --- aur_install.go | 45 +++++++++++++++++++++++++++++++++++++++------ clean.go | 2 +- errors.go | 14 ++++++++++++++ sync.go | 19 +++++++++++++++++-- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/aur_install.go b/aur_install.go index 1bf5500f..7015b954 100644 --- a/aur_install.go +++ b/aur_install.go @@ -21,11 +21,30 @@ import ( type ( PostInstallHookFunc func(ctx context.Context) error Installer struct { - dbExecutor db.Executor - postInstallHooks []PostInstallHookFunc + dbExecutor db.Executor + postInstallHooks []PostInstallHookFunc + failedAndIngnored map[string]error } ) +func NewInstaller(dbExecutor db.Executor) *Installer { + return &Installer{ + dbExecutor: dbExecutor, + postInstallHooks: []PostInstallHookFunc{}, + failedAndIngnored: map[string]error{}, + } +} + +func (installer *Installer) CompileFailedAndIgnored() error { + if len(installer.failedAndIngnored) == 0 { + return nil + } + + return &FailedIgnoredPkgError{ + pkgErrors: installer.failedAndIngnored, + } +} + func (installer *Installer) AddPostInstallHook(hook PostInstallHookFunc) { if hook == nil { return @@ -54,7 +73,7 @@ func (installer *Installer) Install(ctx context.Context, ) error { // Reorganize targets into layers of dependencies for i := len(targets) - 1; i >= 0; i-- { - err := installer.handleLayer(ctx, cmdArgs, targets[i], pkgBuildDirs, srcinfos) + err := installer.handleLayer(ctx, cmdArgs, targets[i], pkgBuildDirs, srcinfos, i == 0) if err != nil { // rollback return err @@ -69,6 +88,7 @@ func (installer *Installer) handleLayer(ctx context.Context, layer map[string]*dep.InstallInfo, pkgBuildDirs map[string]string, srcinfos map[string]*gosrc.Srcinfo, + lastLayer bool, ) error { // Install layer nameToBaseMap := make(map[string]string, 0) @@ -114,7 +134,7 @@ func (installer *Installer) handleLayer(ctx context.Context, } errAur := installer.installAURPackages(ctx, cmdArgs, aurDeps, aurExp, - nameToBaseMap, pkgBuildDirs, true, srcinfos) + nameToBaseMap, pkgBuildDirs, true, srcinfos, lastLayer) return errAur } @@ -125,6 +145,7 @@ func (installer *Installer) installAURPackages(ctx context.Context, nameToBase, pkgBuildDirsByBase map[string]string, installIncompatible bool, srcinfos map[string]*gosrc.Srcinfo, + lastLayer bool, ) error { all := aurDepNames.Union(aurExpNames).ToSlice() if len(all) == 0 { @@ -151,7 +172,13 @@ func (installer *Installer) installAURPackages(ctx context.Context, // pkgver bump if err := config.Runtime.CmdBuilder.Show( config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx, dir, args...)); err != nil { - return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), err) + if !lastLayer { + return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), err) + } + + installer.failedAndIngnored[name] = err + text.Errorln(gotext.Get("error making: %s", base), "-", err) + continue } pkgdests, _, errList := parsePackageList(ctx, dir) @@ -168,7 +195,13 @@ func (installer *Installer) installAURPackages(ctx context.Context, if errMake := config.Runtime.CmdBuilder.Show( config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx, dir, args...)); errMake != nil { - return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), errMake) + if !lastLayer { + return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), errMake) + } + + installer.failedAndIngnored[name] = errMake + text.Errorln(gotext.Get("error making: %s", base), "-", errMake) + continue } newPKGArchives, hasDebug, err := installer.getNewTargets(pkgdests, name) diff --git a/clean.go b/clean.go index 81f4971d..320aa7e6 100644 --- a/clean.go +++ b/clean.go @@ -210,7 +210,7 @@ func cleanAfter(ctx context.Context, cmdBuilder exe.ICmdBuilder, pkgbuildDirs ma if err := config.Runtime.CmdBuilder.Show( config.Runtime.CmdBuilder.BuildGitCmd( - ctx, dir, "clean", "-fx", "--exclude='*.pkg.*'")); err != nil { + ctx, dir, "clean", "-fx", "--exclude", "*.pkg.*")); err != nil { fmt.Fprintln(os.Stderr, err) } diff --git a/errors.go b/errors.go index 50a64046..be0d647a 100644 --- a/errors.go +++ b/errors.go @@ -32,3 +32,17 @@ type PkgDestNotInListError struct { func (e *PkgDestNotInListError) Error() string { return gotext.Get("could not find PKGDEST for: %s", e.name) } + +type FailedIgnoredPkgError struct { + pkgErrors map[string]error +} + +func (e *FailedIgnoredPkgError) Error() string { + msg := gotext.Get("Failed to install the following packages. Manual intervention is required:") + + for pkg, err := range e.pkgErrors { + msg += "\n" + pkg + " - " + err.Error() + } + + return msg +} diff --git a/sync.go b/sync.go index c122c1b8..f816542f 100644 --- a/sync.go +++ b/sync.go @@ -8,6 +8,7 @@ import ( "github.com/Jguer/yay/v11/pkg/completion" "github.com/Jguer/yay/v11/pkg/db" "github.com/Jguer/yay/v11/pkg/dep" + "github.com/Jguer/yay/v11/pkg/multierror" "github.com/Jguer/yay/v11/pkg/settings" "github.com/Jguer/yay/v11/pkg/settings/parser" "github.com/Jguer/yay/v11/pkg/text" @@ -73,8 +74,12 @@ func (o *OperationService) Run(ctx context.Context, cmdArgs *parser.Arguments, targets []map[string]*dep.InstallInfo, ) error { + if len(targets) == 0 { + fmt.Fprintln(os.Stdout, "", gotext.Get("there is nothing to do")) + return nil + } preparer := NewPreparer(o.dbExecutor, config.Runtime.CmdBuilder, config) - installer := &Installer{dbExecutor: o.dbExecutor} + installer := NewInstaller(o.dbExecutor) pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, targets) if err != nil { @@ -110,5 +115,15 @@ func (o *OperationService) Run(ctx context.Context, return err } - return installer.RunPostInstallHooks(ctx) + var multiErr multierror.MultiError + + if err := installer.CompileFailedAndIgnored(); err != nil { + multiErr.Add(err) + } + + if err := installer.RunPostInstallHooks(ctx); err != nil { + multiErr.Add(err) + } + + return multiErr.Return() }