main.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "strings"
  9. "net/url"
  10. alpm "github.com/jguer/go-alpm"
  11. rpc "github.com/mikkeloscar/aur"
  12. )
  13. func setPaths() error {
  14. if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
  15. configHome = filepath.Join(configHome, "yay")
  16. } else if configHome = os.Getenv("HOME"); configHome != "" {
  17. configHome = filepath.Join(configHome, ".config/yay")
  18. } else {
  19. return fmt.Errorf("XDG_CONFIG_HOME and HOME unset")
  20. }
  21. if cacheHome = os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
  22. cacheHome = filepath.Join(cacheHome, "yay")
  23. } else if cacheHome = os.Getenv("HOME"); cacheHome != "" {
  24. cacheHome = filepath.Join(cacheHome, ".cache/yay")
  25. } else {
  26. return fmt.Errorf("XDG_CACHE_HOME and HOME unset")
  27. }
  28. configFile = filepath.Join(configHome, configFileName)
  29. vcsFile = filepath.Join(cacheHome, vcsFileName)
  30. return nil
  31. }
  32. func initConfig() error {
  33. cfile, err := os.Open(configFile)
  34. if !os.IsNotExist(err) && err != nil {
  35. return fmt.Errorf("Failed to open config file '%s': %s", configFile, err)
  36. }
  37. defer cfile.Close()
  38. if !os.IsNotExist(err) {
  39. decoder := json.NewDecoder(cfile)
  40. if err = decoder.Decode(&config); err != nil {
  41. return fmt.Errorf("Failed to read config '%s': %s", configFile, err)
  42. }
  43. }
  44. url, err := url.Parse(config.AURURL)
  45. if err != nil {
  46. return err
  47. }
  48. url.Path = path.Join(url.Path, "")
  49. rpc.AURURL = url.String() + "/rpc.php?"
  50. return nil
  51. }
  52. func initVCS() error {
  53. vfile, err := os.Open(vcsFile)
  54. if !os.IsNotExist(err) && err != nil {
  55. return fmt.Errorf("Failed to open vcs file '%s': %s", vcsFile, err)
  56. }
  57. defer vfile.Close()
  58. if !os.IsNotExist(err) {
  59. decoder := json.NewDecoder(vfile)
  60. if err = decoder.Decode(&savedInfo); err != nil {
  61. return fmt.Errorf("Failed to read vcs '%s': %s", vcsFile, err)
  62. }
  63. }
  64. return nil
  65. }
  66. func initHomeDirs() error {
  67. if _, err := os.Stat(configHome); os.IsNotExist(err) {
  68. if err = os.MkdirAll(configHome, 0755); err != nil {
  69. return fmt.Errorf("Failed to create config directory '%s': %s", configHome, err)
  70. }
  71. } else if err != nil {
  72. return err
  73. }
  74. if _, err := os.Stat(cacheHome); os.IsNotExist(err) {
  75. if err = os.MkdirAll(cacheHome, 0755); err != nil {
  76. return fmt.Errorf("Failed to create cache directory '%s': %s", cacheHome, err)
  77. }
  78. } else if err != nil {
  79. return err
  80. }
  81. return nil
  82. }
  83. func initBuildDir() error {
  84. if _, err := os.Stat(config.BuildDir); os.IsNotExist(err) {
  85. if err = os.MkdirAll(config.BuildDir, 0755); err != nil {
  86. return fmt.Errorf("Failed to create BuildDir directory '%s': %s", config.BuildDir, err)
  87. }
  88. } else if err != nil {
  89. return err
  90. }
  91. return nil
  92. }
  93. func initAlpm() error {
  94. var err error
  95. if alpmConf, err = readAlpmConfig(config.PacmanConf); err != nil {
  96. return fmt.Errorf("Unable to read Pacman conf: %s", err)
  97. }
  98. if value, _, exists := cmdArgs.getArg("dbpath", "b"); exists {
  99. alpmConf.DBPath = value
  100. }
  101. if value, _, exists := cmdArgs.getArg("root", "r"); exists {
  102. alpmConf.RootDir = value
  103. }
  104. if value, _, exists := cmdArgs.getArg("arch"); exists {
  105. alpmConf.Architecture = value
  106. }
  107. if value, _, exists := cmdArgs.getArg("ignore"); exists {
  108. alpmConf.IgnorePkg = append(alpmConf.IgnorePkg, strings.Split(value, ",")...)
  109. }
  110. if value, _, exists := cmdArgs.getArg("ignoregroup"); exists {
  111. alpmConf.IgnoreGroup = append(alpmConf.IgnoreGroup, strings.Split(value, ",")...)
  112. }
  113. //TODO
  114. //current system does not allow duplicate arguments
  115. //but pacman allows multiple cachdirs to be passed
  116. //for now only handle one cache dir
  117. if value, _, exists := cmdArgs.getArg("cachdir"); exists {
  118. alpmConf.CacheDir = []string{value}
  119. }
  120. if value, _, exists := cmdArgs.getArg("gpgdir"); exists {
  121. alpmConf.GPGDir = value
  122. }
  123. if err = initAlpmHandle(); err != nil {
  124. return err
  125. }
  126. if value, _, _ := cmdArgs.getArg("color"); value == "always" || value == "auto" {
  127. useColor = true
  128. } else if value == "never" {
  129. useColor = false
  130. } else {
  131. useColor = alpmConf.Options&alpm.ConfColor > 0
  132. }
  133. return nil
  134. }
  135. func initAlpmHandle() error {
  136. var err error
  137. if alpmHandle != nil {
  138. if err := alpmHandle.Release(); err != nil {
  139. return err
  140. }
  141. }
  142. if alpmHandle, err = alpmConf.CreateHandle(); err != nil {
  143. return fmt.Errorf("Unable to CreateHandle: %s", err)
  144. }
  145. alpmHandle.SetQuestionCallback(questionCallback)
  146. alpmHandle.SetLogCallback(logCallback)
  147. return nil
  148. }
  149. func exitOnError(err error) {
  150. if err != nil {
  151. if str := err.Error(); str != "" {
  152. fmt.Println(str)
  153. }
  154. cleanup()
  155. os.Exit(1)
  156. }
  157. }
  158. func cleanup() int {
  159. if alpmHandle != nil {
  160. if err := alpmHandle.Release(); err != nil {
  161. fmt.Println(err)
  162. return 1
  163. }
  164. }
  165. return 0
  166. }
  167. func main() {
  168. if 0 == os.Geteuid() {
  169. fmt.Println("Please avoid running yay as root/sudo.")
  170. }
  171. exitOnError(setPaths())
  172. defaultSettings(&config)
  173. exitOnError(initHomeDirs())
  174. exitOnError(initConfig())
  175. exitOnError(cmdArgs.parseCommandLine())
  176. exitOnError(initBuildDir())
  177. exitOnError(initVCS())
  178. exitOnError(initAlpm())
  179. exitOnError(handleCmd())
  180. os.Exit(cleanup())
  181. }