github.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package github
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "strings"
  8. alpm "github.com/jguer/go-alpm"
  9. )
  10. // branch contains the information of a repository branch
  11. type branch struct {
  12. Name string `json:"name"`
  13. Commit struct {
  14. SHA string `json:"sha"`
  15. URL string `json:"url"`
  16. } `json:"commit"`
  17. }
  18. type branches []branch
  19. // Info contains the last commit sha of a repo
  20. type Info struct {
  21. Package string `json:"pkgname"`
  22. URL string `json:"url"`
  23. SHA string `json:"sha"`
  24. }
  25. type infos []Info
  26. var savedInfo infos
  27. var configfile string
  28. // Updated returns if database has been updated
  29. var Updated bool
  30. func init() {
  31. Updated = false
  32. configfile = os.Getenv("HOME") + "/.config/yay/yay_vcs.json"
  33. if _, err := os.Stat(configfile); os.IsNotExist(err) {
  34. _ = os.MkdirAll(os.Getenv("HOME")+"/.config/yay", 0755)
  35. return
  36. }
  37. file, err := os.Open(configfile)
  38. if err != nil {
  39. fmt.Println("error:", err)
  40. return
  41. }
  42. decoder := json.NewDecoder(file)
  43. err = decoder.Decode(&savedInfo)
  44. if err != nil {
  45. fmt.Println("error:", err)
  46. }
  47. }
  48. // ParseSource returns owner and repo from source
  49. func ParseSource(source string) (owner string, repo string) {
  50. if !(strings.Contains(source, "git://") ||
  51. strings.Contains(source, ".git") ||
  52. strings.Contains(source, "git+https://")) {
  53. return
  54. }
  55. split := strings.Split(source, "github.com/")
  56. if len(split) > 1 {
  57. secondSplit := strings.Split(split[1], "/")
  58. if len(secondSplit) > 1 {
  59. owner = secondSplit[0]
  60. thirdSplit := strings.Split(secondSplit[1], ".git")
  61. if len(thirdSplit) > 0 {
  62. repo = thirdSplit[0]
  63. }
  64. }
  65. }
  66. return
  67. }
  68. func (info *Info) needsUpdate() bool {
  69. var newRepo branches
  70. r, err := http.Get(info.URL)
  71. if err != nil {
  72. fmt.Println(err)
  73. return false
  74. }
  75. defer r.Body.Close()
  76. err = json.NewDecoder(r.Body).Decode(&newRepo)
  77. if err != nil {
  78. fmt.Println(err)
  79. return false
  80. }
  81. for _, e := range newRepo {
  82. if e.Name == "master" {
  83. if e.Commit.SHA != info.SHA {
  84. return true
  85. } else {
  86. return false
  87. }
  88. }
  89. }
  90. return false
  91. }
  92. // CheckUpdates returns list of outdated packages
  93. func CheckUpdates(foreign map[string]alpm.Package) (toUpdate []string) {
  94. for _, e := range savedInfo {
  95. if e.needsUpdate() {
  96. if _, ok := foreign[e.Package]; ok {
  97. toUpdate = append(toUpdate, e.Package)
  98. } else {
  99. RemovePackage([]string{e.Package})
  100. }
  101. }
  102. }
  103. return
  104. }
  105. func inStore(pkgName string) *Info {
  106. for i, e := range savedInfo {
  107. if pkgName == e.Package {
  108. return &savedInfo[i]
  109. }
  110. }
  111. return nil
  112. }
  113. // RemovePackage removes package from VCS information
  114. func RemovePackage(pkgs []string) {
  115. for _, pkgName := range pkgs {
  116. for i, e := range savedInfo {
  117. if e.Package == pkgName {
  118. savedInfo[i] = savedInfo[len(savedInfo)-1]
  119. savedInfo = savedInfo[:len(savedInfo)-1]
  120. }
  121. }
  122. }
  123. _ = SaveBranchInfo()
  124. return
  125. }
  126. // BranchInfo updates saved information
  127. func BranchInfo(pkgName string, owner string, repo string) (err error) {
  128. Updated = true
  129. var newRepo branches
  130. url := "https://api.github.com/repos/" + owner + "/" + repo + "/branches"
  131. r, err := http.Get(url)
  132. if err != nil {
  133. return
  134. }
  135. defer r.Body.Close()
  136. _ = json.NewDecoder(r.Body).Decode(&newRepo)
  137. packinfo := inStore(pkgName)
  138. for _, e := range newRepo {
  139. if e.Name == "master" {
  140. if packinfo != nil {
  141. packinfo.Package = pkgName
  142. packinfo.URL = url
  143. packinfo.SHA = e.Commit.SHA
  144. } else {
  145. savedInfo = append(savedInfo, Info{Package: pkgName, URL: url, SHA: e.Commit.SHA})
  146. }
  147. }
  148. }
  149. return
  150. }
  151. func SaveBranchInfo() error {
  152. marshalledinfo, err := json.Marshal(savedInfo)
  153. if err != nil || string(marshalledinfo) == "null" {
  154. return err
  155. }
  156. in, err := os.OpenFile(configfile, os.O_RDWR|os.O_CREATE, 0755)
  157. if err != nil {
  158. return err
  159. }
  160. defer in.Close()
  161. _, err = in.Write(marshalledinfo)
  162. if err != nil {
  163. return err
  164. }
  165. err = in.Sync()
  166. return err
  167. }