Parcourir la source

feat(pkgbuild): extract logic

jguer il y a 4 ans
Parent
commit
ee3c51f6f2
7 fichiers modifiés avec 180 ajouts et 174 suppressions
  1. 1 0
      .golangci.yml
  2. 1 2
      cmd.go
  3. 49 0
      pkg/download/abs.go
  4. 35 0
      pkg/download/aur.go
  5. 74 0
      pkg/download/unified.go
  6. 18 34
      print.go
  7. 2 138
      query.go

+ 1 - 0
.golangci.yml

@@ -95,6 +95,7 @@ issues:
         - gomnd
 
   exclude:
+    - G107
     - G204
     - commentedOutCode
 

+ 1 - 2
cmd.go

@@ -240,8 +240,7 @@ func handleYay(cmdArgs *settings.Arguments, dbExecutor db.Executor) error {
 }
 
 func handleGetpkgbuild(cmdArgs *settings.Arguments, dbExecutor db.Executor) error {
-	switch {
-	case cmdArgs.ExistsArg("p", "pkgbuild"):
+	if cmdArgs.ExistsArg("p", "pkgbuild") {
 		return printPkgbuilds(dbExecutor, cmdArgs.Targets)
 	}
 	return getPkgbuilds(cmdArgs.Targets, dbExecutor, cmdArgs.ExistsArg("f", "force"))

+ 49 - 0
pkg/download/abs.go

@@ -0,0 +1,49 @@
+package download
+
+import (
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+)
+
+var ErrInvalidRepository = errors.New("invalid repository")
+var ErrABSPackageNotFound = errors.New("package not found in repos")
+
+const MaxConcurrentFetch = 20
+const ABSPackageURL = "https://git.archlinux.org/svntogit/packages.git/plain/trunk/PKGBUILD?"
+const ABSCommunityURL = "https://git.archlinux.org/svntogit/community.git/plain/trunk/PKGBUILD?"
+
+func getPackageURL(db, pkgName string) (string, error) {
+	values := url.Values{}
+	values.Set("h", "packages/"+pkgName)
+	nameEncoded := values.Encode()
+	switch db {
+	case "core", "extra", "testing":
+		return ABSPackageURL + nameEncoded, nil
+	case "community", "multilib", "community-testing", "multilib-testing":
+		return ABSCommunityURL + nameEncoded, nil
+	}
+	return "", ErrInvalidRepository
+}
+
+func GetABSPkgbuild(dbName, pkgName string) ([]byte, error) {
+	packageURL, err := getPackageURL(dbName, pkgName)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := http.Get(packageURL)
+	if err != nil {
+		return nil, err
+	}
+
+	defer resp.Body.Close()
+
+	pkgBuild, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	return pkgBuild, nil
+}

+ 35 - 0
pkg/download/aur.go

@@ -0,0 +1,35 @@
+package download
+
+import (
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+)
+
+const AURPackageURL = "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?"
+
+var ErrAURPackageNotFound = errors.New("package not found in AUR")
+
+func GetAURPkgbuild(pkgName string) ([]byte, error) {
+	values := url.Values{}
+	values.Set("h", pkgName)
+	pkgURL := AURPackageURL + values.Encode()
+
+	resp, err := http.Get(pkgURL)
+	if err != nil {
+		return nil, err
+	}
+	if resp.StatusCode != 200 {
+		return nil, ErrAURPackageNotFound
+	}
+
+	defer resp.Body.Close()
+
+	pkgBuild, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	return pkgBuild, nil
+}

+ 74 - 0
pkg/download/unified.go

@@ -0,0 +1,74 @@
+package download
+
+import (
+	"sync"
+
+	"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"
+	"github.com/Jguer/yay/v10/pkg/text"
+)
+
+func getURLName(pkg alpm.IPackage) string {
+	name := pkg.Base()
+	if name == "" {
+		name = pkg.Name()
+	}
+	return name
+}
+
+func GetPkgbuilds(dbExecutor db.Executor, targets []string, mode settings.TargetMode) (map[string][]byte, error) {
+	pkgbuilds := make(map[string][]byte, len(targets))
+	var mux sync.Mutex
+	var errs multierror.MultiError
+	var wg sync.WaitGroup
+	sem := make(chan uint8, MaxConcurrentFetch)
+
+	for _, target := range targets {
+		aur := true
+		dbName, name := text.SplitDBFromName(target)
+		if dbName != "aur" && (mode == settings.ModeAny || mode == settings.ModeRepo) {
+			pkg := dbExecutor.SyncPackage(name)
+			if pkg != nil {
+				aur = false
+				name = getURLName(pkg)
+				dbName = pkg.DB().Name()
+			}
+		}
+
+		if aur && mode == settings.ModeRepo {
+			// Mode does not allow AUR packages
+			continue
+		}
+
+		sem <- 1
+		wg.Add(1)
+
+		go func(target, dbName, pkgName string, aur bool) {
+			var err error
+			var pkgbuild []byte
+
+			if aur {
+				pkgbuild, err = GetAURPkgbuild(pkgName)
+			} else {
+				pkgbuild, err = GetABSPkgbuild(dbName, pkgName)
+			}
+
+			if err == nil {
+				mux.Lock()
+				pkgbuilds[target] = pkgbuild
+				mux.Unlock()
+			} else {
+				errs.Add(err)
+			}
+
+			<-sem
+			wg.Done()
+		}(target, dbName, name, aur)
+	}
+
+	wg.Wait()
+	return pkgbuilds, errs.Return()
+}

+ 18 - 34
print.go

@@ -4,12 +4,13 @@ import (
 	"fmt"
 	"os"
 	"strconv"
+	"strings"
 
 	"github.com/leonelquinteros/gotext"
 	rpc "github.com/mikkeloscar/aur"
 
 	"github.com/Jguer/yay/v10/pkg/db"
-	"github.com/Jguer/yay/v10/pkg/multierror"
+	"github.com/Jguer/yay/v10/pkg/download"
 	"github.com/Jguer/yay/v10/pkg/query"
 	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
@@ -268,45 +269,28 @@ outer:
 	return nil
 }
 
-func printPkgbuilds(dbExecutor db.Executor, pkgS []string) error {
-	var pkgbuilds []string
-	var localPkgbuilds []string
-	missing := false
-	pkgS = query.RemoveInvalidTargets(pkgS, config.Runtime.Mode)
-	aurS, repoS := packageSlices(pkgS, dbExecutor)
-	var err error
-	var errs multierror.MultiError
-
-	if len(aurS) != 0 {
-		noDB := make([]string, 0, len(aurS))
-		for _, pkg := range aurS {
-			_, name := text.SplitDBFromName(pkg)
-			noDB = append(noDB, name)
-		}
-		localPkgbuilds, err = aurPkgbuilds(noDB)
-		pkgbuilds = append(pkgbuilds, localPkgbuilds...)
-		errs.Add(err)
-	}
-
-	if len(repoS) != 0 {
-		localPkgbuilds, err = repoPkgbuilds(dbExecutor, repoS)
-		pkgbuilds = append(pkgbuilds, localPkgbuilds...)
-		errs.Add(err)
-	}
-
-	if len(aurS)+len(repoS) != len(pkgbuilds) {
-		missing = true
+func printPkgbuilds(dbExecutor db.Executor, targets []string) error {
+	pkgbuilds, err := download.GetPkgbuilds(dbExecutor, targets, config.Runtime.Mode)
+	if err != nil {
+		text.Errorln(err)
 	}
 
 	if len(pkgbuilds) != 0 {
-		for _, pkgbuild := range pkgbuilds {
-			fmt.Print(pkgbuild)
+		for target, pkgbuild := range pkgbuilds {
+			fmt.Printf("\n\n# %s\n\n", target)
+			fmt.Print(string(pkgbuild))
 		}
 	}
 
-	if missing {
-		err = fmt.Errorf("Missing packages")
+	if len(pkgbuilds) != len(targets) {
+		missing := []string{}
+		for _, target := range targets {
+			if _, ok := pkgbuilds[target]; !ok {
+				missing = append(missing, target)
+			}
+		}
+		text.Warnln("Unable to find the following packages:", strings.Join(missing, ", "))
 	}
 
-	return err
+	return nil
 }

+ 2 - 138
query.go

@@ -3,21 +3,15 @@ package main
 import (
 	"errors"
 	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/url"
 	"os"
 	"sort"
 	"strings"
-	"sync"
 
 	alpm "github.com/Jguer/go-alpm/v2"
 	"github.com/leonelquinteros/gotext"
 	rpc "github.com/mikkeloscar/aur"
 
 	"github.com/Jguer/yay/v10/pkg/db"
-	"github.com/Jguer/yay/v10/pkg/intrange"
-	"github.com/Jguer/yay/v10/pkg/multierror"
 	"github.com/Jguer/yay/v10/pkg/query"
 	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
@@ -259,7 +253,6 @@ func queryRepo(pkgInputN []string, dbExecutor db.Executor) repoQuery {
 func packageSlices(toCheck []string, dbExecutor db.Executor) (aur, repo []string) {
 	for _, _pkg := range toCheck {
 		dbName, name := text.SplitDBFromName(_pkg)
-		found := false
 
 		if dbName == "aur" || config.Runtime.Mode == settings.ModeAUR {
 			aur = append(aur, _pkg)
@@ -269,13 +262,8 @@ func packageSlices(toCheck []string, dbExecutor db.Executor) (aur, repo []string
 			continue
 		}
 
-		found = dbExecutor.SyncSatisfierExists(name)
-
-		if !found {
-			found = len(dbExecutor.PackagesFromGroup(name)) != 0
-		}
-
-		if found {
+		if dbExecutor.SyncSatisfierExists(name) ||
+			len(dbExecutor.PackagesFromGroup(name)) != 0 {
 			repo = append(repo, _pkg)
 		} else {
 			aur = append(aur, _pkg)
@@ -390,127 +378,3 @@ func statistics(dbExecutor db.Executor) *struct {
 
 	return info
 }
-
-func aurPkgbuilds(names []string) ([]string, error) {
-	pkgbuilds := make([]string, 0, len(names))
-	var mux sync.Mutex
-	var wg sync.WaitGroup
-	var errs multierror.MultiError
-
-	makeRequest := func(n, max int) {
-		defer wg.Done()
-
-		for _, name := range names[n:max] {
-			values := url.Values{}
-			values.Set("h", name)
-
-			url := "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?"
-
-			resp, err := http.Get(url + values.Encode())
-			if err != nil {
-				errs.Add(err)
-				continue
-			}
-			if resp.StatusCode != 200 {
-				errs.Add(fmt.Errorf("error code %d for package %s", resp.StatusCode, name))
-				continue
-			}
-			defer resp.Body.Close()
-
-			body, readErr := ioutil.ReadAll(resp.Body)
-			pkgbuild := string(body)
-
-			if readErr != nil {
-				errs.Add(readErr)
-				continue
-			}
-
-			mux.Lock()
-			pkgbuilds = append(pkgbuilds, pkgbuild)
-			mux.Unlock()
-		}
-	}
-
-	for n := 0; n < len(names); n += 20 {
-		max := intrange.Min(len(names), n+20)
-		wg.Add(1)
-		go makeRequest(n, max)
-	}
-
-	wg.Wait()
-
-	if err := errs.Return(); err != nil {
-		return pkgbuilds, err
-	}
-
-	return pkgbuilds, nil
-}
-
-func repoPkgbuilds(dbExecutor db.Executor, names []string) ([]string, error) {
-	pkgbuilds := make([]string, 0, len(names))
-	var mux sync.Mutex
-	var wg sync.WaitGroup
-	var errs multierror.MultiError
-
-	makeRequest := func(full string) {
-		var pkg alpm.IPackage
-		defer wg.Done()
-
-		db, name := text.SplitDBFromName(full)
-
-		if db != "" {
-			pkg = dbExecutor.SatisfierFromDB(name, db)
-		} else {
-			pkg = dbExecutor.SyncSatisfier(name)
-		}
-
-		values := url.Values{}
-		values.Set("h", "packages/"+name)
-
-		var url string
-
-		// TODO: Check existence with ls-remote
-		// https://git.archlinux.org/svntogit/packages.git
-		switch pkg.DB().Name() {
-		case "core", "extra", "testing":
-			url = "https://git.archlinux.org/svntogit/packages.git/plain/trunk/PKGBUILD?"
-		case "community", "multilib", "community-testing", "multilib-testing":
-			url = "https://git.archlinux.org/svntogit/community.git/plain/trunk/PKGBUILD?"
-		default:
-			errs.Add(fmt.Errorf("unable to get PKGBUILD from repo \"%s\"", db))
-			return
-		}
-
-		resp, err := http.Get(url + values.Encode())
-		if err != nil {
-			errs.Add(err)
-			return
-		}
-		if resp.StatusCode != 200 {
-			errs.Add(fmt.Errorf("error code %d for package %s", resp.StatusCode, name))
-			return
-		}
-		defer resp.Body.Close()
-
-		body, readErr := ioutil.ReadAll(resp.Body)
-		pkgbuild := string(body)
-
-		if readErr != nil {
-			errs.Add(readErr)
-			return
-		}
-
-		mux.Lock()
-		pkgbuilds = append(pkgbuilds, pkgbuild)
-		mux.Unlock()
-	}
-
-	for _, full := range names {
-		wg.Add(1)
-		go makeRequest(full)
-	}
-
-	wg.Wait()
-
-	return pkgbuilds, errs.Return()
-}