Jelajahi Sumber

feat(download): respect aur url settings and update deps

jguer 3 tahun lalu
induk
melakukan
08d1305ec5
10 mengubah file dengan 379 tambahan dan 90 penghapusan
  1. 1 1
      cmd.go
  2. 4 2
      get.go
  3. 2 2
      go.mod
  4. 4 0
      go.sum
  5. 68 71
      install.go
  6. 5 3
      pkg/download/aur.go
  7. 26 2
      pkg/download/aur_test.go
  8. 8 7
      pkg/download/unified.go
  9. 199 0
      pkg/download/unified_test.go
  10. 62 2
      pkg/download/utils_test.go

+ 1 - 1
cmd.go

@@ -282,7 +282,7 @@ func handleYay(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
 
 func handleGetpkgbuild(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
 	if cmdArgs.ExistsArg("p", "print") {
-		return printPkgbuilds(dbExecutor, config.Runtime.HTTPClient, cmdArgs.Targets)
+		return printPkgbuilds(dbExecutor, config.Runtime.HTTPClient, cmdArgs.Targets, config.Runtime.Mode, config.AURURL)
 	}
 	return getPkgbuilds(dbExecutor, config, cmdArgs.Targets, cmdArgs.ExistsArg("f", "force"))
 }

+ 4 - 2
get.go

@@ -11,12 +11,14 @@ import (
 	"github.com/Jguer/yay/v10/pkg/db"
 	"github.com/Jguer/yay/v10/pkg/download"
 	"github.com/Jguer/yay/v10/pkg/settings"
+	"github.com/Jguer/yay/v10/pkg/settings/parser"
 	"github.com/Jguer/yay/v10/pkg/text"
 )
 
 // yay -Gp
-func printPkgbuilds(dbExecutor db.Executor, httpClient *http.Client, targets []string) error {
-	pkgbuilds, err := download.PKGBUILDs(dbExecutor, httpClient, targets, config.Runtime.Mode)
+func printPkgbuilds(dbExecutor db.Executor, httpClient *http.Client, targets []string,
+	mode parser.TargetMode, aurURL string) error {
+	pkgbuilds, err := download.PKGBUILDs(dbExecutor, httpClient, targets, aurURL, mode)
 	if err != nil {
 		text.Errorln(err)
 	}

+ 2 - 2
go.mod

@@ -9,9 +9,9 @@ require (
 	github.com/leonelquinteros/gotext v1.5.0
 	github.com/pkg/errors v0.9.1
 	github.com/stretchr/testify v1.7.0
-	golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
+	golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e
 	golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
-	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/text v0.3.7 // indirect
 	gopkg.in/h2non/gock.v1 v1.0.15
 )
 

+ 4 - 0
go.sum

@@ -53,6 +53,8 @@ golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
 golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
@@ -60,6 +62,8 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 68 - 71
install.go

@@ -901,36 +901,6 @@ func buildInstallPkgbuilds(
 	remoteNamesCache := stringset.FromSlice(remoteNames)
 	localNamesCache := stringset.FromSlice(localNames)
 
-	doInstall := func() error {
-		if len(arguments.Targets) == 0 {
-			return nil
-		}
-
-		if errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
-			arguments, config.Runtime.Mode, settings.NoConfirm)); errShow != nil {
-			return errShow
-		}
-
-		if errStore := config.Runtime.VCSStore.Save(); err != nil {
-			fmt.Fprintln(os.Stderr, errStore)
-		}
-
-		if errDeps := asdeps(cmdArgs, deps); err != nil {
-			return errDeps
-		}
-		if errExps := asexp(cmdArgs, exp); err != nil {
-			return errExps
-		}
-
-		settings.NoConfirm = oldConfirm
-
-		arguments.ClearTargets()
-		deps = make([]string, 0)
-		exp = make([]string, 0)
-		settings.NoConfirm = true
-		return nil
-	}
-
 	for _, base := range do.Aur {
 		pkg := base.Pkgbase()
 		dir := filepath.Join(config.BuildDir, pkg)
@@ -951,7 +921,10 @@ func buildInstallPkgbuilds(
 		}
 
 		if !satisfied || !config.BatchInstall {
-			err = doInstall()
+			err = doInstall(arguments, cmdArgs, deps, exp)
+			arguments.ClearTargets()
+			deps = make([]string, 0)
+			exp = make([]string, 0)
 			if err != nil {
 				return err
 			}
@@ -1053,46 +1026,14 @@ func buildInstallPkgbuilds(
 			}
 		}
 
-		doAddTarget := func(name string, optional bool) error {
-			pkgdest, ok := pkgdests[name]
-			if !ok {
-				if optional {
-					return nil
-				}
-
-				return errors.New(gotext.Get("could not find PKGDEST for: %s", name))
-			}
-
-			if _, errStat := os.Stat(pkgdest); os.IsNotExist(errStat) {
-				if optional {
-					return nil
-				}
-
-				return errors.New(
-					gotext.Get(
-						"the PKGDEST for %s is listed by makepkg but does not exist: %s",
-						name, pkgdest))
-			}
-
-			arguments.AddTarget(pkgdest)
-			if cmdArgs.ExistsArg("asdeps", "asdep") {
-				deps = append(deps, name)
-			} else if cmdArgs.ExistsArg("asexplicit", "asexp") {
-				exp = append(exp, name)
-			} else if !dp.Explicit.Get(name) && !localNamesCache.Get(name) && !remoteNamesCache.Get(name) {
-				deps = append(deps, name)
-			}
-
-			return nil
-		}
-
+		var errAdd error
 		for _, split := range base {
-			if errAdd := doAddTarget(split.Name, false); errAdd != nil {
-				return errAdd
-			}
-
-			if errAddDebug := doAddTarget(split.Name+"-debug", true); errAddDebug != nil {
-				return errAddDebug
+			for _, suffix := range []string{"", "-debug"} {
+				deps, exp, errAdd = doAddTarget(dp, localNamesCache, remoteNamesCache,
+					arguments, cmdArgs, pkgdests, deps, exp, split.Name+suffix, false)
+				if errAdd != nil {
+					return errAdd
+				}
 			}
 		}
 
@@ -1106,7 +1047,63 @@ func buildInstallPkgbuilds(
 		wg.Wait()
 	}
 
-	err = doInstall()
+	err = doInstall(arguments, cmdArgs, deps, exp)
 	settings.NoConfirm = oldConfirm
 	return err
 }
+
+func doInstall(arguments, cmdArgs *parser.Arguments, pkgDeps, pkgExp []string) error {
+	if len(arguments.Targets) == 0 {
+		return nil
+	}
+
+	if errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
+		arguments, config.Runtime.Mode, settings.NoConfirm)); errShow != nil {
+		return errShow
+	}
+
+	if errStore := config.Runtime.VCSStore.Save(); errStore != nil {
+		fmt.Fprintln(os.Stderr, errStore)
+	}
+
+	if errDeps := asdeps(cmdArgs, pkgDeps); errDeps != nil {
+		return errDeps
+	}
+
+	return asexp(cmdArgs, pkgExp)
+}
+
+func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.StringSet,
+	arguments, cmdArgs *parser.Arguments, pkgdests map[string]string,
+	deps, exp []string, name string, optional bool) (newDeps, newExp []string, err error) {
+	pkgdest, ok := pkgdests[name]
+	if !ok {
+		if optional {
+			return deps, exp, nil
+		}
+
+		return deps, exp, errors.New(gotext.Get("could not find PKGDEST for: %s", name))
+	}
+
+	if _, errStat := os.Stat(pkgdest); os.IsNotExist(errStat) {
+		if optional {
+			return deps, exp, nil
+		}
+
+		return deps, exp, errors.New(
+			gotext.Get(
+				"the PKGDEST for %s is listed by makepkg but does not exist: %s",
+				name, pkgdest))
+	}
+
+	arguments.AddTarget(pkgdest)
+	if cmdArgs.ExistsArg("asdeps", "asdep") {
+		deps = append(deps, name)
+	} else if cmdArgs.ExistsArg("asexplicit", "asexp") {
+		exp = append(exp, name)
+	} else if !dp.Explicit.Get(name) && !localNamesCache.Get(name) && !remoteNamesCache.Get(name) {
+		deps = append(deps, name)
+	}
+
+	return deps, exp, nil
+}

+ 5 - 3
pkg/download/aur.go

@@ -16,10 +16,10 @@ import (
 
 var AURPackageURL = "https://aur.archlinux.org/cgit/aur.git"
 
-func AURPKGBUILD(httpClient *http.Client, pkgName string) ([]byte, error) {
+func AURPKGBUILD(httpClient *http.Client, pkgName, aurURL string) ([]byte, error) {
 	values := url.Values{}
 	values.Set("h", pkgName)
-	pkgURL := AURPackageURL + "/plain/PKGBUILD?" + values.Encode()
+	pkgURL := aurURL + "/cgit/aur.git/plain/PKGBUILD?" + values.Encode()
 
 	resp, err := httpClient.Get(pkgURL)
 	if err != nil {
@@ -68,17 +68,19 @@ func AURPKGBUILDRepos(
 		go func(target string) {
 			newClone, err := AURPKGBUILDRepo(cmdBuilder, aurURL, target, dest, force)
 
+			progress := 0
 			if err != nil {
 				errs.Add(err)
 			} else {
 				mux.Lock()
 				cloned[target] = newClone
+				progress = len(cloned)
 				mux.Unlock()
 			}
 
 			text.OperationInfoln(
 				gotext.Get("(%d/%d) Downloaded PKGBUILD: %s",
-					len(cloned), len(targets), text.Cyan(target)))
+					progress, len(targets), text.Cyan(target)))
 
 			<-sem
 

+ 26 - 2
pkg/download/aur_test.go

@@ -56,9 +56,8 @@ func TestGetAURPkgbuild(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			AURPackageURL = PKGBuild.URL
 			PKGBuild.Config.Handler = tt.args.handler
-			got, err := AURPKGBUILD(PKGBuild.Client(), tt.args.pkgName)
+			got, err := AURPKGBUILD(PKGBuild.Client(), tt.args.pkgName, PKGBuild.URL)
 			if tt.wantErr {
 				assert.Error(t, err)
 			} else {
@@ -114,3 +113,28 @@ func TestAURPKGBUILDRepoExistsPerms(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, false, cloned)
 }
+
+// GIVEN
+func TestAURPKGBUILDRepos(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	os.MkdirAll(filepath.Join(dir, "yay-bin", ".git"), 0o777)
+
+	targets := []string{"yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		want:  "",
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	cloned, err := AURPKGBUILDRepos(cmdBuilder, targets, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"yay": true, "yay-bin": false, "yay-git": true}, cloned)
+}

+ 8 - 7
pkg/download/unified.go

@@ -8,8 +8,6 @@ import (
 
 	"github.com/leonelquinteros/gotext"
 
-	"github.com/Jguer/go-alpm/v2"
-
 	"github.com/Jguer/yay/v10/pkg/db"
 	"github.com/Jguer/yay/v10/pkg/multierror"
 	"github.com/Jguer/yay/v10/pkg/settings/exe"
@@ -73,7 +71,8 @@ func getURLName(pkg db.IPackage) string {
 	return name
 }
 
-func PKGBUILDs(dbExecutor DBSearcher, httpClient *http.Client, targets []string, mode parser.TargetMode) (map[string][]byte, error) {
+func PKGBUILDs(dbExecutor DBSearcher, httpClient *http.Client, targets []string,
+	aurURL string, mode parser.TargetMode) (map[string][]byte, error) {
 	pkgbuilds := make(map[string][]byte, len(targets))
 
 	var (
@@ -102,7 +101,7 @@ func PKGBUILDs(dbExecutor DBSearcher, httpClient *http.Client, targets []string,
 			)
 
 			if aur {
-				pkgbuild, err = AURPKGBUILD(httpClient, pkgName)
+				pkgbuild, err = AURPKGBUILD(httpClient, pkgName, aurURL)
 			} else {
 				pkgbuild, err = ABSPKGBUILD(httpClient, dbName, pkgName)
 			}
@@ -159,22 +158,24 @@ func PKGBUILDRepos(dbExecutor DBSearcher,
 				newClone, err = ABSPKGBUILDRepo(cmdBuilder, dbName, pkgName, dest, force)
 			}
 
+			progress := 0
 			if err != nil {
 				errs.Add(err)
 			} else {
 				mux.Lock()
 				cloned[target] = newClone
+				progress = len(cloned)
 				mux.Unlock()
 			}
 
 			if aur {
 				text.OperationInfoln(
 					gotext.Get("(%d/%d) Downloaded PKGBUILD: %s",
-						len(cloned), len(targets), text.Cyan(pkgName)))
+						progress, len(targets), text.Cyan(pkgName)))
 			} else {
 				text.OperationInfoln(
 					gotext.Get("(%d/%d) Downloaded PKGBUILD from ABS: %s",
-						len(cloned), len(targets), text.Cyan(pkgName)))
+						progress, len(targets), text.Cyan(pkgName)))
 			}
 
 			<-sem
@@ -194,7 +195,7 @@ func getPackageUsableName(dbExecutor DBSearcher, target string, mode parser.Targ
 
 	dbName, name := text.SplitDBFromName(target)
 	if dbName != "aur" && mode.AtLeastRepo() {
-		var pkg alpm.IPackage
+		var pkg db.IPackage
 		if dbName != "" {
 			pkg = dbExecutor.SatisfierFromDB(name, dbName)
 			if pkg == nil {

+ 199 - 0
pkg/download/unified_test.go

@@ -0,0 +1,199 @@
+package download
+
+import (
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"gopkg.in/h2non/gock.v1"
+
+	"github.com/Jguer/yay/v10/pkg/settings/exe"
+	"github.com/Jguer/yay/v10/pkg/settings/parser"
+)
+
+// GIVEN 2 aur packages and 1 in repo
+// GIVEN package in repo is already present
+// WHEN defining package db as a target
+// THEN all should be found and cloned, except the repo one
+func TestPKGBUILDReposDefinedDBPull(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	os.MkdirAll(filepath.Join(dir, "yay", ".git"), 0o777)
+
+	targets := []string{"core/yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+	cloned, err := PKGBUILDRepos(searcher,
+		cmdBuilder,
+		targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"core/yay": false, "yay-bin": true, "yay-git": true}, cloned)
+}
+
+// GIVEN 2 aur packages and 1 in repo
+// WHEN defining package db as a target
+// THEN all should be found and cloned
+func TestPKGBUILDReposDefinedDBClone(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	targets := []string{"core/yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+	cloned, err := PKGBUILDRepos(searcher,
+		cmdBuilder,
+		targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"core/yay": true, "yay-bin": true, "yay-git": true}, cloned)
+}
+
+// GIVEN 2 aur packages and 1 in repo
+// WHEN defining as non specified targets
+// THEN all should be found and cloned
+func TestPKGBUILDReposClone(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	targets := []string{"yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+	cloned, err := PKGBUILDRepos(searcher,
+		cmdBuilder,
+		targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"yay": true, "yay-bin": true, "yay-git": true}, cloned)
+}
+
+// GIVEN 2 aur packages and 1 in repo but wrong db
+// WHEN defining as non specified targets
+// THEN all aur be found and cloned
+func TestPKGBUILDReposNotFound(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	targets := []string{"extra/yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+	cloned, err := PKGBUILDRepos(searcher,
+		cmdBuilder,
+		targets, parser.ModeAny, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"yay-bin": true, "yay-git": true}, cloned)
+}
+
+// GIVEN 2 aur packages and 1 in repo
+// WHEN defining as non specified targets in repo mode
+// THEN only repo should be cloned
+func TestPKGBUILDReposRepoMode(t *testing.T) {
+	dir, _ := ioutil.TempDir("/tmp/", "yay-test")
+	defer os.RemoveAll(dir)
+
+	targets := []string{"yay", "yay-bin", "yay-git"}
+	cmdRunner := &testRunner{}
+	cmdBuilder := &testGitBuilder{
+		index: 0,
+		test:  t,
+		parentBuilder: &exe.CmdBuilder{
+			Runner:   cmdRunner,
+			GitBin:   "/usr/local/bin/git",
+			GitFlags: []string{},
+		},
+	}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+	cloned, err := PKGBUILDRepos(searcher,
+		cmdBuilder,
+		targets, parser.ModeRepo, "https://aur.archlinux.org", dir, false)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string]bool{"yay": true}, cloned)
+}
+
+// GIVEN 2 aur packages and 1 in repo
+// WHEN defining as specified targets
+// THEN all aur be found and cloned
+func TestPKGBUILDFull(t *testing.T) {
+	defer gock.Off()
+
+	gock.New("https://aur.archlinux.org").
+		Get("/cgit/aur.git/plain/PKGBUILD").MatchParam("h", "yay-git").
+		Reply(200).
+		BodyString("example_yay-git")
+	gock.New("https://aur.archlinux.org").
+		Get("/cgit/aur.git/plain/PKGBUILD").MatchParam("h", "yay-bin").
+		Reply(200).
+		BodyString("example_yay-bin")
+
+	gock.New("https://github.com/").
+		Get("/archlinux/svntogit-packages/raw/packages/yay/trunk/PKGBUILD").
+		Reply(200).
+		BodyString("example_yay")
+
+	targets := []string{"core/yay", "aur/yay-bin", "yay-git"}
+	searcher := &testDBSearcher{
+		absPackagesDB: map[string]string{"yay": "core"},
+	}
+
+	fetched, err := PKGBUILDs(searcher, &http.Client{},
+		targets, "https://aur.archlinux.org", parser.ModeAny)
+
+	assert.NoError(t, err)
+	assert.EqualValues(t, map[string][]byte{
+		"core/yay":    []byte("example_yay"),
+		"aur/yay-bin": []byte("example_yay-bin"),
+		"yay-git":     []byte("example_yay-git"),
+	}, fetched)
+}

+ 62 - 2
pkg/download/utils_test.go

@@ -6,6 +6,9 @@ import (
 
 	"github.com/stretchr/testify/assert"
 
+	"github.com/Jguer/go-alpm/v2"
+
+	"github.com/Jguer/yay/v10/pkg/db"
 	"github.com/Jguer/yay/v10/pkg/settings/exe"
 )
 
@@ -29,9 +32,10 @@ type testGitBuilder struct {
 func (t *testGitBuilder) BuildGitCmd(dir string, extraArgs ...string) *exec.Cmd {
 	cmd := t.parentBuilder.BuildGitCmd(dir, extraArgs...)
 
-	assert.Equal(t.test, t.want, cmd.String())
+	if t.want != "" {
+		assert.Equal(t.test, t.want, cmd.String())
+	}
 
-	t.index += 1
 	return cmd
 }
 
@@ -42,3 +46,59 @@ func (c *testGitBuilder) Show(cmd *exec.Cmd) error {
 func (c *testGitBuilder) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
 	return c.parentBuilder.Capture(cmd, timeout)
 }
+
+type (
+	testDB struct {
+		alpm.IDB
+		name string
+	}
+	testPackage struct {
+		db.IPackage
+		name string
+		base string
+		db   *testDB
+	}
+	testDBSearcher struct {
+		absPackagesDB map[string]string
+	}
+)
+
+func (d *testDB) Name() string {
+	return d.name
+}
+
+func (p *testPackage) Name() string {
+	return p.name
+}
+
+func (p *testPackage) Base() string {
+	return p.base
+}
+
+func (p *testPackage) DB() alpm.IDB {
+	return p.db
+}
+
+func (d *testDBSearcher) SyncPackage(name string) db.IPackage {
+	if v, ok := d.absPackagesDB[name]; ok {
+		return &testPackage{
+			name: name,
+			base: name,
+			db:   &testDB{name: v},
+		}
+	}
+
+	return nil
+}
+
+func (d *testDBSearcher) SatisfierFromDB(name string, db string) db.IPackage {
+	if v, ok := d.absPackagesDB[name]; ok && v == db {
+		return &testPackage{
+			name: name,
+			base: name,
+			db:   &testDB{name: v},
+		}
+	}
+
+	return nil
+}