1
0
mirror of https://github.com/Jguer/yay.git synced 2025-08-21 14:41:17 +02:00

Refactoring code

This commit is contained in:
Jguer 2016-11-30 17:55:56 +00:00
parent c7757668c3
commit 721b7c9ebb
2 changed files with 202 additions and 111 deletions

View File

@ -2,22 +2,19 @@ package aur
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io"
"net/http"
"os" "os"
"os/exec" "os/exec"
"sort" "sort"
"strings" "strings"
"github.com/jguer/go-alpm" alpm "github.com/demizer/go-alpm"
"github.com/jguer/yay/pacman"
) )
var version = "undefined" var version = "undefined"
// TarBin describes the default installation point of tar command // TarBin describes the default installation point of tar command.
// Probably will replace untar with code solution.
const TarBin string = "/usr/bin/tar" const TarBin string = "/usr/bin/tar"
// BaseURL givers the AUR default address. // BaseURL givers the AUR default address.
@ -40,10 +37,10 @@ type Result struct {
URL string `json:"URL"` URL string `json:"URL"`
NumVotes int `json:"NumVotes"` NumVotes int `json:"NumVotes"`
Popularity float32 `json:"Popularity"` Popularity float32 `json:"Popularity"`
OutOfDate interface{} `json:"OutOfDate"` OutOfDate int `json:"OutOfDate"`
Maintainer string `json:"Maintainer"` Maintainer string `json:"Maintainer"`
FirstSubmitted int `json:"FirstSubmitted"` FirstSubmitted int `json:"FirstSubmitted"`
LastModified int `json:"LastModified"` LastModified int64 `json:"LastModified"`
URLPath string `json:"URLPath"` URLPath string `json:"URLPath"`
Depends []string `json:"Depends"` Depends []string `json:"Depends"`
MakeDepends []string `json:"MakeDepends"` MakeDepends []string `json:"MakeDepends"`
@ -54,38 +51,24 @@ type Result struct {
Installed bool Installed bool
} }
// Query describes an AUR json Query // Query is a collection of Results
type Query struct { type Query []Result
Resultcount int `json:"resultcount"`
Results []Result `json:"results"` func (q Query) Len() int {
Type string `json:"type"` return len(q)
Version int `json:"version"`
} }
// Editor gives the default system editor, uses vi in last case func (q Query) Less(i, j int) bool {
var Editor = "vi" return q[i].NumVotes < q[j].NumVotes
func init() {
if os.Getenv("EDITOR") != "" {
Editor = os.Getenv("EDITOR")
}
} }
func (r Query) Len() int { func (q Query) Swap(i, j int) {
return len(r.Results) q[i], q[j] = q[j], q[i]
}
func (r Query) Less(i, j int) bool {
return r.Results[i].NumVotes > r.Results[j].NumVotes
}
func (r Query) Swap(i, j int) {
r.Results[i], r.Results[j] = r.Results[j], r.Results[i]
} }
// PrintSearch handles printing search results in a given format // PrintSearch handles printing search results in a given format
func (r *Query) PrintSearch(start int) { func (q Query) PrintSearch(start int) {
for i, res := range r.Results { for i, res := range q {
switch { switch {
case start != SearchMode && res.Installed == true: case start != SearchMode && res.Installed == true:
fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) \x1b[32;40mInstalled\x1b[0m\n%s\n", fmt.Printf("%d \x1b[1m%s/\x1b[33m%s \x1b[36m%s \x1b[0m(%d) \x1b[32;40mInstalled\x1b[0m\n%s\n",
@ -103,75 +86,129 @@ func (r *Query) PrintSearch(start int) {
} }
} }
func downloadFile(filepath string, url string) (err error) {
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Writer the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
// getJSON handles JSON retrieval and decoding to struct
func getJSON(url string, target interface{}) error {
r, err := http.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
// Search returns an AUR search // Search returns an AUR search
func Search(pkg string, sortS bool) (r Query, err error) { func Search(pkg string, sortS bool) (Query, int, error) {
err = getJSON("https://aur.archlinux.org/rpc/?v=5&type=search&arg="+pkg, &r) type returned struct {
Results Query `json:"results"`
ResultCount int `json:"resultcount"`
}
r := returned{}
err := getJSON("https://aur.archlinux.org/rpc/?v=5&type=search&arg="+pkg, &r)
if sortS { if sortS {
sort.Sort(r) sort.Sort(r.Results)
} }
for i, res := range r.Results { // for _, res := range r.Results {
r.Results[i].Installed, err = IspkgInstalled(res.Name) // res.Installed, err = IspkgInstalled(res.Name)
} // }
return return r.Results, r.ResultCount, err
} }
// Info returns an AUR search with package details // Info returns an AUR search with package details
func Info(pkg string) (r Query, err error) { func Info(pkg string) (Query, int, error) {
err = getJSON("https://aur.archlinux.org/rpc/?v=5&type=info&arg[]="+pkg, &r) type returned struct {
return Results Query `json:"results"`
ResultCount int `json:"resultcount"`
}
r := returned{}
err := getJSON("https://aur.archlinux.org/rpc/?v=5&type=info&arg[]="+pkg, &r)
return r.Results, r.ResultCount, err
} }
// Install sends system commands to make and install a package from pkgName // Install sends system commands to make and install a package from pkgName
func Install(pkg string, baseDir string, conf *alpm.PacmanConfig, flags []string) (err error) { func Install(pkg string, baseDir string, conf *alpm.PacmanConfig, flags []string) (err error) {
info, err := Info(pkg) q, n, err := Info(pkg)
if err != nil { if err != nil {
return return
} }
if info.Resultcount == 0 { if n == 0 {
return fmt.Errorf("Package %s does not exist", pkg) return fmt.Errorf("Package %s does not exist", pkg)
} }
info.Results[0].Install(baseDir, conf, flags) q[0].Install(baseDir, conf, flags)
return err return err
} }
// Upgrade tries to update every foreign package installed in the system
func Upgrade(baseDir string, conf *alpm.PacmanConfig, flags []string) error {
fmt.Println("\x1b[1;36;1m::\x1b[0m\x1b[1m Starting AUR upgrade...\x1b[0m")
foreign, err := pacman.ForeignPackages()
if err != nil {
return err
}
// Find outdated packages
type Outdated struct {
res *Result
pkgVersion string
er error
}
r := make(chan *Outdated) // Allocate a channel.
for name, info := range foreign {
// fmt.Println("Checking number", i, pkg.Name())
go func(name string, date int64, version string) {
q, n, err := Info(name)
if err != nil {
r <- nil
return
}
if n == 0 {
r <- nil
return
}
// Leaving this here for now, warn about downgrades later
if int64(q[0].LastModified) > date {
r <- &Outdated{&q[0], version, err}
} else {
r <- nil
}
}(name, info.Date, info.Version)
}
var outdated []*Result
var checkedPkg *Outdated
for i := 0; i < len(foreign); i++ {
// fmt.Println("Wait Cycle", i)
checkedPkg = <-r
// fmt.Println(checkedPkg)
if checkedPkg != nil {
fmt.Printf("\x1b[1m\x1b[32m==>\x1b[33;1m %s: \x1b[0m%s \x1b[33;1m-> \x1b[0m%s\n",
checkedPkg.res.Name, checkedPkg.pkgVersion, checkedPkg.res.Version)
outdated = append(outdated, checkedPkg.res)
}
}
//If there are no outdated packages, don't prompt
if len(outdated) == 0 {
fmt.Println(" there is nothing to do")
return nil
}
// Install updated packages
if NoConfirm(flags) == false {
fmt.Println("\x1b[1m\x1b[32m==> Proceed with upgrade\x1b[0m\x1b[1m (Y/n)\x1b[0m")
var response string
fmt.Scanln(&response)
if strings.ContainsAny(response, "n & N") {
return nil
}
}
for _, pkg := range outdated {
pkg.Install(baseDir, conf, flags)
}
return nil
}
// UpdatePackages handles AUR updates // UpdatePackages handles AUR updates
func UpdatePackages(baseDir string, conf *alpm.PacmanConfig, flags []string) error { func UpdatePackages(baseDir string, conf *alpm.PacmanConfig, flags []string) error {
@ -222,20 +259,20 @@ func UpdatePackages(baseDir string, conf *alpm.PacmanConfig, flags []string) err
for _, pkg := range foreign { for _, pkg := range foreign {
// fmt.Println("Checking number", i, pkg.Name()) // fmt.Println("Checking number", i, pkg.Name())
go func(pkg alpm.Package) { go func(pkg alpm.Package) {
info, err := Info(pkg.Name()) q, n, err := Info(pkg.Name())
if err != nil { if err != nil {
r <- nil r <- nil
return return
} }
if info.Resultcount == 0 { if n == 0 {
r <- nil r <- nil
return return
} }
// Leaving this here for now, warn about downgrades later // Leaving this here for now, warn about downgrades later
if int64(info.Results[0].LastModified) > pkg.InstallDate().Unix() { if int64(q[0].LastModified) > pkg.InstallDate().Unix() {
r <- &Outdated{&info.Results[0], pkg.Version(), err} r <- &Outdated{&q[0], pkg.Version(), err}
} else { } else {
r <- nil r <- nil
} }
@ -326,13 +363,13 @@ func (a *Result) Install(baseDir string, conf *alpm.PacmanConfig, flags []string
} }
for _, dep := range depS { for _, dep := range depS {
q, errD := Info(dep) q, n, errD := Info(dep)
if errD != nil { if errD != nil {
return errD return errD
} }
if len(q.Results) != 0 { if n != 0 {
q.Results[0].Install(baseDir, conf, []string{"--asdeps"}) q[0].Install(baseDir, conf, []string{"--asdeps"})
} }
} }
@ -371,16 +408,16 @@ func (a *Result) Dependencies(conf *alpm.PacmanConfig) (final []string, err erro
f := func(c rune) bool { f := func(c rune) bool {
return c == '>' || c == '<' || c == '=' || c == ' ' return c == '>' || c == '<' || c == '=' || c == ' '
} }
info, err := Info(a.Name) q, n, err := Info(a.Name)
if err != nil { if err != nil {
return return
} }
if len(info.Results) == 0 { if n == 0 {
return final, fmt.Errorf("Failed to get deps from RPC") return final, fmt.Errorf("Failed to get deps from RPC")
} }
deps := append(info.Results[0].MakeDepends, info.Results[0].Depends...) deps := append(q[0].MakeDepends, q[0].Depends...)
for _, dep := range deps { for _, dep := range deps {
fields := strings.FieldsFunc(dep, f) fields := strings.FieldsFunc(dep, f)
// If package is installed let it go. // If package is installed let it go.
@ -402,12 +439,12 @@ func (a *Result) Dependencies(conf *alpm.PacmanConfig) (final []string, err erro
continue continue
} }
depinfo, err := Search(fields[0], true) _, nd, err := Info(fields[0])
if err != nil { if err != nil {
return final, err return final, err
} }
if len(depinfo.Results) == 0 { if nd == 0 {
return final, fmt.Errorf("Unable to find dependency in repos and AUR.") return final, fmt.Errorf("Unable to find dependency in repos and AUR.")
} }

54
aur/utils.go Normal file
View File

@ -0,0 +1,54 @@
package aur
import (
"encoding/json"
"io"
"net/http"
"os"
)
// Editor gives the default system editor, uses vi in last case
var Editor = "vi"
func init() {
if os.Getenv("EDITOR") != "" {
Editor = os.Getenv("EDITOR")
}
}
// getJSON handles JSON retrieval and decoding to struct
func getJSON(url string, target interface{}) error {
r, err := http.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
func downloadFile(filepath string, url string) (err error) {
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Writer the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}