diff --git a/actions.go b/actions.go index e751f70f..db06c743 100644 --- a/actions.go +++ b/actions.go @@ -110,7 +110,7 @@ func NumberMenu(pkgName string, flags []string) (err error) { if err != nil { return err } else if n != len(aurInstall) { - aur.MissingPackage(aurInstall, q) + q.MissingPackage(aurInstall) } for _, aurpkg := range q { diff --git a/aur/aur.go b/aur/aur.go index e68027b4..50681712 100644 --- a/aur/aur.go +++ b/aur/aur.go @@ -2,180 +2,10 @@ package aur import ( "fmt" - "os" - "os/exec" - "sort" - "strings" "github.com/jguer/yay/pacman" ) -// TarBin describes the default installation point of tar command. -const TarBin string = "/usr/bin/tar" - -// BaseURL givers the AUR default address. -const BaseURL string = "https://aur.archlinux.org" - -// MakepkgBin describes the default installation point of makepkg command. -const MakepkgBin string = "/usr/bin/makepkg" - -// SearchMode is search without numbers. -const SearchMode int = -1 - -// NoConfirm ignores prompts. -var NoConfirm = false - -// SortMode determines top down package or down top package display -var SortMode = DownTop - -// BaseDir is the default building directory for yay -var BaseDir = "/tmp/yaytmp/" - -// Describes Sorting method for numberdisplay -const ( - DownTop = iota - TopDown -) - -// Result describes an AUR package. -type Result struct { - ID int `json:"ID"` - Name string `json:"Name"` - PackageBaseID int `json:"PackageBaseID"` - PackageBase string `json:"PackageBase"` - Version string `json:"Version"` - Description string `json:"Description"` - URL string `json:"URL"` - NumVotes int `json:"NumVotes"` - Popularity float32 `json:"Popularity"` - OutOfDate int `json:"OutOfDate"` - Maintainer string `json:"Maintainer"` - FirstSubmitted int `json:"FirstSubmitted"` - LastModified int64 `json:"LastModified"` - URLPath string `json:"URLPath"` - Installed bool - Depends []string `json:"Depends"` - MakeDepends []string `json:"MakeDepends"` - OptDepends []string `json:"OptDepends"` - Conflicts []string `json:"Conflicts"` - Provides []string `json:"Provides"` - License []string `json:"License"` - Keywords []string `json:"Keywords"` -} - -// Query is a collection of Results -type Query []Result - -func (q Query) Len() int { - return len(q) -} - -func (q Query) Less(i, j int) bool { - if SortMode == DownTop { - return q[i].NumVotes < q[j].NumVotes - } - return q[i].NumVotes > q[j].NumVotes -} - -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 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.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) - } -} - -// Search returns an AUR search -func Search(pkg string, sortS bool) (Query, int, error) { - 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 { - sort.Sort(r.Results) - } - setter := pacman.PFactory(pFSetTrue) - - 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 { - 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 -} - -// MultiInfo takes a slice of strings and returns a slice with the info of each package -func MultiInfo(pkgS []string) (Query, int, error) { - type returned struct { - Results Query `json:"results"` - ResultCount int `json:"resultcount"` - } - 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 -} - // 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) @@ -231,7 +61,7 @@ func Upgrade(flags []string) error { } // Install updated packages - if !continueTask("Proceed with upgrade?", "n & N") { + if !continueTask("Proceed with upgrade?", "nN") { return nil } @@ -241,256 +71,3 @@ func Upgrade(flags []string) error { return nil } - -func (a *Result) setupWorkspace() (err error) { - // No need to use filepath.separators because it won't run on inferior platforms - err = os.MkdirAll(BaseDir+"builds", 0755) - if err != nil { - fmt.Println(err) - return - } - - tarLocation := BaseDir + a.PackageBase + ".tar.gz" - defer os.Remove(BaseDir + a.PackageBase + ".tar.gz") - - err = downloadFile(tarLocation, BaseURL+a.URLPath) - if err != nil { - return - } - - err = exec.Command(TarBin, "-xf", tarLocation, "-C", BaseDir).Run() - if err != nil { - return - } - - return -} - -// Install handles install from Info Result -func (a *Result) Install(flags []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") - } - dir := BaseDir + a.PackageBase + "/" - - if _, err = os.Stat(dir); os.IsNotExist(err) { - if err = a.setupWorkspace(); err != nil { - return - } - } - - // defer os.RemoveAll(BaseDir + a.PackageBase) - - if !continueTask("Edit PKGBUILD?", "y & Y") { - editcmd := exec.Command(Editor, dir+"PKGBUILD") - editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr - editcmd.Run() - } - - runDeps, makeDeps, err := a.Dependencies() - if err != nil { - return - } - - repoDeps := append(runDeps[0], makeDeps[0]...) - aurDeps := append(runDeps[1], makeDeps[1]...) - - if len(aurDeps) != 0 || len(repoDeps) != 0 { - if !continueTask("Continue?", "n & N") { - return fmt.Errorf("user did not like the dependencies") - } - } - - aurQ, n, err := MultiInfo(aurDeps) - if n != len(aurDeps) { - MissingPackage(aurDeps, aurQ) - if !continueTask("Continue?", "n & N") { - return fmt.Errorf("unable to install dependencies") - } - } - - // Handle AUR dependencies first - for _, dep := range aurQ { - errA := dep.Install([]string{"--asdeps", "--noconfirm"}) - if errA != nil { - return errA - } - } - - // Repo dependencies - if len(repoDeps) != 0 { - errR := pacman.Install(repoDeps, []string{"--asdeps", "--noconfirm"}) - if errR != nil { - pacman.CleanRemove(aurDeps) - return errR - } - } - - err = os.Chdir(dir) - if err != nil { - return - } - - var makepkgcmd *exec.Cmd - var args []string - args = append(args, "-sri") - args = append(args, flags...) - makepkgcmd = exec.Command(MakepkgBin, args...) - makepkgcmd.Stdin, makepkgcmd.Stdout, makepkgcmd.Stderr = os.Stdin, os.Stdout, os.Stderr - err = makepkgcmd.Run() - return -} - -func continueTask(s string, def string) (cont bool) { - if NoConfirm { - return true - } - var postFix string - - if def == "n & N" { - postFix = "(Y/n)" - } else { - postFix = "(y/N)" - } - - var response string - fmt.Printf("\x1b[1;32m==> %s\x1b[1;37m %s\x1b[0m\n", s, postFix) - - fmt.Scanln(&response) - if strings.ContainsAny(response, def) { - return false - } - - return true -} - -// MissingPackage warns if the Query was unable to find a package -func MissingPackage(aurDeps []string, aurQ Query) { - for _, depName := range aurDeps { - found := false - for _, dep := range aurQ { - if dep.Name == depName { - found = true - break - } - } - - if !found { - fmt.Println("\x1b[31mUnable to find", depName, "in AUR\x1b[0m") - } - } - return -} - -// PrintInfo prints package info like pacman -Si -func (a *Result) PrintInfo() { - 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) - fmt.Println("\x1b[1;37mDescription :\x1b[0m", a.Description) - if a.URL != "" { - fmt.Println("\x1b[1;37mURL :\x1b[0m", a.URL) - } else { - fmt.Println("\x1b[1;37mURL :\x1b[0m", "None") - } - 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.Depends) != 0 { - fmt.Println("\x1b[1;37mDepends On :\x1b[0m", a.Depends) - } else { - fmt.Println("\x1b[1;37mDepends On :\x1b[0m", "None") - } - - if len(a.MakeDepends) != 0 { - fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", a.MakeDepends) - } else { - fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", "None") - } - - if len(a.OptDepends) != 0 { - fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", a.OptDepends) - } else { - fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", "None") - } - - if len(a.Conflicts) != 0 { - fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", a.Conflicts) - } else { - fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", "None") - } - - if a.Maintainer != "" { - fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", a.Maintainer) - } else { - fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", "None") - } - fmt.Println("\x1b[1;37mVotes :\x1b[0m", a.NumVotes) - fmt.Println("\x1b[1;37mPopularity :\x1b[0m", a.Popularity) - - if a.OutOfDate != 0 { - fmt.Println("\x1b[1;37mOut-of-date :\x1b[0m", "Yes") - } - -} - -// 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) { - 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 { - err = fmt.Errorf("Unable to search dependencies, %s", err) - return - } - } else { - q = append(q, *a) - } - - depSearch := pacman.BuildDependencies(a.Depends) - if len(a.Depends) != 0 { - runDeps[0], runDeps[1] = depSearch(q[0].Depends, true, false) - if len(runDeps[0]) != 0 || len(runDeps[1]) != 0 { - fmt.Println("\x1b[1;32m=>\x1b[1;33m Run Dependencies: \x1b[0m") - printDeps(runDeps[0], runDeps[1]) - } - } - - if len(a.MakeDepends) != 0 { - makeDeps[0], makeDeps[1] = depSearch(q[0].MakeDepends, false, false) - if len(makeDeps[0]) != 0 || len(makeDeps[1]) != 0 { - fmt.Println("\x1b[1;32m=>\x1b[1;33m Make Dependencies: \x1b[0m") - printDeps(makeDeps[0], makeDeps[1]) - } - } - depSearch(a.MakeDepends, false, true) - - err = nil - return -} - -func printDeps(repoDeps []string, aurDeps []string) { - if len(repoDeps) != 0 { - fmt.Print("\x1b[1;32m==> Repository dependencies: \x1b[0m") - for _, repoD := range repoDeps { - fmt.Print("\x1b[33m", repoD, " \x1b[0m") - } - fmt.Print("\n") - - } - if len(aurDeps) != 0 { - fmt.Print("\x1b[1;32m==> AUR dependencies: \x1b[0m") - for _, aurD := range aurDeps { - fmt.Print("\x1b[33m", aurD, " \x1b[0m") - } - fmt.Print("\n") - } -} diff --git a/aur/query.go b/aur/query.go new file mode 100644 index 00000000..8eb7f2a0 --- /dev/null +++ b/aur/query.go @@ -0,0 +1,139 @@ +package aur + +import ( + "fmt" + "sort" + + "github.com/jguer/yay/pacman" +) + +// Query is a collection of Results +type Query []Result + +func (q Query) Len() int { + return len(q) +} + +func (q Query) Less(i, j int) bool { + if SortMode == DownTop { + return q[i].NumVotes < q[j].NumVotes + } + return q[i].NumVotes > q[j].NumVotes +} + +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 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.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) + } +} + +// Info returns an AUR search with package details +func Info(pkg string) (Query, int, error) { + type returned struct { + 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 +} + +// MultiInfo takes a slice of strings and returns a slice with the info of each package +func MultiInfo(pkgS []string) (Query, int, error) { + type returned struct { + Results Query `json:"results"` + ResultCount int `json:"resultcount"` + } + 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(pkg string, sortS bool) (Query, int, error) { + 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 { + sort.Sort(r.Results) + } + setter := pacman.PFactory(pFSetTrue) + + 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 +} + +// MissingPackage warns if the Query was unable to find a package +func (q Query) MissingPackage(pkgS []string) { + for _, depName := range pkgS { + found := false + for _, dep := range q { + if dep.Name == depName { + found = true + break + } + } + + if !found { + fmt.Println("\x1b[31mUnable to find", depName, "in AUR\x1b[0m") + } + } + return +} diff --git a/aur/result.go b/aur/result.go new file mode 100644 index 00000000..ed154b67 --- /dev/null +++ b/aur/result.go @@ -0,0 +1,247 @@ +package aur + +import ( + "fmt" + "os" + "os/exec" + + "github.com/jguer/yay/pacman" +) + +// Result describes an AUR package. +type Result struct { + ID int `json:"ID"` + Name string `json:"Name"` + PackageBaseID int `json:"PackageBaseID"` + PackageBase string `json:"PackageBase"` + Version string `json:"Version"` + Description string `json:"Description"` + URL string `json:"URL"` + NumVotes int `json:"NumVotes"` + Popularity float32 `json:"Popularity"` + OutOfDate int `json:"OutOfDate"` + Maintainer string `json:"Maintainer"` + FirstSubmitted int `json:"FirstSubmitted"` + LastModified int64 `json:"LastModified"` + URLPath string `json:"URLPath"` + Installed bool + Depends []string `json:"Depends"` + MakeDepends []string `json:"MakeDepends"` + OptDepends []string `json:"OptDepends"` + Conflicts []string `json:"Conflicts"` + Provides []string `json:"Provides"` + License []string `json:"License"` + Keywords []string `json:"Keywords"` +} + +// 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) { + 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 { + err = fmt.Errorf("Unable to search dependencies, %s", err) + return + } + } else { + q = append(q, *a) + } + + depSearch := pacman.BuildDependencies(a.Depends) + if len(a.Depends) != 0 { + runDeps[0], runDeps[1] = depSearch(q[0].Depends, true, false) + if len(runDeps[0]) != 0 || len(runDeps[1]) != 0 { + fmt.Println("\x1b[1;32m=>\x1b[1;33m Run Dependencies: \x1b[0m") + printDeps(runDeps[0], runDeps[1]) + } + } + + if len(a.MakeDepends) != 0 { + makeDeps[0], makeDeps[1] = depSearch(q[0].MakeDepends, false, false) + if len(makeDeps[0]) != 0 || len(makeDeps[1]) != 0 { + fmt.Println("\x1b[1;32m=>\x1b[1;33m Make Dependencies: \x1b[0m") + printDeps(makeDeps[0], makeDeps[1]) + } + } + depSearch(a.MakeDepends, false, true) + + err = nil + return +} + +func printDeps(repoDeps []string, aurDeps []string) { + if len(repoDeps) != 0 { + fmt.Print("\x1b[1;32m==> Repository dependencies: \x1b[0m") + for _, repoD := range repoDeps { + fmt.Print("\x1b[33m", repoD, " \x1b[0m") + } + fmt.Print("\n") + + } + if len(aurDeps) != 0 { + fmt.Print("\x1b[1;32m==> AUR dependencies: \x1b[0m") + for _, aurD := range aurDeps { + fmt.Print("\x1b[33m", aurD, " \x1b[0m") + } + fmt.Print("\n") + } +} + +// Install handles install from Info Result +func (a *Result) Install(flags []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") + } + dir := BaseDir + a.PackageBase + "/" + + if _, err = os.Stat(dir); os.IsNotExist(err) { + if err = a.setupWorkspace(); err != nil { + return + } + } + + // defer os.RemoveAll(BaseDir + a.PackageBase) + + if !continueTask("Edit PKGBUILD?", "yY") { + editcmd := exec.Command(Editor, dir+"PKGBUILD") + editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr + editcmd.Run() + } + + runDeps, makeDeps, err := a.Dependencies() + if err != nil { + return + } + + repoDeps := append(runDeps[0], makeDeps[0]...) + aurDeps := append(runDeps[1], makeDeps[1]...) + + if len(aurDeps) != 0 || len(repoDeps) != 0 { + if !continueTask("Continue?", "nN") { + return fmt.Errorf("user did not like the dependencies") + } + } + + aurQ, n, err := MultiInfo(aurDeps) + if n != len(aurDeps) { + aurQ.MissingPackage(aurDeps) + if !continueTask("Continue?", "nN") { + return fmt.Errorf("unable to install dependencies") + } + } + + // Handle AUR dependencies first + for _, dep := range aurQ { + errA := dep.Install([]string{"--asdeps", "--noconfirm"}) + if errA != nil { + return errA + } + } + + // Repo dependencies + if len(repoDeps) != 0 { + errR := pacman.Install(repoDeps, []string{"--asdeps", "--noconfirm"}) + if errR != nil { + pacman.CleanRemove(aurDeps) + return errR + } + } + + err = os.Chdir(dir) + if err != nil { + return + } + + var makepkgcmd *exec.Cmd + var args []string + args = append(args, "-sri") + args = append(args, flags...) + makepkgcmd = exec.Command(MakepkgBin, args...) + makepkgcmd.Stdin, makepkgcmd.Stdout, makepkgcmd.Stderr = os.Stdin, os.Stdout, os.Stderr + err = makepkgcmd.Run() + return +} + +// PrintInfo prints package info like pacman -Si +func (a *Result) PrintInfo() { + 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) + fmt.Println("\x1b[1;37mDescription :\x1b[0m", a.Description) + if a.URL != "" { + fmt.Println("\x1b[1;37mURL :\x1b[0m", a.URL) + } else { + fmt.Println("\x1b[1;37mURL :\x1b[0m", "None") + } + 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.Depends) != 0 { + fmt.Println("\x1b[1;37mDepends On :\x1b[0m", a.Depends) + } else { + fmt.Println("\x1b[1;37mDepends On :\x1b[0m", "None") + } + + if len(a.MakeDepends) != 0 { + fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", a.MakeDepends) + } else { + fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", "None") + } + + if len(a.OptDepends) != 0 { + fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", a.OptDepends) + } else { + fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", "None") + } + + if len(a.Conflicts) != 0 { + fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", a.Conflicts) + } else { + fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", "None") + } + + if a.Maintainer != "" { + fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", a.Maintainer) + } else { + fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", "None") + } + fmt.Println("\x1b[1;37mVotes :\x1b[0m", a.NumVotes) + fmt.Println("\x1b[1;37mPopularity :\x1b[0m", a.Popularity) + + if a.OutOfDate != 0 { + fmt.Println("\x1b[1;37mOut-of-date :\x1b[0m", "Yes") + } + +} + +func (a *Result) setupWorkspace() (err error) { + // No need to use filepath.separators because it won't run on inferior platforms + err = os.MkdirAll(BaseDir+"builds", 0755) + if err != nil { + fmt.Println(err) + return + } + + tarLocation := BaseDir + a.PackageBase + ".tar.gz" + defer os.Remove(BaseDir + a.PackageBase + ".tar.gz") + + err = downloadFile(tarLocation, BaseURL+a.URLPath) + if err != nil { + return + } + + err = exec.Command(TarBin, "-xf", tarLocation, "-C", BaseDir).Run() + if err != nil { + return + } + + return +} diff --git a/aur/utils.go b/aur/utils.go index 55d3845a..ab2e33fa 100644 --- a/aur/utils.go +++ b/aur/utils.go @@ -2,6 +2,7 @@ package aur import ( "encoding/json" + "fmt" "io" "net/http" "os" @@ -10,6 +11,33 @@ import ( // Editor gives the default system editor, uses vi in last case var Editor = "vi" +// TarBin describes the default installation point of tar command. +const TarBin string = "/usr/bin/tar" + +// BaseURL givers the AUR default address. +const BaseURL string = "https://aur.archlinux.org" + +// MakepkgBin describes the default installation point of makepkg command. +const MakepkgBin string = "/usr/bin/makepkg" + +// SearchMode is search without numbers. +const SearchMode int = -1 + +// NoConfirm ignores prompts. +var NoConfirm = false + +// SortMode determines top down package or down top package display +var SortMode = DownTop + +// BaseDir is the default building directory for yay +var BaseDir = "/tmp/yaytmp/" + +// Describes Sorting method for numberdisplay +const ( + DownTop = iota + TopDown +) + func init() { if os.Getenv("EDITOR") != "" { Editor = os.Getenv("EDITOR") @@ -46,3 +74,26 @@ func downloadFile(filepath string, url string) (err error) { _, err = io.Copy(out, resp.Body) return err } + +func continueTask(s string, def string) (cont bool) { + if NoConfirm { + return true + } + var postFix string + + if def == "nN" { + postFix = "(Y/n)" + } else { + postFix = "(y/N)" + } + + var response string + fmt.Printf("\x1b[1;32m==> %s\x1b[1;37m %s\x1b[0m\n", s, postFix) + + fmt.Scanln(&response) + if response == string(def[0]) || response == string(def[1]) { + return false + } + + return true +}