feat(pkgbuild): extract logic

This commit is contained in:
jguer 2020-12-15 01:29:05 +01:00
parent 28c985b378
commit ee3c51f6f2
No known key found for this signature in database
GPG key ID: 6D6CC9BEA8556B35
7 changed files with 180 additions and 174 deletions

View file

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

3
cmd.go
View file

@ -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
pkg/download/abs.go Normal file
View file

@ -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
pkg/download/aur.go Normal file
View file

@ -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
pkg/download/unified.go Normal file
View file

@ -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()
}

View file

@ -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
}

140
query.go
View file

@ -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()
}