actions.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package yay
  2. import (
  3. "bufio"
  4. "fmt"
  5. "math"
  6. "os"
  7. "os/exec"
  8. "strconv"
  9. "strings"
  10. "github.com/jguer/yay/aur"
  11. pac "github.com/jguer/yay/pacman"
  12. )
  13. // BuildDir is the root for package building
  14. const BuildDir string = "/tmp/yaytmp/"
  15. // SearchMode is search without numbers.
  16. const SearchMode int = -1
  17. // NumberMenu presents a CLI for selecting packages to install.
  18. func NumberMenu(pkgName string, flags []string) (err error) {
  19. var num int
  20. var numberString string
  21. var args []string
  22. a, n, err := aur.Search(pkgName, true)
  23. r, err := pac.SearchPackages(pkgName)
  24. if err != nil {
  25. return
  26. }
  27. if len(r.Results) == 0 && n == 0 {
  28. return fmt.Errorf("no Packages match search")
  29. }
  30. r.PrintSearch(0)
  31. a.PrintSearch(len(r.Results))
  32. args = append(args, "pacman", "-S")
  33. fmt.Printf("\x1b[32m%s\x1b[0m\nNumbers:", "Type numbers to install. Separate each number with a space.")
  34. reader := bufio.NewReader(os.Stdin)
  35. numberString, err = reader.ReadString('\n')
  36. if err != nil {
  37. fmt.Println(err)
  38. return
  39. }
  40. var aurInstall []aur.Result
  41. result := strings.Fields(numberString)
  42. for _, numS := range result {
  43. num, err = strconv.Atoi(numS)
  44. if err != nil {
  45. fmt.Println(err)
  46. continue
  47. }
  48. // Install package
  49. if num > len(r.Results)-1 {
  50. aurInstall = append(aurInstall, a[num-len(r.Results)])
  51. } else {
  52. args = append(args, r.Results[num].Name)
  53. }
  54. }
  55. args = append(args, flags...)
  56. if len(args) > 2 {
  57. var cmd *exec.Cmd
  58. cmd = exec.Command("sudo", args...)
  59. cmd.Stdout = os.Stdout
  60. cmd.Stdin = os.Stdin
  61. cmd.Stderr = os.Stderr
  62. err = cmd.Run()
  63. }
  64. for _, aurpkg := range aurInstall {
  65. err = aurpkg.Install(BuildDir, flags)
  66. if err != nil {
  67. // Do not abandon program, we might still be able to install the rest
  68. fmt.Println(err)
  69. }
  70. }
  71. return
  72. }
  73. // Install handles package installs
  74. func Install(pkgs []string, flags []string) error {
  75. var args []string
  76. args = append(args, "pacman")
  77. args = append(args, "-S")
  78. args = append(args, flags...)
  79. aurs, repos, _ := pac.PackageSlices(pkgs)
  80. args = append(args, repos...)
  81. if len(repos) != 0 {
  82. var cmd *exec.Cmd
  83. cmd = exec.Command("sudo", args...)
  84. cmd.Stdout = os.Stdout
  85. cmd.Stdin = os.Stdin
  86. cmd.Stderr = os.Stderr
  87. cmd.Run()
  88. }
  89. q, n, err := aur.MultiInfo(aurs)
  90. if len(aurs) != n {
  91. fmt.Println("Unable to get info on some packages")
  92. }
  93. for _, aurpkg := range q {
  94. err = aurpkg.Install(BuildDir, flags)
  95. if err != nil {
  96. fmt.Println("Error installing", aurpkg.Name, ":", err)
  97. }
  98. }
  99. return nil
  100. }
  101. // Upgrade handles updating the cache and installing updates.
  102. func Upgrade(flags []string) error {
  103. errp := pac.UpdatePackages(flags)
  104. erra := aur.Upgrade(BuildDir, flags)
  105. if errp != nil {
  106. return errp
  107. }
  108. return erra
  109. }
  110. // Search presents a query to the local repos and to the AUR.
  111. func Search(pkg string) (err error) {
  112. a, _, err := aur.Search(pkg, true)
  113. if err != nil {
  114. return err
  115. }
  116. pac.SearchRepos(pkg, SearchMode)
  117. a.PrintSearch(SearchMode)
  118. return nil
  119. }
  120. // LocalStatistics returns installed packages statistics.
  121. func LocalStatistics(version string) error {
  122. pkgmap, info, err := pac.Statistics()
  123. if err != nil {
  124. return err
  125. }
  126. fmt.Printf("\n Yay version r1.%s\n", version)
  127. fmt.Println("\x1B[1;34m===========================================\x1B[0m")
  128. fmt.Printf("\x1B[1;32mTotal installed packages: \x1B[0;33m%d\x1B[0m\n", info.Totaln)
  129. fmt.Printf("\x1B[1;32mExplicitly installed packages: \x1B[0;33m%d\x1B[0m\n", info.Expln)
  130. fmt.Printf("\x1B[1;32mTotal Size occupied by packages: \x1B[0;33m%s\x1B[0m\n", size(info.TotalSize))
  131. fmt.Println("\x1B[1;34m===========================================\x1B[0m")
  132. fmt.Println("\x1B[1;32mTen biggest packages\x1B[0m")
  133. for name, psize := range pkgmap {
  134. fmt.Printf("%s: \x1B[0;33m%s\x1B[0m\n", name, size(psize))
  135. }
  136. fmt.Println("\x1B[1;34m===========================================\x1B[0m")
  137. return nil
  138. }
  139. // Function by pyk https://github.com/pyk/byten
  140. func index(s int64) float64 {
  141. x := math.Log(float64(s)) / math.Log(1024)
  142. return math.Floor(x)
  143. }
  144. // Function by pyk https://github.com/pyk/byten
  145. func countSize(s int64, i float64) float64 {
  146. return float64(s) / math.Pow(1024, math.Floor(i))
  147. }
  148. // Size return a formated string from file size
  149. // Function by pyk https://github.com/pyk/byten
  150. func size(s int64) string {
  151. symbols := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}
  152. i := index(s)
  153. if s < 10 {
  154. return fmt.Sprintf("%dB", s)
  155. }
  156. size := countSize(s, i)
  157. format := "%.0f"
  158. if size < 10 {
  159. format = "%.1f"
  160. }
  161. return fmt.Sprintf(format+"%s", size, symbols[int(i)])
  162. }