config.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "strings"
  8. alpm "github.com/Jguer/go-alpm"
  9. pacmanconf "github.com/Morganamilo/go-pacmanconf"
  10. "github.com/leonelquinteros/gotext"
  11. "github.com/Jguer/yay/v10/pkg/settings"
  12. "github.com/Jguer/yay/v10/pkg/text"
  13. )
  14. // Verbosity settings for search
  15. const (
  16. numberMenu = iota
  17. detailed
  18. minimal
  19. )
  20. var yayVersion = "10.0.0"
  21. var localePath = "/usr/share/locale"
  22. // savedInfo holds the current vcs info
  23. var savedInfo vcsInfo
  24. // vcsfile holds yay vcs info file path.
  25. var vcsFile string
  26. // YayConf holds the current config values for yay.
  27. var config *settings.Configuration
  28. // AlpmConf holds the current config values for pacman.
  29. var pacmanConf *pacmanconf.Config
  30. // AlpmHandle is the alpm handle used by yay.
  31. var alpmHandle *alpm.Handle
  32. var hideMenus = false
  33. func defaultSettings() *settings.Configuration {
  34. newConfig := &settings.Configuration{
  35. AURURL: "https://aur.archlinux.org",
  36. BuildDir: "$HOME/.cache/yay",
  37. ABSDir: "$HOME/.cache/yay/abs",
  38. CleanAfter: false,
  39. Editor: "",
  40. EditorFlags: "",
  41. Devel: false,
  42. MakepkgBin: "makepkg",
  43. MakepkgConf: "",
  44. NoConfirm: false,
  45. PacmanBin: "pacman",
  46. PGPFetch: true,
  47. PacmanConf: "/etc/pacman.conf",
  48. GpgFlags: "",
  49. MFlags: "",
  50. GitFlags: "",
  51. SortMode: settings.BottomUp,
  52. CompletionInterval: 7,
  53. SortBy: "votes",
  54. SearchBy: "name-desc",
  55. SudoLoop: false,
  56. GitBin: "git",
  57. GpgBin: "gpg",
  58. SudoBin: "sudo",
  59. SudoFlags: "",
  60. TimeUpdate: false,
  61. RequestSplitN: 150,
  62. ReDownload: "no",
  63. ReBuild: "no",
  64. BatchInstall: false,
  65. AnswerClean: "",
  66. AnswerDiff: "",
  67. AnswerEdit: "",
  68. AnswerUpgrade: "",
  69. RemoveMake: "ask",
  70. Provides: true,
  71. UpgradeMenu: true,
  72. CleanMenu: true,
  73. DiffMenu: true,
  74. EditMenu: false,
  75. UseAsk: false,
  76. CombinedUpgrade: false,
  77. }
  78. if os.Getenv("XDG_CACHE_HOME") != "" {
  79. newConfig.BuildDir = "$XDG_CACHE_HOME/yay"
  80. }
  81. return newConfig
  82. }
  83. // Editor returns the preferred system editor.
  84. func editor() (editor string, args []string) {
  85. switch {
  86. case config.Editor != "":
  87. editor, err := exec.LookPath(config.Editor)
  88. if err != nil {
  89. fmt.Fprintln(os.Stderr, err)
  90. } else {
  91. return editor, strings.Fields(config.EditorFlags)
  92. }
  93. fallthrough
  94. case os.Getenv("EDITOR") != "":
  95. if editorArgs := strings.Fields(os.Getenv("EDITOR")); len(editorArgs) != 0 {
  96. editor, err := exec.LookPath(editorArgs[0])
  97. if err != nil {
  98. fmt.Fprintln(os.Stderr, err)
  99. } else {
  100. return editor, editorArgs[1:]
  101. }
  102. }
  103. fallthrough
  104. case os.Getenv("VISUAL") != "":
  105. if editorArgs := strings.Fields(os.Getenv("VISUAL")); len(editorArgs) != 0 {
  106. editor, err := exec.LookPath(editorArgs[0])
  107. if err != nil {
  108. fmt.Fprintln(os.Stderr, err)
  109. } else {
  110. return editor, editorArgs[1:]
  111. }
  112. }
  113. fallthrough
  114. default:
  115. fmt.Fprintln(os.Stderr)
  116. text.Errorln(gotext.Get("%s is not set", bold(cyan("$EDITOR"))))
  117. text.Warnln(gotext.Get("Add %s or %s to your environment variables", bold(cyan("$EDITOR")), bold(cyan("$VISUAL"))))
  118. for {
  119. text.Infoln(gotext.Get("Edit PKGBUILD with?"))
  120. editorInput, err := getInput("")
  121. if err != nil {
  122. fmt.Fprintln(os.Stderr, err)
  123. continue
  124. }
  125. editorArgs := strings.Fields(editorInput)
  126. if len(editorArgs) == 0 {
  127. continue
  128. }
  129. editor, err := exec.LookPath(editorArgs[0])
  130. if err != nil {
  131. fmt.Fprintln(os.Stderr, err)
  132. continue
  133. }
  134. return editor, editorArgs[1:]
  135. }
  136. }
  137. }
  138. // ContinueTask prompts if user wants to continue task.
  139. // If NoConfirm is set the action will continue without user input.
  140. func continueTask(s string, cont bool) bool {
  141. if config.NoConfirm {
  142. return cont
  143. }
  144. var response string
  145. var postFix string
  146. yes := gotext.Get("yes")
  147. no := gotext.Get("no")
  148. y := string([]rune(yes)[0])
  149. n := string([]rune(no)[0])
  150. if cont {
  151. postFix = fmt.Sprintf(" [%s/%s] ", strings.ToUpper(y), n)
  152. } else {
  153. postFix = fmt.Sprintf(" [%s/%s] ", y, strings.ToUpper(n))
  154. }
  155. text.Info(bold(s), bold(postFix))
  156. if _, err := fmt.Scanln(&response); err != nil {
  157. return cont
  158. }
  159. response = strings.ToLower(response)
  160. return response == yes || response == y
  161. }
  162. func getInput(defaultValue string) (string, error) {
  163. text.Info()
  164. if defaultValue != "" || config.NoConfirm {
  165. fmt.Println(defaultValue)
  166. return defaultValue, nil
  167. }
  168. reader := bufio.NewReader(os.Stdin)
  169. buf, overflow, err := reader.ReadLine()
  170. if err != nil {
  171. return "", err
  172. }
  173. if overflow {
  174. return "", fmt.Errorf(gotext.Get("input too long"))
  175. }
  176. return string(buf), nil
  177. }
  178. func toUsage(usages []string) alpm.Usage {
  179. if len(usages) == 0 {
  180. return alpm.UsageAll
  181. }
  182. var ret alpm.Usage
  183. for _, usage := range usages {
  184. switch usage {
  185. case "Sync":
  186. ret |= alpm.UsageSync
  187. case "Search":
  188. ret |= alpm.UsageSearch
  189. case "Install":
  190. ret |= alpm.UsageInstall
  191. case "Upgrade":
  192. ret |= alpm.UsageUpgrade
  193. case "All":
  194. ret |= alpm.UsageAll
  195. }
  196. }
  197. return ret
  198. }
  199. func configureAlpm() error {
  200. // TODO: set SigLevel
  201. // sigLevel := alpm.SigPackage | alpm.SigPackageOptional | alpm.SigDatabase | alpm.SigDatabaseOptional
  202. // localFileSigLevel := alpm.SigUseDefault
  203. // remoteFileSigLevel := alpm.SigUseDefault
  204. for _, repo := range pacmanConf.Repos {
  205. // TODO: set SigLevel
  206. db, err := alpmHandle.RegisterSyncDB(repo.Name, 0)
  207. if err != nil {
  208. return err
  209. }
  210. db.SetServers(repo.Servers)
  211. db.SetUsage(toUsage(repo.Usage))
  212. }
  213. if err := alpmHandle.SetCacheDirs(pacmanConf.CacheDir); err != nil {
  214. return err
  215. }
  216. // add hook directories 1-by-1 to avoid overwriting the system directory
  217. for _, dir := range pacmanConf.HookDir {
  218. if err := alpmHandle.AddHookDir(dir); err != nil {
  219. return err
  220. }
  221. }
  222. if err := alpmHandle.SetGPGDir(pacmanConf.GPGDir); err != nil {
  223. return err
  224. }
  225. if err := alpmHandle.SetLogFile(pacmanConf.LogFile); err != nil {
  226. return err
  227. }
  228. if err := alpmHandle.SetIgnorePkgs(pacmanConf.IgnorePkg); err != nil {
  229. return err
  230. }
  231. if err := alpmHandle.SetIgnoreGroups(pacmanConf.IgnoreGroup); err != nil {
  232. return err
  233. }
  234. if err := alpmHandle.SetArch(pacmanConf.Architecture); err != nil {
  235. return err
  236. }
  237. if err := alpmHandle.SetNoUpgrades(pacmanConf.NoUpgrade); err != nil {
  238. return err
  239. }
  240. if err := alpmHandle.SetNoExtracts(pacmanConf.NoExtract); err != nil {
  241. return err
  242. }
  243. /*if err := alpmHandle.SetDefaultSigLevel(sigLevel); err != nil {
  244. return err
  245. }
  246. if err := alpmHandle.SetLocalFileSigLevel(localFileSigLevel); err != nil {
  247. return err
  248. }
  249. if err := alpmHandle.SetRemoteFileSigLevel(remoteFileSigLevel); err != nil {
  250. return err
  251. }*/
  252. if err := alpmHandle.SetUseSyslog(pacmanConf.UseSyslog); err != nil {
  253. return err
  254. }
  255. return alpmHandle.SetCheckSpace(pacmanConf.CheckSpace)
  256. }