implement yay -Pp option

fix linting errors

format with make fmt

fix completions

resolve most of the requested changes

move loop over dbSlice back into makeRequest

query aur in chunks of 20

check for status codes

continue instead of return in for loop

format code
This commit is contained in:
nycex 2020-05-09 19:39:08 +02:00 committed by jguer
parent 5bef39b728
commit d9b440c929
No known key found for this signature in database
GPG key ID: 6D6CC9BEA8556B35
6 changed files with 161 additions and 2 deletions

5
cmd.go
View file

@ -38,7 +38,7 @@ operations:
New operations:
yay {-Y --yay} [options] [package(s)]
yay {-P --show} [options]
yay {-P --show} [options] [package(s)]
yay {-G --getpkgbuild} [package(s)]
If no arguments are provided 'yay -Syu' will be performed
@ -131,6 +131,7 @@ show specific options:
-g --currentconfig Print current yay configuration
-s --stats Display system package statistics
-w --news Print arch news
-p --pkgbuild Print pkgbuild of packages
yay specific options:
-c --clean Remove unneeded dependencies
@ -216,6 +217,8 @@ func handlePrint(cmdArgs *settings.Arguments, dbExecutor db.Executor) (err error
err = completion.Show(dbExecutor, config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, false)
case cmdArgs.ExistsArg("s", "stats"):
err = localStatistics(dbExecutor)
case cmdArgs.existsArg("p", "pkgbuild"):
err = printPkgbuilds(cmdArgs.targets)
default:
err = nil
}

View file

@ -79,7 +79,7 @@ _yay() {
searchby batchinstall nobatchinstall'
'b d h q r v')
yays=('clean gendb' 'c')
show=('complete defaultconfig currentconfig stats news' 'c d g s w')
show=('complete defaultconfig currentconfig stats news pkgbuild' 'c d g s w p')
getpkgbuild=('force' 'f')
for o in 'D database' 'F files' 'Q query' 'R remove' 'S sync' 'U upgrade' 'Y yays' 'P show' 'G getpkgbuild'; do
@ -119,6 +119,9 @@ _yay() {
G)
_yay_pkg
;;
P)
_arch_incomp 'p pkgbuild' && _yay_pkg
;;
esac
fi
true

View file

@ -172,6 +172,8 @@ complete -c $progname -n "$show" -s d -l defaultconfig -d 'Print default yay con
complete -c $progname -n "$show" -s g -l currentconfig -d 'Print current yay configuration' -f
complete -c $progname -n "$show" -s s -l stats -d 'Display system package statistics' -f
complete -c $progname -n "$show" -s w -l news -d 'Print arch news' -f
complete -c $progname -n "$show" -s p -l pkgbuild -d 'Print pkgbuild of packages' -f
complete -c $progname -n "$pkgbuild" -xa "$listall"
complete -c $progname -n "$show" -s q -l quiet -d 'Do not print news description' -f
# Getpkgbuild options

View file

@ -171,6 +171,7 @@ _pacman_opts_print_modifiers=(
{-s,--stats}'[Display system package statistics]'
{-u,--upgrades}'[Print update list]'
{-w,--news}'[Print arch news]'
{-p,--pkgbuild}'[Print PKGBUILDs]:package:_pacman_completions_all_packages'
)
# options for passing to _arguments: options for --remove command
_pacman_opts_remove=(
@ -507,6 +508,11 @@ _pacman_zsh_comp() {
Q*)
_pacman_action_query
;;
P*p*)
_arguments -s : \
"$_pacman_opts_print_modifiers[@]" \
"*:package:_pacman_all_packages"
;;
P*)
_arguments -s : \
"$_pacman_opts_print_modifiers[@]"

View file

@ -124,6 +124,10 @@ Print new news from the Archlinux homepage. News is considered new if it is
newer than the build date of all native packages. Pass this twice to show all
available news.
.TP
.B \-p, \-\-pkgbuild
Prints the PKGBUILD of the given packages to stdout.
.TP
.B \-q, \-\-quiet
Only show titles when printing news.

141
query.go
View file

@ -3,6 +3,9 @@ package main
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"sort"
"strings"
@ -12,6 +15,8 @@ import (
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"
@ -384,3 +389,139 @@ 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(names []string) ([]string, error) {
pkgbuilds := make([]string, 0, len(names))
var mux sync.Mutex
var wg sync.WaitGroup
var errs multierror.MultiError
dbList, dbErr := alpmHandle.SyncDBs()
if dbErr != nil {
return nil, dbErr
}
dbSlice := dbList.Slice()
makeRequest := func(full string) {
defer wg.Done()
db, name := splitDBFromName(full)
if db == "" {
var pkg *alpm.Package
for _, alpmDB := range dbSlice {
if pkg = alpmDB.Pkg(name); pkg != nil {
db = alpmDB.Name()
name = pkg.Base()
if name == "" {
name = pkg.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 db {
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()
}