mirror of
https://github.com/Jguer/yay.git
synced 2025-12-27 11:06:51 -05:00
feat(local_install): check PKGBUILD and .SRCINFO presence and generate .SRCINFO if necessary (#1938)
check build file presence and generate if needed
This commit is contained in:
@@ -1,6 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/leonelquinteros/gotext"
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/leonelquinteros/gotext"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrPackagesNotFound = errors.New(gotext.Get("could not find all required packages"))
|
||||||
|
|
||||||
type NoPkgDestsFoundError struct {
|
type NoPkgDestsFoundError struct {
|
||||||
dir string
|
dir string
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -11,6 +13,7 @@ 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/topo"
|
"github.com/Jguer/yay/v11/pkg/topo"
|
||||||
|
|
||||||
@@ -19,7 +22,38 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInstallRepoPkgs = errors.New(gotext.Get("error installing repo packages"))
|
var (
|
||||||
|
ErrInstallRepoPkgs = errors.New(gotext.Get("error installing repo packages"))
|
||||||
|
ErrNoBuildFiles = errors.New(gotext.Get("cannot find PKGBUILD and .SRCINFO in directory"))
|
||||||
|
)
|
||||||
|
|
||||||
|
func srcinfoExists(ctx context.Context,
|
||||||
|
cmdBuilder exe.ICmdBuilder, targetDir string,
|
||||||
|
) error {
|
||||||
|
srcInfoDir := filepath.Join(targetDir, ".SRCINFO")
|
||||||
|
pkgbuildDir := filepath.Join(targetDir, "PKGBUILD")
|
||||||
|
if _, err := os.Stat(srcInfoDir); err == nil {
|
||||||
|
if _, err := os.Stat(pkgbuildDir); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(pkgbuildDir); err == nil {
|
||||||
|
// run makepkg to generate .SRCINFO
|
||||||
|
srcinfo, stderr, err := cmdBuilder.Capture(cmdBuilder.BuildMakepkgCmd(ctx, targetDir, "--printsrcinfo"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to generate .SRCINFO: %w - %s", err, stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(srcInfoDir, []byte(srcinfo), 0o600); err != nil {
|
||||||
|
return fmt.Errorf("unable to write .SRCINFO: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("%w: %s", ErrNoBuildFiles, targetDir)
|
||||||
|
}
|
||||||
|
|
||||||
func installLocalPKGBUILD(
|
func installLocalPKGBUILD(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@@ -38,17 +72,20 @@ func installLocalPKGBUILD(
|
|||||||
cmdArgs.ExistsDouble("d", "nodeps"), noCheck, cmdArgs.ExistsArg("needed"),
|
cmdArgs.ExistsDouble("d", "nodeps"), noCheck, cmdArgs.ExistsArg("needed"),
|
||||||
config.Runtime.Logger.Child("grapher"))
|
config.Runtime.Logger.Child("grapher"))
|
||||||
graph := topo.New[string, *dep.InstallInfo]()
|
graph := topo.New[string, *dep.InstallInfo]()
|
||||||
for _, target := range cmdArgs.Targets {
|
for _, targetDir := range cmdArgs.Targets {
|
||||||
var errG error
|
if err := srcinfoExists(ctx, config.Runtime.CmdBuilder, targetDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
pkgbuild, err := gosrc.ParseFile(filepath.Join(target, ".SRCINFO"))
|
pkgbuild, err := gosrc.ParseFile(filepath.Join(targetDir, ".SRCINFO"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, gotext.Get("failed to parse .SRCINFO"))
|
return errors.Wrap(err, gotext.Get("failed to parse .SRCINFO"))
|
||||||
}
|
}
|
||||||
|
|
||||||
graph, errG = grapher.GraphFromSrcInfo(ctx, graph, target, pkgbuild)
|
var errG error
|
||||||
|
graph, errG = grapher.GraphFromSrcInfo(ctx, graph, targetDir, pkgbuild)
|
||||||
if errG != nil {
|
if errG != nil {
|
||||||
return err
|
return errG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +93,7 @@ func installLocalPKGBUILD(
|
|||||||
multiErr := &multierror.MultiError{}
|
multiErr := &multierror.MultiError{}
|
||||||
targets := graph.TopoSortedLayerMap(func(name string, ii *dep.InstallInfo) error {
|
targets := graph.TopoSortedLayerMap(func(name string, ii *dep.InstallInfo) error {
|
||||||
if ii.Source == dep.Missing {
|
if ii.Source == dep.Missing {
|
||||||
multiErr.Add(errors.New(gotext.Get("could not find %s%s", name, ii.Version)))
|
multiErr.Add(fmt.Errorf("%w: %s %s", ErrPackagesNotFound, name, ii.Version))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -169,7 +170,7 @@ func TestIntegrationLocalInstall(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIntegrationLocalInstallMissingDep(t *testing.T) {
|
func TestIntegrationLocalInstallMissingDep(t *testing.T) {
|
||||||
wantErr := "could not find dotnet-sdk<7"
|
wantErr := ErrPackagesNotFound
|
||||||
makepkgBin := t.TempDir() + "/makepkg"
|
makepkgBin := t.TempDir() + "/makepkg"
|
||||||
pacmanBin := t.TempDir() + "/pacman"
|
pacmanBin := t.TempDir() + "/pacman"
|
||||||
gitBin := t.TempDir() + "/git"
|
gitBin := t.TempDir() + "/git"
|
||||||
@@ -270,8 +271,7 @@ func TestIntegrationLocalInstallMissingDep(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = handleCmd(context.Background(), config, cmdArgs, db)
|
err = handleCmd(context.Background(), config, cmdArgs, db)
|
||||||
require.Error(t, err)
|
require.ErrorContains(t, err, wantErr.Error())
|
||||||
require.EqualError(t, err, wantErr)
|
|
||||||
|
|
||||||
require.Len(t, mockRunner.ShowCalls, len(wantShow))
|
require.Len(t, mockRunner.ShowCalls, len(wantShow))
|
||||||
require.Len(t, mockRunner.CaptureCalls, len(wantCapture))
|
require.Len(t, mockRunner.CaptureCalls, len(wantCapture))
|
||||||
@@ -445,3 +445,300 @@ func TestIntegrationLocalInstallNeeded(t *testing.T) {
|
|||||||
assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
|
assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIntegrationLocalInstallGenerateSRCINFO(t *testing.T) {
|
||||||
|
makepkgBin := t.TempDir() + "/makepkg"
|
||||||
|
pacmanBin := t.TempDir() + "/pacman"
|
||||||
|
gitBin := t.TempDir() + "/git"
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
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())
|
||||||
|
|
||||||
|
f, err = os.OpenFile(gitBin, os.O_RDONLY|os.O_CREATE, 0o755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
|
srcinfo, err := os.ReadFile("testdata/jfin/.SRCINFO")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, strings.HasPrefix(string(srcinfo), "pkgbase = jellyfin"), string(srcinfo))
|
||||||
|
|
||||||
|
targetDir := t.TempDir()
|
||||||
|
f, err = os.OpenFile(filepath.Join(targetDir, "PKGBUILD"), os.O_RDONLY|os.O_CREATE, 0o755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
|
tars := []string{
|
||||||
|
tmpDir + "/jellyfin-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
tmpDir + "/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
tmpDir + "/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
}
|
||||||
|
|
||||||
|
wantShow := []string{
|
||||||
|
"makepkg --verifysource -Ccf",
|
||||||
|
"pacman -S --config /etc/pacman.conf -- community/dotnet-sdk-6.0 community/dotnet-runtime-6.0",
|
||||||
|
"pacman -D -q --asdeps --config /etc/pacman.conf -- dotnet-runtime-6.0 dotnet-sdk-6.0",
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -c --nobuild --noextract --ignorearch",
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -c --nobuild --noextract --ignorearch",
|
||||||
|
"makepkg --nobuild -fC --ignorearch",
|
||||||
|
"makepkg -c --nobuild --noextract --ignorearch",
|
||||||
|
"pacman -U --config /etc/pacman.conf -- /testdir/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst /testdir/jellyfin-10.8.4-1-x86_64.pkg.tar.zst /testdir/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
"pacman -D -q --asexplicit --config /etc/pacman.conf -- jellyfin-server jellyfin jellyfin-web",
|
||||||
|
}
|
||||||
|
|
||||||
|
wantCapture := []string{
|
||||||
|
"makepkg --printsrcinfo",
|
||||||
|
"makepkg --packagelist",
|
||||||
|
"git -C testdata/jfin git reset --hard HEAD",
|
||||||
|
"git -C testdata/jfin git merge --no-edit --ff",
|
||||||
|
"makepkg --packagelist",
|
||||||
|
"makepkg --packagelist",
|
||||||
|
}
|
||||||
|
|
||||||
|
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||||
|
for _, arg := range cmd.Args {
|
||||||
|
if arg == "--printsrcinfo" {
|
||||||
|
return string(srcinfo), "", nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(tars, "\n"), "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
once := sync.Once{}
|
||||||
|
|
||||||
|
showOverride := func(cmd *exec.Cmd) error {
|
||||||
|
once.Do(func() {
|
||||||
|
for _, tar := range tars {
|
||||||
|
f, err := os.OpenFile(tar, os.O_RDONLY|os.O_CREATE, 0o666)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mockRunner := &exe.MockRunner{CaptureFn: captureOverride, ShowFn: showOverride}
|
||||||
|
cmdBuilder := &exe.CmdBuilder{
|
||||||
|
MakepkgBin: makepkgBin,
|
||||||
|
SudoBin: "su",
|
||||||
|
PacmanBin: pacmanBin,
|
||||||
|
PacmanConfigPath: "/etc/pacman.conf",
|
||||||
|
GitBin: "git",
|
||||||
|
Runner: mockRunner,
|
||||||
|
SudoLoopEnabled: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdArgs := parser.MakeArguments()
|
||||||
|
cmdArgs.AddArg("B")
|
||||||
|
cmdArgs.AddArg("i")
|
||||||
|
cmdArgs.AddTarget(targetDir)
|
||||||
|
settings.NoConfirm = true
|
||||||
|
defer func() { settings.NoConfirm = false }()
|
||||||
|
db := &mock.DBExecutor{
|
||||||
|
AlpmArchitecturesFn: func() ([]string, error) {
|
||||||
|
return []string{"x86_64"}, nil
|
||||||
|
},
|
||||||
|
LocalSatisfierExistsFn: func(s string) bool {
|
||||||
|
switch s {
|
||||||
|
case "dotnet-sdk>=6", "dotnet-sdk<7", "dotnet-runtime>=6", "dotnet-runtime<7", "jellyfin-server=10.8.4", "jellyfin-web=10.8.4":
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
SyncSatisfierFn: func(s string) mock.IPackage {
|
||||||
|
switch s {
|
||||||
|
case "dotnet-runtime>=6", "dotnet-runtime<7":
|
||||||
|
return &mock.Package{
|
||||||
|
PName: "dotnet-runtime-6.0",
|
||||||
|
PBase: "dotnet-runtime-6.0",
|
||||||
|
PVersion: "6.0.100-1",
|
||||||
|
PDB: mock.NewDB("community"),
|
||||||
|
}
|
||||||
|
case "dotnet-sdk>=6", "dotnet-sdk<7":
|
||||||
|
return &mock.Package{
|
||||||
|
PName: "dotnet-sdk-6.0",
|
||||||
|
PBase: "dotnet-sdk-6.0",
|
||||||
|
PVersion: "6.0.100-1",
|
||||||
|
PDB: mock.NewDB("community"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &settings.Configuration{
|
||||||
|
RemoveMake: "no",
|
||||||
|
Debug: false,
|
||||||
|
Runtime: &settings.Runtime{
|
||||||
|
Logger: text.NewLogger(io.Discard, strings.NewReader(""), true, "test"),
|
||||||
|
CmdBuilder: cmdBuilder,
|
||||||
|
VCSStore: &vcs.Mock{},
|
||||||
|
AURCache: &mockaur.MockAUR{
|
||||||
|
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||||
|
return []aur.Pkg{}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = handleCmd(context.Background(), config, cmdArgs, db)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Len(t, mockRunner.ShowCalls, len(wantShow))
|
||||||
|
require.Len(t, mockRunner.CaptureCalls, len(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")
|
||||||
|
show = strings.ReplaceAll(show, gitBin, "pacman")
|
||||||
|
|
||||||
|
// options are in a different order on different systems and on CI root user is used
|
||||||
|
assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntegrationLocalInstallMissingFiles(t *testing.T) {
|
||||||
|
makepkgBin := t.TempDir() + "/makepkg"
|
||||||
|
pacmanBin := t.TempDir() + "/pacman"
|
||||||
|
gitBin := t.TempDir() + "/git"
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
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())
|
||||||
|
|
||||||
|
f, err = os.OpenFile(gitBin, os.O_RDONLY|os.O_CREATE, 0o755)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
|
||||||
|
srcinfo, err := os.ReadFile("testdata/jfin/.SRCINFO")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
targetDir := t.TempDir()
|
||||||
|
|
||||||
|
tars := []string{
|
||||||
|
tmpDir + "/jellyfin-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
tmpDir + "/jellyfin-web-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
tmpDir + "/jellyfin-server-10.8.4-1-x86_64.pkg.tar.zst",
|
||||||
|
}
|
||||||
|
|
||||||
|
wantShow := []string{}
|
||||||
|
|
||||||
|
wantCapture := []string{}
|
||||||
|
|
||||||
|
captureOverride := func(cmd *exec.Cmd) (stdout string, stderr string, err error) {
|
||||||
|
fmt.Println(cmd.Args)
|
||||||
|
if cmd.Args[1] == "--printsrcinfo" {
|
||||||
|
return string(srcinfo), "", nil
|
||||||
|
}
|
||||||
|
return strings.Join(tars, "\n"), "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
once := sync.Once{}
|
||||||
|
|
||||||
|
showOverride := func(cmd *exec.Cmd) error {
|
||||||
|
once.Do(func() {
|
||||||
|
for _, tar := range tars {
|
||||||
|
f, err := os.OpenFile(tar, os.O_RDONLY|os.O_CREATE, 0o666)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, f.Close())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mockRunner := &exe.MockRunner{CaptureFn: captureOverride, ShowFn: showOverride}
|
||||||
|
cmdBuilder := &exe.CmdBuilder{
|
||||||
|
MakepkgBin: makepkgBin,
|
||||||
|
SudoBin: "su",
|
||||||
|
PacmanBin: pacmanBin,
|
||||||
|
PacmanConfigPath: "/etc/pacman.conf",
|
||||||
|
GitBin: "git",
|
||||||
|
Runner: mockRunner,
|
||||||
|
SudoLoopEnabled: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdArgs := parser.MakeArguments()
|
||||||
|
cmdArgs.AddArg("B")
|
||||||
|
cmdArgs.AddArg("i")
|
||||||
|
cmdArgs.AddTarget(targetDir)
|
||||||
|
settings.NoConfirm = true
|
||||||
|
defer func() { settings.NoConfirm = false }()
|
||||||
|
db := &mock.DBExecutor{
|
||||||
|
AlpmArchitecturesFn: func() ([]string, error) {
|
||||||
|
return []string{"x86_64"}, nil
|
||||||
|
},
|
||||||
|
LocalSatisfierExistsFn: func(s string) bool {
|
||||||
|
switch s {
|
||||||
|
case "dotnet-sdk>=6", "dotnet-sdk<7", "dotnet-runtime>=6", "dotnet-runtime<7", "jellyfin-server=10.8.4", "jellyfin-web=10.8.4":
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
SyncSatisfierFn: func(s string) mock.IPackage {
|
||||||
|
switch s {
|
||||||
|
case "dotnet-runtime>=6", "dotnet-runtime<7":
|
||||||
|
return &mock.Package{
|
||||||
|
PName: "dotnet-runtime-6.0",
|
||||||
|
PBase: "dotnet-runtime-6.0",
|
||||||
|
PVersion: "6.0.100-1",
|
||||||
|
PDB: mock.NewDB("community"),
|
||||||
|
}
|
||||||
|
case "dotnet-sdk>=6", "dotnet-sdk<7":
|
||||||
|
return &mock.Package{
|
||||||
|
PName: "dotnet-sdk-6.0",
|
||||||
|
PBase: "dotnet-sdk-6.0",
|
||||||
|
PVersion: "6.0.100-1",
|
||||||
|
PDB: mock.NewDB("community"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &settings.Configuration{
|
||||||
|
RemoveMake: "no",
|
||||||
|
Runtime: &settings.Runtime{
|
||||||
|
Logger: text.NewLogger(io.Discard, strings.NewReader(""), true, "test"),
|
||||||
|
CmdBuilder: cmdBuilder,
|
||||||
|
VCSStore: &vcs.Mock{},
|
||||||
|
AURCache: &mockaur.MockAUR{
|
||||||
|
GetFn: func(ctx context.Context, query *aur.Query) ([]aur.Pkg, error) {
|
||||||
|
return []aur.Pkg{}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = handleCmd(context.Background(), config, cmdArgs, db)
|
||||||
|
require.ErrorIs(t, err, ErrNoBuildFiles)
|
||||||
|
|
||||||
|
require.Len(t, mockRunner.ShowCalls, len(wantShow))
|
||||||
|
require.Len(t, mockRunner.CaptureCalls, len(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")
|
||||||
|
show = strings.ReplaceAll(show, gitBin, "pacman")
|
||||||
|
|
||||||
|
// options are in a different order on different systems and on CI root user is used
|
||||||
|
assert.Subset(t, strings.Split(show, " "), strings.Split(wantShow[i], " "), fmt.Sprintf("%d - %s", i, show))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -67,7 +67,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Debug {
|
if config.Debug {
|
||||||
text.DebugMode = true
|
text.GlobalLogger.Debug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if errS := config.RunMigrations(
|
if errS := config.RunMigrations(
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ func (dp *Pool) CheckMissing(noDeps, noCheckDeps bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
text.Errorln(gotext.Get("Could not find all required packages:"))
|
text.Errorln(gotext.Get("could not find all required packages:"))
|
||||||
|
|
||||||
for dep, trees := range missing.Missing {
|
for dep, trees := range missing.Missing {
|
||||||
for _, tree := range trees {
|
for _, tree := range trees {
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ func (l *Logger) GetInput(defaultValue string, noConfirm bool) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetInput(r io.Reader, defaultValue string, noConfirm bool) (string, error) {
|
func GetInput(r io.Reader, defaultValue string, noConfirm bool) (string, error) {
|
||||||
return globalLogger.GetInput(defaultValue, noConfirm)
|
return GlobalLogger.GetInput(defaultValue, noConfirm)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,56 +20,55 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
cachedColumnCount = -1
|
cachedColumnCount = -1
|
||||||
DebugMode = false
|
GlobalLogger = NewLogger(os.Stdout, os.Stdin, false, "global")
|
||||||
globalLogger = NewLogger(os.Stdout, os.Stdin, DebugMode, "global")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Debugln(a ...interface{}) {
|
func Debugln(a ...interface{}) {
|
||||||
globalLogger.Debugln(a...)
|
GlobalLogger.Debugln(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OperationInfoln(a ...interface{}) {
|
func OperationInfoln(a ...interface{}) {
|
||||||
globalLogger.OperationInfoln(a...)
|
GlobalLogger.OperationInfoln(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OperationInfo(a ...interface{}) {
|
func OperationInfo(a ...interface{}) {
|
||||||
globalLogger.OperationInfo(a...)
|
GlobalLogger.OperationInfo(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SprintOperationInfo(a ...interface{}) string {
|
func SprintOperationInfo(a ...interface{}) string {
|
||||||
return globalLogger.SprintOperationInfo(a...)
|
return GlobalLogger.SprintOperationInfo(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Info(a ...interface{}) {
|
func Info(a ...interface{}) {
|
||||||
globalLogger.Info(a...)
|
GlobalLogger.Info(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Infoln(a ...interface{}) {
|
func Infoln(a ...interface{}) {
|
||||||
globalLogger.Infoln(a...)
|
GlobalLogger.Infoln(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SprintWarn(a ...interface{}) string {
|
func SprintWarn(a ...interface{}) string {
|
||||||
return globalLogger.SprintWarn(a...)
|
return GlobalLogger.SprintWarn(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warn(a ...interface{}) {
|
func Warn(a ...interface{}) {
|
||||||
globalLogger.Warn(a...)
|
GlobalLogger.Warn(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Warnln(a ...interface{}) {
|
func Warnln(a ...interface{}) {
|
||||||
globalLogger.Warnln(a...)
|
GlobalLogger.Warnln(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SprintError(a ...interface{}) string {
|
func SprintError(a ...interface{}) string {
|
||||||
return globalLogger.SprintError(a...)
|
return GlobalLogger.SprintError(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Error(a ...interface{}) {
|
func Error(a ...interface{}) {
|
||||||
globalLogger.Error(a...)
|
GlobalLogger.Error(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Errorln(a ...interface{}) {
|
func Errorln(a ...interface{}) {
|
||||||
globalLogger.Errorln(a...)
|
GlobalLogger.Errorln(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getColumnCount() int {
|
func getColumnCount() int {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
name string
|
name string
|
||||||
debug bool
|
Debug bool
|
||||||
w io.Writer
|
w io.Writer
|
||||||
r io.Reader
|
r io.Reader
|
||||||
}
|
}
|
||||||
@@ -16,17 +16,17 @@ func NewLogger(w io.Writer, r io.Reader, debug bool, name string) *Logger {
|
|||||||
return &Logger{
|
return &Logger{
|
||||||
w: w,
|
w: w,
|
||||||
name: name,
|
name: name,
|
||||||
debug: debug,
|
Debug: debug,
|
||||||
r: r,
|
r: r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Child(name string) *Logger {
|
func (l *Logger) Child(name string) *Logger {
|
||||||
return NewLogger(l.w, l.r, l.debug, name)
|
return NewLogger(l.w, l.r, l.Debug, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Debugln(a ...any) {
|
func (l *Logger) Debugln(a ...any) {
|
||||||
if !DebugMode {
|
if !l.Debug {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
sync.go
3
sync.go
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -70,7 +69,7 @@ func syncInstall(ctx context.Context,
|
|||||||
multiErr := &multierror.MultiError{}
|
multiErr := &multierror.MultiError{}
|
||||||
targets := graph.TopoSortedLayerMap(func(s string, ii *dep.InstallInfo) error {
|
targets := graph.TopoSortedLayerMap(func(s string, ii *dep.InstallInfo) error {
|
||||||
if ii.Source == dep.Missing {
|
if ii.Source == dep.Missing {
|
||||||
multiErr.Add(errors.New(gotext.Get("could not find %s%s", s, ii.Version)))
|
multiErr.Add(fmt.Errorf("%w: %s %s", ErrPackagesNotFound, s, ii.Version))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
0
testdata/jfin/PKGBUILD
vendored
Normal file
0
testdata/jfin/PKGBUILD
vendored
Normal file
Reference in New Issue
Block a user