upgrade.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package upgrade
  2. import (
  3. "fmt"
  4. "strings"
  5. "unicode"
  6. "github.com/Jguer/yay/v12/pkg/db"
  7. "github.com/Jguer/yay/v12/pkg/intrange"
  8. "github.com/Jguer/yay/v12/pkg/text"
  9. )
  10. // Filter decides if specific package should be included in theincluded in the results.
  11. type Filter func(*Upgrade) bool
  12. // Upgrade type describes a system upgrade.
  13. type Upgrade = db.Upgrade
  14. func StylizedNameWithRepository(u *Upgrade) string {
  15. return text.Bold(text.ColorHash(u.Repository)) + "/" + text.Bold(u.Name)
  16. }
  17. // upSlice is a slice of Upgrades.
  18. type UpSlice struct {
  19. Up []Upgrade
  20. Repos []string
  21. }
  22. func (u UpSlice) Len() int { return len(u.Up) }
  23. func (u UpSlice) Swap(i, j int) { u.Up[i], u.Up[j] = u.Up[j], u.Up[i] }
  24. func (u UpSlice) Less(i, j int) bool {
  25. if u.Up[i].Repository == u.Up[j].Repository {
  26. iRunes := []rune(u.Up[i].Name)
  27. jRunes := []rune(u.Up[j].Name)
  28. return text.LessRunes(iRunes, jRunes)
  29. }
  30. for _, db := range u.Repos {
  31. if db == u.Up[i].Repository {
  32. return true
  33. } else if db == u.Up[j].Repository {
  34. return false
  35. }
  36. }
  37. iRunes := []rune(u.Up[i].Repository)
  38. jRunes := []rune(u.Up[j].Repository)
  39. return text.LessRunes(iRunes, jRunes)
  40. }
  41. func GetVersionDiff(oldVersion, newVersion string) (left, right string) {
  42. if oldVersion == newVersion {
  43. return oldVersion + text.Red(""), newVersion + text.Green("")
  44. }
  45. diffPosition := 0
  46. checkWords := func(str string, index int, words ...string) bool {
  47. for _, word := range words {
  48. wordLength := len(word)
  49. nextIndex := index + 1
  50. if (index < len(str)-wordLength) &&
  51. (str[nextIndex:(nextIndex+wordLength)] == word) {
  52. return true
  53. }
  54. }
  55. return false
  56. }
  57. for index, char := range oldVersion {
  58. charIsSpecial := !(unicode.IsLetter(char) || unicode.IsNumber(char))
  59. if (index >= len(newVersion)) || (char != rune(newVersion[index])) {
  60. if charIsSpecial {
  61. diffPosition = index
  62. }
  63. break
  64. }
  65. if charIsSpecial ||
  66. (((index == len(oldVersion)-1) || (index == len(newVersion)-1)) &&
  67. ((len(oldVersion) != len(newVersion)) ||
  68. (oldVersion[index] == newVersion[index]))) ||
  69. checkWords(oldVersion, index, "rc", "pre", "alpha", "beta") {
  70. diffPosition = index + 1
  71. }
  72. }
  73. samePart := oldVersion[0:diffPosition]
  74. left = samePart + text.Red(oldVersion[diffPosition:])
  75. right = samePart + text.Green(newVersion[diffPosition:])
  76. return left, right
  77. }
  78. // Print prints the details of the packages to upgrade.
  79. func (u UpSlice) Print(logger *text.Logger) {
  80. longestName, longestVersion := 0, 0
  81. for k := range u.Up {
  82. upgrade := &u.Up[k]
  83. packNameLen := len(StylizedNameWithRepository(upgrade))
  84. packVersion, _ := GetVersionDiff(upgrade.LocalVersion, upgrade.RemoteVersion)
  85. packVersionLen := len(packVersion)
  86. longestName = intrange.Max(packNameLen, longestName)
  87. longestVersion = intrange.Max(packVersionLen, longestVersion)
  88. }
  89. lenUp := len(u.Up)
  90. longestNumber := len(fmt.Sprintf("%v", lenUp))
  91. namePadding := fmt.Sprintf("%%-%ds ", longestName)
  92. versionPadding := fmt.Sprintf("%%-%ds", longestVersion)
  93. numberPadding := fmt.Sprintf("%%%dd ", longestNumber)
  94. for k := range u.Up {
  95. upgrade := &u.Up[k]
  96. left, right := GetVersionDiff(upgrade.LocalVersion, upgrade.RemoteVersion)
  97. logger.Printf(text.Magenta(fmt.Sprintf(numberPadding, lenUp-k)))
  98. logger.Printf(namePadding, StylizedNameWithRepository(upgrade))
  99. logger.Printf("%s -> %s\n", fmt.Sprintf(versionPadding, left), right)
  100. if upgrade.Extra != "" {
  101. logger.Println(strings.Repeat(" ", longestNumber), upgrade.Extra)
  102. }
  103. }
  104. }