From fd90684c4d53edeb1c238c2cf6b71ab9548c4346 Mon Sep 17 00:00:00 2001 From: jguer Date: Sun, 20 Nov 2022 13:30:24 +0100 Subject: [PATCH 1/4] fix: do not instantiate cleaning hooks if there's no AUR pkg --- preparer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/preparer.go b/preparer.go index c9db044ec..afbc345d5 100644 --- a/preparer.go +++ b/preparer.go @@ -58,7 +58,7 @@ func NewPreparer(dbExecutor db.Executor, cmdBuilder exe.ICmdBuilder, config *set } func (preper *Preparer) ShouldCleanAURDirs(pkgBuildDirs map[string]string) PostInstallHookFunc { - if !preper.config.CleanAfter { + if !preper.config.CleanAfter || len(pkgBuildDirs) == 0 { return nil } From c3bbd671ed523e5e2cae553960271875dfe31bcd Mon Sep 17 00:00:00 2001 From: jguer Date: Sun, 20 Nov 2022 13:53:55 +0100 Subject: [PATCH 2/4] chore: squash local and sync install --- local_install.go | 41 ++--------------------------------------- pkg/menus/clean_menu.go | 2 +- sync.go | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 31 insertions(+), 48 deletions(-) diff --git a/local_install.go b/local_install.go index dcd628836..7cd5ee1ce 100644 --- a/local_install.go +++ b/local_install.go @@ -11,7 +11,6 @@ import ( "github.com/Jguer/yay/v11/pkg/dep" "github.com/Jguer/yay/v11/pkg/settings" "github.com/Jguer/yay/v11/pkg/settings/parser" - "github.com/Jguer/yay/v11/pkg/text" "github.com/Jguer/yay/v11/pkg/topo" gosrc "github.com/Morganamilo/go-srcinfo" @@ -49,42 +48,6 @@ func installLocalPKGBUILD( } } - topoSorted := graph.TopoSortedLayerMap() - - preparer := &Preparer{ - dbExecutor: dbExecutor, - cmdBuilder: config.Runtime.CmdBuilder, - config: config, - } - installer := &Installer{dbExecutor: dbExecutor} - - pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, topoSorted) - if err != nil { - return err - } - - if cleanFunc := preparer.ShouldCleanMakeDeps(); cleanFunc != nil { - installer.AddPostInstallHook(cleanFunc) - } - - if cleanAURDirsFunc := preparer.ShouldCleanAURDirs(pkgBuildDirs); cleanAURDirsFunc != nil { - installer.AddPostInstallHook(cleanAURDirsFunc) - } - - 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) - } - - return err - } - - return installer.RunPostInstallHooks(ctx) + opService := NewOperationService(ctx, config, dbExecutor) + return opService.Run(ctx, cmdArgs, graph.TopoSortedLayerMap()) } diff --git a/pkg/menus/clean_menu.go b/pkg/menus/clean_menu.go index fea2e95ca..3d0330dc7 100644 --- a/pkg/menus/clean_menu.go +++ b/pkg/menus/clean_menu.go @@ -59,7 +59,7 @@ func CleanFn(ctx context.Context, config *settings.Configuration, w io.Writer, p dir := pkgbuildDirsByBase[base] text.OperationInfoln(gotext.Get("Deleting (%d/%d): %s", i+1, len(toClean), text.Cyan(dir))) - if err := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildGitCmd(ctx, dir, "reset", "--hard")); err != nil { + if err := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildGitCmd(ctx, dir, "reset", "--hard", "HEAD")); err != nil { text.Warnln(gotext.Get("Unable to clean:"), dir) return err diff --git a/sync.go b/sync.go index 0f0a51813..210729c64 100644 --- a/sync.go +++ b/sync.go @@ -51,12 +51,33 @@ func syncInstall(ctx context.Context, } } - topoSorted := graph.TopoSortedLayerMap() + opService := NewOperationService(ctx, config, dbExecutor) + return opService.Run(ctx, cmdArgs, graph.TopoSortedLayerMap()) +} + +type OperationService struct { + ctx context.Context + config *settings.Configuration + dbExecutor db.Executor + updateCompletions bool +} - preparer := NewPreparer(dbExecutor, config.Runtime.CmdBuilder, config) - installer := &Installer{dbExecutor: dbExecutor} +func NewOperationService(ctx context.Context, config *settings.Configuration, dbExecutor db.Executor) *OperationService { + return &OperationService{ + ctx: ctx, + config: config, + dbExecutor: dbExecutor, + } +} - pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, topoSorted) +func (o *OperationService) Run(ctx context.Context, + cmdArgs *parser.Arguments, + targets []map[string]*dep.InstallInfo, +) error { + preparer := NewPreparer(o.dbExecutor, config.Runtime.CmdBuilder, config) + installer := &Installer{dbExecutor: o.dbExecutor} + + pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, targets) if err != nil { return err } @@ -70,19 +91,18 @@ func syncInstall(ctx context.Context, installer.AddPostInstallHook(cleanAURDirsFunc) } - srcinfoOp := srcinfoOperator{dbExecutor: dbExecutor} - + srcinfoOp := srcinfoOperator{dbExecutor: o.dbExecutor} srcinfos, err := srcinfoOp.Run(pkgBuildDirs) if err != nil { return err } go func() { - _ = completion.Update(ctx, config.Runtime.HTTPClient, dbExecutor, + _ = completion.Update(ctx, config.Runtime.HTTPClient, o.dbExecutor, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false) }() - err = installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs, srcinfos) + err = installer.Install(ctx, cmdArgs, targets, pkgBuildDirs, srcinfos) if err != nil { if errHook := installer.RunPostInstallHooks(ctx); errHook != nil { text.Errorln(errHook) From 8565fee47189b9debe91b84386188836ab8d3a89 Mon Sep 17 00:00:00 2001 From: jguer Date: Sun, 20 Nov 2022 13:54:13 +0100 Subject: [PATCH 3/4] still update completions in local mode --- sync.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sync.go b/sync.go index 210729c64..c122c1b87 100644 --- a/sync.go +++ b/sync.go @@ -56,10 +56,9 @@ func syncInstall(ctx context.Context, } type OperationService struct { - ctx context.Context - config *settings.Configuration - dbExecutor db.Executor - updateCompletions bool + ctx context.Context + config *settings.Configuration + dbExecutor db.Executor } func NewOperationService(ctx context.Context, config *settings.Configuration, dbExecutor db.Executor) *OperationService { From da408cc925c38c1f6b00b1f5a86f765f3fc926ba Mon Sep 17 00:00:00 2001 From: jguer Date: Sun, 20 Nov 2022 19:07:47 +0100 Subject: [PATCH 4/4] 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 1bf5500fe..7015b9544 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 81f4971dd..320aa7e61 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 50a640461..be0d647a0 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 c122c1b87..f816542f3 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() }