mirror of
				https://github.com/Jguer/yay.git
				synced 2025-11-04 00:03:44 -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/multierror"
 | 
			
		||||
	"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/text"
 | 
			
		||||
	"github.com/Jguer/yay/v11/pkg/vcs"
 | 
			
		||||
 | 
			
		||||
	gosrc "github.com/Morganamilo/go-srcinfo"
 | 
			
		||||
	mapset "github.com/deckarep/golang-set/v2"
 | 
			
		||||
@ -24,14 +26,20 @@ type (
 | 
			
		||||
		dbExecutor        db.Executor
 | 
			
		||||
		postInstallHooks  []PostInstallHookFunc
 | 
			
		||||
		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{
 | 
			
		||||
		dbExecutor:        dbExecutor,
 | 
			
		||||
		postInstallHooks:  []PostInstallHookFunc{},
 | 
			
		||||
		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 {
 | 
			
		||||
		base := nameToBase[name]
 | 
			
		||||
		dir := pkgBuildDirsByBase[base]
 | 
			
		||||
		args := []string{"--nobuild", "-fC"}
 | 
			
		||||
 | 
			
		||||
		if installIncompatible {
 | 
			
		||||
			args = append(args, "--ignorearch")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 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 {
 | 
			
		||||
		pkgdests, errMake := installer.buildPkg(ctx, dir, base, installIncompatible, cmdArgs.ExistsArg("needed"))
 | 
			
		||||
		if errMake != nil {
 | 
			
		||||
			if !lastLayer {
 | 
			
		||||
				return fmt.Errorf("%s - %w", gotext.Get("error making: %s", base), errMake)
 | 
			
		||||
			}
 | 
			
		||||
@ -204,6 +183,11 @@ func (installer *Installer) installAURPackages(ctx context.Context,
 | 
			
		||||
			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)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
@ -223,22 +207,89 @@ func (installer *Installer) installAURPackages(ctx context.Context,
 | 
			
		||||
 | 
			
		||||
		srcinfo := srcinfos[base]
 | 
			
		||||
		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()
 | 
			
		||||
 | 
			
		||||
	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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 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 {
 | 
			
		||||
	switch {
 | 
			
		||||
	case cmdArgs.ExistsArg("asdeps", "asdep"):
 | 
			
		||||
@ -279,7 +330,7 @@ func (installer *Installer) getNewTargets(pkgdests map[string]string, name strin
 | 
			
		||||
	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
 | 
			
		||||
	syncExp mapset.Set[string], // repo targets that are exp
 | 
			
		||||
) error {
 | 
			
		||||
@ -297,14 +348,14 @@ func (*Installer) installSyncPackages(ctx context.Context, cmdArgs *parser.Argum
 | 
			
		||||
	arguments.ClearTargets()
 | 
			
		||||
	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))
 | 
			
		||||
 | 
			
		||||
	if errD := asdeps(ctx, cmdArgs, syncDeps.ToSlice()); errD != nil {
 | 
			
		||||
	if errD := asdeps(ctx, installer.exeCmd, installer.targetMode, cmdArgs, syncDeps.ToSlice()); errD != nil {
 | 
			
		||||
		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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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"
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	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/stringset"
 | 
			
		||||
	"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 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@ -56,20 +61,26 @@ func setPkgReason(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string,
 | 
			
		||||
		cmdArgs.AddTarget(pkgName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
 | 
			
		||||
		cmdArgs, config.Runtime.Mode, settings.NoConfirm)); err != nil {
 | 
			
		||||
	if err := cmdBuilder.Show(cmdBuilder.BuildPacmanCmd(ctx,
 | 
			
		||||
		cmdArgs, mode, settings.NoConfirm)); err != nil {
 | 
			
		||||
		return &SetPkgReasonError{exp: exp}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func asdeps(ctx context.Context, cmdArgs *parser.Arguments, pkgs []string) error {
 | 
			
		||||
	return setPkgReason(ctx, cmdArgs, pkgs, false)
 | 
			
		||||
func asdeps(ctx context.Context,
 | 
			
		||||
	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 {
 | 
			
		||||
	return setPkgReason(ctx, cmdArgs, pkgs, true)
 | 
			
		||||
func asexp(ctx context.Context,
 | 
			
		||||
	cmdBuilder exe.ICmdBuilder,
 | 
			
		||||
	mode parser.TargetMode, cmdArgs *parser.Arguments, pkgs []string,
 | 
			
		||||
) error {
 | 
			
		||||
	return setPkgReason(ctx, cmdBuilder, mode, cmdArgs, pkgs, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if errExp := asexp(ctx, cmdArgs, exp); errExp != nil {
 | 
			
		||||
		if errExp := asexp(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, exp); errExp != nil {
 | 
			
		||||
			return errExp
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -487,9 +498,11 @@ nextpkg:
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parsePackageList(ctx context.Context, dir string) (pkgdests map[string]string, pkgVersion string, err error) {
 | 
			
		||||
	stdout, stderr, err := config.Runtime.CmdBuilder.Capture(
 | 
			
		||||
		config.Runtime.CmdBuilder.BuildMakepkgCmd(ctx, dir, "--packagelist"))
 | 
			
		||||
func parsePackageList(ctx context.Context, cmdBuilder exe.ICmdBuilder,
 | 
			
		||||
	dir string,
 | 
			
		||||
) (pkgdests map[string]string, pkgVersion string, err error) {
 | 
			
		||||
	stdout, stderr, err := cmdBuilder.Capture(
 | 
			
		||||
		cmdBuilder.BuildMakepkgCmd(ctx, dir, "--packagelist"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(pkgdests) == 0 {
 | 
			
		||||
		return nil, "", &NoPkgDestsFoundError{dir}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pkgdests, pkgVersion, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -644,8 +661,9 @@ func buildInstallPkgbuilds(
 | 
			
		||||
 | 
			
		||||
		if !satisfied || !config.BatchInstall {
 | 
			
		||||
			text.Debugln("non batch installing archives:", pkgArchives)
 | 
			
		||||
			errArchive := installPkgArchive(ctx, cmdArgs, pkgArchives)
 | 
			
		||||
			errReason := setInstallReason(ctx, cmdArgs, deps, exp)
 | 
			
		||||
			errArchive := installPkgArchive(ctx, config.Runtime.CmdBuilder,
 | 
			
		||||
				config.Runtime.Mode, config.Runtime.VCSStore, cmdArgs, pkgArchives)
 | 
			
		||||
			errReason := setInstallReason(ctx, config.Runtime.CmdBuilder, config.Runtime.Mode, cmdArgs, deps, exp)
 | 
			
		||||
 | 
			
		||||
			deps = make([]string, 0)
 | 
			
		||||
			exp = make([]string, 0)
 | 
			
		||||
@ -678,7 +696,7 @@ func buildInstallPkgbuilds(
 | 
			
		||||
			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 {
 | 
			
		||||
			return errList
 | 
			
		||||
		}
 | 
			
		||||
@ -797,12 +815,12 @@ func buildInstallPkgbuilds(
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 {
 | 
			
		||||
		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 {
 | 
			
		||||
		go config.Runtime.VCSStore.RemovePackage([]string{do.Aur[len(do.Aur)-1].String()})
 | 
			
		||||
	}
 | 
			
		||||
@ -812,7 +830,13 @@ func buildInstallPkgbuilds(
 | 
			
		||||
	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 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@ -833,28 +857,31 @@ func installPkgArchive(ctx context.Context, cmdArgs *parser.Arguments, pkgArchiv
 | 
			
		||||
 | 
			
		||||
	arguments.AddTarget(pkgArchives...)
 | 
			
		||||
 | 
			
		||||
	if errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
 | 
			
		||||
		arguments, config.Runtime.Mode, settings.NoConfirm)); errShow != nil {
 | 
			
		||||
	if errShow := cmdBuilder.Show(cmdBuilder.BuildPacmanCmd(ctx,
 | 
			
		||||
		arguments, mode, settings.NoConfirm)); errShow != nil {
 | 
			
		||||
		return errShow
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if errStore := config.Runtime.VCSStore.Save(); errStore != nil {
 | 
			
		||||
	if errStore := vcsStore.Save(); errStore != nil {
 | 
			
		||||
		fmt.Fprintln(os.Stderr, errStore)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if errDeps := asdeps(ctx, cmdArgs, deps); errDeps != nil {
 | 
			
		||||
	if errDeps := asdeps(ctx, cmdBuilder, mode, cmdArgs, deps); errDeps != nil {
 | 
			
		||||
		return errDeps
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return asexp(ctx, cmdArgs, exps)
 | 
			
		||||
	return asexp(ctx, cmdBuilder, mode, cmdArgs, exps)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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, errors.New(
 | 
			
		||||
			gotext.Get(
 | 
			
		||||
				"the PKGDEST for %s is listed by makepkg but does not exist: %s",
 | 
			
		||||
				name, pkgdest))
 | 
			
		||||
		return deps, exp, pkgArchives, &FindPkgDestError{pkgDest: pkgdest, name: name}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pkgArchives = append(pkgArchives, pkgdest)
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ type (
 | 
			
		||||
 | 
			
		||||
type DBExecutor struct {
 | 
			
		||||
	db.Executor
 | 
			
		||||
	IsCorrectVersionInstalledFunc func(string, string) bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t DBExecutor) AlpmArchitectures() ([]string, error) {
 | 
			
		||||
@ -31,6 +32,9 @@ func (t DBExecutor) Cleanup() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t DBExecutor) IsCorrectVersionInstalled(s, s2 string) bool {
 | 
			
		||||
	if t.IsCorrectVersionInstalledFunc != nil {
 | 
			
		||||
		return t.IsCorrectVersionInstalledFunc(s, s2)
 | 
			
		||||
	}
 | 
			
		||||
	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"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
// Containing a map of last commit SHAs of a repo.
 | 
			
		||||
type InfoStore struct {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								sync.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								sync.go
									
									
									
									
									
								
							@ -58,14 +58,14 @@ func syncInstall(ctx context.Context,
 | 
			
		||||
 | 
			
		||||
type OperationService struct {
 | 
			
		||||
	ctx        context.Context
 | 
			
		||||
	config     *settings.Configuration
 | 
			
		||||
	cfg        *settings.Configuration
 | 
			
		||||
	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{
 | 
			
		||||
		ctx:        ctx,
 | 
			
		||||
		config:     config,
 | 
			
		||||
		cfg:        cfg,
 | 
			
		||||
		dbExecutor: dbExecutor,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -79,7 +79,7 @@ func (o *OperationService) Run(ctx context.Context,
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	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)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user