depCheck.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. "sync"
  6. alpm "github.com/jguer/go-alpm"
  7. // gopkg "github.com/mikkeloscar/gopkgbuild"
  8. )
  9. func (dp *depPool) checkInnerConflict(name string, conflict string, conflicts mapStringSet) {
  10. for _, pkg := range dp.Aur {
  11. if pkg.Name == name {
  12. continue
  13. }
  14. if satisfiesAur(conflict, pkg) {
  15. conflicts.Add(name, pkg.Name)
  16. }
  17. }
  18. for _, pkg := range dp.Repo {
  19. if pkg.Name() == name {
  20. continue
  21. }
  22. if satisfiesRepo(conflict, pkg) {
  23. conflicts.Add(name, pkg.Name())
  24. }
  25. }
  26. }
  27. func (dp *depPool) checkForwardConflict(name string, conflict string, conflicts mapStringSet) {
  28. dp.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
  29. if pkg.Name() == name {
  30. return nil
  31. }
  32. if satisfiesRepo(conflict, &pkg) {
  33. n := pkg.Name()
  34. if n != conflict {
  35. n += " (" + conflict + ")"
  36. }
  37. conflicts.Add(name, n)
  38. }
  39. return nil
  40. })
  41. }
  42. func (dp *depPool) checkReverseConflict(name string, conflict string, conflicts mapStringSet) {
  43. for _, pkg := range dp.Aur {
  44. if pkg.Name == name {
  45. continue
  46. }
  47. if satisfiesAur(conflict, pkg) {
  48. if name != conflict {
  49. name += " (" + conflict + ")"
  50. }
  51. conflicts.Add(pkg.Name, name)
  52. }
  53. }
  54. for _, pkg := range dp.Repo {
  55. if pkg.Name() == name {
  56. continue
  57. }
  58. if satisfiesRepo(conflict, pkg) {
  59. if name != conflict {
  60. name += " (" + conflict + ")"
  61. }
  62. conflicts.Add(pkg.Name(), name)
  63. }
  64. }
  65. }
  66. func (dp *depPool) checkInnerConflicts(conflicts mapStringSet) {
  67. for _, pkg := range dp.Aur {
  68. for _, conflict := range pkg.Conflicts {
  69. dp.checkInnerConflict(pkg.Name, conflict, conflicts)
  70. }
  71. }
  72. for _, pkg := range dp.Repo {
  73. pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
  74. dp.checkInnerConflict(pkg.Name(), conflict.String(), conflicts)
  75. return nil
  76. })
  77. }
  78. }
  79. func (dp *depPool) checkForwardConflicts(conflicts mapStringSet) {
  80. for _, pkg := range dp.Aur {
  81. for _, conflict := range pkg.Conflicts {
  82. dp.checkForwardConflict(pkg.Name, conflict, conflicts)
  83. }
  84. }
  85. for _, pkg := range dp.Repo {
  86. pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
  87. dp.checkForwardConflict(pkg.Name(), conflict.String(), conflicts)
  88. return nil
  89. })
  90. }
  91. }
  92. func (dp *depPool) checkReverseConflicts(conflicts mapStringSet) {
  93. dp.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
  94. pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
  95. dp.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
  96. return nil
  97. })
  98. return nil
  99. })
  100. }
  101. func (dp *depPool) CheckConflicts() error {
  102. var wg sync.WaitGroup
  103. innerConflicts := make(mapStringSet)
  104. conflicts := make(mapStringSet)
  105. wg.Add(2)
  106. fmt.Println(bold(cyan("::") + bold(" Checking for conflicts...")))
  107. go func() {
  108. dp.checkForwardConflicts(conflicts)
  109. dp.checkReverseConflicts(conflicts)
  110. wg.Done()
  111. }()
  112. fmt.Println(bold(cyan("::") + bold(" Checking for inner conflicts...")))
  113. go func() {
  114. dp.checkInnerConflicts(innerConflicts)
  115. wg.Done()
  116. }()
  117. wg.Wait()
  118. if len(innerConflicts) != 0 {
  119. fmt.Println()
  120. fmt.Println(bold(red(arrow)), bold("Inner conflicts found:"))
  121. for name, pkgs := range innerConflicts {
  122. str := red(bold(smallArrow)) + " " + name + ":"
  123. for pkg := range pkgs {
  124. str += " " + cyan(pkg) + ","
  125. }
  126. str = strings.TrimSuffix(str, ",")
  127. fmt.Println(str)
  128. }
  129. return fmt.Errorf("Unresolvable package conflicts, aborting")
  130. }
  131. if len(conflicts) != 0 {
  132. fmt.Println()
  133. fmt.Println(bold(red(arrow)), bold("Package conflicts found:"))
  134. for name, pkgs := range conflicts {
  135. str := red(bold(smallArrow)) + " Installing " + cyan(name) + " will remove:"
  136. for pkg := range pkgs {
  137. str += " " + cyan(pkg) + ","
  138. }
  139. str = strings.TrimSuffix(str, ",")
  140. fmt.Println(str)
  141. }
  142. fmt.Println()
  143. }
  144. return nil
  145. }
  146. type missing struct {
  147. Good stringSet
  148. Missing map[string][][]string
  149. }
  150. func (dp *depPool) _checkMissing(dep string, stack []string, missing *missing) {
  151. if _, err := dp.LocalDb.PkgCache().FindSatisfier(dep); err == nil {
  152. missing.Good.set(dep)
  153. return
  154. }
  155. if missing.Good.get(dep) {
  156. return
  157. }
  158. if trees, ok := missing.Missing[dep]; ok {
  159. for _, tree := range trees {
  160. if stringSliceEqual(tree, stack) {
  161. return
  162. }
  163. }
  164. missing.Missing[dep] = append(missing.Missing[dep], stack)
  165. return
  166. }
  167. aurPkg := dp.findSatisfierAur(dep)
  168. if aurPkg != nil {
  169. missing.Good.set(dep)
  170. for _, deps := range [3][]string{aurPkg.Depends, aurPkg.MakeDepends, aurPkg.CheckDepends} {
  171. for _, aurDep := range deps {
  172. dp._checkMissing(aurDep, append(stack, aurPkg.Name), missing)
  173. }
  174. }
  175. return
  176. }
  177. repoPkg := dp.findSatisfierRepo(dep)
  178. if repoPkg != nil {
  179. missing.Good.set(dep)
  180. repoPkg.Depends().ForEach(func(repoDep alpm.Depend) error {
  181. dp._checkMissing(repoDep.String(), append(stack, repoPkg.Name()), missing)
  182. return nil
  183. })
  184. return
  185. }
  186. missing.Missing[dep] = [][]string{stack}
  187. }
  188. func (dp *depPool) CheckMissing() error {
  189. missing := &missing{
  190. make(stringSet),
  191. make(map[string][][]string),
  192. }
  193. for _, target := range dp.Targets {
  194. dp._checkMissing(target.DepString(), make([]string, 0), missing)
  195. }
  196. if len(missing.Missing) == 0 {
  197. return nil
  198. }
  199. fmt.Println(bold(red(arrow+" Error: ")) + "Could not find all required packages:")
  200. for dep, trees := range missing.Missing {
  201. for _, tree := range trees {
  202. fmt.Print(" "+cyan(dep), " (Tree: ")
  203. if len(tree) == 0 {
  204. fmt.Print(cyan("Target "))
  205. } else {
  206. for _, pkg := range tree {
  207. fmt.Print(cyan(pkg), " -> ")
  208. }
  209. }
  210. fmt.Println(")")
  211. }
  212. }
  213. return fmt.Errorf("")
  214. }