result.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package aur
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "github.com/jguer/yay/pacman"
  7. "github.com/jguer/yay/util"
  8. )
  9. // Result describes an AUR package.
  10. type Result struct {
  11. Conflicts []string `json:"Conflicts"`
  12. Depends []string `json:"Depends"`
  13. Description string `json:"Description"`
  14. FirstSubmitted int `json:"FirstSubmitted"`
  15. ID int `json:"ID"`
  16. Keywords []string `json:"Keywords"`
  17. LastModified int64 `json:"LastModified"`
  18. License []string `json:"License"`
  19. Maintainer string `json:"Maintainer"`
  20. MakeDepends []string `json:"MakeDepends"`
  21. Name string `json:"Name"`
  22. NumVotes int `json:"NumVotes"`
  23. OptDepends []string `json:"OptDepends"`
  24. OutOfDate int `json:"OutOfDate"`
  25. PackageBase string `json:"PackageBase"`
  26. PackageBaseID int `json:"PackageBaseID"`
  27. Provides []string `json:"Provides"`
  28. URL string `json:"URL"`
  29. URLPath string `json:"URLPath"`
  30. Version string `json:"Version"`
  31. Installed bool
  32. Popularity float32 `json:"Popularity"`
  33. }
  34. // Dependencies returns package dependencies not installed belonging to AUR
  35. // 0 is Repo, 1 is Foreign.
  36. func (a *Result) Dependencies() (runDeps [2][]string, makeDeps [2][]string, err error) {
  37. var q Query
  38. if len(a.Depends) == 0 && len(a.MakeDepends) == 0 {
  39. var n int
  40. q, n, err = Info(a.Name)
  41. if n == 0 || err != nil {
  42. err = fmt.Errorf("Unable to search dependencies, %s", err)
  43. return
  44. }
  45. } else {
  46. q = append(q, *a)
  47. }
  48. depSearch := pacman.BuildDependencies(a.Depends)
  49. if len(a.Depends) != 0 {
  50. runDeps[0], runDeps[1] = depSearch(q[0].Depends, true, false)
  51. if len(runDeps[0]) != 0 || len(runDeps[1]) != 0 {
  52. fmt.Println("\x1b[1;32m=>\x1b[1;33m Run Dependencies: \x1b[0m")
  53. printDeps(runDeps[0], runDeps[1])
  54. }
  55. }
  56. if len(a.MakeDepends) != 0 {
  57. makeDeps[0], makeDeps[1] = depSearch(q[0].MakeDepends, false, false)
  58. if len(makeDeps[0]) != 0 || len(makeDeps[1]) != 0 {
  59. fmt.Println("\x1b[1;32m=>\x1b[1;33m Make Dependencies: \x1b[0m")
  60. printDeps(makeDeps[0], makeDeps[1])
  61. }
  62. }
  63. depSearch(a.MakeDepends, false, true)
  64. err = nil
  65. return
  66. }
  67. func printDeps(repoDeps []string, aurDeps []string) {
  68. if len(repoDeps) != 0 {
  69. fmt.Print("\x1b[1;32m==> Repository dependencies: \x1b[0m")
  70. for _, repoD := range repoDeps {
  71. fmt.Print("\x1b[33m", repoD, " \x1b[0m")
  72. }
  73. fmt.Print("\n")
  74. }
  75. if len(aurDeps) != 0 {
  76. fmt.Print("\x1b[1;32m==> AUR dependencies: \x1b[0m")
  77. for _, aurD := range aurDeps {
  78. fmt.Print("\x1b[33m", aurD, " \x1b[0m")
  79. }
  80. fmt.Print("\n")
  81. }
  82. }
  83. // Install handles install from Info Result.
  84. func (a *Result) Install(flags []string) (finalmdeps []string, err error) {
  85. fmt.Printf("\x1b[1;32m==> Installing\x1b[33m %s\x1b[0m\n", a.Name)
  86. if a.Maintainer == "" {
  87. fmt.Println("\x1b[1;31;40m==> Warning:\x1b[0;;40m This package is orphaned.\x1b[0m")
  88. }
  89. dir := util.BaseDir + a.PackageBase + "/"
  90. if _, err = os.Stat(dir); os.IsNotExist(err) {
  91. if err = util.DownloadAndUnpack(BaseURL+a.URLPath, util.BaseDir, false); err != nil {
  92. return
  93. }
  94. } else {
  95. if !util.ContinueTask("Directory exists. Clean Build?", "yY") {
  96. os.RemoveAll(util.BaseDir + a.PackageBase)
  97. if err = util.DownloadAndUnpack(BaseURL+a.URLPath, util.BaseDir, false); err != nil {
  98. return
  99. }
  100. }
  101. }
  102. if !util.ContinueTask("Edit PKGBUILD?", "yY") {
  103. editcmd := exec.Command(util.Editor(), dir+"PKGBUILD")
  104. editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
  105. editcmd.Run()
  106. }
  107. runDeps, makeDeps, err := a.Dependencies()
  108. if err != nil {
  109. return
  110. }
  111. repoDeps := append(runDeps[0], makeDeps[0]...)
  112. aurDeps := append(runDeps[1], makeDeps[1]...)
  113. finalmdeps = append(finalmdeps, makeDeps[0]...)
  114. finalmdeps = append(finalmdeps, makeDeps[1]...)
  115. if len(aurDeps) != 0 || len(repoDeps) != 0 {
  116. if !util.ContinueTask("Continue?", "nN") {
  117. return finalmdeps, fmt.Errorf("user did not like the dependencies")
  118. }
  119. }
  120. aurQ, n, _ := MultiInfo(aurDeps)
  121. if n != len(aurDeps) {
  122. aurQ.MissingPackage(aurDeps)
  123. if !util.ContinueTask("Continue?", "nN") {
  124. return finalmdeps, fmt.Errorf("unable to install dependencies")
  125. }
  126. }
  127. var depArgs []string
  128. if util.NoConfirm {
  129. depArgs = []string{"--asdeps", "--noconfirm"}
  130. } else {
  131. depArgs = []string{"--asdeps"}
  132. }
  133. // Repo dependencies
  134. if len(repoDeps) != 0 {
  135. errR := pacman.Install(repoDeps, depArgs)
  136. if errR != nil {
  137. return finalmdeps, errR
  138. }
  139. }
  140. // Handle AUR dependencies
  141. for _, dep := range aurQ {
  142. finalmdepsR, errA := dep.Install(depArgs)
  143. finalmdeps = append(finalmdeps, finalmdepsR...)
  144. if errA != nil {
  145. pacman.CleanRemove(repoDeps)
  146. pacman.CleanRemove(aurDeps)
  147. return finalmdeps, errA
  148. }
  149. }
  150. err = os.Chdir(dir)
  151. if err != nil {
  152. return
  153. }
  154. args := []string{"-sri"}
  155. args = append(args, flags...)
  156. makepkgcmd := exec.Command(util.MakepkgBin, args...)
  157. makepkgcmd.Stdin, makepkgcmd.Stdout, makepkgcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
  158. err = makepkgcmd.Run()
  159. return
  160. }
  161. // PrintInfo prints package info like pacman -Si.
  162. func (a *Result) PrintInfo() {
  163. fmt.Println("\x1b[1;37mRepository :\x1b[0m", "aur")
  164. fmt.Println("\x1b[1;37mName :\x1b[0m", a.Name)
  165. fmt.Println("\x1b[1;37mVersion :\x1b[0m", a.Version)
  166. fmt.Println("\x1b[1;37mDescription :\x1b[0m", a.Description)
  167. if a.URL != "" {
  168. fmt.Println("\x1b[1;37mURL :\x1b[0m", a.URL)
  169. } else {
  170. fmt.Println("\x1b[1;37mURL :\x1b[0m", "None")
  171. }
  172. fmt.Println("\x1b[1;37mLicenses :\x1b[0m", a.License)
  173. if len(a.Provides) != 0 {
  174. fmt.Println("\x1b[1;37mProvides :\x1b[0m", a.Provides)
  175. } else {
  176. fmt.Println("\x1b[1;37mProvides :\x1b[0m", "None")
  177. }
  178. if len(a.Depends) != 0 {
  179. fmt.Println("\x1b[1;37mDepends On :\x1b[0m", a.Depends)
  180. } else {
  181. fmt.Println("\x1b[1;37mDepends On :\x1b[0m", "None")
  182. }
  183. if len(a.MakeDepends) != 0 {
  184. fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", a.MakeDepends)
  185. } else {
  186. fmt.Println("\x1b[1;37mMake depends On :\x1b[0m", "None")
  187. }
  188. if len(a.OptDepends) != 0 {
  189. fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", a.OptDepends)
  190. } else {
  191. fmt.Println("\x1b[1;37mOptional Deps :\x1b[0m", "None")
  192. }
  193. if len(a.Conflicts) != 0 {
  194. fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", a.Conflicts)
  195. } else {
  196. fmt.Println("\x1b[1;37mConflicts With :\x1b[0m", "None")
  197. }
  198. if a.Maintainer != "" {
  199. fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", a.Maintainer)
  200. } else {
  201. fmt.Println("\x1b[1;37mMaintainer :\x1b[0m", "None")
  202. }
  203. fmt.Println("\x1b[1;37mVotes :\x1b[0m", a.NumVotes)
  204. fmt.Println("\x1b[1;37mPopularity :\x1b[0m", a.Popularity)
  205. if a.OutOfDate != 0 {
  206. fmt.Println("\x1b[1;37mOut-of-date :\x1b[0m", "Yes")
  207. }
  208. }
  209. // RemoveMakeDeps receives a make dependency list and removes those
  210. // that are no longer necessary.
  211. func RemoveMakeDeps(depS []string) (err error) {
  212. hanging := pacman.SliceHangingPackages(depS)
  213. if len(hanging) != 0 {
  214. if !util.ContinueTask("Confirm Removal?", "nN") {
  215. return nil
  216. }
  217. err = pacman.CleanRemove(hanging)
  218. }
  219. return
  220. }