mirror of
https://github.com/Jguer/yay.git
synced 2025-10-04 00:03:11 -04:00
refactor(build): optimize allocations and add tests (#2601)
* perf(build): optimize map/slice allocations and use strings.Builder * test(build): add tests for parsePackageList
This commit is contained in:
parent
95fc0938fd
commit
2dcf94544c
@ -2,6 +2,7 @@ package build
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
@ -13,13 +14,17 @@ type FailedIgnoredPkgError struct {
|
||||
}
|
||||
|
||||
func (e *FailedIgnoredPkgError) Error() string {
|
||||
msg := gotext.Get("Failed to install the following packages. Manual intervention is required:")
|
||||
var sb strings.Builder
|
||||
sb.WriteString(gotext.Get("Failed to install the following packages. Manual intervention is required:"))
|
||||
|
||||
for pkg, err := range e.pkgErrors {
|
||||
msg += "\n" + pkg + " - " + err.Error()
|
||||
sb.WriteString("\n")
|
||||
sb.WriteString(pkg)
|
||||
sb.WriteString(" - ")
|
||||
sb.WriteString(err.Error())
|
||||
}
|
||||
|
||||
return msg
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
type PkgDestNotInListError struct {
|
||||
|
@ -145,7 +145,7 @@ func (installer *Installer) handleLayer(ctx context.Context,
|
||||
excluded []string,
|
||||
) error {
|
||||
// Install layer
|
||||
nameToBaseMap := make(map[string]string, 0)
|
||||
nameToBaseMap := make(map[string]string, len(layer))
|
||||
syncDeps, syncExp, syncGroups := mapset.NewThreadUnsafeSet[string](),
|
||||
mapset.NewThreadUnsafeSet[string](), mapset.NewThreadUnsafeSet[string]()
|
||||
aurDeps, aurExp, aurOrigTargetBases := mapset.NewThreadUnsafeSet[string](),
|
||||
@ -225,8 +225,9 @@ func (installer *Installer) installAURPackages(ctx context.Context,
|
||||
}
|
||||
|
||||
builtPkgDests := make(map[string]map[string]string)
|
||||
deps, exps := make([]string, 0, aurDepNames.Cardinality()), make([]string, 0, aurExpNames.Cardinality())
|
||||
pkgArchives := make([]string, 0, len(exps)+len(deps))
|
||||
deps := make([]string, 0, aurDepNames.Cardinality())
|
||||
exps := make([]string, 0, aurExpNames.Cardinality())
|
||||
pkgArchives := make([]string, 0, len(all))
|
||||
|
||||
for _, name := range all {
|
||||
base := nameToBase[name]
|
||||
|
@ -134,7 +134,7 @@ func parsePackageList(ctx context.Context, cmdBuilder exe.ICmdBuilder,
|
||||
}
|
||||
|
||||
lines := strings.Split(stdout, "\n")
|
||||
pkgdests = make(map[string]string)
|
||||
pkgdests = make(map[string]string, len(lines))
|
||||
|
||||
for _, line := range lines {
|
||||
if line == "" {
|
||||
|
166
pkg/sync/build/pkg_archive_test.go
Normal file
166
pkg/sync/build/pkg_archive_test.go
Normal file
@ -0,0 +1,166 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/Jguer/yay/v12/pkg/settings/exe"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParsePackageList(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testCase struct {
|
||||
desc string
|
||||
mockStdout string
|
||||
mockStderr string
|
||||
mockErr error
|
||||
wantPkgDests map[string]string
|
||||
wantPkgVersion string
|
||||
wantErr bool
|
||||
wantErrText string // Optional: specific error text to check
|
||||
}
|
||||
|
||||
testCases := []testCase{
|
||||
{
|
||||
desc: "Standard package",
|
||||
mockStdout: "/path/to/package-1.2.3-4-x86_64.pkg.tar.zst\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"package": "/path/to/package-1.2.3-4-x86_64.pkg.tar.zst",
|
||||
},
|
||||
wantPkgVersion: "1.2.3-4",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Package with dash in name",
|
||||
mockStdout: "/path/to/package-name-with-dash-1.0.0-1-any.pkg.tar.gz\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"package-name-with-dash": "/path/to/package-name-with-dash-1.0.0-1-any.pkg.tar.gz",
|
||||
},
|
||||
wantPkgVersion: "1.0.0-1",
|
||||
wantErr: false, // This should fail with current logic but pass with regex
|
||||
},
|
||||
{
|
||||
desc: "Multiple packages",
|
||||
mockStdout: "/path/to/pkg1-1.0-1-x86_64.pkg.tar.zst\n/other/path/pkg2-2.5-3-any.pkg.tar.xz\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"pkg1": "/path/to/pkg1-1.0-1-x86_64.pkg.tar.zst",
|
||||
"pkg2": "/other/path/pkg2-2.5-3-any.pkg.tar.xz",
|
||||
},
|
||||
wantPkgVersion: "2.5-3", // Version of the last package processed
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Empty input",
|
||||
mockStdout: "",
|
||||
wantErr: true, // Expect NoPkgDestsFoundError
|
||||
},
|
||||
{
|
||||
desc: "Input with only newline",
|
||||
mockStdout: "\n",
|
||||
wantErr: true, // Expect NoPkgDestsFoundError
|
||||
},
|
||||
{
|
||||
desc: "Makepkg error",
|
||||
mockStderr: "makepkg failed",
|
||||
mockErr: fmt.Errorf("exit status 1"),
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "Malformed filename (too few dashes)",
|
||||
mockStdout: "/path/to/malformed-package.pkg.tar.zst\n",
|
||||
wantErr: true, // Expect "cannot find package name" error
|
||||
},
|
||||
{
|
||||
desc: "Package with epoch",
|
||||
mockStdout: "/path/to/epochpkg-1:2.0.0-1-x86_64.pkg.tar.zst\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"epochpkg": "/path/to/epochpkg-1:2.0.0-1-x86_64.pkg.tar.zst",
|
||||
},
|
||||
wantPkgVersion: "1:2.0.0-1",
|
||||
wantErr: false, // This might fail with current logic
|
||||
},
|
||||
{
|
||||
desc: "Package with .zst extension",
|
||||
mockStdout: "/path/to/zstdpkg-3.3-1-any.pkg.tar.zst\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"zstdpkg": "/path/to/zstdpkg-3.3-1-any.pkg.tar.zst",
|
||||
},
|
||||
wantPkgVersion: "3.3-1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Package with .gz extension",
|
||||
mockStdout: "/path/to/gzpkg-3.3-1-any.pkg.tar.gz\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"gzpkg": "/path/to/gzpkg-3.3-1-any.pkg.tar.gz",
|
||||
},
|
||||
wantPkgVersion: "3.3-1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Package with .xz extension",
|
||||
mockStdout: "/path/to/xzpkg-3.3-1-any.pkg.tar.xz\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"xzpkg": "/path/to/xzpkg-3.3-1-any.pkg.tar.xz",
|
||||
},
|
||||
wantPkgVersion: "3.3-1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Package with .bz2 extension",
|
||||
mockStdout: "/path/to/bz2pkg-3.3-1-any.pkg.tar.bz2\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"bz2pkg": "/path/to/bz2pkg-3.3-1-any.pkg.tar.bz2",
|
||||
},
|
||||
wantPkgVersion: "3.3-1",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
desc: "Package with .tar extension (uncompressed)",
|
||||
mockStdout: "/path/to/tarpkg-3.3-1-any.pkg.tar\n",
|
||||
wantPkgDests: map[string]string{
|
||||
"tarpkg": "/path/to/tarpkg-3.3-1-any.pkg.tar",
|
||||
},
|
||||
wantPkgVersion: "3.3-1",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc // capture range variable
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockRunner := &exe.MockRunner{
|
||||
CaptureFn: func(cmd *exec.Cmd) (string, string, error) {
|
||||
// Basic check to ensure the command looks right
|
||||
require.Contains(t, cmd.String(), "--packagelist")
|
||||
return tc.mockStdout, tc.mockStderr, tc.mockErr
|
||||
},
|
||||
}
|
||||
cmdBuilder := &exe.CmdBuilder{Runner: mockRunner} // Simplified for this test
|
||||
|
||||
pkgdests, pkgVersion, err := parsePackageList(context.Background(), cmdBuilder, "/fake/dir")
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(t, err)
|
||||
if tc.wantErrText != "" {
|
||||
assert.Contains(t, err.Error(), tc.wantErrText)
|
||||
}
|
||||
// Check for specific error types if needed
|
||||
if tc.desc == "Empty input" || tc.desc == "Input with only newline" {
|
||||
assert.IsType(t, &NoPkgDestsFoundError{}, err)
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.wantPkgDests, pkgdests)
|
||||
assert.Equal(t, tc.wantPkgVersion, pkgVersion)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user