Explorar o código

chore(new_engine): use new engine for -Qu (#1954)

* use new engine for -Qu

* fix devel search showing up in -Quq

* test empty upgrade menu
Jo %!s(int64=2) %!d(string=hai) anos
pai
achega
7e7764a797
Modificáronse 7 ficheiros con 208 adicións e 75 borrados
  1. 12 11
      pkg/upgrade/service.go
  2. 127 1
      pkg/upgrade/service_test.go
  3. 8 5
      pkg/upgrade/sources.go
  4. 8 2
      pkg/upgrade/sources_test.go
  5. 44 53
      print.go
  6. 7 1
      sync.go
  7. 2 2
      upgrade.go

+ 12 - 11
pkg/upgrade/service.go

@@ -74,13 +74,13 @@ func (u *UpgradeService) upGraph(ctx context.Context, graph *topo.Graph[string,
 				aurdata[pkg.Name] = pkg
 			}
 
-			aurUp = UpAUR(remote, aurdata, u.cfg.TimeUpdate, enableDowngrade)
+			aurUp = UpAUR(u.log, remote, aurdata, u.cfg.TimeUpdate, enableDowngrade)
 		}
 
 		if u.cfg.Devel {
 			u.log.OperationInfoln(gotext.Get("Checking development packages..."))
 
-			develUp = UpDevel(ctx, remote, aurdata, u.vcsStore)
+			develUp = UpDevel(ctx, u.log, remote, aurdata, u.vcsStore)
 
 			u.vcsStore.CleanOrphans(remote)
 		}
@@ -219,30 +219,31 @@ func (u *UpgradeService) graphToUpSlice(graph *topo.Graph[string, *dep.InstallIn
 
 func (u *UpgradeService) GraphUpgrades(ctx context.Context,
 	graph *topo.Graph[string, *dep.InstallInfo],
-	enableDowngrade bool,
-) ([]string, *topo.Graph[string, *dep.InstallInfo], error) {
+	enableDowngrade bool, filter Filter,
+) (*topo.Graph[string, *dep.InstallInfo], error) {
 	if graph == nil {
 		graph = topo.New[string, *dep.InstallInfo]()
 	}
 
-	err := u.upGraph(ctx, graph, enableDowngrade,
-		func(*Upgrade) bool { return true })
+	err := u.upGraph(ctx, graph, enableDowngrade, filter)
 	if err != nil {
-		return []string{}, graph, err
+		return graph, err
 	}
 
 	if graph.Len() == 0 {
-		return []string{}, graph, nil
+		return graph, nil
 	}
 
-	excluded, errUp := u.userExcludeUpgrades(graph)
-	return excluded, graph, errUp
+	return graph, nil
 }
 
 // userExcludeUpgrades asks the user which packages to exclude from the upgrade and
 // removes them from the graph
-func (u *UpgradeService) userExcludeUpgrades(graph *topo.Graph[string, *dep.InstallInfo]) ([]string, error) {
+func (u *UpgradeService) UserExcludeUpgrades(graph *topo.Graph[string, *dep.InstallInfo]) ([]string, error) {
 	allUpLen := graph.Len()
+	if allUpLen == 0 {
+		return []string{}, nil
+	}
 	aurUp, repoUp := u.graphToUpSlice(graph)
 
 	sort.Sort(repoUp)

+ 127 - 1
pkg/upgrade/service_test.go

@@ -9,6 +9,7 @@ import (
 	"github.com/Jguer/aur"
 	"github.com/Jguer/go-alpm/v2"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	"github.com/Jguer/yay/v12/pkg/db"
 	"github.com/Jguer/yay/v12/pkg/db/mock"
@@ -27,6 +28,7 @@ func ptrString(s string) *string {
 }
 
 func TestUpgradeService_GraphUpgrades(t *testing.T) {
+	t.Parallel()
 	linuxDepInfo := &dep.InstallInfo{
 		Reason:       dep.Explicit,
 		Source:       dep.Sync,
@@ -276,12 +278,136 @@ func TestUpgradeService_GraphUpgrades(t *testing.T) {
 				noConfirm:  tt.fields.noConfirm,
 			}
 
-			excluded, got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade)
+			got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
 			if (err != nil) != tt.wantErr {
 				t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 
+			excluded, err := u.UserExcludeUpgrades(got)
+			require.NoError(t, err)
+
+			for node, info := range tt.mustExist {
+				assert.True(t, got.Exists(node), node)
+				assert.Equal(t, info, got.GetNodeInfo(node).Value)
+			}
+
+			for node := range tt.mustNotExist {
+				assert.False(t, got.Exists(node), node)
+			}
+
+			assert.ElementsMatch(t, tt.wantExclude, excluded)
+		})
+	}
+}
+
+func TestUpgradeService_GraphUpgradesNoUpdates(t *testing.T) {
+	t.Parallel()
+	dbExe := &mock.DBExecutor{
+		InstalledRemotePackageNamesFn: func() []string {
+			return []string{"yay", "example-git"}
+		},
+		InstalledRemotePackagesFn: func() map[string]mock.IPackage {
+			mapRemote := make(map[string]mock.IPackage)
+			mapRemote["yay"] = &mock.Package{
+				PName:    "yay",
+				PBase:    "yay",
+				PVersion: "10.2.3",
+				PReason:  alpm.PkgReasonExplicit,
+			}
+
+			mapRemote["example-git"] = &mock.Package{
+				PName:    "example-git",
+				PBase:    "example",
+				PVersion: "2.2.1.r32.41baa362-1",
+				PReason:  alpm.PkgReasonDepend,
+			}
+
+			return mapRemote
+		},
+		SyncUpgradesFn: func(bool) (map[string]db.SyncUpgrade, error) {
+			mapUpgrades := make(map[string]db.SyncUpgrade)
+			return mapUpgrades, nil
+		},
+		ReposFn: func() []string { return []string{"core"} },
+	}
+	vcsStore := &vcs.Mock{
+		ToUpgradeReturn: []string{},
+	}
+
+	mockAUR := &mockaur.MockAUR{
+		GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
+			return []aur.Pkg{}, nil
+		},
+	}
+	type fields struct {
+		input     io.Reader
+		output    io.Writer
+		noConfirm bool
+		devel     bool
+	}
+	type args struct {
+		graph           *topo.Graph[string, *dep.InstallInfo]
+		enableDowngrade bool
+	}
+	tests := []struct {
+		name         string
+		fields       fields
+		args         args
+		mustExist    map[string]*dep.InstallInfo
+		mustNotExist map[string]bool
+		wantExclude  []string
+		wantErr      bool
+	}{
+		{
+			name: "no input",
+			fields: fields{
+				input:     strings.NewReader(""),
+				output:    io.Discard,
+				noConfirm: false,
+			},
+			args: args{
+				graph:           nil,
+				enableDowngrade: false,
+			},
+			mustExist:    map[string]*dep.InstallInfo{},
+			mustNotExist: map[string]bool{},
+			wantErr:      false,
+			wantExclude:  []string{},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			grapher := dep.NewGrapher(dbExe, mockAUR,
+				false, true, false, false, false, text.NewLogger(tt.fields.output,
+					tt.fields.input, true, "test"))
+
+			cfg := &settings.Configuration{
+				Runtime: &settings.Runtime{Mode: parser.ModeAny},
+				Devel:   tt.fields.devel,
+			}
+
+			u := &UpgradeService{
+				log: text.NewLogger(tt.fields.output,
+					tt.fields.input, true, "test"),
+				grapher:    grapher,
+				aurCache:   mockAUR,
+				dbExecutor: dbExe,
+				vcsStore:   vcsStore,
+				runtime:    cfg.Runtime,
+				cfg:        cfg,
+				noConfirm:  tt.fields.noConfirm,
+			}
+
+			got, err := u.GraphUpgrades(context.Background(), tt.args.graph, tt.args.enableDowngrade, func(*Upgrade) bool { return true })
+			if (err != nil) != tt.wantErr {
+				t.Errorf("UpgradeService.GraphUpgrades() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			excluded, err := u.UserExcludeUpgrades(got)
+			require.NoError(t, err)
+
 			for node, info := range tt.mustExist {
 				assert.True(t, got.Exists(node), node)
 				assert.Equal(t, info, got.GetNodeInfo(node).Value)

+ 8 - 5
pkg/upgrade/sources.go

@@ -14,6 +14,7 @@ import (
 
 func UpDevel(
 	ctx context.Context,
+	log *text.Logger,
 	remote map[string]db.IPackage,
 	aurdata map[string]*query.Pkg,
 	localCache vcs.Store,
@@ -31,7 +32,7 @@ func UpDevel(
 			}
 
 			if pkg.ShouldIgnore() {
-				printIgnoringPackage(pkg, "latest-commit")
+				printIgnoringPackage(log, pkg, "latest-commit")
 				continue
 			}
 
@@ -52,10 +53,10 @@ func UpDevel(
 	return toUpgrade
 }
 
-func printIgnoringPackage(pkg db.IPackage, newPkgVersion string) {
+func printIgnoringPackage(logger *text.Logger, pkg db.IPackage, newPkgVersion string) {
 	left, right := GetVersionDiff(pkg.Version(), newPkgVersion)
 
-	text.Warnln(gotext.Get("%s: ignoring package upgrade (%s => %s)",
+	logger.Warnln(gotext.Get("%s: ignoring package upgrade (%s => %s)",
 		text.Cyan(pkg.Name()),
 		left, right,
 	))
@@ -63,7 +64,9 @@ func printIgnoringPackage(pkg db.IPackage, newPkgVersion string) {
 
 // UpAUR gathers foreign packages and checks if they have new versions.
 // Output: Upgrade type package list.
-func UpAUR(remote map[string]db.IPackage, aurdata map[string]*query.Pkg, timeUpdate, enableDowngrade bool) UpSlice {
+func UpAUR(log *text.Logger, remote map[string]db.IPackage, aurdata map[string]*query.Pkg,
+	timeUpdate, enableDowngrade bool,
+) UpSlice {
 	toUpgrade := UpSlice{Up: make([]Upgrade, 0), Repos: []string{"aur"}}
 
 	for name, pkg := range remote {
@@ -75,7 +78,7 @@ func UpAUR(remote map[string]db.IPackage, aurdata map[string]*query.Pkg, timeUpd
 		if (timeUpdate && (int64(aurPkg.LastModified) > pkg.BuildDate().Unix())) ||
 			(db.VerCmp(pkg.Version(), aurPkg.Version) < 0) || enableDowngrade {
 			if pkg.ShouldIgnore() {
-				printIgnoringPackage(pkg, aurPkg.Version)
+				printIgnoringPackage(log, pkg, aurPkg.Version)
 			} else {
 				toUpgrade.Up = append(toUpgrade.Up,
 					Upgrade{

+ 8 - 2
pkg/upgrade/sources_test.go

@@ -2,6 +2,8 @@ package upgrade
 
 import (
 	"context"
+	"io"
+	"strings"
 	"testing"
 	"time"
 
@@ -11,6 +13,7 @@ import (
 	alpm "github.com/Jguer/go-alpm/v2"
 
 	"github.com/Jguer/yay/v12/pkg/db/mock"
+	"github.com/Jguer/yay/v12/pkg/text"
 	"github.com/Jguer/yay/v12/pkg/vcs"
 )
 
@@ -71,7 +74,8 @@ func Test_upAUR(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			t.Parallel()
 
-			got := UpAUR(tt.args.remote, tt.args.aurdata, tt.args.timeUpdate, false)
+			got := UpAUR(text.NewLogger(io.Discard, strings.NewReader(""), false, "test"),
+				tt.args.remote, tt.args.aurdata, tt.args.timeUpdate, false)
 			assert.EqualValues(t, tt.want, got)
 		})
 	}
@@ -173,7 +177,9 @@ func Test_upDevel(t *testing.T) {
 		tt := tt
 		t.Run(tt.name, func(t *testing.T) {
 			t.Parallel()
-			got := UpDevel(context.Background(), tt.args.remote, tt.args.aurdata, tt.args.cached)
+			got := UpDevel(context.Background(),
+				text.NewLogger(io.Discard, strings.NewReader(""), false, "test"),
+				tt.args.remote, tt.args.aurdata, tt.args.cached)
 			assert.ElementsMatch(t, tt.want.Up, got.Up)
 		})
 	}

+ 44 - 53
print.go

@@ -3,17 +3,19 @@ package main
 import (
 	"context"
 	"fmt"
+	"io"
 	"os"
 	"strconv"
 
 	aur "github.com/Jguer/aur"
+	mapset "github.com/deckarep/golang-set/v2"
 	"github.com/leonelquinteros/gotext"
 
 	"github.com/Jguer/yay/v12/pkg/db"
+	"github.com/Jguer/yay/v12/pkg/dep"
 	"github.com/Jguer/yay/v12/pkg/query"
 	"github.com/Jguer/yay/v12/pkg/settings"
 	"github.com/Jguer/yay/v12/pkg/settings/parser"
-	"github.com/Jguer/yay/v12/pkg/stringset"
 	"github.com/Jguer/yay/v12/pkg/text"
 	"github.com/Jguer/yay/v12/pkg/upgrade"
 )
@@ -100,74 +102,63 @@ func localStatistics(ctx context.Context, cfg *settings.Configuration, dbExecuto
 func printUpdateList(ctx context.Context, cfg *settings.Configuration, cmdArgs *parser.Arguments,
 	dbExecutor db.Executor, enableDowngrade bool, filter upgrade.Filter,
 ) error {
-	targets := stringset.FromSlice(cmdArgs.Targets)
-	warnings := query.NewWarnings()
-	old := os.Stdout // keep backup of the real stdout
-	os.Stdout = nil
+	quietMode := cmdArgs.ExistsArg("q", "quiet")
+	logger := cfg.Runtime.Logger.Child("update-list")
+	if quietMode { // TODO: handle quiet mode in a better way
+		logger = text.NewLogger(io.Discard, os.Stdin, cfg.Debug, "update-list")
+	}
 
-	remoteNames := dbExecutor.InstalledRemotePackageNames()
-	localNames := dbExecutor.InstalledSyncPackageNames()
+	targets := mapset.NewThreadUnsafeSet(cmdArgs.Targets...)
+	grapher := dep.NewGrapher(dbExecutor, cfg.Runtime.AURCache, false, settings.NoConfirm,
+		false, false, cmdArgs.ExistsArg("needed"), logger.Child("grapher"))
 
-	aurUp, repoUp, err := upList(ctx, cfg, warnings, dbExecutor, enableDowngrade, filter)
-	os.Stdout = old // restoring the real stdout
+	upService := upgrade.NewUpgradeService(
+		grapher, cfg.Runtime.AURCache, dbExecutor, cfg.Runtime.VCSStore,
+		cfg.Runtime, cfg, settings.NoConfirm, logger.Child("upgrade"))
 
-	if err != nil {
-		return err
+	graph, errSysUp := upService.GraphUpgrades(ctx, nil,
+		enableDowngrade, filter)
+	if errSysUp != nil {
+		return errSysUp
 	}
 
-	if (len(aurUp.Up) + len(repoUp.Up)) == 0 {
+	if graph.Len() == 0 {
 		return fmt.Errorf("")
 	}
 
-	noTargets := len(targets) == 0
+	noTargets := targets.Cardinality() == 0
+	foreignFilter := cmdArgs.ExistsArg("m", "foreign")
+	nativeFilter := cmdArgs.ExistsArg("n", "native")
 
-	if !cmdArgs.ExistsArg("m", "foreign") {
-		for _, pkg := range repoUp.Up {
-			if noTargets || targets.Get(pkg.Name) {
-				if cmdArgs.ExistsArg("q", "quiet") {
-					fmt.Printf("%s\n", pkg.Name)
-				} else {
-					fmt.Printf("%s %s -> %s\n", text.Bold(pkg.Name), text.Green(pkg.LocalVersion), text.Green(pkg.RemoteVersion))
-				}
-
-				delete(targets, pkg.Name)
+	_ = graph.ForEach(func(pkgName string, ii *dep.InstallInfo) error {
+		if noTargets || targets.Contains(pkgName) {
+			if ii.Source == dep.Sync && foreignFilter {
+				return nil
+			} else if ii.Source == dep.AUR && nativeFilter {
+				return nil
 			}
-		}
-	}
-
-	if !cmdArgs.ExistsArg("n", "native") {
-		for _, pkg := range aurUp.Up {
-			if noTargets || targets.Get(pkg.Name) {
-				if cmdArgs.ExistsArg("q", "quiet") {
-					fmt.Printf("%s\n", pkg.Name)
-				} else {
-					fmt.Printf("%s %s -> %s\n", text.Bold(pkg.Name), text.Green(pkg.LocalVersion), text.Green(pkg.RemoteVersion))
-				}
 
-				delete(targets, pkg.Name)
+			if quietMode {
+				fmt.Printf("%s\n", pkgName)
+			} else {
+				fmt.Printf("%s %s -> %s\n", text.Bold(pkgName), text.Green(ii.LocalVersion),
+					text.Green(ii.Version))
 			}
-		}
-	}
 
-	missing := false
-
-outer:
-	for pkg := range targets {
-		for _, name := range localNames {
-			if name == pkg {
-				continue outer
-			}
+			targets.Remove(pkgName)
 		}
 
-		for _, name := range remoteNames {
-			if name == pkg {
-				continue outer
-			}
-		}
+		return nil
+	})
 
-		text.Errorln(gotext.Get("package '%s' was not found", pkg))
-		missing = true
-	}
+	missing := false
+	targets.Each(func(pkgName string) bool {
+		if dbExecutor.LocalPackage(pkgName) == nil {
+			cfg.Runtime.Logger.Errorln(gotext.Get("package '%s' was not found", pkgName))
+			missing = true
+		}
+		return false
+	})
 
 	if missing {
 		return fmt.Errorf("")

+ 7 - 1
sync.go

@@ -60,7 +60,13 @@ func syncInstall(ctx context.Context,
 			grapher, aurCache, dbExecutor, cfg.Runtime.VCSStore,
 			cfg.Runtime, cfg, settings.NoConfirm, cfg.Runtime.Logger.Child("upgrade"))
 
-		excluded, graph, errSysUp = upService.GraphUpgrades(ctx, graph, cmdArgs.ExistsDouble("u", "sysupgrade"))
+		graph, errSysUp = upService.GraphUpgrades(ctx,
+			graph, cmdArgs.ExistsDouble("u", "sysupgrade"),
+			func(*upgrade.Upgrade) bool { return true })
+		if errSysUp != nil {
+			return errSysUp
+		}
+		excluded, errSysUp = upService.UserExcludeUpgrades(graph)
 		if errSysUp != nil {
 			return errSysUp
 		}

+ 2 - 2
upgrade.go

@@ -86,7 +86,7 @@ func upList(ctx context.Context, cfg *settings.Configuration,
 			wg.Add(1)
 
 			go func() {
-				aurUp = upgrade.UpAUR(remote, aurdata, cfg.TimeUpdate, enableDowngrade)
+				aurUp = upgrade.UpAUR(cfg.Runtime.Logger, remote, aurdata, cfg.TimeUpdate, enableDowngrade)
 
 				wg.Done()
 			}()
@@ -96,7 +96,7 @@ func upList(ctx context.Context, cfg *settings.Configuration,
 				wg.Add(1)
 
 				go func() {
-					develUp = upgrade.UpDevel(ctx, remote, aurdata, cfg.Runtime.VCSStore)
+					develUp = upgrade.UpDevel(ctx, cfg.Runtime.Logger, remote, aurdata, cfg.Runtime.VCSStore)
 
 					cfg.Runtime.VCSStore.CleanOrphans(remote)
 					wg.Done()