From e4fdc9a4d42701902852fd6491468a5e93f2104f Mon Sep 17 00:00:00 2001 From: jguer Date: Tue, 20 Sep 2022 00:01:19 +0200 Subject: [PATCH] readd makedep primitives --- cmd.go | 3 + install.go | 11 +-- local_install.go | 128 +++++++++++++++++++++++++++++++---- pkg/dep/depGraph.go | 35 ++++++---- pkg/metadata/metadata_aur.go | 4 +- pkg/settings/config.go | 3 + sync.go | 70 +++++++++++++++++++ 7 files changed, 219 insertions(+), 35 deletions(-) create mode 100644 sync.go diff --git a/cmd.go b/cmd.go index b32eb465..a3c4c7b7 100644 --- a/cmd.go +++ b/cmd.go @@ -356,6 +356,9 @@ func handleSync(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Ex case cmdArgs.ExistsArg("i", "info"): return syncInfo(ctx, cmdArgs, targets, dbExecutor) case cmdArgs.ExistsArg("u", "sysupgrade") || len(cmdArgs.Targets) > 0: + if config.NewInstallEngine { + return syncInstall(ctx, config, cmdArgs, dbExecutor) + } return install(ctx, cmdArgs, dbExecutor, false) case cmdArgs.ExistsArg("y", "refresh"): return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx, diff --git a/install.go b/install.go index b0ee01a0..129484bb 100644 --- a/install.go +++ b/install.go @@ -22,6 +22,7 @@ import ( "github.com/Jguer/yay/v11/pkg/pgp" "github.com/Jguer/yay/v11/pkg/query" "github.com/Jguer/yay/v11/pkg/settings" + "github.com/Jguer/yay/v11/pkg/settings/exe" "github.com/Jguer/yay/v11/pkg/settings/parser" "github.com/Jguer/yay/v11/pkg/stringset" "github.com/Jguer/yay/v11/pkg/text" @@ -204,7 +205,7 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu switch config.RemoveMake { case "yes": defer func() { - err = removeMake(ctx, do) + err = removeMake(ctx, config.Runtime.CmdBuilder, do.GetMake()) }() case "no": @@ -212,7 +213,7 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu default: if text.ContinueTask(os.Stdin, gotext.Get("Remove make dependencies after install?"), false, settings.NoConfirm) { defer func() { - err = removeMake(ctx, do) + err = removeMake(ctx, config.Runtime.CmdBuilder, do.GetMake()) }() } } @@ -351,7 +352,7 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu return nil } -func removeMake(ctx context.Context, do *dep.Order) error { +func removeMake(ctx context.Context, cmdBuilder exe.ICmdBuilder, makeDeps []string) error { removeArguments := parser.MakeArguments() err := removeArguments.AddArg("R", "u") @@ -359,13 +360,13 @@ func removeMake(ctx context.Context, do *dep.Order) error { return err } - for _, pkg := range do.GetMake() { + for _, pkg := range makeDeps { removeArguments.AddTarget(pkg) } oldValue := settings.NoConfirm settings.NoConfirm = true - err = config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx, + err = cmdBuilder.Show(cmdBuilder.BuildPacmanCmd(ctx, removeArguments, config.Runtime.Mode, settings.NoConfirm)) settings.NoConfirm = oldValue diff --git a/local_install.go b/local_install.go index edb1895d..39d32c60 100644 --- a/local_install.go +++ b/local_install.go @@ -5,13 +5,16 @@ package main import ( "context" "fmt" + "io" "os" "path/filepath" + "strings" "github.com/Jguer/yay/v11/pkg/db" "github.com/Jguer/yay/v11/pkg/dep" "github.com/Jguer/yay/v11/pkg/download" "github.com/Jguer/yay/v11/pkg/metadata" + "github.com/Jguer/yay/v11/pkg/multierror" "github.com/Jguer/yay/v11/pkg/settings" "github.com/Jguer/yay/v11/pkg/settings/exe" "github.com/Jguer/yay/v11/pkg/settings/parser" @@ -63,41 +66,120 @@ func installLocalPKGBUILD( topoSorted := graph.TopoSortedLayerMap() fmt.Println(topoSorted, len(topoSorted)) - preparer := &Preparer{dbExecutor: dbExecutor, cmdBuilder: config.Runtime.CmdBuilder} + preparer := &Preparer{ + dbExecutor: dbExecutor, + cmdBuilder: config.Runtime.CmdBuilder, + config: config, + } installer := &Installer{dbExecutor: dbExecutor} + err = preparer.Present(os.Stdout, topoSorted) + if err != nil { + return err + } + + cleanFunc := preparer.ShouldCleanMakeDeps(ctx) + if cleanFunc != nil { + installer.AddPostInstallHook(cleanFunc) + } + pkgBuildDirs, err := preparer.PrepareWorkspace(ctx, topoSorted) if err != nil { return err } - return installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs) + err = installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs) + if err != nil { + if errHook := installer.RunPostInstallHooks(ctx); errHook != nil { + text.Errorln(errHook) + } + + return err + } + + return installer.RunPostInstallHooks(ctx) } type Preparer struct { - dbExecutor db.Executor - cmdBuilder exe.ICmdBuilder - aurBases []string + dbExecutor db.Executor + cmdBuilder exe.ICmdBuilder + config *settings.Configuration + pkgBuildDirs []string + makeDeps []string } -func (preper *Preparer) PrepareWorkspace(ctx context.Context, targets []map[string]*dep.InstallInfo, -) (map[string]string, error) { +func (preper *Preparer) ShouldCleanMakeDeps(ctx context.Context) PostInstallHookFunc { + if len(preper.makeDeps) == 0 { + return nil + } + + switch preper.config.RemoveMake { + case "yes": + break + case "no": + return nil + default: + if !text.ContinueTask(os.Stdin, gotext.Get("Remove make dependencies after install?"), false, settings.NoConfirm) { + return nil + } + } + + return func(ctx context.Context) error { + return removeMake(ctx, preper.config.Runtime.CmdBuilder, preper.makeDeps) + } +} + +func (preper *Preparer) Present(w io.Writer, targets []map[string]*dep.InstallInfo) error { + pkgsBySourceAndReason := map[string]map[string][]string{} + + for _, layer := range targets { + for pkgName, info := range layer { + source := dep.SourceNames[info.Source] + reason := dep.ReasonNames[info.Reason] + pkgStr := text.Cyan(fmt.Sprintf("%s-%s", pkgName, info.Version)) + if _, ok := pkgsBySourceAndReason[source]; !ok { + pkgsBySourceAndReason[source] = map[string][]string{} + } + + pkgsBySourceAndReason[source][reason] = append(pkgsBySourceAndReason[source][reason], pkgStr) + if info.Reason == dep.MakeDep { + preper.makeDeps = append(preper.makeDeps, pkgName) + } + } + } + + for source, pkgsByReason := range pkgsBySourceAndReason { + for reason, pkgs := range pkgsByReason { + fmt.Fprintf(w, text.Bold("%s %s (%d):")+" %s\n", + source, + reason, + len(pkgs), + strings.Join(pkgs, ", ")) + } + } + + return nil +} + +func (preper *Preparer) PrepareWorkspace(ctx context.Context, targets []map[string]*dep.InstallInfo) (map[string]string, error) { + aurBases := mapset.NewThreadUnsafeSet[string]() pkgBuildDirs := make(map[string]string, 0) for _, layer := range targets { - for pkgBase, info := range layer { + for pkgName, info := range layer { if info.Source == dep.AUR { - preper.aurBases = append(preper.aurBases, pkgBase) - pkgBuildDirs[pkgBase] = filepath.Join(config.BuildDir, pkgBase) + pkgBase := *info.AURBase + aurBases.Add(pkgBase) + pkgBuildDirs[pkgName] = filepath.Join(config.BuildDir, pkgBase) } else if info.Source == dep.SrcInfo { - pkgBuildDirs[pkgBase] = *info.SrcinfoPath + pkgBuildDirs[pkgName] = *info.SrcinfoPath } } } if _, errA := download.AURPKGBUILDRepos(ctx, - preper.cmdBuilder, preper.aurBases, config.AURURL, config.BuildDir, false); errA != nil { + preper.cmdBuilder, aurBases.ToSlice(), config.AURURL, config.BuildDir, false); errA != nil { return nil, errA } @@ -108,8 +190,26 @@ func (preper *Preparer) PrepareWorkspace(ctx context.Context, targets []map[stri return pkgBuildDirs, nil } -type Installer struct { - dbExecutor db.Executor +type ( + PostInstallHookFunc func(ctx context.Context) error + Installer struct { + dbExecutor db.Executor + postInstallHooks []PostInstallHookFunc + } +) + +func (installer *Installer) AddPostInstallHook(hook PostInstallHookFunc) { + installer.postInstallHooks = append(installer.postInstallHooks, hook) +} + +func (Installer *Installer) RunPostInstallHooks(ctx context.Context) error { + var errMulti multierror.MultiError + for _, hook := range Installer.postInstallHooks { + if err := hook(ctx); err != nil { + errMulti.Add(err) + } + } + return errMulti.Return() } func (installer *Installer) Install(ctx context.Context, diff --git a/pkg/dep/depGraph.go b/pkg/dep/depGraph.go index 90168968..12d68049 100644 --- a/pkg/dep/depGraph.go +++ b/pkg/dep/depGraph.go @@ -19,6 +19,7 @@ import ( type InstallInfo struct { Source Source Reason Reason + Version string SrcinfoPath *string AURBase *string } @@ -33,11 +34,11 @@ type ( ) func (r Reason) String() string { - return reasonNames[r] + return ReasonNames[r] } func (s Source) String() string { - return sourceNames[s] + return SourceNames[s] } const ( @@ -47,11 +48,11 @@ const ( CheckDep // 3 ) -var reasonNames = map[Reason]string{ - Explicit: gotext.Get("explicit"), - Dep: gotext.Get("dep"), - MakeDep: gotext.Get("makedep"), - CheckDep: gotext.Get("checkdep"), +var ReasonNames = map[Reason]string{ + Explicit: gotext.Get("Explicit"), + Dep: gotext.Get("Dependency"), + MakeDep: gotext.Get("Make Dependency"), + CheckDep: gotext.Get("Check Dependency"), } const ( @@ -62,12 +63,12 @@ const ( Missing ) -var sourceNames = map[Source]string{ - AUR: gotext.Get("aur"), - Sync: gotext.Get("sync"), - Local: gotext.Get("local"), - SrcInfo: gotext.Get("srcinfo"), - Missing: gotext.Get("missing"), +var SourceNames = map[Source]string{ + AUR: gotext.Get("AUR"), + Sync: gotext.Get("Sync"), + Local: gotext.Get("Local"), + SrcInfo: gotext.Get("SRCINFO"), + Missing: gotext.Get("Missing"), } var bgColorMap = map[Source]string{ @@ -121,6 +122,7 @@ func (g *Grapher) GraphFromSrcInfo(pkgBuildDir string, pkgbuild *gosrc.Srcinfo) Reason: Explicit, SrcinfoPath: &pkgBuildDir, AURBase: &pkg.PackageBase, + Version: pkg.Version, }, }) @@ -158,6 +160,7 @@ func (g *Grapher) GraphFromAURCache(targets []string) (*topo.Graph[string, *Inst Source: AUR, Reason: Explicit, AURBase: &pkg.PackageBase, + Version: pkg.Version, }, }) @@ -225,8 +228,9 @@ func (g *Grapher) addNodes( Color: colorMap[depType], Background: bgColorMap[Sync], Value: &InstallInfo{ - Source: Sync, - Reason: depType, + Source: Sync, + Reason: depType, + Version: alpmPkg.Version(), }, }) @@ -262,6 +266,7 @@ func (g *Grapher) addNodes( Source: AUR, Reason: depType, AURBase: &pkg.PackageBase, + Version: pkg.Version, }, }) g.addDepNodes(pkg, graph) diff --git a/pkg/metadata/metadata_aur.go b/pkg/metadata/metadata_aur.go index c021936f..6d540129 100644 --- a/pkg/metadata/metadata_aur.go +++ b/pkg/metadata/metadata_aur.go @@ -114,7 +114,9 @@ func (a *AURCache) gojqGet(searchTerm string) ([]*aur.Pkg, error) { } func makeGoJQ() *gojq.Code { - pattern := ".[] | select((.PackageBase == $x) or (.Name == $x) or (.Provides[]? == ($x)))" + // pattern := ".[] | select((.PackageBase == $x) or (.Name == $x) or (.Provides[]? == ($x)))" + pattern := ".[] | select((.Name == $x) or (.Provides[]? == ($x)))" + query, err := gojq.Parse(pattern) if err != nil { log.Fatalln(err) diff --git a/pkg/settings/config.go b/pkg/settings/config.go index bf39cabc..ed1c9da9 100644 --- a/pkg/settings/config.go +++ b/pkg/settings/config.go @@ -74,6 +74,7 @@ type Configuration struct { SingleLineResults bool `json:"singlelineresults"` SeparateSources bool `json:"separatesources"` Runtime *Runtime `json:"-"` + NewInstallEngine bool `json:"newinstallengine"` Version string `json:"version"` } @@ -221,6 +222,7 @@ func DefaultConfig(version string) *Configuration { UseAsk: false, CombinedUpgrade: false, SeparateSources: true, + NewInstallEngine: false, Version: version, } } @@ -278,6 +280,7 @@ func NewConfig(version string) (*Configuration, error) { HTTPClient: &http.Client{}, AURClient: nil, VoteClient: voteClient, + QueryBuilder: nil, } var errAUR error diff --git a/sync.go b/sync.go new file mode 100644 index 00000000..93788821 --- /dev/null +++ b/sync.go @@ -0,0 +1,70 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "github.com/Jguer/yay/v11/pkg/db" + "github.com/Jguer/yay/v11/pkg/dep" + "github.com/Jguer/yay/v11/pkg/metadata" + "github.com/Jguer/yay/v11/pkg/settings" + "github.com/Jguer/yay/v11/pkg/settings/parser" + "github.com/Jguer/yay/v11/pkg/text" + "github.com/leonelquinteros/gotext" + "github.com/pkg/errors" +) + +func syncInstall(ctx context.Context, + config *settings.Configuration, + cmdArgs *parser.Arguments, dbExecutor db.Executor, +) error { + aurCache, err := metadata.NewAURCache(filepath.Join(config.BuildDir, "aur.json")) + if err != nil { + return errors.Wrap(err, gotext.Get("failed to retrieve aur Cache")) + } + + grapher := dep.NewGrapher(dbExecutor, aurCache, false, settings.NoConfirm, os.Stdout) + + graph, err := grapher.GraphFromAURCache(cmdArgs.Targets) + if err != nil { + return err + } + + topoSorted := graph.TopoSortedLayerMap() + fmt.Println(topoSorted, len(topoSorted)) + + preparer := &Preparer{ + dbExecutor: dbExecutor, + cmdBuilder: config.Runtime.CmdBuilder, + config: config, + } + installer := &Installer{dbExecutor: dbExecutor} + + err = preparer.Present(os.Stdout, topoSorted) + if err != nil { + return err + } + + cleanFunc := preparer.ShouldCleanMakeDeps(ctx) + if cleanFunc != nil { + installer.AddPostInstallHook(cleanFunc) + } + + pkgBuildDirs, err := preparer.PrepareWorkspace(ctx, topoSorted) + if err != nil { + return err + } + + err = installer.Install(ctx, cmdArgs, topoSorted, pkgBuildDirs) + if err != nil { + if errHook := installer.RunPostInstallHooks(ctx); errHook != nil { + text.Errorln(errHook) + } + + return err + } + + return installer.RunPostInstallHooks(ctx) +}