Added SortOrder
This commit is contained in:
1 parent
7d6eb8fdbe
commit
2f2df47639
5 files changed
+210
-144
No files matched your search
+80
-27
@@ -19,23 +19,43 @@ const BuildDir string = "/tmp/yaytmp/"
|
||||
// SearchMode is search without numbers.
|
||||
const SearchMode int = -1
|
||||
|
||||
// SortMode NumberMenu and Search
|
||||
var SortMode = DownTop
|
||||
|
||||
// Determines NumberMenu and Search Order
|
||||
const (
|
||||
DownTop = iota
|
||||
TopDown
|
||||
)
|
||||
|
||||
// Config copies settings over to AUR and Pacman packages
|
||||
func Config() {
|
||||
aur.SortMode = SortMode
|
||||
}
|
||||
|
||||
// NumberMenu presents a CLI for selecting packages to install.
|
||||
func NumberMenu(pkgName string, flags []string) (err error) {
|
||||
var num int
|
||||
var numberString string
|
||||
var args []string
|
||||
|
||||
a, n, err := aur.Search(pkgName, true)
|
||||
r, err := pac.SearchPackages(pkgName)
|
||||
a, nA, err := aur.Search(pkgName, true)
|
||||
r, nR, err := pac.Search(pkgName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(r.Results) == 0 && n == 0 {
|
||||
return fmt.Errorf("no Packages match search")
|
||||
if nR == 0 && nA == 0 {
|
||||
return fmt.Errorf("no packages match search")
|
||||
}
|
||||
|
||||
if aur.SortMode == aur.DownTop {
|
||||
a.PrintSearch(nR)
|
||||
r.PrintSearch(0)
|
||||
} else {
|
||||
r.PrintSearch(0)
|
||||
a.PrintSearch(nR)
|
||||
}
|
||||
r.PrintSearch(0)
|
||||
a.PrintSearch(len(r.Results))
|
||||
|
||||
args = append(args, "pacman", "-S")
|
||||
|
||||
@@ -52,15 +72,24 @@ func NumberMenu(pkgName string, flags []string) (err error) {
|
||||
for _, numS := range result {
|
||||
num, err = strconv.Atoi(numS)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Install package
|
||||
if num > len(r.Results)-1 {
|
||||
aurInstall = append(aurInstall, a[num-len(r.Results)])
|
||||
if num > nA+nR-1 || num < 0 {
|
||||
continue
|
||||
} else if num > nR-1 {
|
||||
if aur.SortMode == aur.DownTop {
|
||||
aurInstall = append(aurInstall, a[nA+nR-num-1])
|
||||
} else {
|
||||
aurInstall = append(aurInstall, a[num-nR])
|
||||
}
|
||||
} else {
|
||||
args = append(args, r.Results[num].Name)
|
||||
if aur.SortMode == aur.DownTop {
|
||||
args = append(args, r[nR-num-1].Name)
|
||||
} else {
|
||||
args = append(args, r[num].Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,23 +116,9 @@ func NumberMenu(pkgName string, flags []string) (err error) {
|
||||
|
||||
// Install handles package installs
|
||||
func Install(pkgs []string, flags []string) error {
|
||||
var args []string
|
||||
args = append(args, "pacman")
|
||||
args = append(args, "-S")
|
||||
|
||||
args = append(args, flags...)
|
||||
|
||||
aurs, repos, _ := pac.PackageSlices(pkgs)
|
||||
|
||||
args = append(args, repos...)
|
||||
if len(repos) != 0 {
|
||||
var cmd *exec.Cmd
|
||||
cmd = exec.Command("sudo", args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Run()
|
||||
}
|
||||
pac.Install(repos, flags)
|
||||
|
||||
q, n, err := aur.MultiInfo(aurs)
|
||||
if len(aurs) != n {
|
||||
@@ -138,9 +153,18 @@ func Search(pkg string) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, _, err := pac.Search(pkg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pac.SearchRepos(pkg, SearchMode)
|
||||
a.PrintSearch(SearchMode)
|
||||
if aur.SortMode == aur.DownTop {
|
||||
a.PrintSearch(SearchMode)
|
||||
r.PrintSearch(SearchMode)
|
||||
} else {
|
||||
r.PrintSearch(SearchMode)
|
||||
a.PrintSearch(SearchMode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -195,3 +219,32 @@ func size(s int64) string {
|
||||
|
||||
return fmt.Sprintf(format+"%s", size, symbols[int(i)])
|
||||
}
|
||||
|
||||
// PassToPacman outsorces execution to pacman binary without modifications.
|
||||
func PassToPacman(op string, pkgs []string, flags []string) error {
|
||||
var cmd *exec.Cmd
|
||||
var args []string
|
||||
|
||||
args = append(args, op)
|
||||
if len(pkgs) != 0 {
|
||||
args = append(args, pkgs...)
|
||||
}
|
||||
|
||||
if len(flags) != 0 {
|
||||
args = append(args, flags...)
|
||||
}
|
||||
|
||||
if strings.Contains(op, "-Q") {
|
||||
cmd = exec.Command("pacman", args...)
|
||||
} else {
|
||||
args = append([]string{"pacman"}, args...)
|
||||
cmd = exec.Command("sudo", args...)
|
||||
}
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
return err
|
||||
|
||||
}
|
||||
+47
-19
@@ -23,6 +23,15 @@ const MakepkgBin string = "/usr/bin/makepkg"
|
||||
// SearchMode is search without numbers.
|
||||
const SearchMode int = -1
|
||||
|
||||
// SortMode determines top down package or down top package display
|
||||
var SortMode = DownTop
|
||||
|
||||
// Describes Sorting method for numberdisplay
|
||||
const (
|
||||
DownTop = iota
|
||||
TopDown
|
||||
)
|
||||
|
||||
// Result describes an AUR package.
|
||||
type Result struct {
|
||||
ID int `json:"ID"`
|
||||
@@ -57,7 +66,10 @@ func (q Query) Len() int {
|
||||
}
|
||||
|
||||
func (q Query) Less(i, j int) bool {
|
||||
return q[i].NumVotes < q[j].NumVotes
|
||||
if SortMode == DownTop {
|
||||
return q[i].NumVotes < q[j].NumVotes
|
||||
}
|
||||
return q[i].NumVotes > q[j].NumVotes
|
||||
}
|
||||
|
||||
func (q Query) Swap(i, j int) {
|
||||
@@ -67,20 +79,20 @@ func (q Query) Swap(i, j int) {
|
||||
// PrintSearch handles printing search results in a given format
|
||||
func (q Query) PrintSearch(start int) {
|
||||
for i, res := range q {
|
||||
switch {
|
||||
case start != SearchMode && res.Installed:
|
||||
fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) \x1b[32;40mInstalled\x1b[0m\n%s\n",
|
||||
start+i, "aur", res.Name, res.Version, res.NumVotes, res.Description)
|
||||
case start != SearchMode && !res.Installed:
|
||||
fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d)\n%s\n",
|
||||
start+i, "aur", res.Name, res.Version, res.NumVotes, res.Description)
|
||||
case start == SearchMode && res.Installed:
|
||||
fmt.Printf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[32;40mInstalled\x1b[0m\n%s\n",
|
||||
"aur", res.Name, res.Version, res.Description)
|
||||
case start == SearchMode && !res.Installed:
|
||||
fmt.Printf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s\x1b[0m\n%s\n",
|
||||
"aur", res.Name, res.Version, res.Description)
|
||||
var toprint string
|
||||
if start != SearchMode {
|
||||
if SortMode == DownTop {
|
||||
toprint += fmt.Sprintf("%d ", len(q)+start-i-1)
|
||||
} else {
|
||||
toprint += fmt.Sprintf("%d ", start+i)
|
||||
}
|
||||
}
|
||||
toprint += fmt.Sprintf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) ", "aur", res.Name, res.Version, res.NumVotes)
|
||||
if res.Installed == true {
|
||||
toprint += fmt.Sprintf("\x1b[32;40mInstalled\x1b[0m")
|
||||
}
|
||||
toprint += "\n" + res.Description
|
||||
fmt.Println(toprint)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,13 +108,30 @@ func Search(pkg string, sortS bool) (Query, int, error) {
|
||||
if sortS {
|
||||
sort.Sort(r.Results)
|
||||
}
|
||||
setter := pacman.PFactory(pFSetTrue)
|
||||
|
||||
// for _, res := range r.Results {
|
||||
// res.Installed, err = IspkgInstalled(res.Name)
|
||||
// }
|
||||
for i, res := range r.Results {
|
||||
if i == len(r.Results)-1 {
|
||||
setter(res.Name, &r.Results[i], true)
|
||||
continue
|
||||
}
|
||||
setter(res.Name, &r.Results[i], false)
|
||||
}
|
||||
return r.Results, r.ResultCount, err
|
||||
}
|
||||
|
||||
// This is very dirty but it works so good.
|
||||
func pFSetTrue(res interface{}) {
|
||||
f, ok := res.(*Result)
|
||||
if !ok {
|
||||
fmt.Println("Unable to convert back to Result")
|
||||
return
|
||||
}
|
||||
f.Installed = true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Info returns an AUR search with package details
|
||||
func Info(pkg string) (Query, int, error) {
|
||||
type returned struct {
|
||||
@@ -180,7 +209,6 @@ func Upgrade(baseDir string, flags []string) error {
|
||||
outdated = append(outdated, res)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//If there are no outdated packages, don't prompt
|
||||
@@ -265,7 +293,7 @@ func (a *Result) Install(baseDir string, flags []string) (err error) {
|
||||
|
||||
// Repo dependencies
|
||||
if len(repoDeps) != 0 {
|
||||
pacman.PassToPacman("-S", repoDeps, []string{"--asdeps", "--needed"})
|
||||
pacman.Install(repoDeps, []string{"--asdeps", "--needed"})
|
||||
}
|
||||
|
||||
err = os.Chdir(dir.String())
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
eN := "yay"
|
||||
eD := "Yet another pacman wrapper with AUR support"
|
||||
eD := "Yet another yogurt. Pacman wrapper with AUR support written in go."
|
||||
result, _, err := Search("yay", true)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected err to be nil but it was %s", err)
|
||||
@@ -39,7 +39,7 @@ func BenchmarkSearchComplexSorted(b *testing.B) { benchmarkSearch("linux", true,
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
eN := "yay"
|
||||
eD := "Yet another pacman wrapper with AUR support"
|
||||
eD := "Yet another yogurt. Pacman wrapper with AUR support written in go."
|
||||
eM := []string{"go", "git"}
|
||||
result, _, err := Info("yay")
|
||||
if err != nil {
|
||||
|
||||
+9
-4
@@ -5,7 +5,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/jguer/yay"
|
||||
pac "github.com/jguer/yay/pacman"
|
||||
)
|
||||
|
||||
func usage() {
|
||||
@@ -42,8 +41,13 @@ func parser() (op string, options []string, packages []string, err error) {
|
||||
if arg[0] == '-' && arg[1] == '-' {
|
||||
if arg == "--help" {
|
||||
op = arg
|
||||
} else if arg == "--topdown" {
|
||||
yay.SortMode = yay.TopDown
|
||||
} else if arg == "--downtop" {
|
||||
yay.SortMode = yay.DownTop
|
||||
} else {
|
||||
options = append(options, arg)
|
||||
}
|
||||
options = append(options, arg)
|
||||
}
|
||||
|
||||
if arg[0] != '-' {
|
||||
@@ -59,13 +63,14 @@ func parser() (op string, options []string, packages []string, err error) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
op, options, pkgs, err := parser()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
yay.Config()
|
||||
|
||||
switch op {
|
||||
case "-Qstats":
|
||||
err = yay.LocalStatistics(version)
|
||||
@@ -85,7 +90,7 @@ func main() {
|
||||
case "--help", "-h":
|
||||
usage()
|
||||
default:
|
||||
err = pac.PassToPacman(op, pkgs, options)
|
||||
err = yay.PassToPacman(op, pkgs, options)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
+72
-92
@@ -10,9 +10,7 @@ import (
|
||||
)
|
||||
|
||||
// RepoSearch describes a Repository search.
|
||||
type RepoSearch struct {
|
||||
Results []Result
|
||||
}
|
||||
type RepoSearch []Result
|
||||
|
||||
// Result describes a pkg.
|
||||
type Result struct {
|
||||
@@ -20,12 +18,10 @@ type Result struct {
|
||||
Repository string
|
||||
Version string
|
||||
Description string
|
||||
Group string
|
||||
Installed bool
|
||||
}
|
||||
|
||||
// SearchMode is search without numbers.
|
||||
const SearchMode int = -1
|
||||
|
||||
// PacmanConf describes the default pacman config file
|
||||
const PacmanConf string = "/etc/pacman.conf"
|
||||
|
||||
@@ -63,75 +59,41 @@ func UpdatePackages(flags []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// SearchRepos searches and prints packages in repo
|
||||
func SearchRepos(pkgName string, mode int) (err error) {
|
||||
// Search handles repo searches. Creates a RepoSearch struct.
|
||||
func Search(pkgName string) (s RepoSearch, n int, err error) {
|
||||
h, err := conf.CreateHandle()
|
||||
defer h.Release()
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
dbList, _ := h.SyncDbs()
|
||||
localdb, _ := h.LocalDb()
|
||||
|
||||
var installed bool
|
||||
var i int
|
||||
for _, db := range dbList.Slice() {
|
||||
for _, pkg := range db.PkgCache().Slice() {
|
||||
if strings.Contains(pkg.Name(), pkgName) {
|
||||
if r, _ := localdb.PkgByName(pkg.Name()); r != nil {
|
||||
installed = true
|
||||
} else {
|
||||
installed = false
|
||||
}
|
||||
|
||||
switch {
|
||||
case mode != SearchMode && !installed:
|
||||
fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[32;40mInstalled\x1b[0m\n%s\n",
|
||||
i, db.Name(), pkg.Name(), pkg.Version(), pkg.Description())
|
||||
case mode != SearchMode && !installed:
|
||||
fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s\x1b[0m\n%s\n",
|
||||
i, db.Name(), pkg.Name(), pkg.Version(), pkg.Description())
|
||||
case mode == SearchMode && !installed:
|
||||
fmt.Printf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[32;40mInstalled\x1b[0m\n%s\n",
|
||||
db.Name(), pkg.Name(), pkg.Version(), pkg.Description())
|
||||
case mode == SearchMode && !installed:
|
||||
fmt.Printf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s\x1b[0m\n%s\n",
|
||||
db.Name(), pkg.Name(), pkg.Version(), pkg.Description())
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SearchPackages handles repo searches. Creates a RepoSearch struct.
|
||||
func SearchPackages(pkgName string) (s RepoSearch, err error) {
|
||||
h, err := conf.CreateHandle()
|
||||
defer h.Release()
|
||||
localDb, err := h.LocalDb()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dbList, err := h.SyncDbs()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dbList, _ := h.SyncDbs()
|
||||
localdb, _ := h.LocalDb()
|
||||
|
||||
var installed bool
|
||||
for _, db := range dbList.Slice() {
|
||||
for _, pkg := range db.PkgCache().Slice() {
|
||||
if strings.Contains(pkg.Name(), pkgName) {
|
||||
if r, _ := localdb.PkgByName(pkg.Name()); r != nil {
|
||||
if r, _ := localDb.PkgByName(pkg.Name()); r != nil {
|
||||
installed = true
|
||||
} else {
|
||||
installed = false
|
||||
}
|
||||
|
||||
s.Results = append(s.Results, Result{
|
||||
s = append(s, Result{
|
||||
Name: pkg.Name(),
|
||||
Description: pkg.Description(),
|
||||
Version: pkg.Version(),
|
||||
Repository: db.Name(),
|
||||
Group: strings.Join(pkg.Groups().Slice(), ","),
|
||||
Installed: installed,
|
||||
})
|
||||
n++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,52 +101,49 @@ func SearchPackages(pkgName string) (s RepoSearch, err error) {
|
||||
}
|
||||
|
||||
//PrintSearch receives a RepoSearch type and outputs pretty text.
|
||||
func (s *RepoSearch) PrintSearch(mode int) {
|
||||
for i, pkg := range s.Results {
|
||||
switch {
|
||||
case mode != SearchMode && pkg.Installed:
|
||||
fmt.Printf("%d \033[1m%s/\x1B[33m%s \x1B[36m%s \x1B[32;40mInstalled\033[0m\n%s\n",
|
||||
i, pkg.Repository, pkg.Name, pkg.Version, pkg.Description)
|
||||
case mode != SearchMode && !pkg.Installed:
|
||||
fmt.Printf("%d \033[1m%s/\x1B[33m%s \x1B[36m%s\033[0m\n%s\n",
|
||||
i, pkg.Repository, pkg.Name, pkg.Version, pkg.Description)
|
||||
case mode == SearchMode && pkg.Installed:
|
||||
fmt.Printf("\033[1m%s/\x1B[33m%s \x1B[36m%s \x1B[32;40mInstalled\033[0m\n%s\n",
|
||||
pkg.Repository, pkg.Name, pkg.Version, pkg.Description)
|
||||
case mode == SearchMode && !pkg.Installed:
|
||||
fmt.Printf("\033[1m%s/\x1B[33m%s \x1B[36m%s\033[0m\n%s\n",
|
||||
pkg.Repository, pkg.Name, pkg.Version, pkg.Description)
|
||||
func (s RepoSearch) PrintSearch(mode int) {
|
||||
for i, res := range s {
|
||||
var toprint string
|
||||
if mode != -1 {
|
||||
if mode == 0 {
|
||||
toprint += fmt.Sprintf("%d ", len(s)-i-1)
|
||||
} else {
|
||||
toprint += fmt.Sprintf("%d ", i)
|
||||
}
|
||||
}
|
||||
toprint += fmt.Sprintf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m",
|
||||
res.Repository, res.Name, res.Version)
|
||||
|
||||
if len(res.Group) != 0 {
|
||||
toprint += fmt.Sprintf("(%s) ", res.Group)
|
||||
}
|
||||
|
||||
if res.Installed == true {
|
||||
toprint += fmt.Sprintf("\x1b[32;40mInstalled\x1b[0m")
|
||||
}
|
||||
|
||||
toprint += "\n" + res.Description
|
||||
fmt.Println(toprint)
|
||||
}
|
||||
}
|
||||
|
||||
// PassToPacman outsorces execution to pacman binary without modifications.
|
||||
func PassToPacman(op string, pkgs []string, flags []string) error {
|
||||
var cmd *exec.Cmd
|
||||
var args []string
|
||||
// PFactory execute an action over a series of packages without reopening the handle everytime.
|
||||
// Everybody told me it wouln't work. It does. It's just not pretty.
|
||||
// When it worked: https://youtu.be/a4Z5BdEL0Ag?t=1m11s
|
||||
func PFactory(action func(interface{})) func(name string, object interface{}, rel bool) {
|
||||
h, _ := conf.CreateHandle()
|
||||
localDb, _ := h.LocalDb()
|
||||
|
||||
args = append(args, op)
|
||||
if len(pkgs) != 0 {
|
||||
args = append(args, pkgs...)
|
||||
return func(name string, object interface{}, rel bool) {
|
||||
_, err := localDb.PkgByName(name)
|
||||
if err == nil {
|
||||
action(object)
|
||||
}
|
||||
|
||||
if rel {
|
||||
h.Release()
|
||||
}
|
||||
}
|
||||
|
||||
if len(flags) != 0 {
|
||||
args = append(args, flags...)
|
||||
}
|
||||
|
||||
if strings.Contains(op, "-Q") {
|
||||
cmd = exec.Command("pacman", args...)
|
||||
} else {
|
||||
args = append([]string{"pacman"}, args...)
|
||||
cmd = exec.Command("sudo", args...)
|
||||
}
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
// PackageSlices separates an input slice into aur and repo slices
|
||||
@@ -281,6 +240,27 @@ func OutofRepo(toCheck []string) (aur []string, repo []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Install sends an install command to pacman with the pkgName slice
|
||||
func Install(pkgName []string, flags []string) (err error) {
|
||||
if len(pkgName) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
var args []string
|
||||
args = append(args, "pacman")
|
||||
args = append(args, "-S")
|
||||
args = append(args, pkgName...)
|
||||
args = append(args, flags...)
|
||||
|
||||
cmd = exec.Command("sudo", args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Run()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForeignPackages returns a map of foreign packages, with their version and date as values.
|
||||
func ForeignPackages() (foreign map[string]*struct {
|
||||
Version string
|
||||
|
||||
Reference in new issue
Block a user