dep_graph.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package dep
  2. import (
  3. "context"
  4. "fmt"
  5. mapset "github.com/deckarep/golang-set/v2"
  6. "github.com/leonelquinteros/gotext"
  7. "github.com/Jguer/yay/v12/pkg/db"
  8. "github.com/Jguer/yay/v12/pkg/dep/topo"
  9. "github.com/Jguer/yay/v12/pkg/text"
  10. )
  11. const (
  12. sourceAUR = "aur"
  13. sourceCacheSRCINFO = "srcinfo"
  14. )
  15. type InstallInfo struct {
  16. Source Source
  17. Reason Reason
  18. Version string
  19. LocalVersion string
  20. SrcinfoPath *string
  21. AURBase *string
  22. SyncDBName *string
  23. IsGroup bool
  24. Upgrade bool
  25. Devel bool
  26. }
  27. func (i *InstallInfo) String() string {
  28. return fmt.Sprintf("InstallInfo{Source: %v, Reason: %v}", i.Source, i.Reason)
  29. }
  30. type (
  31. Reason int
  32. Source int
  33. )
  34. func (r Reason) String() string {
  35. return ReasonNames[r]
  36. }
  37. func (s Source) String() string {
  38. return SourceNames[s]
  39. }
  40. const (
  41. Explicit Reason = iota // 0
  42. Dep // 1
  43. MakeDep // 2
  44. CheckDep // 3
  45. )
  46. var ReasonNames = map[Reason]string{
  47. Explicit: gotext.Get("Explicit"),
  48. Dep: gotext.Get("Dependency"),
  49. MakeDep: gotext.Get("Make Dependency"),
  50. CheckDep: gotext.Get("Check Dependency"),
  51. }
  52. const (
  53. AUR Source = iota
  54. Sync
  55. Local
  56. SrcInfo
  57. Missing
  58. )
  59. var SourceNames = map[Source]string{
  60. AUR: gotext.Get("AUR"),
  61. Sync: gotext.Get("Sync"),
  62. Local: gotext.Get("Local"),
  63. SrcInfo: gotext.Get("SRCINFO"),
  64. Missing: gotext.Get("Missing"),
  65. }
  66. var bgColorMap = map[Source]string{
  67. AUR: "lightblue",
  68. Sync: "lemonchiffon",
  69. Local: "darkolivegreen1",
  70. Missing: "tomato",
  71. }
  72. var colorMap = map[Reason]string{
  73. Explicit: "black",
  74. Dep: "deeppink",
  75. MakeDep: "navyblue",
  76. CheckDep: "forestgreen",
  77. }
  78. type SourceHandler interface {
  79. Graph(ctx context.Context, graph *topo.Graph[string, *InstallInfo]) error
  80. Test(target Target) bool
  81. }
  82. type UpgradeHandler interface {
  83. GraphUpgrades(ctx context.Context, graph *topo.Graph[string, *InstallInfo],
  84. enableDowngrade bool, filter Filter,
  85. )
  86. }
  87. type Grapher struct {
  88. logger *text.Logger
  89. handlers map[string][]SourceHandler
  90. upgradeHandlers map[string][]UpgradeHandler
  91. }
  92. func NewGrapher(logger *text.Logger) *Grapher {
  93. grapher := &Grapher{
  94. logger: logger,
  95. handlers: make(map[string][]SourceHandler),
  96. }
  97. return grapher
  98. }
  99. func NewGraph() *topo.Graph[string, *InstallInfo] {
  100. return topo.New[string, *InstallInfo]()
  101. }
  102. func (g *Grapher) RegisterSourceHandler(handler SourceHandler, source string) {
  103. g.handlers[source] = append(g.handlers[source], handler)
  104. if upgradeHandler, ok := handler.(UpgradeHandler); ok {
  105. g.upgradeHandlers[source] = append(g.upgradeHandlers[source], upgradeHandler)
  106. }
  107. }
  108. func (g *Grapher) GraphFromTargets(ctx context.Context,
  109. graph *topo.Graph[string, *InstallInfo], targets []string,
  110. ) (*topo.Graph[string, *InstallInfo], error) {
  111. if graph == nil {
  112. graph = NewGraph()
  113. }
  114. sources := mapset.NewThreadUnsafeSetFromMapKeys[string, []SourceHandler](g.handlers)
  115. nextTarget:
  116. for _, targetString := range targets {
  117. target := ToTarget(targetString)
  118. for _, handler := range g.handlers[target.DB] {
  119. if handler.Test(target) {
  120. continue nextTarget
  121. }
  122. }
  123. g.logger.Errorln(gotext.Get("No package found for"), " ", target)
  124. }
  125. for source := range sources.Iter() {
  126. for _, handler := range g.handlers[source] {
  127. if err := handler.Graph(ctx, graph); err != nil {
  128. g.logger.Errorln(gotext.Get("Error graphing targets"), ":", err)
  129. }
  130. }
  131. }
  132. return graph, nil
  133. }
  134. // Filter decides if specific package should be included in theincluded in the results.
  135. type Filter func(*db.Upgrade) bool
  136. func (g *Grapher) GraphUpgrades(ctx context.Context,
  137. graph *topo.Graph[string, *InstallInfo], enableDowngrade bool,
  138. ) (*topo.Graph[string, *InstallInfo], error) {
  139. if graph == nil {
  140. graph = NewGraph()
  141. }
  142. return graph, nil
  143. }