config.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package config
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "os"
  8. "os/exec"
  9. "strings"
  10. alpm "github.com/jguer/go-alpm"
  11. )
  12. // Verbosity settings for search
  13. const (
  14. NumberMenu = iota
  15. Detailed
  16. Minimal
  17. )
  18. // Describes Sorting method for numberdisplay
  19. const (
  20. BottomUp = iota
  21. TopDown
  22. )
  23. // Configuration stores yay's config.
  24. type Configuration struct {
  25. BuildDir string `json:"buildDir"`
  26. Editor string `json:"editor"`
  27. MakepkgBin string `json:"makepkgbin"`
  28. Shell string `json:"-"`
  29. NoConfirm bool `json:"noconfirm"`
  30. Devel bool `json:"devel"`
  31. PacmanBin string `json:"pacmanbin"`
  32. PacmanConf string `json:"pacmanconf"`
  33. SearchMode int `json:"-"`
  34. SortMode int `json:"sortmode"`
  35. TarBin string `json:"tarbin"`
  36. TimeUpdate bool `json:"timeupdate"`
  37. }
  38. // YayConf holds the current config values for yay.
  39. var YayConf Configuration
  40. // AlpmConf holds the current config values for pacman.
  41. var AlpmConf alpm.PacmanConfig
  42. // AlpmHandle is the alpm handle used by yay.
  43. var AlpmHandle *alpm.Handle
  44. func init() {
  45. defaultSettings(&YayConf)
  46. var err error
  47. configfile := os.Getenv("HOME") + "/.config/yay/config.json"
  48. if _, err = os.Stat(configfile); os.IsNotExist(err) {
  49. _ = os.MkdirAll(os.Getenv("HOME")+"/.config/yay", 0755)
  50. // Save the default config if nothing is found
  51. SaveConfig()
  52. } else {
  53. file, err := os.Open(configfile)
  54. if err != nil {
  55. fmt.Println("Error reading config:", err)
  56. } else {
  57. decoder := json.NewDecoder(file)
  58. err = decoder.Decode(&YayConf)
  59. if err != nil {
  60. fmt.Println("Loading default Settings\nError reading config:", err)
  61. defaultSettings(&YayConf)
  62. }
  63. }
  64. }
  65. AlpmConf, err = readAlpmConfig(YayConf.PacmanConf)
  66. if err != nil {
  67. fmt.Println("Unable to read Pacman conf", err)
  68. os.Exit(1)
  69. }
  70. AlpmHandle, err = AlpmConf.CreateHandle()
  71. if err != nil {
  72. fmt.Println("Unable to CreateHandle", err)
  73. os.Exit(1)
  74. }
  75. }
  76. func readAlpmConfig(pacmanconf string) (conf alpm.PacmanConfig, err error) {
  77. file, err := os.Open(pacmanconf)
  78. if err != nil {
  79. return
  80. }
  81. conf, err = alpm.ParseConfig(file)
  82. if err != nil {
  83. return
  84. }
  85. return
  86. }
  87. // SaveConfig writes yay config to file.
  88. func SaveConfig() error {
  89. YayConf.NoConfirm = false
  90. configfile := os.Getenv("HOME") + "/.config/yay/config.json"
  91. marshalledinfo, _ := json.MarshalIndent(YayConf, "", "\t")
  92. in, err := os.OpenFile(configfile, os.O_RDWR|os.O_CREATE, 0755)
  93. if err != nil {
  94. return err
  95. }
  96. defer in.Close()
  97. _, err = in.Write(marshalledinfo)
  98. if err != nil {
  99. return err
  100. }
  101. err = in.Sync()
  102. return err
  103. }
  104. func defaultSettings(config *Configuration) {
  105. config.BuildDir = "/tmp/yaytmp/"
  106. config.Editor = ""
  107. config.Devel = false
  108. config.MakepkgBin = "/usr/bin/makepkg"
  109. config.NoConfirm = false
  110. config.PacmanBin = "/usr/bin/pacman"
  111. config.PacmanConf = "/etc/pacman.conf"
  112. config.SortMode = BottomUp
  113. config.TarBin = "/usr/bin/bsdtar"
  114. config.TimeUpdate = false
  115. }
  116. // Editor returns the preferred system editor.
  117. func Editor() string {
  118. switch {
  119. case YayConf.Editor != "":
  120. editor, err := exec.LookPath(YayConf.Editor)
  121. if err != nil {
  122. fmt.Println(err)
  123. } else {
  124. return editor
  125. }
  126. fallthrough
  127. case os.Getenv("EDITOR") != "":
  128. editor, err := exec.LookPath(os.Getenv("EDITOR"))
  129. if err != nil {
  130. fmt.Println(err)
  131. } else {
  132. return editor
  133. }
  134. fallthrough
  135. case os.Getenv("VISUAL") != "":
  136. editor, err := exec.LookPath(os.Getenv("VISUAL"))
  137. if err != nil {
  138. fmt.Println(err)
  139. } else {
  140. return editor
  141. }
  142. fallthrough
  143. default:
  144. fmt.Printf("\x1b[1;31;40mWarning: \x1B[1;33;40m$EDITOR\x1b[0;37;40m is not set.\x1b[0m\nPlease add $EDITOR or to your environment variables.\n")
  145. editorLoop:
  146. fmt.Printf("\x1b[32m%s\x1b[0m ", "Edit PKGBUILD with:")
  147. var editorInput string
  148. _, err := fmt.Scanln(&editorInput)
  149. if err != nil {
  150. fmt.Println(err)
  151. goto editorLoop
  152. }
  153. editor, err := exec.LookPath(editorInput)
  154. if err != nil {
  155. fmt.Println(err)
  156. goto editorLoop
  157. }
  158. return editor
  159. }
  160. }
  161. // ContinueTask prompts if user wants to continue task.
  162. //If NoConfirm is set the action will continue without user input.
  163. func ContinueTask(s string, def string) (cont bool) {
  164. if YayConf.NoConfirm {
  165. return true
  166. }
  167. var postFix string
  168. if def == "nN" {
  169. postFix = "[Y/n] "
  170. } else {
  171. postFix = "[y/N] "
  172. }
  173. var response string
  174. fmt.Printf("\x1b[1;32m==> %s\x1b[1;37m %s\x1b[0m", s, postFix)
  175. n, err := fmt.Scanln(&response)
  176. if err != nil || n == 0 {
  177. return true
  178. }
  179. if response == string(def[0]) || response == string(def[1]) {
  180. return false
  181. }
  182. return true
  183. }
  184. func downloadFile(path string, url string) (err error) {
  185. // Create the file
  186. out, err := os.Create(path)
  187. if err != nil {
  188. return err
  189. }
  190. defer out.Close()
  191. // Get the data
  192. resp, err := http.Get(url)
  193. if err != nil {
  194. return err
  195. }
  196. defer resp.Body.Close()
  197. // Writer the body to file
  198. _, err = io.Copy(out, resp.Body)
  199. return err
  200. }
  201. // DownloadAndUnpack downloads url tgz and extracts to path.
  202. func DownloadAndUnpack(url string, path string, trim bool) (err error) {
  203. err = os.MkdirAll(path, 0755)
  204. if err != nil {
  205. return
  206. }
  207. tokens := strings.Split(url, "/")
  208. fileName := tokens[len(tokens)-1]
  209. tarLocation := path + fileName
  210. defer os.Remove(tarLocation)
  211. err = downloadFile(tarLocation, url)
  212. if err != nil {
  213. return
  214. }
  215. if trim {
  216. err = exec.Command("/bin/sh", "-c",
  217. YayConf.TarBin+" --strip-components 2 --include='*/"+fileName[:len(fileName)-7]+"/trunk/' -xf "+tarLocation+" -C "+path).Run()
  218. os.Rename(path+"trunk", path+fileName[:len(fileName)-7]) // kurwa
  219. } else {
  220. err = exec.Command(YayConf.TarBin, "-xf", tarLocation, "-C", path).Run()
  221. }
  222. if err != nil {
  223. return
  224. }
  225. return
  226. }
  227. // PassToPacman outsorces execution to pacman binary without modifications.
  228. func PassToPacman(op string, pkgs []string, flags []string) error {
  229. var cmd *exec.Cmd
  230. var args []string
  231. args = append(args, op)
  232. if len(pkgs) != 0 {
  233. args = append(args, pkgs...)
  234. }
  235. if len(flags) != 0 {
  236. args = append(args, flags...)
  237. }
  238. if strings.Contains(op, "-Q") || op == "Si" {
  239. cmd = exec.Command(YayConf.PacmanBin, args...)
  240. } else {
  241. args = append([]string{YayConf.PacmanBin}, args...)
  242. cmd = exec.Command("sudo", args...)
  243. }
  244. cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
  245. err := cmd.Run()
  246. return err
  247. }