local_install.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Experimental code for install local with dependency refactoring
  2. // Not at feature parity with install.go
  3. package main
  4. import (
  5. "context"
  6. "fmt"
  7. "os"
  8. "path/filepath"
  9. "github.com/Jguer/yay/v11/pkg/db"
  10. "github.com/Jguer/yay/v11/pkg/dep"
  11. "github.com/Jguer/yay/v11/pkg/download"
  12. "github.com/Jguer/yay/v11/pkg/metadata"
  13. "github.com/Jguer/yay/v11/pkg/settings"
  14. "github.com/Jguer/yay/v11/pkg/settings/exe"
  15. "github.com/Jguer/yay/v11/pkg/settings/parser"
  16. gosrc "github.com/Morganamilo/go-srcinfo"
  17. "github.com/leonelquinteros/gotext"
  18. "github.com/pkg/errors"
  19. )
  20. var ErrInstallRepoPkgs = errors.New(gotext.Get("error installing repo packages"))
  21. func installLocalPKGBUILD(
  22. ctx context.Context,
  23. cmdArgs *parser.Arguments,
  24. dbExecutor db.Executor,
  25. ) error {
  26. aurCache, err := metadata.NewAURCache(filepath.Join(config.BuildDir, "aur.json"))
  27. if err != nil {
  28. return errors.Wrap(err, gotext.Get("failed to retrieve aur Cache"))
  29. }
  30. wd, err := os.Getwd()
  31. if err != nil {
  32. return errors.Wrap(err, gotext.Get("failed to retrieve working directory"))
  33. }
  34. if len(cmdArgs.Targets) > 1 {
  35. return errors.New(gotext.Get("only one target is allowed"))
  36. }
  37. if len(cmdArgs.Targets) == 1 {
  38. wd = cmdArgs.Targets[0]
  39. }
  40. pkgbuild, err := gosrc.ParseFile(filepath.Join(wd, ".SRCINFO"))
  41. if err != nil {
  42. return errors.Wrap(err, gotext.Get("failed to parse .SRCINFO"))
  43. }
  44. grapher := dep.NewGrapher(dbExecutor, aurCache, false, settings.NoConfirm, os.Stdout)
  45. graph, err := grapher.GraphFromSrcInfo(pkgbuild)
  46. if err != nil {
  47. return err
  48. }
  49. topoSorted := graph.TopoSortedLayerMap()
  50. fmt.Println(topoSorted, len(topoSorted))
  51. preparer := &Preparer{dbExecutor: dbExecutor, cmdBuilder: config.Runtime.CmdBuilder}
  52. installer := &Installer{dbExecutor: dbExecutor}
  53. if err := preparer.PrepareWorkspace(ctx, topoSorted); err != nil {
  54. return err
  55. }
  56. return installer.Install(ctx, cmdArgs, topoSorted)
  57. }
  58. type Preparer struct {
  59. dbExecutor db.Executor
  60. cmdBuilder exe.ICmdBuilder
  61. aurBases []string
  62. }
  63. func (preper *Preparer) PrepareWorkspace(ctx context.Context, targets []map[string]*dep.InstallInfo,
  64. ) error {
  65. for _, layer := range targets {
  66. for pkgBase, info := range layer {
  67. if info.Source == dep.AUR {
  68. preper.aurBases = append(preper.aurBases, pkgBase)
  69. }
  70. }
  71. }
  72. _, errA := download.AURPKGBUILDRepos(ctx,
  73. preper.cmdBuilder, preper.aurBases, config.AURURL, config.BuildDir, false)
  74. if errA != nil {
  75. return errA
  76. }
  77. return nil
  78. }
  79. type Installer struct {
  80. dbExecutor db.Executor
  81. }
  82. func (installer *Installer) Install(ctx context.Context, cmdArgs *parser.Arguments, targets []map[string]*dep.InstallInfo) error {
  83. // Reorganize targets into layers of dependencies
  84. for i := len(targets) - 1; i >= 0; i-- {
  85. err := installer.handleLayer(ctx, cmdArgs, targets[i])
  86. if err != nil {
  87. // rollback
  88. return err
  89. }
  90. }
  91. return nil
  92. }
  93. type MapBySourceAndType map[dep.Source]map[dep.Reason][]string
  94. func (m *MapBySourceAndType) String() string {
  95. var s string
  96. for source, reasons := range *m {
  97. s += fmt.Sprintf("%s: [", source)
  98. for reason, names := range reasons {
  99. s += fmt.Sprintf(" %d: [%v] ", reason, names)
  100. }
  101. s += "], "
  102. }
  103. return s
  104. }
  105. func (installer *Installer) handleLayer(ctx context.Context, cmdArgs *parser.Arguments, layer map[string]*dep.InstallInfo) error {
  106. // Install layer
  107. depByTypeAndReason := make(MapBySourceAndType)
  108. for name, info := range layer {
  109. if _, ok := depByTypeAndReason[info.Source]; !ok {
  110. depByTypeAndReason[info.Source] = make(map[dep.Reason][]string)
  111. }
  112. depByTypeAndReason[info.Source][info.Reason] = append(depByTypeAndReason[info.Source][info.Reason], name)
  113. }
  114. fmt.Printf("%v\n", depByTypeAndReason)
  115. syncDeps, syncExp := make([]string, 0), make([]string, 0)
  116. repoTargets := make([]string, 0)
  117. for source, reasons := range depByTypeAndReason {
  118. switch source {
  119. case dep.AUR:
  120. case dep.Sync:
  121. for reason, names := range reasons {
  122. switch reason {
  123. case dep.Explicit:
  124. if cmdArgs.ExistsArg("asdeps", "asdep") {
  125. syncDeps = append(syncDeps, names...)
  126. } else {
  127. syncExp = append(syncExp, names...)
  128. }
  129. case dep.CheckDep:
  130. fallthrough
  131. case dep.MakeDep:
  132. fallthrough
  133. case dep.Dep:
  134. syncDeps = append(syncDeps, names...)
  135. }
  136. repoTargets = append(repoTargets, names...)
  137. }
  138. }
  139. }
  140. fmt.Println(syncDeps, syncExp)
  141. errShow := installer.installRepoPackages(ctx, cmdArgs, repoTargets, syncDeps, syncExp)
  142. if errShow != nil {
  143. return ErrInstallRepoPkgs
  144. }
  145. return nil
  146. }
  147. func (*Installer) installRepoPackages(ctx context.Context, cmdArgs *parser.Arguments,
  148. repoTargets, // all repo targets
  149. syncDeps, // repo targets that are deps
  150. syncExp []string, // repo targets that are exp
  151. ) error {
  152. arguments := cmdArgs.Copy()
  153. arguments.DelArg("asdeps", "asdep")
  154. arguments.DelArg("asexplicit", "asexp")
  155. arguments.DelArg("i", "install")
  156. arguments.Op = "S"
  157. arguments.ClearTargets()
  158. arguments.AddTarget(repoTargets...)
  159. errShow := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,
  160. arguments, config.Runtime.Mode, settings.NoConfirm))
  161. if errD := asdeps(ctx, cmdArgs, syncDeps); errD != nil {
  162. return errD
  163. }
  164. if errE := asexp(ctx, cmdArgs, syncExp); errE != nil {
  165. return errE
  166. }
  167. return errShow
  168. }