mirror of
https://github.com/Jguer/yay.git
synced 2025-11-09 00:13:56 -05:00
feat(new engine): skip built and respect --needed (#1852)
* add built package check * respect --needed for new engine * add needed check and test * add test for not built
This commit is contained in:
parent
c826456d4d
commit
7da9f4869d
129
aur_install.go
129
aur_install.go
@ -10,8 +10,10 @@ import (
|
|||||||
"github.com/Jguer/yay/v11/pkg/dep"
|
"github.com/Jguer/yay/v11/pkg/dep"
|
||||||
"github.com/Jguer/yay/v11/pkg/multierror"
|
"github.com/Jguer/yay/v11/pkg/multierror"
|
||||||
"github.com/Jguer/yay/v11/pkg/settings"
|
"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/settings/parser"
|
||||||
"github.com/Jguer/yay/v11/pkg/text"
|
"github.com/Jguer/yay/v11/pkg/text"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/vcs"
|
||||||
|
|
||||||
gosrc "github.com/Morganamilo/go-srcinfo"
|
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||||
mapset "github.com/deckarep/golang-set/v2"
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
@ -24,14 +26,20 @@ type (
|
|||||||
dbExecutor db.Executor
|
dbExecutor db.Executor
|
||||||
postInstallHooks []PostInstallHookFunc
|
postInstallHooks []PostInstallHookFunc
|
||||||
failedAndIngnored map[string]error
|
failedAndIngnored map[string]error
|
||||||
|
exeCmd exe.ICmdBuilder
|
||||||
|
vcsStore vcs.Store
|
||||||
|
targetMode parser.TargetMode
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewInstaller(dbExecutor db.Executor) *Installer {
|
func NewInstaller(dbExecutor db.Executor, exeCmd exe.ICmdBuilder, vcsStore vcs.Store, targetMode parser.TargetMode) *Installer {
|
||||||
return &Installer{
|
return &Installer{
|
||||||
dbExecutor: dbExecutor,
|
dbExecutor: dbExecutor,
|
||||||
postInstallHooks: []PostInstallHookFunc{},
|
postInstallHooks: []PostInstallHookFunc{},
|
||||||
failedAndIngnored: map[string]error{},
|
failedAndIngnored: map[string]error{},
|
||||||
|
exeCmd: exeCmd,
|
||||||
|
vcsStore: vcsStore,
|
||||||
|
targetMode: targetMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,38 +171,9 @@ func (installer *Installer) installAURPackages(ctx context.Context,
|
|||||||
for _, name := range all {
|
for _, name := range all {
|
||||||
base := nameToBase[name]
|
base := nameToBase[name]
|
||||||
dir := pkgBuildDirsByBase[base]
|
dir := pkgBuildDirsByBase[base]
|
||||||
args := []string{"--nobuild", "-fC"}
|
|
||||||
|
|
||||||
if installIncompatible {
|
pkgdests, errMake := installer.buildPkg(ctx, dir, base, installIncompatible, cmdArgs.ExistsArg("needed"))
|
||||||
args = append(args, "--ignorearch")
|
if errMake != nil {
|
||||||
}
|
|
||||||
|
|
||||||
// pkgver bump
|
|
||||||
if err := config.Runtime.CmdBuilder.Show(
|
|
||||||
config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx, dir, args...)); err != nil {
|
|
||||||
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)
|
|
||||||
if errList != nil {
|
|
||||||
return errList
|
|
||||||
}
|
|
||||||
|
|
||||||
args = []string{"-cf", "--noconfirm", "--noextract", "--noprepare", "--holdver"}
|
|
||||||
|
|
||||||
if installIncompatible {
|
|
||||||
args = append(args, "--ignorearch")
|
|
||||||
}
|
|
||||||
|
|
||||||
if errMake := config.Runtime.CmdBuilder.Show(
|
|
||||||
config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx,
|
|
||||||
dir, args...)); errMake != nil {
|
|
||||||
if !lastLayer {
|
if !lastLayer {
|
||||||
return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), errMake)
|
return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), errMake)
|
||||||
}
|
}
|
||||||
@ -204,6 +183,11 @@ func (installer *Installer) installAURPackages(ctx context.Context,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(pkgdests) == 0 {
|
||||||
|
text.Warnln(gotext.Get("nothing to install for %s", text.Cyan(base)))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
newPKGArchives, hasDebug, err := installer.getNewTargets(pkgdests, name)
|
newPKGArchives, hasDebug, err := installer.getNewTargets(pkgdests, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -223,22 +207,89 @@ func (installer *Installer) installAURPackages(ctx context.Context,
|
|||||||
|
|
||||||
srcinfo := srcinfos[base]
|
srcinfo := srcinfos[base]
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go config.Runtime.VCSStore.Update(ctx, name, srcinfo.Source, &mux, &wg)
|
go installer.vcsStore.Update(ctx, name, srcinfo.Source, &mux, &wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if err := installPkgArchive(ctx, cmdArgs, pkgArchives); err != nil {
|
if err := installPkgArchive(ctx, installer.exeCmd, installer.targetMode, installer.vcsStore, cmdArgs, pkgArchives); err != nil {
|
||||||
return fmt.Errorf("%s - %w", fmt.Sprintf(gotext.Get("error installing:")+" %v", pkgArchives), err)
|
return fmt.Errorf("%s - %w", fmt.Sprintf(gotext.Get("error installing:")+" %v", pkgArchives), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setInstallReason(ctx, cmdArgs, deps, exps); err != nil {
|
if err := setInstallReason(ctx, installer.exeCmd, installer.targetMode, cmdArgs, deps, exps); err != nil {
|
||||||
return fmt.Errorf("%s - %w", fmt.Sprintf(gotext.Get("error installing:")+" %v", pkgArchives), err)
|
return fmt.Errorf("%s - %w", fmt.Sprintf(gotext.Get("error installing:")+" %v", pkgArchives), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (installer *Installer) buildPkg(ctx context.Context,
|
||||||
|
dir, base string,
|
||||||
|
installIncompatible, needed bool,
|
||||||
|
) (map[string]string, error) {
|
||||||
|
args := []string{"--nobuild", "-fC"}
|
||||||
|
|
||||||
|
if installIncompatible {
|
||||||
|
args = append(args, "--ignorearch")
|
||||||
|
}
|
||||||
|
|
||||||
|
// pkgver bump
|
||||||
|
if err := installer.exeCmd.Show(
|
||||||
|
installer.exeCmd.BuildMakepkgCmd(ctx, dir, args...)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgdests, pkgVersion, errList := parsePackageList(ctx, installer.exeCmd, dir)
|
||||||
|
if errList != nil {
|
||||||
|
return nil, errList
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case needed && installer.pkgsAreAlreadyInstalled(pkgdests, pkgVersion):
|
||||||
|
args = []string{"-c", "--nobuild", "--noextract", "--ignorearch"}
|
||||||
|
pkgdests = map[string]string{}
|
||||||
|
text.Warnln(gotext.Get("%s is up to date -- skipping", text.Cyan(base+"-"+pkgVersion)))
|
||||||
|
case pkgsAreBuilt(pkgdests):
|
||||||
|
args = []string{"-c", "--nobuild", "--noextract", "--ignorearch"}
|
||||||
|
text.Warnln(gotext.Get("%s already made -- skipping build", text.Cyan(base+"-"+pkgVersion)))
|
||||||
|
default:
|
||||||
|
args = []string{"-cf", "--noconfirm", "--noextract", "--noprepare", "--holdver"}
|
||||||
|
if installIncompatible {
|
||||||
|
args = append(args, "--ignorearch")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errMake := installer.exeCmd.Show(
|
||||||
|
installer.exeCmd.BuildMakepkgCmd(ctx,
|
||||||
|
dir, args...))
|
||||||
|
if errMake != nil {
|
||||||
|
return nil, errMake
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkgdests, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (installer *Installer) pkgsAreAlreadyInstalled(pkgdests map[string]string, pkgVersion string) bool {
|
||||||
|
for pkgName := range pkgdests {
|
||||||
|
if !installer.dbExecutor.IsCorrectVersionInstalled(pkgName, pkgVersion) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func pkgsAreBuilt(pkgdests map[string]string) bool {
|
||||||
|
for _, pkgdest := range pkgdests {
|
||||||
|
if _, err := os.Stat(pkgdest); err != nil {
|
||||||
|
text.Debugln("pkgIsBuilt:", pkgdest, "does not exist")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (*Installer) isDep(cmdArgs *parser.Arguments, aurExpNames mapset.Set[string], name string) bool {
|
func (*Installer) isDep(cmdArgs *parser.Arguments, aurExpNames mapset.Set[string], name string) bool {
|
||||||
switch {
|
switch {
|
||||||
case cmdArgs.ExistsArg("asdeps", "asdep"):
|
case cmdArgs.ExistsArg("asdeps", "asdep"):
|
||||||
@ -279,7 +330,7 @@ func (installer *Installer) getNewTargets(pkgdests map[string]string, name strin
|
|||||||
return pkgArchives, ok, nil
|
return pkgArchives, ok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Installer) installSyncPackages(ctx context.Context, cmdArgs *parser.Arguments,
|
func (installer *Installer) installSyncPackages(ctx context.Context, cmdArgs *parser.Arguments,
|
||||||
syncDeps, // repo targets that are deps
|
syncDeps, // repo targets that are deps
|
||||||
syncExp mapset.Set[string], // repo targets that are exp
|
syncExp mapset.Set[string], // repo targets that are exp
|
||||||
) error {
|
) error {
|
||||||
@ -297,14 +348,14 @@ func (*Installer) installSyncPackages(ctx context.Context, cmdArgs *parser.Argum
|
|||||||
arguments.ClearTargets()
|
arguments.ClearTargets()
|
||||||
arguments.AddTarget(repoTargets...)
|
arguments.AddTarget(repoTargets...)
|
||||||
|
|
||||||
errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
|
errShow := installer.exeCmd.Show(installer.exeCmd.BuildPacmanCmd(ctx,
|
||||||
arguments, config.Runtime.Mode, settings.NoConfirm))
|
arguments, config.Runtime.Mode, settings.NoConfirm))
|
||||||
|
|
||||||
if errD := asdeps(ctx, cmdArgs, syncDeps.ToSlice()); errD != nil {
|
if errD := asdeps(ctx, installer.exeCmd, installer.targetMode, cmdArgs, syncDeps.ToSlice()); errD != nil {
|
||||||
return errD
|
return errD
|
||||||
}
|
}
|
||||||
|
|
||||||
if errE := asexp(ctx, cmdArgs, syncExp.ToSlice()); errE != nil {
|
if errE := asexp(ctx, installer.exeCmd, installer.targetMode, cmdArgs, syncExp.ToSlice()); errE != nil {
|
||||||
return errE
|
return errE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
179
aur_install_test.go
Normal file
179
aur_install_test.go
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/Jguer/yay/v11/pkg/db/mock"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/dep"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/settings/exe"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/settings/parser"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/vcs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ptrString(s string) *string {
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInstaller_InstallNeeded(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
makepkgBin := t.TempDir() + "/makepkg"
|
||||||
|
pacmanBin := t.TempDir() + "/pacman"
|
||||||
|
f, err := os.OpenFile(makepkgBin, os.O_RDONLY|os.O_CREATE, 0o755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
|
f, err = os.OpenFile(pacmanBin, os.O_RDONLY|os.O_CREATE, 0o755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
desc string
|
||||||
|
isInstalled bool
|
||||||
|
isBuilt bool
|
||||||
|
wantShow []string
|
||||||
|
wantCapture []string
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []testCase{
|
||||||
|
{
|
||||||
|
desc: "not installed and not built",
|
||||||
|
isInstalled: false,
|
||||||
|
isBuilt: false,
|
||||||
|
wantShow: []string{
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -cf --noconfirm --noextract --noprepare --holdver --ignorearch",
|
||||||
|
"pacman -U --needed --config -- /testdir/yay-91.0.0-1-x86_64.pkg.tar.zst",
|
||||||
|
"pacman -D -q --asexplicit --config -- yay",
|
||||||
|
},
|
||||||
|
wantCapture: []string{"makepkg --packagelist"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "not installed and built",
|
||||||
|
isInstalled: false,
|
||||||
|
isBuilt: true,
|
||||||
|
wantShow: []string{
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -c --nobuild --noextract --ignorearch",
|
||||||
|
"pacman -U --needed --config -- /testdir/yay-91.0.0-1-x86_64.pkg.tar.zst",
|
||||||
|
"pacman -D -q --asexplicit --config -- yay",
|
||||||
|
},
|
||||||
|
wantCapture: []string{"makepkg --packagelist"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "installed",
|
||||||
|
isInstalled: true,
|
||||||
|
isBuilt: false,
|
||||||
|
wantShow: []string{
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -c --nobuild --noextract --ignorearch",
|
||||||
|
},
|
||||||
|
wantCapture: []string{"makepkg --packagelist"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.desc, func(td *testing.T) {
|
||||||
|
tmpDir := td.TempDir()
|
||||||
|
pkgTar := tmpDir + "/yay-91.0.0-1-x86_64.pkg.tar.zst"
|
||||||
|
|
||||||
|
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||||
|
return pkgTar, "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
showOverride := func(cmd *exec.Cmd) error {
|
||||||
|
i++
|
||||||
|
if i == 2 {
|
||||||
|
if !tc.isBuilt {
|
||||||
|
f, err := os.OpenFile(pkgTar, os.O_RDONLY|os.O_CREATE, 0o666)
|
||||||
|
require.NoError(td, err)
|
||||||
|
require.NoError(td, f.Close())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a mock file
|
||||||
|
if tc.isBuilt {
|
||||||
|
f, err := os.OpenFile(pkgTar, os.O_RDONLY|os.O_CREATE, 0o666)
|
||||||
|
require.NoError(td, err)
|
||||||
|
require.NoError(td, f.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
isCorrectInstalledOverride := func(string, string) bool {
|
||||||
|
return tc.isInstalled
|
||||||
|
}
|
||||||
|
|
||||||
|
mockDB := &mock.DBExecutor{IsCorrectVersionInstalledFunc: isCorrectInstalledOverride}
|
||||||
|
mockRunner := &exe.MockRunner{CaptureFn: captureOverride, ShowFn: showOverride}
|
||||||
|
cmdBuilder := &exe.CmdBuilder{
|
||||||
|
MakepkgBin: makepkgBin,
|
||||||
|
SudoBin: "su",
|
||||||
|
PacmanBin: pacmanBin,
|
||||||
|
Runner: mockRunner,
|
||||||
|
SudoLoopEnabled: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdBuilder.Runner = mockRunner
|
||||||
|
|
||||||
|
installer := NewInstaller(mockDB, cmdBuilder, &vcs.Mock{}, parser.ModeAny)
|
||||||
|
|
||||||
|
cmdArgs := parser.MakeArguments()
|
||||||
|
cmdArgs.AddArg("needed")
|
||||||
|
cmdArgs.AddTarget("yay")
|
||||||
|
|
||||||
|
pkgBuildDirs := map[string]string{
|
||||||
|
"yay": tmpDir,
|
||||||
|
}
|
||||||
|
|
||||||
|
srcInfos := map[string]*gosrc.Srcinfo{"yay": {}}
|
||||||
|
|
||||||
|
targets := []map[string]*dep.InstallInfo{
|
||||||
|
{
|
||||||
|
"yay": {
|
||||||
|
Source: dep.AUR,
|
||||||
|
Reason: dep.Explicit,
|
||||||
|
Version: "91.0.0-1",
|
||||||
|
SrcinfoPath: ptrString(tmpDir + "/.SRCINFO"),
|
||||||
|
AURBase: ptrString("yay"),
|
||||||
|
SyncDBName: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
errI := installer.Install(context.Background(), cmdArgs, targets, pkgBuildDirs, srcInfos)
|
||||||
|
require.NoError(td, errI)
|
||||||
|
|
||||||
|
require.Len(td, mockRunner.ShowCalls, len(tc.wantShow))
|
||||||
|
require.Len(td, mockRunner.CaptureCalls, len(tc.wantCapture))
|
||||||
|
|
||||||
|
for i, call := range mockRunner.ShowCalls {
|
||||||
|
show := call.Args[0].(*exec.Cmd).String()
|
||||||
|
show = strings.ReplaceAll(show, tmpDir, "/testdir") // replace the temp dir with a static path
|
||||||
|
show = strings.ReplaceAll(show, makepkgBin, "makepkg")
|
||||||
|
show = strings.ReplaceAll(show, pacmanBin, "pacman")
|
||||||
|
|
||||||
|
// options are in a different order on different systems and on CI root user is used
|
||||||
|
assert.Subset(td, strings.Split(show, " "), strings.Split(tc.wantShow[i], " "), show)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, call := range mockRunner.CaptureCalls {
|
||||||
|
capture := call.Args[0].(*exec.Cmd).String()
|
||||||
|
capture = strings.ReplaceAll(capture, tmpDir, "/testdir") // replace the temp dir with a static path
|
||||||
|
capture = strings.ReplaceAll(capture, makepkgBin, "makepkg")
|
||||||
|
capture = strings.ReplaceAll(capture, pacmanBin, "pacman")
|
||||||
|
assert.Subset(td, strings.Split(capture, " "), strings.Split(tc.wantCapture[i], " "), capture)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,14 @@ package main
|
|||||||
|
|
||||||
import "github.com/leonelquinteros/gotext"
|
import "github.com/leonelquinteros/gotext"
|
||||||
|
|
||||||
|
type NoPkgDestsFoundError struct {
|
||||||
|
dir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NoPkgDestsFoundError) Error() string {
|
||||||
|
return gotext.Get("could not find any package archives listed in %s", e.dir)
|
||||||
|
}
|
||||||
|
|
||||||
type SetPkgReasonError struct {
|
type SetPkgReasonError struct {
|
||||||
exp bool // explicit
|
exp bool // explicit
|
||||||
}
|
}
|
||||||
|
|||||||
80
install.go
80
install.go
@ -27,9 +27,14 @@ import (
|
|||||||
"github.com/Jguer/yay/v11/pkg/settings/parser"
|
"github.com/Jguer/yay/v11/pkg/settings/parser"
|
||||||
"github.com/Jguer/yay/v11/pkg/stringset"
|
"github.com/Jguer/yay/v11/pkg/stringset"
|
||||||
"github.com/Jguer/yay/v11/pkg/text"
|
"github.com/Jguer/yay/v11/pkg/text"
|
||||||
|
"github.com/Jguer/yay/v11/pkg/vcs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setPkgReason(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string, exp bool) error {
|
func setPkgReason(ctx context.Context,
|
||||||
|
cmdBuilder exe.ICmdBuilder,
|
||||||
|
mode parser.TargetMode,
|
||||||
|
cmdArgs *parser.Arguments, pkgs []string, exp bool,
|
||||||
|
) error {
|
||||||
if len(pkgs) == 0 {
|
if len(pkgs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -56,20 +61,26 @@ func setPkgReason(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string,
|
|||||||
cmdArgs.AddTarget(pkgName)
|
cmdArgs.AddTarget(pkgName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
|
if err := cmdBuilder.Show(cmdBuilder.BuildPacmanCmd(ctx,
|
||||||
cmdArgs, config.Runtime.Mode, settings.NoConfirm)); err != nil {
|
cmdArgs, mode, settings.NoConfirm)); err != nil {
|
||||||
return &SetPkgReasonError{exp: exp}
|
return &SetPkgReasonError{exp: exp}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func asdeps(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string) error {
|
func asdeps(ctx context.Context,
|
||||||
return setPkgReason(ctx, cmdArgs, pkgs, false)
|
cmdBuilder exe.ICmdBuilder,
|
||||||
|
mode parser.TargetMode, cmdArgs *parser.Arguments, pkgs []string,
|
||||||
|
) error {
|
||||||
|
return setPkgReason(ctx, cmdBuilder, mode, cmdArgs, pkgs, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asexp(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string) error {
|
func asexp(ctx context.Context,
|
||||||
return setPkgReason(ctx, cmdArgs, pkgs, true)
|
cmdBuilder exe.ICmdBuilder,
|
||||||
|
mode parser.TargetMode, cmdArgs *parser.Arguments, pkgs []string,
|
||||||
|
) error {
|
||||||
|
return setPkgReason(ctx, cmdBuilder, mode, cmdArgs, pkgs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install handles package installs.
|
// Install handles package installs.
|
||||||
@ -323,11 +334,11 @@ func install(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.Execu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if errDeps := asdeps(ctx, cmdArgs, deps); errDeps != nil {
|
if errDeps := asdeps(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, deps); errDeps != nil {
|
||||||
return errDeps
|
return errDeps
|
||||||
}
|
}
|
||||||
|
|
||||||
if errExp := asexp(ctx, cmdArgs, exp); errExp != nil {
|
if errExp := asexp(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, exp); errExp != nil {
|
||||||
return errExp
|
return errExp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,9 +498,11 @@ nextpkg:
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePackageList(ctx context.Context, dir string) (pkgdests map[string]string, pkgVersion string, err error) {
|
func parsePackageList(ctx context.Context, cmdBuilder exe.ICmdBuilder,
|
||||||
stdout, stderr, err := config.Runtime.CmdBuilder.Capture(
|
dir string,
|
||||||
config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx, dir, "--packagelist"))
|
) (pkgdests map[string]string, pkgVersion string, err error) {
|
||||||
|
stdout, stderr, err := cmdBuilder.Capture(
|
||||||
|
cmdBuilder.BuildMakepkgCmd(ctx, dir, "--packagelist"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("%s %s", stderr, err)
|
return nil, "", fmt.Errorf("%s %s", stderr, err)
|
||||||
}
|
}
|
||||||
@ -517,6 +530,10 @@ func parsePackageList(ctx context.Context, dir string) (pkgdests map[string]stri
|
|||||||
pkgdests[pkgName] = line
|
pkgdests[pkgName] = line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(pkgdests) == 0 {
|
||||||
|
return nil, "", &NoPkgDestsFoundError{dir}
|
||||||
|
}
|
||||||
|
|
||||||
return pkgdests, pkgVersion, nil
|
return pkgdests, pkgVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,8 +661,9 @@ func buildInstallPkgbuilds(
|
|||||||
|
|
||||||
if !satisfied || !config.BatchInstall {
|
if !satisfied || !config.BatchInstall {
|
||||||
text.Debugln("non batch installing archives:", pkgArchives)
|
text.Debugln("non batch installing archives:", pkgArchives)
|
||||||
errArchive := installPkgArchive(ctx, cmdArgs, pkgArchives)
|
errArchive := installPkgArchive(ctx, config.Runtime.CmdBuilder,
|
||||||
errReason := setInstallReason(ctx, cmdArgs, deps, exp)
|
config.Runtime.Mode, config.Runtime.VCSStore, cmdArgs, pkgArchives)
|
||||||
|
errReason := setInstallReason(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, deps, exp)
|
||||||
|
|
||||||
deps = make([]string, 0)
|
deps = make([]string, 0)
|
||||||
exp = make([]string, 0)
|
exp = make([]string, 0)
|
||||||
@ -678,7 +696,7 @@ func buildInstallPkgbuilds(
|
|||||||
return errors.New(gotext.Get("error making: %s", base.String()))
|
return errors.New(gotext.Get("error making: %s", base.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgdests, pkgVersion, errList := parsePackageList(ctx, dir)
|
pkgdests, pkgVersion, errList := parsePackageList(ctx, config.Runtime.CmdBuilder, dir)
|
||||||
if errList != nil {
|
if errList != nil {
|
||||||
return errList
|
return errList
|
||||||
}
|
}
|
||||||
@ -797,12 +815,12 @@ func buildInstallPkgbuilds(
|
|||||||
}
|
}
|
||||||
|
|
||||||
text.Debugln("installing archives:", pkgArchives)
|
text.Debugln("installing archives:", pkgArchives)
|
||||||
errArchive := installPkgArchive(ctx, cmdArgs, pkgArchives)
|
errArchive := installPkgArchive(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, config.Runtime.VCSStore, cmdArgs, pkgArchives)
|
||||||
if errArchive != nil {
|
if errArchive != nil {
|
||||||
go config.Runtime.VCSStore.RemovePackage([]string{do.Aur[len(do.Aur)-1].String()})
|
go config.Runtime.VCSStore.RemovePackage([]string{do.Aur[len(do.Aur)-1].String()})
|
||||||
}
|
}
|
||||||
|
|
||||||
errReason := setInstallReason(ctx, cmdArgs, deps, exp)
|
errReason := setInstallReason(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, deps, exp)
|
||||||
if errReason != nil {
|
if errReason != nil {
|
||||||
go config.Runtime.VCSStore.RemovePackage([]string{do.Aur[len(do.Aur)-1].String()})
|
go config.Runtime.VCSStore.RemovePackage([]string{do.Aur[len(do.Aur)-1].String()})
|
||||||
}
|
}
|
||||||
@ -812,7 +830,13 @@ func buildInstallPkgbuilds(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func installPkgArchive(ctx context.Context, cmdArgs *parser.Arguments, pkgArchives []string) error {
|
func installPkgArchive(ctx context.Context,
|
||||||
|
cmdBuilder exe.ICmdBuilder,
|
||||||
|
mode parser.TargetMode,
|
||||||
|
vcsStore vcs.Store,
|
||||||
|
cmdArgs *parser.Arguments,
|
||||||
|
pkgArchives []string,
|
||||||
|
) error {
|
||||||
if len(pkgArchives) == 0 {
|
if len(pkgArchives) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -833,28 +857,31 @@ func installPkgArchive(ctx context.Context, cmdArgs *parser.Arguments, pkgArchiv
|
|||||||
|
|
||||||
arguments.AddTarget(pkgArchives...)
|
arguments.AddTarget(pkgArchives...)
|
||||||
|
|
||||||
if errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
|
if errShow := cmdBuilder.Show(cmdBuilder.BuildPacmanCmd(ctx,
|
||||||
arguments, config.Runtime.Mode, settings.NoConfirm)); errShow != nil {
|
arguments, mode, settings.NoConfirm)); errShow != nil {
|
||||||
return errShow
|
return errShow
|
||||||
}
|
}
|
||||||
|
|
||||||
if errStore := config.Runtime.VCSStore.Save(); errStore != nil {
|
if errStore := vcsStore.Save(); errStore != nil {
|
||||||
fmt.Fprintln(os.Stderr, errStore)
|
fmt.Fprintln(os.Stderr, errStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInstallReason(ctx context.Context, cmdArgs *parser.Arguments, deps, exps []string) error {
|
func setInstallReason(ctx context.Context,
|
||||||
|
cmdBuilder exe.ICmdBuilder, mode parser.TargetMode,
|
||||||
|
cmdArgs *parser.Arguments, deps, exps []string,
|
||||||
|
) error {
|
||||||
if len(deps)+len(exps) == 0 {
|
if len(deps)+len(exps) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if errDeps := asdeps(ctx, cmdArgs, deps); errDeps != nil {
|
if errDeps := asdeps(ctx, cmdBuilder, mode, cmdArgs, deps); errDeps != nil {
|
||||||
return errDeps
|
return errDeps
|
||||||
}
|
}
|
||||||
|
|
||||||
return asexp(ctx, cmdArgs, exps)
|
return asexp(ctx, cmdBuilder, mode, cmdArgs, exps)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.StringSet,
|
func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.StringSet,
|
||||||
@ -875,10 +902,7 @@ func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.Strin
|
|||||||
return deps, exp, pkgArchives, nil
|
return deps, exp, pkgArchives, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return deps, exp, pkgArchives, errors.New(
|
return deps, exp, pkgArchives, &FindPkgDestError{pkgDest: pkgdest, name: name}
|
||||||
gotext.Get(
|
|
||||||
"the PKGDEST for %s is listed by makepkg but does not exist: %s",
|
|
||||||
name, pkgdest))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgArchives = append(pkgArchives, pkgdest)
|
pkgArchives = append(pkgArchives, pkgdest)
|
||||||
|
|||||||
@ -16,6 +16,7 @@ type (
|
|||||||
|
|
||||||
type DBExecutor struct {
|
type DBExecutor struct {
|
||||||
db.Executor
|
db.Executor
|
||||||
|
IsCorrectVersionInstalledFunc func(string, string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t DBExecutor) AlpmArchitectures() ([]string, error) {
|
func (t DBExecutor) AlpmArchitectures() ([]string, error) {
|
||||||
@ -31,6 +32,9 @@ func (t DBExecutor) Cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t DBExecutor) IsCorrectVersionInstalled(s, s2 string) bool {
|
func (t DBExecutor) IsCorrectVersionInstalled(s, s2 string) bool {
|
||||||
|
if t.IsCorrectVersionInstalledFunc != nil {
|
||||||
|
return t.IsCorrectVersionInstalledFunc(s, s2)
|
||||||
|
}
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
pkg/settings/exe/mock.go
Normal file
109
pkg/settings/exe/mock.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package exe
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/Jguer/yay/v11/pkg/settings/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Call struct {
|
||||||
|
Res []interface{}
|
||||||
|
Args []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockBuilder struct {
|
||||||
|
Runner Runner
|
||||||
|
BuildMakepkgCmdCalls []Call
|
||||||
|
BuildMakepkgCmdFn func(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd
|
||||||
|
BuildPacmanCmdFn func(ctx context.Context, args *parser.Arguments, mode parser.TargetMode, noConfirm bool) *exec.Cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
type MockRunner struct {
|
||||||
|
ShowCalls []Call
|
||||||
|
CaptureCalls []Call
|
||||||
|
ShowFn func(cmd *exec.Cmd) error
|
||||||
|
CaptureFn func(cmd *exec.Cmd) (stdout string, stderr string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) BuildMakepkgCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||||
|
var res *exec.Cmd
|
||||||
|
if m.BuildMakepkgCmdFn != nil {
|
||||||
|
res = m.BuildMakepkgCmdFn(ctx, dir, extraArgs...)
|
||||||
|
} else {
|
||||||
|
res = exec.CommandContext(ctx, "makepkg", extraArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.BuildMakepkgCmdCalls = append(m.BuildMakepkgCmdCalls, Call{
|
||||||
|
Res: []interface{}{res},
|
||||||
|
Args: []interface{}{
|
||||||
|
ctx,
|
||||||
|
dir,
|
||||||
|
extraArgs,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) AddMakepkgFlag(flag string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) BuildGitCmd(ctx context.Context, dir string, extraArgs ...string) *exec.Cmd {
|
||||||
|
return exec.CommandContext(ctx, "git", extraArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) BuildPacmanCmd(ctx context.Context, args *parser.Arguments, mode parser.TargetMode, noConfirm bool) *exec.Cmd {
|
||||||
|
var res *exec.Cmd
|
||||||
|
|
||||||
|
if m.BuildPacmanCmdFn != nil {
|
||||||
|
res = m.BuildPacmanCmdFn(ctx, args, mode, noConfirm)
|
||||||
|
} else {
|
||||||
|
res = exec.CommandContext(ctx, "pacman")
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) SetPacmanDBPath(path string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) SudoLoop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) Capture(cmd *exec.Cmd) (stdout, stderr string, err error) {
|
||||||
|
return m.Runner.Capture(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockBuilder) Show(cmd *exec.Cmd) error {
|
||||||
|
return m.Runner.Show(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockRunner) Capture(cmd *exec.Cmd) (stdout, stderr string, err error) {
|
||||||
|
m.CaptureCalls = append(m.CaptureCalls, Call{
|
||||||
|
Args: []interface{}{
|
||||||
|
cmd,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if m.CaptureFn != nil {
|
||||||
|
return m.CaptureFn(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockRunner) Show(cmd *exec.Cmd) error {
|
||||||
|
var err error
|
||||||
|
if m.ShowFn != nil {
|
||||||
|
err = m.ShowFn(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.ShowCalls = append(m.ShowCalls, Call{
|
||||||
|
Args: []interface{}{
|
||||||
|
cmd,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
25
pkg/vcs/mock.go
Normal file
25
pkg/vcs/mock.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package vcs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mock struct{}
|
||||||
|
|
||||||
|
func (m *Mock) Update(ctx context.Context, pkgName string, sources []gosrc.ArchString, mux sync.Locker, wg *sync.WaitGroup) {
|
||||||
|
wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mock) Save() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mock) RemovePackage(pkgs []string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mock) Load() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -17,6 +17,15 @@ import (
|
|||||||
"github.com/Jguer/yay/v11/pkg/text"
|
"github.com/Jguer/yay/v11/pkg/text"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Store interface {
|
||||||
|
Update(ctx context.Context, pkgName string,
|
||||||
|
sources []gosrc.ArchString, mux sync.Locker, wg *sync.WaitGroup,
|
||||||
|
)
|
||||||
|
Save() error
|
||||||
|
RemovePackage(pkgs []string)
|
||||||
|
Load() error
|
||||||
|
}
|
||||||
|
|
||||||
// InfoStore is a collection of OriginInfoByURL by Package.
|
// InfoStore is a collection of OriginInfoByURL by Package.
|
||||||
// Containing a map of last commit SHAs of a repo.
|
// Containing a map of last commit SHAs of a repo.
|
||||||
type InfoStore struct {
|
type InfoStore struct {
|
||||||
|
|||||||
8
sync.go
8
sync.go
@ -58,14 +58,14 @@ func syncInstall(ctx context.Context,
|
|||||||
|
|
||||||
type OperationService struct {
|
type OperationService struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
config *settings.Configuration
|
cfg *settings.Configuration
|
||||||
dbExecutor db.Executor
|
dbExecutor db.Executor
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOperationService(ctx context.Context, config *settings.Configuration, dbExecutor db.Executor) *OperationService {
|
func NewOperationService(ctx context.Context, cfg *settings.Configuration, dbExecutor db.Executor) *OperationService {
|
||||||
return &OperationService{
|
return &OperationService{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
config: config,
|
cfg: cfg,
|
||||||
dbExecutor: dbExecutor,
|
dbExecutor: dbExecutor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ func (o *OperationService) Run(ctx context.Context,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
preparer := NewPreparer(o.dbExecutor, config.Runtime.CmdBuilder, config)
|
preparer := NewPreparer(o.dbExecutor, config.Runtime.CmdBuilder, config)
|
||||||
installer := NewInstaller(o.dbExecutor)
|
installer := NewInstaller(o.dbExecutor, o.cfg.Runtime.CmdBuilder, o.cfg.Runtime.VCSStore, o.cfg.Runtime.Mode)
|
||||||
|
|
||||||
pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, targets)
|
pkgBuildDirs, err := preparer.Run(ctx, os.Stdout, targets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user