types.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. package query
  2. import (
  3. "fmt"
  4. "io"
  5. "strconv"
  6. "github.com/Jguer/aur"
  7. "github.com/Jguer/go-alpm/v2"
  8. "github.com/leonelquinteros/gotext"
  9. "github.com/Jguer/yay/v11/pkg/db"
  10. "github.com/Jguer/yay/v11/pkg/settings"
  11. "github.com/Jguer/yay/v11/pkg/text"
  12. )
  13. type (
  14. aurQuery []aur.Pkg // Query is a collection of Results.
  15. repoQuery []alpm.IPackage // Query holds the results of a repository search.
  16. )
  17. type aurSortable struct {
  18. aurQuery
  19. sortBy string
  20. sortMode int
  21. }
  22. func (r repoQuery) Reverse() {
  23. for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
  24. r[i], r[j] = r[j], r[i]
  25. }
  26. }
  27. func (r repoQuery) Less(i, j int) bool {
  28. return text.LessRunes([]rune(r[i].Name()), []rune(r[j].Name()))
  29. }
  30. func (q aurSortable) Len() int {
  31. return len(q.aurQuery)
  32. }
  33. func (q aurSortable) Less(i, j int) bool {
  34. var result bool
  35. switch q.sortBy {
  36. case "votes":
  37. result = q.aurQuery[i].NumVotes > q.aurQuery[j].NumVotes
  38. case "popularity":
  39. result = q.aurQuery[i].Popularity > q.aurQuery[j].Popularity
  40. case "name":
  41. result = text.LessRunes([]rune(q.aurQuery[i].Name), []rune(q.aurQuery[j].Name))
  42. case "base":
  43. result = text.LessRunes([]rune(q.aurQuery[i].PackageBase), []rune(q.aurQuery[j].PackageBase))
  44. case "submitted":
  45. result = q.aurQuery[i].FirstSubmitted < q.aurQuery[j].FirstSubmitted
  46. case "modified":
  47. result = q.aurQuery[i].LastModified < q.aurQuery[j].LastModified
  48. case "id":
  49. result = q.aurQuery[i].ID < q.aurQuery[j].ID
  50. case "baseid":
  51. result = q.aurQuery[i].PackageBaseID < q.aurQuery[j].PackageBaseID
  52. }
  53. if q.sortMode == settings.BottomUp {
  54. return !result
  55. }
  56. return result
  57. }
  58. func (q aurSortable) Swap(i, j int) {
  59. q.aurQuery[i], q.aurQuery[j] = q.aurQuery[j], q.aurQuery[i]
  60. }
  61. func getSearchBy(value string) aur.By {
  62. switch value {
  63. case "name":
  64. return aur.Name
  65. case "maintainer":
  66. return aur.Maintainer
  67. case "depends":
  68. return aur.Depends
  69. case "makedepends":
  70. return aur.MakeDepends
  71. case "optdepends":
  72. return aur.OptDepends
  73. case "checkdepends":
  74. return aur.CheckDepends
  75. default:
  76. return aur.NameDesc
  77. }
  78. }
  79. // PrintSearch handles printing search results in a given format.
  80. func (q aurQuery) printSearch(
  81. w io.Writer,
  82. start int,
  83. dbExecutor db.Executor,
  84. searchMode SearchVerbosity,
  85. sortMode int,
  86. singleLineResults bool,
  87. ) {
  88. for i := range q {
  89. var toprint string
  90. if searchMode == NumberMenu {
  91. switch sortMode {
  92. case settings.TopDown:
  93. toprint += text.Magenta(strconv.Itoa(start+i) + " ")
  94. case settings.BottomUp:
  95. toprint += text.Magenta(strconv.Itoa(len(q)+start-i-1) + " ")
  96. default:
  97. text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
  98. }
  99. } else if searchMode == Minimal {
  100. _, _ = fmt.Fprintln(w, q[i].Name)
  101. continue
  102. }
  103. toprint += text.Bold(text.ColorHash("aur")) + "/" + text.Bold(q[i].Name) +
  104. " " + text.Cyan(q[i].Version) +
  105. text.Bold(" (+"+strconv.Itoa(q[i].NumVotes)) +
  106. " " + text.Bold(strconv.FormatFloat(q[i].Popularity, 'f', 2, 64)+") ")
  107. if q[i].Maintainer == "" {
  108. toprint += text.Bold(text.Red(gotext.Get("(Orphaned)"))) + " "
  109. }
  110. if q[i].OutOfDate != 0 {
  111. toprint += text.Bold(text.Red(gotext.Get("(Out-of-date: %s)", text.FormatTime(q[i].OutOfDate)))) + " "
  112. }
  113. if pkg := dbExecutor.LocalPackage(q[i].Name); pkg != nil {
  114. if pkg.Version() != q[i].Version {
  115. toprint += text.Bold(text.Green(gotext.Get("(Installed: %s)", pkg.Version())))
  116. } else {
  117. toprint += text.Bold(text.Green(gotext.Get("(Installed)")))
  118. }
  119. }
  120. if singleLineResults {
  121. toprint += "\t"
  122. } else {
  123. toprint += "\n "
  124. }
  125. toprint += q[i].Description
  126. _, _ = fmt.Fprintln(w, toprint)
  127. }
  128. }
  129. // PrintSearch receives a RepoSearch type and outputs pretty text.
  130. func (r repoQuery) printSearch(w io.Writer, dbExecutor db.Executor, searchMode SearchVerbosity, sortMode int, singleLineResults bool) {
  131. for i, res := range r {
  132. var toprint string
  133. if searchMode == NumberMenu {
  134. switch sortMode {
  135. case settings.TopDown:
  136. toprint += text.Magenta(strconv.Itoa(i+1) + " ")
  137. case settings.BottomUp:
  138. toprint += text.Magenta(strconv.Itoa(len(r)-i) + " ")
  139. default:
  140. text.Warnln(gotext.Get("invalid sort mode. Fix with yay -Y --bottomup --save"))
  141. }
  142. } else if searchMode == Minimal {
  143. _, _ = fmt.Fprintln(w, res.Name())
  144. continue
  145. }
  146. toprint += text.Bold(text.ColorHash(res.DB().Name())) + "/" + text.Bold(res.Name()) +
  147. " " + text.Cyan(res.Version()) +
  148. text.Bold(" ("+text.Human(res.Size())+
  149. " "+text.Human(res.ISize())+") ")
  150. packageGroups := dbExecutor.PackageGroups(res)
  151. if len(packageGroups) != 0 {
  152. toprint += fmt.Sprint(packageGroups, " ")
  153. }
  154. if pkg := dbExecutor.LocalPackage(res.Name()); pkg != nil {
  155. if pkg.Version() != res.Version() {
  156. toprint += text.Bold(text.Green(gotext.Get("(Installed: %s)", pkg.Version())))
  157. } else {
  158. toprint += text.Bold(text.Green(gotext.Get("(Installed)")))
  159. }
  160. }
  161. if singleLineResults {
  162. toprint += "\t"
  163. } else {
  164. toprint += "\n "
  165. }
  166. toprint += res.Description()
  167. _, _ = fmt.Fprintln(w, toprint)
  168. }
  169. }