mirror of
https://github.com/Jguer/yay
synced 2024-10-01 13:53:32 +00:00
feat(yay): simplify sort mode and use it for calculating number menu indices, fixes #1627
This commit is contained in:
parent
53e8ec70f8
commit
e38d0138a6
4
cmd.go
4
cmd.go
|
@ -274,7 +274,7 @@ func handlePrint(ctx context.Context, cmdArgs *parser.Arguments, dbExecutor db.E
|
|||
double := cmdArgs.ExistsDouble("w", "news")
|
||||
quiet := cmdArgs.ExistsArg("q", "quiet")
|
||||
|
||||
return news.PrintNewsFeed(ctx, config.Runtime.HTTPClient, dbExecutor.LastBuildTime(), config.SortMode, double, quiet)
|
||||
return news.PrintNewsFeed(ctx, config.Runtime.HTTPClient, dbExecutor.LastBuildTime(), config.BottomUp, double, quiet)
|
||||
case cmdArgs.ExistsDouble("c", "complete"):
|
||||
return completion.Show(ctx, config.Runtime.HTTPClient, dbExecutor,
|
||||
config.AURURL, config.Runtime.CompletionPath, config.CompletionInterval, true)
|
||||
|
@ -357,7 +357,7 @@ func handleRemove(ctx context.Context, cmdArgs *parser.Arguments, localCache *vc
|
|||
|
||||
// NumberMenu presents a CLI for selecting packages to install.
|
||||
func displayNumberMenu(ctx context.Context, pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Arguments) error {
|
||||
queryBuilder := query.NewSourceQueryBuilder(config.SortMode, config.SortBy, config.Runtime.Mode, config.SearchBy, config.SingleLineResults)
|
||||
queryBuilder := query.NewSourceQueryBuilder(config.SortBy, config.Runtime.Mode, config.SearchBy, config.BottomUp, config.SingleLineResults)
|
||||
|
||||
queryBuilder.Execute(ctx, dbExecutor, config.Runtime.AURClient, pkgS)
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Jguer/yay/v11/pkg/settings"
|
||||
"github.com/Jguer/yay/v11/pkg/text"
|
||||
)
|
||||
|
||||
|
@ -61,7 +60,7 @@ type rss struct {
|
|||
Channel channel `xml:"channel"`
|
||||
}
|
||||
|
||||
func PrintNewsFeed(ctx context.Context, client *http.Client, cutOffDate time.Time, sortMode int, all, quiet bool) error {
|
||||
func PrintNewsFeed(ctx context.Context, client *http.Client, cutOffDate time.Time, bottomUp, all, quiet bool) error {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "https://archlinux.org/feeds/news", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -86,7 +85,7 @@ func PrintNewsFeed(ctx context.Context, client *http.Client, cutOffDate time.Tim
|
|||
return err
|
||||
}
|
||||
|
||||
if sortMode == settings.BottomUp {
|
||||
if bottomUp {
|
||||
for i := len(rssGot.Channel.Items) - 1; i >= 0; i-- {
|
||||
rssGot.Channel.Items[i].print(cutOffDate, all, quiet)
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ func TestPrintNewsFeed(t *testing.T) {
|
|||
|
||||
type args struct {
|
||||
cutOffDate time.Time
|
||||
sortMode int
|
||||
bottomUp bool
|
||||
all bool
|
||||
quiet bool
|
||||
}
|
||||
|
@ -116,10 +116,10 @@ func TestPrintNewsFeed(t *testing.T) {
|
|||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "all-verbose", args: args{cutOffDate: time.Now(), all: true, quiet: false}, wantErr: false},
|
||||
{name: "all-quiet", args: args{cutOffDate: lastNewsTime, all: true, quiet: true}, wantErr: false},
|
||||
{name: "latest-quiet", args: args{cutOffDate: lastNewsTime, all: false, quiet: true}, wantErr: false},
|
||||
{name: "latest-quiet-topdown", args: args{sortMode: 1, cutOffDate: lastNewsTime, all: false, quiet: true}, wantErr: false},
|
||||
{name: "all-verbose", args: args{bottomUp: true, cutOffDate: time.Now(), all: true, quiet: false}, wantErr: false},
|
||||
{name: "all-quiet", args: args{bottomUp: true, cutOffDate: lastNewsTime, all: true, quiet: true}, wantErr: false},
|
||||
{name: "latest-quiet", args: args{bottomUp: true, cutOffDate: lastNewsTime, all: false, quiet: true}, wantErr: false},
|
||||
{name: "latest-quiet-topdown", args: args{bottomUp: false, cutOffDate: lastNewsTime, all: false, quiet: true}, wantErr: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
@ -135,7 +135,7 @@ func TestPrintNewsFeed(t *testing.T) {
|
|||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
err := PrintNewsFeed(context.TODO(), &http.Client{}, tt.args.cutOffDate, tt.args.sortMode, tt.args.all, tt.args.quiet)
|
||||
err := PrintNewsFeed(context.TODO(), &http.Client{}, tt.args.cutOffDate, tt.args.bottomUp, tt.args.all, tt.args.quiet)
|
||||
assert.NoError(t, err)
|
||||
|
||||
w.Close()
|
||||
|
@ -164,7 +164,7 @@ func TestPrintNewsFeedSameDay(t *testing.T) {
|
|||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
err := PrintNewsFeed(context.TODO(), &http.Client{}, lastNewsTime, 0, false, false)
|
||||
err := PrintNewsFeed(context.TODO(), &http.Client{}, lastNewsTime, true, false, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
w.Close()
|
||||
|
|
|
@ -13,13 +13,6 @@ func (e ErrAURSearch) Error() string {
|
|||
return gotext.Get("Error during AUR search: %s\n", e.inner.Error())
|
||||
}
|
||||
|
||||
// ErrInvalidSortMode means that the sort mode provided was not valid.
|
||||
type ErrInvalidSortMode struct{}
|
||||
|
||||
func (e ErrInvalidSortMode) Error() string {
|
||||
return gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save")
|
||||
}
|
||||
|
||||
// ErrNoQuery means that query was not executed.
|
||||
type ErrNoQuery struct{}
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/Jguer/aur"
|
||||
"github.com/Jguer/go-alpm/v2"
|
||||
"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"
|
||||
|
@ -29,7 +29,7 @@ const (
|
|||
type SourceQueryBuilder struct {
|
||||
repoQuery
|
||||
aurQuery
|
||||
sortMode int
|
||||
bottomUp bool
|
||||
sortBy string
|
||||
targetMode parser.TargetMode
|
||||
searchBy string
|
||||
|
@ -37,14 +37,16 @@ type SourceQueryBuilder struct {
|
|||
}
|
||||
|
||||
func NewSourceQueryBuilder(
|
||||
sortMode int,
|
||||
sortBy string,
|
||||
targetMode parser.TargetMode,
|
||||
searchBy string,
|
||||
bottomUp,
|
||||
singleLineResults bool,
|
||||
) *SourceQueryBuilder {
|
||||
return &SourceQueryBuilder{
|
||||
sortMode: sortMode,
|
||||
repoQuery: []alpm.IPackage{},
|
||||
aurQuery: []aur.Pkg{},
|
||||
bottomUp: bottomUp,
|
||||
sortBy: sortBy,
|
||||
targetMode: targetMode,
|
||||
searchBy: searchBy,
|
||||
|
@ -58,11 +60,11 @@ func (s *SourceQueryBuilder) Execute(ctx context.Context, dbExecutor db.Executor
|
|||
pkgS = RemoveInvalidTargets(pkgS, s.targetMode)
|
||||
|
||||
if s.targetMode.AtLeastAUR() {
|
||||
s.aurQuery, aurErr = queryAUR(ctx, aurClient, pkgS, s.searchBy, s.sortMode, s.sortBy)
|
||||
s.aurQuery, aurErr = queryAUR(ctx, aurClient, pkgS, s.searchBy, s.bottomUp, s.sortBy)
|
||||
}
|
||||
|
||||
if s.targetMode.AtLeastRepo() {
|
||||
s.repoQuery = queryRepo(pkgS, dbExecutor, s.sortMode)
|
||||
s.repoQuery = queryRepo(pkgS, dbExecutor, s.bottomUp)
|
||||
}
|
||||
|
||||
if aurErr != nil && len(s.repoQuery) != 0 {
|
||||
|
@ -72,29 +74,26 @@ func (s *SourceQueryBuilder) Execute(ctx context.Context, dbExecutor db.Executor
|
|||
}
|
||||
|
||||
func (s *SourceQueryBuilder) Results(w io.Writer, dbExecutor db.Executor, verboseSearch SearchVerbosity) error {
|
||||
if s.aurQuery == nil && s.repoQuery == nil {
|
||||
if s.aurQuery == nil || s.repoQuery == nil {
|
||||
return ErrNoQuery{}
|
||||
}
|
||||
|
||||
switch s.sortMode {
|
||||
case settings.TopDown:
|
||||
if s.targetMode.AtLeastRepo() {
|
||||
s.repoQuery.printSearch(w, dbExecutor, verboseSearch, s.sortMode, s.singleLineResults)
|
||||
}
|
||||
|
||||
if s.bottomUp {
|
||||
if s.targetMode.AtLeastAUR() {
|
||||
s.aurQuery.printSearch(w, 1, dbExecutor, verboseSearch, s.sortMode, s.singleLineResults)
|
||||
}
|
||||
case settings.BottomUp:
|
||||
if s.targetMode.AtLeastAUR() {
|
||||
s.aurQuery.printSearch(w, 1, dbExecutor, verboseSearch, s.sortMode, s.singleLineResults)
|
||||
s.aurQuery.printSearch(w, len(s.repoQuery)+1, dbExecutor, verboseSearch, s.bottomUp, s.singleLineResults)
|
||||
}
|
||||
|
||||
if s.targetMode.AtLeastRepo() {
|
||||
s.repoQuery.printSearch(w, dbExecutor, verboseSearch, s.sortMode, s.singleLineResults)
|
||||
s.repoQuery.printSearch(w, dbExecutor, verboseSearch, s.bottomUp, s.singleLineResults)
|
||||
}
|
||||
} else {
|
||||
if s.targetMode.AtLeastRepo() {
|
||||
s.repoQuery.printSearch(w, dbExecutor, verboseSearch, s.bottomUp, s.singleLineResults)
|
||||
}
|
||||
|
||||
if s.targetMode.AtLeastAUR() {
|
||||
s.aurQuery.printSearch(w, len(s.repoQuery)+1, dbExecutor, verboseSearch, s.bottomUp, s.singleLineResults)
|
||||
}
|
||||
default:
|
||||
return ErrInvalidSortMode{}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -113,13 +112,10 @@ func (s *SourceQueryBuilder) GetTargets(include, exclude intrange.IntRanges,
|
|||
for i, pkg := range s.repoQuery {
|
||||
var target int
|
||||
|
||||
switch s.sortMode {
|
||||
case settings.TopDown:
|
||||
target = i + 1
|
||||
case settings.BottomUp:
|
||||
if s.bottomUp {
|
||||
target = len(s.repoQuery) - i
|
||||
default:
|
||||
return targets, ErrInvalidSortMode{}
|
||||
} else {
|
||||
target = i + 1
|
||||
}
|
||||
|
||||
if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
|
||||
|
@ -130,13 +126,10 @@ func (s *SourceQueryBuilder) GetTargets(include, exclude intrange.IntRanges,
|
|||
for i := range s.aurQuery {
|
||||
var target int
|
||||
|
||||
switch s.sortMode {
|
||||
case settings.TopDown:
|
||||
target = i + 1 + len(s.repoQuery)
|
||||
case settings.BottomUp:
|
||||
if s.bottomUp {
|
||||
target = len(s.aurQuery) - i + len(s.repoQuery)
|
||||
default:
|
||||
return targets, ErrInvalidSortMode{}
|
||||
} else {
|
||||
target = i + 1 + len(s.repoQuery)
|
||||
}
|
||||
|
||||
if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
|
||||
|
@ -148,10 +141,10 @@ func (s *SourceQueryBuilder) GetTargets(include, exclude intrange.IntRanges,
|
|||
}
|
||||
|
||||
// queryRepo handles repo searches. Creates a RepoSearch struct.
|
||||
func queryRepo(pkgInputN []string, dbExecutor db.Executor, sortMode int) repoQuery {
|
||||
func queryRepo(pkgInputN []string, dbExecutor db.Executor, bottomUp bool) repoQuery {
|
||||
s := repoQuery(dbExecutor.SyncPackages(pkgInputN...))
|
||||
|
||||
if sortMode == settings.BottomUp {
|
||||
if bottomUp {
|
||||
s.Reverse()
|
||||
}
|
||||
|
||||
|
@ -159,7 +152,7 @@ func queryRepo(pkgInputN []string, dbExecutor db.Executor, sortMode int) repoQue
|
|||
}
|
||||
|
||||
// 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) {
|
||||
func queryAUR(ctx context.Context, aurClient *aur.Client, pkgS []string, searchBy string, bottomUp bool, sortBy string) (aurQuery, error) {
|
||||
var (
|
||||
r []aur.Pkg
|
||||
err error
|
||||
|
@ -189,7 +182,7 @@ func queryAUR(ctx context.Context, aurClient *aur.Client, pkgS []string, searchB
|
|||
sort.Sort(aurSortable{
|
||||
aurQuery: r,
|
||||
sortBy: sortBy,
|
||||
sortMode: sortMode,
|
||||
bottomUp: bottomUp,
|
||||
})
|
||||
|
||||
return r, err
|
||||
|
@ -229,7 +222,7 @@ func queryAUR(ctx context.Context, aurClient *aur.Client, pkgS []string, searchB
|
|||
sort.Sort(aurSortable{
|
||||
aurQuery: aq,
|
||||
sortBy: sortBy,
|
||||
sortMode: sortMode,
|
||||
bottomUp: bottomUp,
|
||||
})
|
||||
|
||||
return aq, err
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/leonelquinteros/gotext"
|
||||
|
||||
"github.com/Jguer/yay/v11/pkg/db"
|
||||
"github.com/Jguer/yay/v11/pkg/settings"
|
||||
"github.com/Jguer/yay/v11/pkg/text"
|
||||
)
|
||||
|
||||
|
@ -22,7 +21,7 @@ type (
|
|||
type aurSortable struct {
|
||||
aurQuery
|
||||
sortBy string
|
||||
sortMode int
|
||||
bottomUp bool
|
||||
}
|
||||
|
||||
func (r repoQuery) Reverse() {
|
||||
|
@ -61,7 +60,7 @@ func (q aurSortable) Less(i, j int) bool {
|
|||
result = q.aurQuery[i].PackageBaseID < q.aurQuery[j].PackageBaseID
|
||||
}
|
||||
|
||||
if q.sortMode == settings.BottomUp {
|
||||
if q.bottomUp {
|
||||
return !result
|
||||
}
|
||||
|
||||
|
@ -97,24 +96,23 @@ func (q aurQuery) printSearch(
|
|||
start int,
|
||||
dbExecutor db.Executor,
|
||||
searchMode SearchVerbosity,
|
||||
sortMode int,
|
||||
bottomUp,
|
||||
singleLineResults bool,
|
||||
) {
|
||||
for i := range q {
|
||||
if searchMode == Minimal {
|
||||
_, _ = fmt.Fprintln(w, q[i].Name)
|
||||
continue
|
||||
}
|
||||
|
||||
var toprint string
|
||||
|
||||
if searchMode == NumberMenu {
|
||||
switch sortMode {
|
||||
case settings.TopDown:
|
||||
toprint += text.Magenta(strconv.Itoa(start+i) + " ")
|
||||
case settings.BottomUp:
|
||||
if bottomUp {
|
||||
toprint += text.Magenta(strconv.Itoa(len(q)+start-i-1) + " ")
|
||||
default:
|
||||
text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
|
||||
} else {
|
||||
toprint += text.Magenta(strconv.Itoa(start+i) + " ")
|
||||
}
|
||||
} else if searchMode == Minimal {
|
||||
_, _ = fmt.Fprintln(w, q[i].Name)
|
||||
continue
|
||||
}
|
||||
|
||||
toprint += text.Bold(text.ColorHash("aur")) + "/" + text.Bold(q[i].Name) +
|
||||
|
@ -150,22 +148,21 @@ func (q aurQuery) printSearch(
|
|||
}
|
||||
|
||||
// PrintSearch receives a RepoSearch type and outputs pretty text.
|
||||
func (r repoQuery) printSearch(w io.Writer, dbExecutor db.Executor, searchMode SearchVerbosity, sortMode int, singleLineResults bool) {
|
||||
func (r repoQuery) printSearch(w io.Writer, dbExecutor db.Executor, searchMode SearchVerbosity, bottomUp, singleLineResults bool) {
|
||||
for i, res := range r {
|
||||
if searchMode == Minimal {
|
||||
_, _ = fmt.Fprintln(w, res.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
var toprint string
|
||||
|
||||
if searchMode == NumberMenu {
|
||||
switch sortMode {
|
||||
case settings.TopDown:
|
||||
toprint += text.Magenta(strconv.Itoa(i+1) + " ")
|
||||
case settings.BottomUp:
|
||||
if bottomUp {
|
||||
toprint += text.Magenta(strconv.Itoa(len(r)-i) + " ")
|
||||
default:
|
||||
text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
|
||||
} else {
|
||||
toprint += text.Magenta(strconv.Itoa(i+1) + " ")
|
||||
}
|
||||
} else if searchMode == Minimal {
|
||||
_, _ = fmt.Fprintln(w, res.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
toprint += text.Bold(text.ColorHash(res.DB().Name())) + "/" + text.Bold(res.Name()) +
|
||||
|
|
|
@ -134,12 +134,11 @@ func Test_aurQuery_printSearch(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
w := &strings.Builder{}
|
||||
sortMode := 1
|
||||
executor := mock.DBExecutor{}
|
||||
text.UseColor = tt.useColor
|
||||
|
||||
// Fire
|
||||
tt.q.printSearch(w, 1, executor, tt.args.searchMode, sortMode, tt.args.singleLineResults)
|
||||
tt.q.printSearch(w, 1, executor, tt.args.searchMode, false, tt.args.singleLineResults)
|
||||
|
||||
got := w.String()
|
||||
assert.Equal(t, tt.want, got)
|
||||
|
@ -237,12 +236,11 @@ func Test_repoQuery_printSearch(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
w := &strings.Builder{}
|
||||
sortMode := 1
|
||||
executor := mock.DBExecutor{}
|
||||
text.UseColor = tt.useColor
|
||||
|
||||
// Fire
|
||||
tt.q.printSearch(w, executor, tt.args.searchMode, sortMode, tt.args.singleLineResults)
|
||||
tt.q.printSearch(w, executor, tt.args.searchMode, false, tt.args.singleLineResults)
|
||||
|
||||
got := w.String()
|
||||
assert.Equal(t, tt.want, got)
|
||||
|
|
|
@ -50,9 +50,9 @@ func (c *Configuration) handleOption(option, value string) bool {
|
|||
case "notimeupdate":
|
||||
c.TimeUpdate = false
|
||||
case "topdown":
|
||||
c.SortMode = TopDown
|
||||
c.BottomUp = false
|
||||
case "bottomup":
|
||||
c.SortMode = BottomUp
|
||||
c.BottomUp = true
|
||||
case "singlelineresults":
|
||||
c.SingleLineResults = true
|
||||
case "doublelineresults":
|
||||
|
|
|
@ -21,12 +21,6 @@ import (
|
|||
"github.com/Jguer/yay/v11/pkg/vcs"
|
||||
)
|
||||
|
||||
const (
|
||||
// Describes Sorting method for numberdisplay.
|
||||
BottomUp = iota
|
||||
TopDown
|
||||
)
|
||||
|
||||
// HideMenus indicates if pacman's provider menus must be hidden.
|
||||
var HideMenus = false
|
||||
|
||||
|
@ -60,8 +54,8 @@ type Configuration struct {
|
|||
SudoBin string `json:"sudobin"`
|
||||
SudoFlags string `json:"sudoflags"`
|
||||
RequestSplitN int `json:"requestsplitn"`
|
||||
SortMode int `json:"sortmode"`
|
||||
CompletionInterval int `json:"completionrefreshtime"`
|
||||
BottomUp bool `json:"bottomup"`
|
||||
SudoLoop bool `json:"sudoloop"`
|
||||
TimeUpdate bool `json:"timeupdate"`
|
||||
Devel bool `json:"devel"`
|
||||
|
@ -185,7 +179,7 @@ func DefaultConfig() *Configuration {
|
|||
GpgFlags: "",
|
||||
MFlags: "",
|
||||
GitFlags: "",
|
||||
SortMode: BottomUp,
|
||||
BottomUp: true,
|
||||
CompletionInterval: 7,
|
||||
SortBy: "votes",
|
||||
SearchBy: "name-desc",
|
||||
|
|
2
query.go
2
query.go
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
// SyncSearch presents a query to the local repos and to the AUR.
|
||||
func syncSearch(ctx context.Context, pkgS []string, aurClient *aur.Client, dbExecutor db.Executor, verbose bool) error {
|
||||
queryBuilder := query.NewSourceQueryBuilder(config.SortMode, config.SortBy, config.Runtime.Mode, config.SearchBy, config.SingleLineResults)
|
||||
queryBuilder := query.NewSourceQueryBuilder(config.SortBy, config.Runtime.Mode, config.SearchBy, config.BottomUp, config.SingleLineResults)
|
||||
|
||||
queryBuilder.Execute(ctx, dbExecutor, aurClient, pkgS)
|
||||
|
||||
|
|
Loading…
Reference in a new issue