Added SortOrder

This commit is contained in:
Jguer committed 2016-12-02 12:19:03 +00:00
1 parent 7d6eb8fdbe
commit 2f2df47639
5 files changed
+210 -144

No files matched your search

+80 -27
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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