yay.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "github.com/jguer/yay/aur"
  9. vcs "github.com/jguer/yay/aur/vcs"
  10. "github.com/jguer/yay/config"
  11. pac "github.com/jguer/yay/pacman"
  12. )
  13. func usage() {
  14. fmt.Println(`usage: yay <operation> [...]
  15. operations:
  16. yay {-h --help}
  17. yay {-V --version}
  18. yay {-D --database} <options> <package(s)>
  19. yay {-F --files} [options] [package(s)]
  20. yay {-Q --query} [options] [package(s)]
  21. yay {-R --remove} [options] <package(s)>
  22. yay {-S --sync} [options] [package(s)]
  23. yay {-T --deptest} [options] [package(s)]
  24. yay {-U --upgrade} [options] <file(s)>
  25. New operations:
  26. yay -Qstats displays system information
  27. yay -Cd remove unneeded dependencies
  28. yay -G [package(s)] get pkgbuild from ABS or AUR
  29. New options:
  30. --topdown shows repository's packages first and then aur's
  31. --bottomup shows aur's packages first and then repository's
  32. --noconfirm skip user input on package install
  33. --devel Check -git/-svn/-hg development version
  34. --nodevel Disable development version checking
  35. `)
  36. }
  37. var version = "2.116"
  38. func parser() (op string, options []string, packages []string, changedConfig bool, err error) {
  39. if len(os.Args) < 2 {
  40. err = fmt.Errorf("no operation specified")
  41. return
  42. }
  43. changedConfig = false
  44. op = "yogurt"
  45. for _, arg := range os.Args[1:] {
  46. if arg[0] == '-' && arg[1] != '-' {
  47. switch arg {
  48. default:
  49. op = arg
  50. }
  51. continue
  52. }
  53. if arg[0] == '-' && arg[1] == '-' {
  54. changedConfig = true
  55. switch arg {
  56. case "--printconfig":
  57. fmt.Printf("%+v", config.YayConf)
  58. os.Exit(0)
  59. case "--gendb":
  60. err = aur.CreateDevelDB()
  61. if err != nil {
  62. fmt.Println(err)
  63. }
  64. err = vcs.SaveBranchInfo()
  65. if err != nil {
  66. fmt.Println(err)
  67. }
  68. os.Exit(0)
  69. case "--devel":
  70. config.YayConf.Devel = true
  71. case "--nodevel":
  72. config.YayConf.Devel = false
  73. case "--timeupdate":
  74. config.YayConf.TimeUpdate = true
  75. case "--notimeupdate":
  76. config.YayConf.TimeUpdate = false
  77. case "--topdown":
  78. config.YayConf.SortMode = config.TopDown
  79. case "--complete":
  80. config.YayConf.Shell = "sh"
  81. _ = complete()
  82. os.Exit(0)
  83. case "--fcomplete":
  84. config.YayConf.Shell = "fish"
  85. _ = complete()
  86. os.Exit(0)
  87. case "--help":
  88. usage()
  89. os.Exit(0)
  90. case "--noconfirm":
  91. config.YayConf.NoConfirm = true
  92. fallthrough
  93. default:
  94. options = append(options, arg)
  95. }
  96. continue
  97. }
  98. packages = append(packages, arg)
  99. }
  100. return
  101. }
  102. func main() {
  103. op, options, pkgs, changedConfig, err := parser()
  104. if err != nil {
  105. fmt.Println(err)
  106. os.Exit(1)
  107. }
  108. switch op {
  109. case "-Cd":
  110. err = cleanDependencies(pkgs)
  111. case "-G":
  112. for _, pkg := range pkgs {
  113. err = getPkgbuild(pkg)
  114. if err != nil {
  115. fmt.Println(pkg+":", err)
  116. }
  117. }
  118. case "-Qstats":
  119. err = localStatistics(version)
  120. case "-Ss", "-Ssq", "-Sqs":
  121. if op == "-Ss" {
  122. config.YayConf.SearchMode = config.Detailed
  123. } else {
  124. config.YayConf.SearchMode = config.Minimal
  125. }
  126. if pkgs != nil {
  127. err = syncSearch(pkgs)
  128. }
  129. case "-S":
  130. err = install(pkgs, options)
  131. case "-Syu", "-Suy":
  132. err = upgrade(options)
  133. case "-Si":
  134. err = syncInfo(pkgs, options)
  135. case "yogurt":
  136. config.YayConf.SearchMode = config.NumberMenu
  137. if pkgs != nil {
  138. err = numberMenu(pkgs, options)
  139. }
  140. default:
  141. if op[0] == 'R' {
  142. vcs.RemovePackage(pkgs)
  143. }
  144. err = config.PassToPacman(op, pkgs, options)
  145. }
  146. var erra error
  147. if vcs.Updated {
  148. erra = vcs.SaveBranchInfo()
  149. if erra != nil {
  150. fmt.Println(err)
  151. }
  152. }
  153. if changedConfig {
  154. erra = config.SaveConfig()
  155. if erra != nil {
  156. fmt.Println(err)
  157. }
  158. }
  159. erra = config.AlpmHandle.Release()
  160. if erra != nil {
  161. fmt.Println(err)
  162. }
  163. if err != nil {
  164. fmt.Println(err)
  165. os.Exit(1)
  166. }
  167. }
  168. // NumberMenu presents a CLI for selecting packages to install.
  169. func numberMenu(pkgS []string, flags []string) (err error) {
  170. var num int
  171. aq, err := aur.NarrowSearch(pkgS, true)
  172. if err != nil {
  173. fmt.Println("Error during AUR search:", err)
  174. }
  175. numaq := len(aq)
  176. pq, numpq, err := pac.Search(pkgS)
  177. if err != nil {
  178. return
  179. }
  180. if numpq == 0 && numaq == 0 {
  181. return fmt.Errorf("no packages match search")
  182. }
  183. if config.YayConf.SortMode == config.BottomUp {
  184. printAURSearch(aq, numpq)
  185. pq.PrintSearch()
  186. } else {
  187. pq.PrintSearch()
  188. printAURSearch(aq, numpq)
  189. }
  190. fmt.Printf("\x1b[32m%s\x1b[0m\nNumbers: ", "Type numbers to install. Separate each number with a space.")
  191. reader := bufio.NewReader(os.Stdin)
  192. numberBuf, overflow, err := reader.ReadLine()
  193. if err != nil || overflow {
  194. fmt.Println(err)
  195. return
  196. }
  197. numberString := string(numberBuf)
  198. var aurInstall []string
  199. var repoInstall []string
  200. result := strings.Fields(numberString)
  201. for _, numS := range result {
  202. num, err = strconv.Atoi(numS)
  203. if err != nil {
  204. continue
  205. }
  206. // Install package
  207. if num > numaq+numpq-1 || num < 0 {
  208. continue
  209. } else if num > numpq-1 {
  210. if config.YayConf.SortMode == config.BottomUp {
  211. aurInstall = append(aurInstall, aq[numaq+numpq-num-1].Name)
  212. } else {
  213. aurInstall = append(aurInstall, aq[num-numpq].Name)
  214. }
  215. } else {
  216. if config.YayConf.SortMode == config.BottomUp {
  217. repoInstall = append(repoInstall, pq[numpq-num-1].Name())
  218. } else {
  219. repoInstall = append(repoInstall, pq[num].Name())
  220. }
  221. }
  222. }
  223. if len(repoInstall) != 0 {
  224. err = config.PassToPacman("-S", repoInstall, flags)
  225. }
  226. if len(aurInstall) != 0 {
  227. err = aur.Install(aurInstall, flags)
  228. }
  229. return err
  230. }