alpm.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package db
  2. import (
  3. "errors"
  4. alpm "github.com/Jguer/go-alpm"
  5. "github.com/Morganamilo/go-pacmanconf"
  6. "github.com/leonelquinteros/gotext"
  7. "github.com/Jguer/yay/v10/pkg/text"
  8. )
  9. type AlpmExecutor struct {
  10. handle *alpm.Handle
  11. localDB *alpm.DB
  12. syncDB alpm.DBList
  13. conf *pacmanconf.Config
  14. questionCallback func(question alpm.QuestionAny)
  15. }
  16. func NewAlpmExecutor(handle *alpm.Handle,
  17. pacamnConf *pacmanconf.Config,
  18. questionCallback func(question alpm.QuestionAny)) (*AlpmExecutor, error) {
  19. localDB, err := handle.LocalDB()
  20. if err != nil {
  21. return nil, err
  22. }
  23. syncDB, err := handle.SyncDBs()
  24. if err != nil {
  25. return nil, err
  26. }
  27. return &AlpmExecutor{handle: handle, localDB: localDB, syncDB: syncDB, conf: pacamnConf, questionCallback: questionCallback}, nil
  28. }
  29. func toUsage(usages []string) alpm.Usage {
  30. if len(usages) == 0 {
  31. return alpm.UsageAll
  32. }
  33. var ret alpm.Usage
  34. for _, usage := range usages {
  35. switch usage {
  36. case "Sync":
  37. ret |= alpm.UsageSync
  38. case "Search":
  39. ret |= alpm.UsageSearch
  40. case "Install":
  41. ret |= alpm.UsageInstall
  42. case "Upgrade":
  43. ret |= alpm.UsageUpgrade
  44. case "All":
  45. ret |= alpm.UsageAll
  46. }
  47. }
  48. return ret
  49. }
  50. func configureAlpm(pacmanConf *pacmanconf.Config, alpmHandle *alpm.Handle) error {
  51. // TODO: set SigLevel
  52. // sigLevel := alpm.SigPackage | alpm.SigPackageOptional | alpm.SigDatabase | alpm.SigDatabaseOptional
  53. // localFileSigLevel := alpm.SigUseDefault
  54. // remoteFileSigLevel := alpm.SigUseDefault
  55. for _, repo := range pacmanConf.Repos {
  56. // TODO: set SigLevel
  57. db, err := alpmHandle.RegisterSyncDB(repo.Name, 0)
  58. if err != nil {
  59. return err
  60. }
  61. db.SetServers(repo.Servers)
  62. db.SetUsage(toUsage(repo.Usage))
  63. }
  64. if err := alpmHandle.SetCacheDirs(pacmanConf.CacheDir); err != nil {
  65. return err
  66. }
  67. // add hook directories 1-by-1 to avoid overwriting the system directory
  68. for _, dir := range pacmanConf.HookDir {
  69. if err := alpmHandle.AddHookDir(dir); err != nil {
  70. return err
  71. }
  72. }
  73. if err := alpmHandle.SetGPGDir(pacmanConf.GPGDir); err != nil {
  74. return err
  75. }
  76. if err := alpmHandle.SetLogFile(pacmanConf.LogFile); err != nil {
  77. return err
  78. }
  79. if err := alpmHandle.SetIgnorePkgs(pacmanConf.IgnorePkg); err != nil {
  80. return err
  81. }
  82. if err := alpmHandle.SetIgnoreGroups(pacmanConf.IgnoreGroup); err != nil {
  83. return err
  84. }
  85. if err := alpmHandle.SetArch(pacmanConf.Architecture); err != nil {
  86. return err
  87. }
  88. if err := alpmHandle.SetNoUpgrades(pacmanConf.NoUpgrade); err != nil {
  89. return err
  90. }
  91. if err := alpmHandle.SetNoExtracts(pacmanConf.NoExtract); err != nil {
  92. return err
  93. }
  94. /*if err := alpmHandle.SetDefaultSigLevel(sigLevel); err != nil {
  95. return err
  96. }
  97. if err := alpmHandle.SetLocalFileSigLevel(localFileSigLevel); err != nil {
  98. return err
  99. }
  100. if err := alpmHandle.SetRemoteFileSigLevel(remoteFileSigLevel); err != nil {
  101. return err
  102. }*/
  103. if err := alpmHandle.SetUseSyslog(pacmanConf.UseSyslog); err != nil {
  104. return err
  105. }
  106. return alpmHandle.SetCheckSpace(pacmanConf.CheckSpace)
  107. }
  108. func logCallback(level alpm.LogLevel, str string) {
  109. switch level {
  110. case alpm.LogWarning:
  111. text.Warn(str)
  112. case alpm.LogError:
  113. text.Error(str)
  114. }
  115. }
  116. func (ae *AlpmExecutor) RefreshHandle() error {
  117. if ae.handle != nil {
  118. if errRelease := ae.handle.Release(); errRelease != nil {
  119. return errRelease
  120. }
  121. }
  122. alpmHandle, err := alpm.Initialize(ae.conf.RootDir, ae.conf.DBPath)
  123. if err != nil {
  124. return errors.New(gotext.Get("unable to CreateHandle: %s", err))
  125. }
  126. if errConf := configureAlpm(ae.conf, alpmHandle); errConf != nil {
  127. return errConf
  128. }
  129. alpmHandle.SetQuestionCallback(ae.questionCallback)
  130. alpmHandle.SetLogCallback(logCallback)
  131. ae.handle = alpmHandle
  132. ae.syncDB, err = alpmHandle.SyncDBs()
  133. if err != nil {
  134. return err
  135. }
  136. ae.localDB, err = alpmHandle.LocalDB()
  137. return err
  138. }
  139. func (ae *AlpmExecutor) LocalSatisfierExists(pkgName string) bool {
  140. if _, err := ae.localDB.PkgCache().FindSatisfier(pkgName); err != nil {
  141. return false
  142. }
  143. return true
  144. }
  145. func (ae *AlpmExecutor) IsCorrectVersionInstalled(pkgName, versionRequired string) bool {
  146. alpmPackage := ae.localDB.Pkg(pkgName)
  147. if alpmPackage == nil {
  148. return false
  149. }
  150. return alpmPackage.Version() == versionRequired
  151. }
  152. func (ae *AlpmExecutor) SyncSatisfier(pkgName string) RepoPackage {
  153. foundPkg, err := ae.syncDB.FindSatisfier(pkgName)
  154. if err != nil {
  155. return nil
  156. }
  157. return foundPkg
  158. }
  159. func (ae *AlpmExecutor) PackagesFromGroup(groupName string) []RepoPackage {
  160. groupPackages := []RepoPackage{}
  161. _ = ae.syncDB.FindGroupPkgs(groupName).ForEach(func(pkg alpm.Package) error {
  162. groupPackages = append(groupPackages, &pkg)
  163. return nil
  164. })
  165. return groupPackages
  166. }
  167. func (ae *AlpmExecutor) LocalPackages() []RepoPackage {
  168. localPackages := []RepoPackage{}
  169. _ = ae.localDB.PkgCache().ForEach(func(pkg alpm.Package) error {
  170. localPackages = append(localPackages, RepoPackage(&pkg))
  171. return nil
  172. })
  173. return localPackages
  174. }
  175. // SyncPackages searches SyncDB for packages or returns all packages if no search param is given
  176. func (ae *AlpmExecutor) SyncPackages(pkgNames ...string) []RepoPackage {
  177. repoPackages := []RepoPackage{}
  178. _ = ae.syncDB.ForEach(func(db alpm.DB) error {
  179. if len(pkgNames) == 0 {
  180. _ = db.PkgCache().ForEach(func(pkg alpm.Package) error {
  181. repoPackages = append(repoPackages, RepoPackage(&pkg))
  182. return nil
  183. })
  184. } else {
  185. _ = db.Search(pkgNames).ForEach(func(pkg alpm.Package) error {
  186. repoPackages = append(repoPackages, RepoPackage(&pkg))
  187. return nil
  188. })
  189. }
  190. return nil
  191. })
  192. return repoPackages
  193. }
  194. func (ae *AlpmExecutor) LocalPackage(pkgName string) RepoPackage {
  195. return ae.localDB.Pkg(pkgName)
  196. }
  197. func (ae *AlpmExecutor) PackageFromDB(pkgName, dbName string) RepoPackage {
  198. singleDB, err := ae.handle.SyncDBByName(dbName)
  199. if err != nil {
  200. return nil
  201. }
  202. foundPkg, err := singleDB.PkgCache().FindSatisfier(pkgName)
  203. if err != nil {
  204. return nil
  205. }
  206. return foundPkg
  207. }
  208. func (ae *AlpmExecutor) PackageDepends(pkg RepoPackage) []alpm.Depend {
  209. alpmPackage := pkg.(*alpm.Package)
  210. return alpmPackage.Depends().Slice()
  211. }
  212. func (ae *AlpmExecutor) PackageProvides(pkg RepoPackage) []alpm.Depend {
  213. alpmPackage := pkg.(*alpm.Package)
  214. return alpmPackage.Provides().Slice()
  215. }
  216. func (ae *AlpmExecutor) PackageConflicts(pkg RepoPackage) []alpm.Depend {
  217. alpmPackage := pkg.(*alpm.Package)
  218. return alpmPackage.Conflicts().Slice()
  219. }
  220. func (ae *AlpmExecutor) PackageGroups(pkg RepoPackage) []string {
  221. alpmPackage := pkg.(*alpm.Package)
  222. return alpmPackage.Groups().Slice()
  223. }