mirror of
https://github.com/Jguer/yay
synced 2024-10-31 04:12:51 +00:00
227 lines
4.6 KiB
Go
227 lines
4.6 KiB
Go
package query
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/Jguer/aur"
|
|
"github.com/leonelquinteros/gotext"
|
|
|
|
"github.com/Jguer/yay/v11/pkg/db"
|
|
"github.com/Jguer/yay/v11/pkg/intrange"
|
|
"github.com/Jguer/yay/v11/pkg/settings"
|
|
"github.com/Jguer/yay/v11/pkg/settings/parser"
|
|
"github.com/Jguer/yay/v11/pkg/stringset"
|
|
"github.com/Jguer/yay/v11/pkg/text"
|
|
)
|
|
|
|
type SearchVerbosity int
|
|
|
|
// Verbosity settings for search.
|
|
const (
|
|
NumberMenu SearchVerbosity = iota
|
|
Detailed
|
|
Minimal
|
|
)
|
|
|
|
type SourceQueryBuilder struct {
|
|
repoQuery
|
|
aurQuery
|
|
sortMode int
|
|
sortBy string
|
|
targetMode parser.TargetMode
|
|
searchBy string
|
|
}
|
|
|
|
func NewSourceQueryBuilder(sortMode int, sortBy string, targetMode parser.TargetMode, searchBy string) *SourceQueryBuilder {
|
|
return &SourceQueryBuilder{
|
|
sortMode: sortMode,
|
|
sortBy: sortBy,
|
|
targetMode: targetMode,
|
|
searchBy: searchBy,
|
|
}
|
|
}
|
|
|
|
func (s *SourceQueryBuilder) Execute(ctx context.Context, dbExecutor db.Executor, aurClient *aur.Client, pkgS []string) {
|
|
var aurErr error
|
|
|
|
pkgS = RemoveInvalidTargets(pkgS, s.targetMode)
|
|
|
|
if s.targetMode.AtLeastAUR() {
|
|
s.aurQuery, aurErr = queryAUR(ctx, aurClient, pkgS, s.searchBy, s.sortMode, s.sortBy)
|
|
}
|
|
|
|
if s.targetMode.AtLeastRepo() {
|
|
s.repoQuery = queryRepo(pkgS, dbExecutor, s.sortMode)
|
|
}
|
|
|
|
if aurErr != nil && len(s.repoQuery) != 0 {
|
|
text.Errorln(ErrAURSearch{inner: aurErr})
|
|
text.Warnln(gotext.Get("Showing repo packages only"))
|
|
}
|
|
}
|
|
|
|
func (s *SourceQueryBuilder) Results(dbExecutor db.Executor, verboseSearch SearchVerbosity) error {
|
|
if s.aurQuery == nil && s.repoQuery == nil {
|
|
return ErrNoQuery{}
|
|
}
|
|
|
|
switch s.sortMode {
|
|
case settings.TopDown:
|
|
if s.targetMode.AtLeastRepo() {
|
|
s.repoQuery.printSearch(dbExecutor, verboseSearch, s.sortMode)
|
|
}
|
|
|
|
if s.targetMode.AtLeastAUR() {
|
|
s.aurQuery.printSearch(1, dbExecutor, verboseSearch, s.sortMode)
|
|
}
|
|
case settings.BottomUp:
|
|
if s.targetMode.AtLeastAUR() {
|
|
s.aurQuery.printSearch(1, dbExecutor, verboseSearch, s.sortMode)
|
|
}
|
|
|
|
if s.targetMode.AtLeastRepo() {
|
|
s.repoQuery.printSearch(dbExecutor, verboseSearch, s.sortMode)
|
|
}
|
|
default:
|
|
return ErrInvalidSortMode{}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *SourceQueryBuilder) Len() int {
|
|
return len(s.repoQuery) + len(s.aurQuery)
|
|
}
|
|
|
|
func (s *SourceQueryBuilder) GetTargets(include, exclude intrange.IntRanges,
|
|
otherExclude stringset.StringSet) ([]string, error) {
|
|
isInclude := len(exclude) == 0 && len(otherExclude) == 0
|
|
|
|
var targets []string
|
|
|
|
for i, pkg := range s.repoQuery {
|
|
var target int
|
|
|
|
switch s.sortMode {
|
|
case settings.TopDown:
|
|
target = i + 1
|
|
case settings.BottomUp:
|
|
target = len(s.repoQuery) - i
|
|
default:
|
|
return targets, ErrInvalidSortMode{}
|
|
}
|
|
|
|
if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
|
|
targets = append(targets, pkg.DB().Name()+"/"+pkg.Name())
|
|
}
|
|
}
|
|
|
|
for i := range s.aurQuery {
|
|
var target int
|
|
|
|
switch s.sortMode {
|
|
case settings.TopDown:
|
|
target = i + 1 + len(s.repoQuery)
|
|
case settings.BottomUp:
|
|
target = len(s.aurQuery) - i + len(s.repoQuery)
|
|
default:
|
|
return targets, ErrInvalidSortMode{}
|
|
}
|
|
|
|
if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
|
|
targets = append(targets, "aur/"+s.aurQuery[i].Name)
|
|
}
|
|
}
|
|
|
|
return targets, nil
|
|
}
|
|
|
|
// queryRepo handles repo searches. Creates a RepoSearch struct.
|
|
func queryRepo(pkgInputN []string, dbExecutor db.Executor, sortMode int) repoQuery {
|
|
s := repoQuery(dbExecutor.SyncPackages(pkgInputN...))
|
|
|
|
if sortMode == settings.BottomUp {
|
|
s.Reverse()
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// queryAUR searches AUR and narrows based on subarguments.
|
|
func queryAUR(ctx context.Context, aurClient *aur.Client, pkgS []string, searchBy string, sortMode int, sortBy string) (aurQuery, error) {
|
|
var (
|
|
r []aur.Pkg
|
|
err error
|
|
usedIndex int
|
|
)
|
|
|
|
by := getSearchBy(searchBy)
|
|
|
|
if len(pkgS) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
for i, word := range pkgS {
|
|
r, err = aurClient.Search(ctx, word, by)
|
|
if err == nil {
|
|
usedIndex = i
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(pkgS) == 1 {
|
|
sort.Sort(aurSortable{
|
|
aurQuery: r,
|
|
sortBy: sortBy,
|
|
sortMode: sortMode,
|
|
})
|
|
|
|
return r, err
|
|
}
|
|
|
|
var (
|
|
aq aurQuery
|
|
n int
|
|
)
|
|
|
|
for i := range r {
|
|
match := true
|
|
|
|
for j, pkgN := range pkgS {
|
|
if usedIndex == j {
|
|
continue
|
|
}
|
|
|
|
name := strings.ToLower(r[i].Name)
|
|
desc := strings.ToLower(r[i].Description)
|
|
targ := strings.ToLower(pkgN)
|
|
|
|
if !(strings.Contains(name, targ) || strings.Contains(desc, targ)) {
|
|
match = false
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
if match {
|
|
n++
|
|
|
|
aq = append(aq, r[i])
|
|
}
|
|
}
|
|
|
|
sort.Sort(aurSortable{
|
|
aurQuery: aq,
|
|
sortBy: sortBy,
|
|
sortMode: sortMode,
|
|
})
|
|
|
|
return aq, err
|
|
}
|