main.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. alpm "github.com/jguer/go-alpm"
  9. )
  10. func setPaths() error {
  11. if _configHome, set := os.LookupEnv("XDG_CONFIG_HOME"); set {
  12. if _configHome == "" {
  13. return fmt.Errorf("XDG_CONFIG_HOME set but empty")
  14. }
  15. configHome = filepath.Join(_configHome, "yay")
  16. } else if _configHome, set := os.LookupEnv("HOME"); set {
  17. if _configHome == "" {
  18. return fmt.Errorf("HOME set but empty")
  19. }
  20. configHome = filepath.Join(_configHome, ".config/yay")
  21. } else {
  22. return fmt.Errorf("XDG_CONFIG_HOME and HOME unset")
  23. }
  24. if _cacheHome, set := os.LookupEnv("XDG_CACHE_HOME"); set {
  25. if _cacheHome == "" {
  26. return fmt.Errorf("XDG_CACHE_HOME set but empty")
  27. }
  28. cacheHome = filepath.Join(_cacheHome, "yay")
  29. } else if _cacheHome, set := os.LookupEnv("HOME"); set {
  30. if _cacheHome == "" {
  31. return fmt.Errorf("XDG_CACHE_HOME set but empty")
  32. }
  33. cacheHome = filepath.Join(_cacheHome, ".cache/yay")
  34. } else {
  35. return fmt.Errorf("XDG_CACHE_HOME and HOME unset")
  36. }
  37. configFile = filepath.Join(configHome, configFileName)
  38. vcsFile = filepath.Join(cacheHome, vcsFileName)
  39. return nil
  40. }
  41. func initConfig() error {
  42. defaultSettings(&config)
  43. if _, err := os.Stat(configFile); os.IsNotExist(err) {
  44. err = os.MkdirAll(filepath.Dir(configFile), 0755)
  45. if err != nil {
  46. err = fmt.Errorf("Unable to create config directory:\n%s\n"+
  47. "The error was:\n%s", filepath.Dir(configFile), err)
  48. return err
  49. }
  50. // Save the default config if nothing is found
  51. config.saveConfig()
  52. return err
  53. }
  54. cfile, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE, 0644)
  55. if err != nil {
  56. fmt.Printf("Error reading config: %s\n", err)
  57. return err
  58. }
  59. defer cfile.Close()
  60. decoder := json.NewDecoder(cfile)
  61. if err := decoder.Decode(&config); err != nil {
  62. fmt.Println("Loading default Settings.\nError reading config:", err)
  63. defaultSettings(&config)
  64. return err
  65. }
  66. if _, err := os.Stat(config.BuildDir); os.IsNotExist(err) {
  67. if err = os.MkdirAll(config.BuildDir, 0755); err != nil {
  68. return fmt.Errorf("Unable to create BuildDir directory:\n%s\n"+
  69. "The error was:\n%s", config.BuildDir, err)
  70. }
  71. }
  72. return nil
  73. }
  74. func initVCS() (err error) {
  75. if _, err = os.Stat(vcsFile); os.IsNotExist(err) {
  76. err = os.MkdirAll(filepath.Dir(vcsFile), 0755)
  77. if err != nil {
  78. err = fmt.Errorf("Unable to create vcs directory:\n%s\n"+
  79. "The error was:\n%s", filepath.Dir(configFile), err)
  80. return
  81. }
  82. return
  83. }
  84. vfile, err := os.OpenFile(vcsFile, os.O_RDONLY|os.O_CREATE, 0644)
  85. if err == nil {
  86. defer vfile.Close()
  87. decoder := json.NewDecoder(vfile)
  88. _ = decoder.Decode(&savedInfo)
  89. }
  90. return err
  91. }
  92. func initAlpm() (err error) {
  93. var value string
  94. var exists bool
  95. alpmConf, err = readAlpmConfig(config.PacmanConf)
  96. if err != nil {
  97. err = fmt.Errorf("Unable to read Pacman conf: %s", err)
  98. return
  99. }
  100. value, _, exists = cmdArgs.getArg("dbpath", "b")
  101. if exists {
  102. alpmConf.DBPath = value
  103. }
  104. value, _, exists = cmdArgs.getArg("root", "r")
  105. if exists {
  106. alpmConf.RootDir = value
  107. }
  108. value, _, exists = cmdArgs.getArg("arch")
  109. if exists {
  110. alpmConf.Architecture = value
  111. }
  112. value, _, exists = cmdArgs.getArg("ignore")
  113. if exists {
  114. alpmConf.IgnorePkg = append(alpmConf.IgnorePkg, strings.Split(value, ",")...)
  115. }
  116. value, _, exists = cmdArgs.getArg("ignoregroup")
  117. if exists {
  118. alpmConf.IgnoreGroup = append(alpmConf.IgnoreGroup, strings.Split(value, ",")...)
  119. }
  120. //TODO
  121. //current system does not allow duplicate arguments
  122. //but pacman allows multiple cachdirs to be passed
  123. //for now only handle one cache dir
  124. value, _, exists = cmdArgs.getArg("cachdir")
  125. if exists {
  126. alpmConf.CacheDir = []string{value}
  127. }
  128. value, _, exists = cmdArgs.getArg("gpgdir")
  129. if exists {
  130. alpmConf.GPGDir = value
  131. }
  132. err = initAlpmHandle()
  133. if err != nil {
  134. return
  135. }
  136. value, _, _ = cmdArgs.getArg("color")
  137. if value == "always" || value == "auto" {
  138. useColor = true
  139. } else if value == "never" {
  140. useColor = false
  141. } else {
  142. useColor = alpmConf.Options&alpm.ConfColor > 0
  143. }
  144. return
  145. }
  146. func initAlpmHandle() error {
  147. if alpmHandle != nil {
  148. if err := alpmHandle.Release(); err != nil {
  149. return err
  150. }
  151. }
  152. var err error
  153. if alpmHandle, err = alpmConf.CreateHandle(); err != nil {
  154. return fmt.Errorf("Unable to CreateHandle: %s", err)
  155. }
  156. alpmHandle.SetQuestionCallback(questionCallback)
  157. return nil
  158. }
  159. func cleanup() {
  160. if alpmHandle != nil {
  161. temp := alpmHandle
  162. // set alpmHandle to nil to avoid entering this
  163. // branch of code again, at cleanup time.
  164. alpmHandle = nil
  165. must(temp.Release())
  166. }
  167. }
  168. // must outputs the error if there is one,
  169. // then calls cleanup() and ends the program with exit code 1.
  170. // If err == nil, no action is taken.
  171. func must(err error) {
  172. if err != nil {
  173. fmt.Fprintln(os.Stderr, err)
  174. cleanup()
  175. os.Exit(1)
  176. }
  177. }
  178. func main() {
  179. if os.Geteuid() == 0 {
  180. fmt.Println("Please avoid running yay as root/sudo.")
  181. }
  182. // Ensure release of alpmHandle
  183. defer cleanup()
  184. must(cmdArgs.parseCommandLine())
  185. must(setPaths())
  186. must(initConfig())
  187. cmdArgs.extractYayOptions()
  188. must(initVCS())
  189. must(initAlpm())
  190. must(handleCmd())
  191. }