PackageManager just because
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
3.8 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package Filesystem
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "github.com/vbauerster/mpb"
  7. "github.com/zenthangplus/goccm"
  8. bolt "go.etcd.io/bbolt"
  9. "PackageManager/Client/Database"
  10. "PackageManager/Client/ProgressBar"
  11. "PackageManager/Color"
  12. "PackageManager/Variables"
  13. )
  14. type FilesystemStatus struct {
  15. NewFiles []string
  16. PickedFiles []string
  17. ModifiedFiles []string
  18. MissingFiles []string
  19. }
  20. func ShowFilesystemDiff(root string) error {
  21. var (
  22. fsStatus FilesystemStatus
  23. //f string
  24. e error
  25. )
  26. fsStatus, e = GetFilesystemDiff(root)
  27. if e != nil {
  28. return e
  29. }
  30. fmt.Println("New files:")
  31. PrintFilesOrLength(fsStatus.NewFiles, Color.Green)
  32. fmt.Println("Added files:")
  33. PrintFilesOrLength(fsStatus.PickedFiles, Color.Green)
  34. fmt.Println("Modified files:")
  35. PrintFilesOrLength(fsStatus.ModifiedFiles, Color.Warning)
  36. fmt.Println("Deleted files:")
  37. PrintFilesOrLength(fsStatus.MissingFiles, Color.Fatal)
  38. return nil
  39. }
  40. func GetFilesystemLength(root string) (int, error) {
  41. var (
  42. rootStat os.FileInfo
  43. fsCount int = 0
  44. e error
  45. )
  46. rootStat, e = os.Stat(root)
  47. if e != nil {
  48. return fsCount, e
  49. }
  50. if rootStat.IsDir() && root[len(root)-1:] != "/" {
  51. root = root + "/"
  52. }
  53. filepath.Walk(root, func(p string, i os.FileInfo, _ error) error {
  54. // Ignore path in Variables.PruneRegexPaths
  55. if i.IsDir() && matchAny(p, PruneRegex) {
  56. return filepath.SkipDir
  57. }
  58. // Ignore path in Variables.IgnoreRegexPaths
  59. if matchAny(p, IgnoreRegex) {
  60. return nil
  61. }
  62. if !i.Mode().IsRegular() && (i.Mode()&os.ModeSymlink == 0) {
  63. return nil
  64. }
  65. fsCount++
  66. return nil
  67. })
  68. return fsCount, e
  69. }
  70. func (fsStatus *FilesystemStatus) parseFile(indexBucket, picksBucket *bolt.Bucket, p string, bar *mpb.Bar, c goccm.ConcurrencyManager) {
  71. var (
  72. newFileObject FileObject
  73. knownFileObject FileObject
  74. pick, known []byte
  75. e error
  76. )
  77. defer func() {
  78. bar.Increment()
  79. c.Done()
  80. }()
  81. pick = picksBucket.Get([]byte(p))
  82. known = indexBucket.Get([]byte(p))
  83. if pick != nil {
  84. fsStatus.PickedFiles = append(fsStatus.PickedFiles, p)
  85. return
  86. }
  87. if known != nil {
  88. newFileObject, e = CreateFileObject(p)
  89. if e != nil {
  90. return
  91. }
  92. knownFileObject, e = FromBytes(known)
  93. if e != nil {
  94. return
  95. }
  96. e = newFileObject.IsDifferent(knownFileObject)
  97. if e != nil {
  98. fsStatus.ModifiedFiles = append(fsStatus.ModifiedFiles, p)
  99. }
  100. return
  101. }
  102. fsStatus.NewFiles = append(fsStatus.NewFiles, p)
  103. return
  104. }
  105. func GetFilesystemDiff(root string) (FilesystemStatus, error) {
  106. var (
  107. fsStatus FilesystemStatus = FilesystemStatus{}
  108. rootStat os.FileInfo
  109. picksBucket *bolt.Bucket
  110. indexBucket *bolt.Bucket
  111. bar *mpb.Bar
  112. fsCount int
  113. c goccm.ConcurrencyManager
  114. e error
  115. )
  116. rootStat, e = os.Stat(root)
  117. if e != nil {
  118. return fsStatus, e
  119. }
  120. if rootStat.IsDir() && root[len(root)-1:] != "/" {
  121. root = root + "/"
  122. }
  123. fsCount, e = GetFilesystemLength(root)
  124. if e != nil {
  125. return fsStatus, e
  126. }
  127. bar = ProgressBar.InitBar("Scanning...", fsCount)
  128. e = Database.FsDB.View(func(tx *bolt.Tx) error {
  129. picksBucket = tx.Bucket(Variables.FsHashPicksBucket)
  130. indexBucket = tx.Bucket(Variables.FsHashIndexBucket)
  131. filepath.Walk(root, func(p string, i os.FileInfo, _ error) error {
  132. // Ignore path in Variables.PruneRegexPaths
  133. if i.IsDir() && matchAny(p, PruneRegex) {
  134. return filepath.SkipDir
  135. }
  136. // Ignore path in Variables.IgnoreRegexPaths
  137. if matchAny(p, IgnoreRegex) {
  138. return nil
  139. }
  140. if !i.Mode().IsRegular() && (i.Mode()&os.ModeSymlink == 0) {
  141. return nil
  142. }
  143. go fsStatus.parseFile(indexBucket, picksBucket, p, bar, c)
  144. return nil
  145. })
  146. indexBucket.ForEach(func(k, v []byte) error {
  147. _, e = os.Lstat(string(k))
  148. if os.IsNotExist(e) {
  149. fsStatus.MissingFiles = append(fsStatus.MissingFiles, string(k))
  150. }
  151. return nil
  152. })
  153. ProgressBar.CloseBar(bar)
  154. return nil
  155. })
  156. return fsStatus, e
  157. }