main.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package main // import "github.com/Jguer/yay"
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. alpm "github.com/Jguer/go-alpm"
  10. pacmanconf "github.com/Morganamilo/go-pacmanconf"
  11. "github.com/leonelquinteros/gotext"
  12. "github.com/Jguer/yay/v9/pkg/text"
  13. )
  14. func setPaths() error {
  15. if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
  16. configHome = filepath.Join(configHome, "yay")
  17. } else if configHome = os.Getenv("HOME"); configHome != "" {
  18. configHome = filepath.Join(configHome, ".config/yay")
  19. } else {
  20. return errors.New(gotext.Get("XDG_CONFIG_HOME and HOME unset"))
  21. }
  22. if cacheHome = os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
  23. cacheHome = filepath.Join(cacheHome, "yay")
  24. } else if cacheHome = os.Getenv("HOME"); cacheHome != "" {
  25. cacheHome = filepath.Join(cacheHome, ".cache/yay")
  26. } else {
  27. return errors.New(gotext.Get("XDG_CACHE_HOME and HOME unset"))
  28. }
  29. configFile = filepath.Join(configHome, configFileName)
  30. vcsFile = filepath.Join(cacheHome, vcsFileName)
  31. return nil
  32. }
  33. func initGotext() {
  34. gotext.Configure(localePath, os.Getenv("LANG"), "yay")
  35. }
  36. func initConfig() error {
  37. cfile, err := os.Open(configFile)
  38. if !os.IsNotExist(err) && err != nil {
  39. return errors.New(gotext.Get("failed to open config file '%s': %s", configFile, err))
  40. }
  41. defer cfile.Close()
  42. if !os.IsNotExist(err) {
  43. decoder := json.NewDecoder(cfile)
  44. if err = decoder.Decode(&config); err != nil {
  45. return errors.New(gotext.Get("failed to read config file '%s': %s", configFile, err))
  46. }
  47. }
  48. aurdest := os.Getenv("AURDEST")
  49. if aurdest != "" {
  50. config.BuildDir = aurdest
  51. }
  52. return nil
  53. }
  54. func initVCS() error {
  55. vfile, err := os.Open(vcsFile)
  56. if !os.IsNotExist(err) && err != nil {
  57. return errors.New(gotext.Get("failed to open vcs file '%s': %s", vcsFile, err))
  58. }
  59. defer vfile.Close()
  60. if !os.IsNotExist(err) {
  61. decoder := json.NewDecoder(vfile)
  62. if err = decoder.Decode(&savedInfo); err != nil {
  63. return errors.New(gotext.Get("failed to read vcs file '%s': %s", vcsFile, err))
  64. }
  65. }
  66. return nil
  67. }
  68. func initHomeDirs() error {
  69. if _, err := os.Stat(configHome); os.IsNotExist(err) {
  70. if err = os.MkdirAll(configHome, 0755); err != nil {
  71. return errors.New(gotext.Get("failed to create config directory '%s': %s", configHome, err))
  72. }
  73. } else if err != nil {
  74. return err
  75. }
  76. if _, err := os.Stat(cacheHome); os.IsNotExist(err) {
  77. if err = os.MkdirAll(cacheHome, 0755); err != nil {
  78. return errors.New(gotext.Get("failed to create cache directory '%s': %s", cacheHome, err))
  79. }
  80. } else if err != nil {
  81. return err
  82. }
  83. return nil
  84. }
  85. func initBuildDir() error {
  86. if _, err := os.Stat(config.BuildDir); os.IsNotExist(err) {
  87. if err = os.MkdirAll(config.BuildDir, 0755); err != nil {
  88. return errors.New(gotext.Get("failed to create BuildDir directory '%s': %s", config.BuildDir, err))
  89. }
  90. } else if err != nil {
  91. return err
  92. }
  93. return nil
  94. }
  95. func initAlpm() error {
  96. var err error
  97. var stderr string
  98. root := "/"
  99. if value, _, exists := cmdArgs.getArg("root", "r"); exists {
  100. root = value
  101. }
  102. pacmanConf, stderr, err = pacmanconf.PacmanConf("--config", config.PacmanConf, "--root", root)
  103. if err != nil {
  104. return fmt.Errorf("%s", stderr)
  105. }
  106. if value, _, exists := cmdArgs.getArg("dbpath", "b"); exists {
  107. pacmanConf.DBPath = value
  108. }
  109. if value, _, exists := cmdArgs.getArg("arch"); exists {
  110. pacmanConf.Architecture = value
  111. }
  112. if value, _, exists := cmdArgs.getArg("ignore"); exists {
  113. pacmanConf.IgnorePkg = append(pacmanConf.IgnorePkg, strings.Split(value, ",")...)
  114. }
  115. if value, _, exists := cmdArgs.getArg("ignoregroup"); exists {
  116. pacmanConf.IgnoreGroup = append(pacmanConf.IgnoreGroup, strings.Split(value, ",")...)
  117. }
  118. // TODO
  119. // current system does not allow duplicate arguments
  120. // but pacman allows multiple cachedirs to be passed
  121. // for now only handle one cache dir
  122. if value, _, exists := cmdArgs.getArg("cachedir"); exists {
  123. pacmanConf.CacheDir = []string{value}
  124. }
  125. if value, _, exists := cmdArgs.getArg("gpgdir"); exists {
  126. pacmanConf.GPGDir = value
  127. }
  128. if err := initAlpmHandle(); err != nil {
  129. return err
  130. }
  131. switch value, _, _ := cmdArgs.getArg("color"); value {
  132. case "always":
  133. useColor = true
  134. case "auto":
  135. useColor = isTty()
  136. case "never":
  137. useColor = false
  138. default:
  139. useColor = pacmanConf.Color && isTty()
  140. }
  141. return nil
  142. }
  143. func initAlpmHandle() error {
  144. if alpmHandle != nil {
  145. if errRelease := alpmHandle.Release(); errRelease != nil {
  146. return errRelease
  147. }
  148. }
  149. var err error
  150. if alpmHandle, err = alpm.Initialize(pacmanConf.RootDir, pacmanConf.DBPath); err != nil {
  151. return errors.New(gotext.Get("unable to CreateHandle: %s", err))
  152. }
  153. if err := configureAlpm(); err != nil {
  154. return err
  155. }
  156. alpmHandle.SetQuestionCallback(questionCallback)
  157. alpmHandle.SetLogCallback(logCallback)
  158. return nil
  159. }
  160. func exitOnError(err error) {
  161. if err != nil {
  162. if str := err.Error(); str != "" {
  163. fmt.Fprintln(os.Stderr, str)
  164. }
  165. cleanup()
  166. os.Exit(1)
  167. }
  168. }
  169. func cleanup() int {
  170. if alpmHandle != nil {
  171. if err := alpmHandle.Release(); err != nil {
  172. fmt.Fprintln(os.Stderr, err)
  173. return 1
  174. }
  175. }
  176. return 0
  177. }
  178. func main() {
  179. initGotext()
  180. if os.Geteuid() == 0 {
  181. text.Warnln(gotext.Get("Avoid running yay as root/sudo."))
  182. }
  183. exitOnError(setPaths())
  184. config = defaultSettings()
  185. exitOnError(initHomeDirs())
  186. exitOnError(initConfig())
  187. exitOnError(cmdArgs.parseCommandLine())
  188. if shouldSaveConfig {
  189. err := config.saveConfig()
  190. if err != nil {
  191. fmt.Fprintln(os.Stderr, err)
  192. }
  193. }
  194. config.expandEnv()
  195. exitOnError(initBuildDir())
  196. exitOnError(initVCS())
  197. exitOnError(initAlpm())
  198. exitOnError(handleCmd())
  199. os.Exit(cleanup())
  200. }