From 9b4667344e9c17fb591e7ef2b0e85c4e614b92bb Mon Sep 17 00:00:00 2001 From: Jguer Date: Tue, 2 May 2017 16:46:14 +0100 Subject: [PATCH] Refactored yay to use mikkeloscars aur package --- actions.go | 28 +++---------- aur/aur.go | 74 ++++++++++++++++++++++++++++----- aur/aur_test.go | 87 -------------------------------------- aur/query.go | 108 ++---------------------------------------------- aur/result.go | 60 ++++++++------------------- query.go | 61 ++++++++++++++++++++++----- utils.go | 4 +- yay.go | 48 +++++++-------------- 8 files changed, 158 insertions(+), 312 deletions(-) delete mode 100644 aur/aur_test.go diff --git a/actions.go b/actions.go index a2ac4dc0..21b6aeb6 100644 --- a/actions.go +++ b/actions.go @@ -10,7 +10,7 @@ import ( ) // Install handles package installs -func Install(pkgs []string, flags []string) error { +func install(pkgs []string, flags []string) error { aurs, repos, _ := pac.PackageSlices(pkgs) err := pac.Install(repos, flags) @@ -18,29 +18,13 @@ func Install(pkgs []string, flags []string) error { fmt.Println("Error installing repo packages.") } - q, n, err := aur.MultiInfo(aurs) - if len(aurs) != n || err != nil { - fmt.Println("Unable to get info on some packages") - } + err = aur.Install(aurs, flags) - var finalrm []string - for _, aurpkg := range q { - finalmdeps, err := aurpkg.Install(flags) - finalrm = append(finalrm, finalmdeps...) - if err != nil { - fmt.Println("Error installing", aurpkg.Name, ":", err) - } - } - - if len(finalrm) != 0 { - aur.RemoveMakeDeps(finalrm) - } - - return nil + return err } // Upgrade handles updating the cache and installing updates. -func Upgrade(flags []string) error { +func upgrade(flags []string) error { errp := pac.UpdatePackages(flags) erra := aur.Upgrade(flags) @@ -52,7 +36,7 @@ func Upgrade(flags []string) error { } // CleanDependencies removels all dangling dependencies in system -func CleanDependencies(pkgs []string) error { +func cleanDependencies(pkgs []string) error { hanging, err := pac.HangingPackages() if err != nil { return err @@ -69,7 +53,7 @@ func CleanDependencies(pkgs []string) error { } // GetPkgbuild gets the pkgbuild of the package 'pkg' trying the ABS first and then the AUR trying the ABS first and then the AUR. -func GetPkgbuild(pkg string) (err error) { +func getPkgbuild(pkg string) (err error) { wd, err := os.Getwd() if err != nil { return diff --git a/aur/aur.go b/aur/aur.go index bcb41620..d4c0bde2 100644 --- a/aur/aur.go +++ b/aur/aur.go @@ -5,23 +5,75 @@ import ( "fmt" "net/http" "os" + "sort" + "strings" "github.com/jguer/yay/pacman" "github.com/jguer/yay/util" + rpc "github.com/mikkeloscar/aur" ) +// NarrowSearch searches AUR and narrows based on subarguments +func NarrowSearch(pkgS []string, sortS bool) (Query, error) { + if len(pkgS) == 0 { + return nil, nil + } + + r, err := rpc.Search(pkgS[0]) + + if len(pkgS) == 1 { + return r, err + } + + var aq Query + var n int = 0 + + for _, res := range r { + match := true + for _, pkgN := range pkgS[1:] { + if !(strings.Contains(res.Name, pkgN) || strings.Contains(strings.ToLower(res.Description), pkgN)) { + match = false + break + } + } + + if match { + n++ + aq = append(aq, res) + } + } + + if sortS { + sort.Sort(aq) + } + + return aq, err +} + // Install sends system commands to make and install a package from pkgName -func Install(pkg string, flags []string) (err error) { - q, n, err := Info(pkg) +func Install(pkgName []string, flags []string) (err error) { + q, err := rpc.Info(pkgName) if err != nil { return } - if n == 0 { - return fmt.Errorf("Package %s does not exist", pkg) + if len(q) != len(pkgName) { + return fmt.Errorf("Some package from list\n%+v\ndoes not exist", pkgName) + } + + var finalrm []string + for _, i := range q { + mrm, err := PkgInstall(&i, flags) + if err != nil { + fmt.Println("Error installing", i.Name, ":", err) + } + finalrm = append(finalrm, mrm...) + } + + if len(finalrm) != 0 { + err = RemoveMakeDeps(finalrm) } - q[0].Install(flags) return err } @@ -41,7 +93,7 @@ func Upgrade(flags []string) error { i++ } - q, _, err := MultiInfo(keys) + q, err := rpc.Info(keys) if err != nil { return err } @@ -50,7 +102,7 @@ func Upgrade(flags []string) error { for _, res := range q { if _, ok := foreign[res.Name]; ok { // Leaving this here for now, warn about downgrades later - if res.LastModified > foreign[res.Name].Date { + if res.LastModified > int(foreign[res.Name].Date) { fmt.Printf("\x1b[1m\x1b[32m==>\x1b[33;1m %s: \x1b[0m%s \x1b[33;1m-> \x1b[0m%s\n", res.Name, foreign[res.Name].Version, res.Version) outdated = append(outdated, res) @@ -69,8 +121,8 @@ func Upgrade(flags []string) error { return nil } - for _, pkg := range outdated { - pkg.Install(flags) + for _, pkgi := range outdated { + PkgInstall(&pkgi, flags) } return nil @@ -78,12 +130,12 @@ func Upgrade(flags []string) error { // GetPkgbuild downloads pkgbuild from the AUR. func GetPkgbuild(pkgN string, dir string) (err error) { - aq, numaq, err := Info(pkgN) + aq, err := rpc.Info([]string{pkgN}) if err != nil { return err } - if numaq == 0 { + if len(aq) == 0 { return fmt.Errorf("no results") } diff --git a/aur/aur_test.go b/aur/aur_test.go deleted file mode 100644 index edae5abb..00000000 --- a/aur/aur_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package aur - -import ( - "os" - "reflect" - "testing" -) - -func TestSearch(t *testing.T) { - - eN := "yay" - result, _, err := Search([]string{"yay"}, true) - if err != nil { - t.Fatalf("Expected err to be nil but it was %s", err) - } - - // t.Logf("Got struct: %+v", result) - found := false - for _, v := range result { - if v.Name == eN { - found = true - } - } - - if !found { - t.Fatalf("Expected to find yay, found %+v", result) - } -} - -func benchmarkSearch(search string, sort bool, b *testing.B) { - - for n := 0; n < b.N; n++ { - Search([]string{search}, sort) - } -} - -func BenchmarkSearchSimpleNoSort(b *testing.B) { benchmarkSearch("yay", false, b) } -func BenchmarkSearchComplexNoSort(b *testing.B) { benchmarkSearch("linux", false, b) } -func BenchmarkSearchSimpleSorted(b *testing.B) { benchmarkSearch("yay", true, b) } -func BenchmarkSearchComplexSorted(b *testing.B) { benchmarkSearch("linux", true, b) } - -func TestInfo(t *testing.T) { - - eN := "yay" - eM := []string{"go", "git"} - result, _, err := Info("yay") - if err != nil { - t.Fatalf("Expected err to be nil but it was %s", err) - } - - // t.Logf("Got struct: %+v", result) - found := false - for _, v := range result { - if v.Name == eN && reflect.DeepEqual(v.MakeDepends, eM) { - found = true - } - } - - if !found { - t.Fatalf("Expected to find yay, found %+v", result) - } -} - -func TestUpgrade(t *testing.T) { - old := os.Stdout - _, w, _ := os.Pipe() - os.Stdout = w - - err := Upgrade([]string{}) - if err != nil { - t.Fatalf("Expected err to be nil but it was %s", err) - } - - os.Stdout = old -} - -func BenchmarkUpgrade(b *testing.B) { - old := os.Stdout - _, w, _ := os.Pipe() - os.Stdout = w - - for n := 0; n < b.N; n++ { - Upgrade([]string{}) - } - - os.Stdout = old -} diff --git a/aur/query.go b/aur/query.go index d9aa1dac..077c4ee4 100644 --- a/aur/query.go +++ b/aur/query.go @@ -2,19 +2,15 @@ package aur import ( "fmt" - "sort" - "strings" "github.com/jguer/yay/util" + rpc "github.com/mikkeloscar/aur" ) -// Query is a collection of Results -type Query []Result +const aurURL = "https://aur.archlinux.org/rpc/?" -type returned struct { - Results Query `json:"results"` - ResultCount int `json:"resultcount"` -} +// Query is a collection of Results +type Query []rpc.Pkg func (q Query) Len() int { return len(q) @@ -31,102 +27,6 @@ func (q Query) Swap(i, j int) { q[i], q[j] = q[j], q[i] } -// PrintSearch handles printing search results in a given format -func (q Query) PrintSearch(start int) { - for i, res := range q { - var toprint string - if util.SearchVerbosity == util.NumberMenu { - if util.SortMode == util.BottomUp { - toprint += fmt.Sprintf("%d ", len(q)+start-i-1) - } else { - toprint += fmt.Sprintf("%d ", start+i) - } - } else if util.SearchVerbosity == util.Minimal { - fmt.Println(res.Name) - continue - } - toprint += fmt.Sprintf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) ", "aur", res.Name, res.Version, res.NumVotes) - if res.Maintainer == "" { - toprint += fmt.Sprintf("\x1b[31;40m(Orphaned)\x1b[0m ") - } - - if res.OutOfDate != 0 { - toprint += fmt.Sprintf("\x1b[31;40m(Out-of-date)\x1b[0m ") - } - - if res.Installed == true { - toprint += fmt.Sprintf("\x1b[32;40mInstalled\x1b[0m") - } - toprint += "\n" + res.Description - fmt.Println(toprint) - } - - return -} - -// Info returns an AUR search with package details -func Info(pkg string) (Query, int, error) { - r := returned{} - - err := getJSON("https://aur.archlinux.org/rpc/?v=5&type=info&arg[]="+pkg, &r) - - return r.Results, r.ResultCount, err -} - -// MultiInfo takes a slice of strings and returns a slice with the info of each package -func MultiInfo(pkgS []string) (Query, int, error) { - r := returned{} - - var pkg string - for _, pkgn := range pkgS { - pkg += "&arg[]=" + pkgn - } - - err := getJSON("https://aur.archlinux.org/rpc/?v=5&type=info"+pkg, &r) - - return r.Results, r.ResultCount, err -} - -// Search returns an AUR search -func Search(pkgS []string, sortS bool) (Query, int, error) { - r := returned{} - err := getJSON("https://aur.archlinux.org/rpc/?v=5&type=search&arg="+pkgS[0], &r) - - var aq Query - n := 0 - - h, _ := util.Conf.CreateHandle() - localDb, _ := h.LocalDb() - - var fri int - for _, res := range r.Results { - match := true - for _, pkgN := range pkgS[1:] { - if !(strings.Contains(res.Name, pkgN) || strings.Contains(strings.ToLower(res.Description), pkgN)) { - match = false - break - } - } - - if match { - n++ - aq = append(aq, res) - fri = len(aq) - 1 - _, err := localDb.PkgByName(res.Name) - if err == nil { - aq[fri].Installed = true - } - } - } - - if sortS { - sort.Sort(aq) - } - - h.Release() - return aq, n, err -} - // MissingPackage warns if the Query was unable to find a package func (q Query) MissingPackage(pkgS []string) { for _, depName := range pkgS { diff --git a/aur/result.go b/aur/result.go index de4019f5..7ae6bbdc 100644 --- a/aur/result.go +++ b/aur/result.go @@ -7,42 +7,16 @@ import ( "github.com/jguer/yay/pacman" "github.com/jguer/yay/util" + rpc "github.com/mikkeloscar/aur" ) -// Result describes an AUR package. -type Result struct { - Conflicts []string `json:"Conflicts"` - Depends []string `json:"Depends"` - Description string `json:"Description"` - FirstSubmitted int `json:"FirstSubmitted"` - ID int `json:"ID"` - Keywords []string `json:"Keywords"` - LastModified int64 `json:"LastModified"` - License []string `json:"License"` - Maintainer string `json:"Maintainer"` - MakeDepends []string `json:"MakeDepends"` - Name string `json:"Name"` - NumVotes int `json:"NumVotes"` - OptDepends []string `json:"OptDepends"` - OutOfDate int `json:"OutOfDate"` - PackageBase string `json:"PackageBase"` - PackageBaseID int `json:"PackageBaseID"` - Provides []string `json:"Provides"` - URL string `json:"URL"` - URLPath string `json:"URLPath"` - Version string `json:"Version"` - Installed bool - Popularity float32 `json:"Popularity"` -} - // Dependencies returns package dependencies not installed belonging to AUR // 0 is Repo, 1 is Foreign. -func (a *Result) Dependencies() (runDeps [2][]string, makeDeps [2][]string, err error) { +func PkgDependencies(a *rpc.Pkg) (runDeps [2][]string, makeDeps [2][]string, err error) { var q Query if len(a.Depends) == 0 && len(a.MakeDepends) == 0 { - var n int - q, n, err = Info(a.Name) - if n == 0 || err != nil { + q, err = rpc.Info([]string{a.Name}) + if len(q) == 0 || err != nil { err = fmt.Errorf("Unable to search dependencies, %s", err) return } @@ -91,7 +65,7 @@ func printDeps(repoDeps []string, aurDeps []string) { } // Install handles install from Info Result. -func (a *Result) Install(flags []string) (finalmdeps []string, err error) { +func PkgInstall(a *rpc.Pkg, flags []string) (finalmdeps []string, err error) { fmt.Printf("\x1b[1;32m==> Installing\x1b[33m %s\x1b[0m\n", a.Name) if a.Maintainer == "" { fmt.Println("\x1b[1;31;40m==> Warning:\x1b[0;;40m This package is orphaned.\x1b[0m") @@ -100,7 +74,7 @@ func (a *Result) Install(flags []string) (finalmdeps []string, err error) { if _, err = os.Stat(dir); os.IsExist(err) { if !util.ContinueTask("Directory exists. Clean Build?", "yY") { - os.RemoveAll(util.BaseDir + a.PackageBase) + _ = os.RemoveAll(util.BaseDir + a.PackageBase) } } @@ -114,7 +88,7 @@ func (a *Result) Install(flags []string) (finalmdeps []string, err error) { editcmd.Run() } - runDeps, makeDeps, err := a.Dependencies() + runDeps, makeDeps, err := PkgDependencies(a) if err != nil { return } @@ -130,9 +104,9 @@ func (a *Result) Install(flags []string) (finalmdeps []string, err error) { } } - aurQ, n, _ := MultiInfo(aurDeps) - if n != len(aurDeps) { - aurQ.MissingPackage(aurDeps) + aurQ, _ := rpc.Info(aurDeps) + if len(aurQ) != len(aurDeps) { + (Query)(aurQ).MissingPackage(aurDeps) if !util.ContinueTask("Continue?", "nN") { return finalmdeps, fmt.Errorf("unable to install dependencies") } @@ -154,7 +128,7 @@ func (a *Result) Install(flags []string) (finalmdeps []string, err error) { // Handle AUR dependencies for _, dep := range aurQ { - finalmdepsR, errA := dep.Install(depArgs) + finalmdepsR, errA := PkgInstall(&dep, depArgs) finalmdeps = append(finalmdeps, finalmdepsR...) if errA != nil { @@ -178,7 +152,7 @@ func (a *Result) Install(flags []string) (finalmdeps []string, err error) { } // PrintInfo prints package info like pacman -Si. -func (a *Result) PrintInfo() { +func AURPrintInfo(a *rpc.Pkg) { fmt.Println("\x1b[1;37mRepository :\x1b[0m", "aur") fmt.Println("\x1b[1;37mName :\x1b[0m", a.Name) fmt.Println("\x1b[1;37mVersion :\x1b[0m", a.Version) @@ -190,11 +164,11 @@ func (a *Result) PrintInfo() { } fmt.Println("\x1b[1;37mLicenses :\x1b[0m", a.License) - if len(a.Provides) != 0 { - fmt.Println("\x1b[1;37mProvides :\x1b[0m", a.Provides) - } else { - fmt.Println("\x1b[1;37mProvides :\x1b[0m", "None") - } + // if len(a.Provides) != 0 { + // fmt.Println("\x1b[1;37mProvides :\x1b[0m", a.Provides) + // } else { + // fmt.Println("\x1b[1;37mProvides :\x1b[0m", "None") + // } if len(a.Depends) != 0 { fmt.Println("\x1b[1;37mDepends On :\x1b[0m", a.Depends) diff --git a/query.go b/query.go index c9752264..06a422c5 100644 --- a/query.go +++ b/query.go @@ -6,11 +6,52 @@ import ( "github.com/jguer/yay/aur" pac "github.com/jguer/yay/pacman" "github.com/jguer/yay/util" + rpc "github.com/mikkeloscar/aur" ) +// PrintSearch handles printing search results in a given format +func printAURSearch(q aur.Query, start int) { + h, err := util.Conf.CreateHandle() + defer h.Release() + if err != nil { + } + + localDb, _ := h.LocalDb() + + for i, res := range q { + var toprint string + if util.SearchVerbosity == util.NumberMenu { + if util.SortMode == util.BottomUp { + toprint += fmt.Sprintf("%d ", len(q)+start-i-1) + } else { + toprint += fmt.Sprintf("%d ", start+i) + } + } else if util.SearchVerbosity == util.Minimal { + fmt.Println(res.Name) + continue + } + toprint += fmt.Sprintf("\x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) ", "aur", res.Name, res.Version, res.NumVotes) + if res.Maintainer == "" { + toprint += fmt.Sprintf("\x1b[31;40m(Orphaned)\x1b[0m ") + } + + if res.OutOfDate != 0 { + toprint += fmt.Sprintf("\x1b[31;40m(Out-of-date)\x1b[0m ") + } + + if _, err := localDb.PkgByName(res.Name); err == nil { + toprint += fmt.Sprintf("\x1b[32;40mInstalled\x1b[0m") + } + toprint += "\n" + res.Description + fmt.Println(toprint) + } + + return +} + // SyncSearch presents a query to the local repos and to the AUR. -func SyncSearch(pkgS []string) (err error) { - aq, _, err := aur.Search(pkgS, true) +func syncSearch(pkgS []string) (err error) { + aq, err := aur.NarrowSearch(pkgS, true) if err != nil { return err } @@ -20,41 +61,41 @@ func SyncSearch(pkgS []string) (err error) { } if util.SortMode == util.BottomUp { - aq.PrintSearch(0) + printAURSearch(aq, 0) pq.PrintSearch() } else { pq.PrintSearch() - aq.PrintSearch(0) + printAURSearch(aq, 0) } return nil } // SyncInfo serves as a pacman -Si for repo packages and AUR packages. -func SyncInfo(pkgS []string, flags []string) (err error) { +func syncInfo(pkgS []string, flags []string) (err error) { aurS, repoS, err := pac.PackageSlices(pkgS) if err != nil { return } - q, _, err := aur.MultiInfo(aurS) + q, err := rpc.Info(aurS) if err != nil { fmt.Println(err) } for _, aurP := range q { - aurP.PrintInfo() + aur.AURPrintInfo(&aurP) } if len(repoS) != 0 { - err = PassToPacman("-Si", repoS, flags) + err = passToPacman("-Si", repoS, flags) } return } // LocalStatistics returns installed packages statistics. -func LocalStatistics(version string) error { +func localStatistics(version string) error { info, err := pac.Statistics() if err != nil { return err @@ -79,7 +120,7 @@ func LocalStatistics(version string) error { keys[i] = k i++ } - q, _, err := aur.MultiInfo(keys) + q, err := rpc.Info(keys) if err != nil { return err } diff --git a/utils.go b/utils.go index 4952a5bc..1912ed16 100644 --- a/utils.go +++ b/utils.go @@ -15,7 +15,7 @@ import ( ) // PassToPacman outsorces execution to pacman binary without modifications. -func PassToPacman(op string, pkgs []string, flags []string) error { +func passToPacman(op string, pkgs []string, flags []string) error { var cmd *exec.Cmd var args []string @@ -43,7 +43,7 @@ func PassToPacman(op string, pkgs []string, flags []string) error { } // Complete provides completion info for shells -func Complete() (err error) { +func complete() (err error) { path := os.Getenv("HOME") + "/.cache/yay/aur_" + util.Shell + ".cache" if info, err := os.Stat(path); os.IsNotExist(err) || time.Since(info.ModTime()).Hours() > 48 { diff --git a/yay.go b/yay.go index fb1a1ea1..c7c61790 100644 --- a/yay.go +++ b/yay.go @@ -68,11 +68,11 @@ func parser() (op string, options []string, packages []string, err error) { case "--complete": util.Shell = "sh" - Complete() + complete() os.Exit(0) case "--fcomplete": util.Shell = "fish" - Complete() + complete() os.Exit(0) case "--help": usage() @@ -100,16 +100,16 @@ func main() { switch op { case "-Cd": - err = CleanDependencies(pkgs) + err = cleanDependencies(pkgs) case "-G": for _, pkg := range pkgs { - err = GetPkgbuild(pkg) + err = getPkgbuild(pkg) if err != nil { fmt.Println(pkg+":", err) } } case "-Qstats": - err = LocalStatistics(version) + err = localStatistics(version) case "-Ss", "-Ssq", "-Sqs": if op == "-Ss" { util.SearchVerbosity = util.Detailed @@ -118,14 +118,14 @@ func main() { } if pkgs != nil { - err = SyncSearch(pkgs) + err = syncSearch(pkgs) } case "-S": - err = Install(pkgs, options) + err = install(pkgs, options) case "-Syu", "-Suy": - err = Upgrade(options) + err = upgrade(options) case "-Si": - err = SyncInfo(pkgs, options) + err = syncInfo(pkgs, options) case "yogurt": util.SearchVerbosity = util.NumberMenu @@ -133,7 +133,7 @@ func main() { err = numberMenu(pkgs, options) } default: - err = PassToPacman(op, pkgs, options) + err = passToPacman(op, pkgs, options) } if err != nil { @@ -146,10 +146,11 @@ func main() { func numberMenu(pkgS []string, flags []string) (err error) { var num int - aq, numaq, err := aur.Search(pkgS, true) + aq, err := aur.NarrowSearch(pkgS, true) if err != nil { fmt.Println("Error during AUR search:", err) } + numaq := len(aq) pq, numpq, err := pac.Search(pkgS) if err != nil { return @@ -160,11 +161,11 @@ func numberMenu(pkgS []string, flags []string) (err error) { } if util.SortMode == util.BottomUp { - aq.PrintSearch(numpq) + printAURSearch(aq, numpq) pq.PrintSearch() } else { pq.PrintSearch() - aq.PrintSearch(numpq) + printAURSearch(aq, numpq) } fmt.Printf("\x1b[32m%s\x1b[0m\nNumbers:", "Type numbers to install. Separate each number with a space.") @@ -208,26 +209,7 @@ func numberMenu(pkgS []string, flags []string) (err error) { } if len(aurInstall) != 0 { - q, n, err := aur.MultiInfo(aurInstall) - if err != nil { - return err - } else if n != len(aurInstall) { - q.MissingPackage(aurInstall) - } - - var finalrm []string - for _, aurpkg := range q { - finalmdeps, err := aurpkg.Install(flags) - finalrm = append(finalrm, finalmdeps...) - if err != nil { - // Do not abandon program, we might still be able to install the rest - fmt.Println(err) - } - } - - if len(finalrm) != 0 { - aur.RemoveMakeDeps(finalrm) - } + aur.Install(aurInstall, flags) } return nil