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.

239 lines
4.6 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
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. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "runtime"
  8. "sync"
  9. "github.com/vbauerster/mpb"
  10. bolt "go.etcd.io/bbolt"
  11. "golang.org/x/sync/semaphore"
  12. "PackageManager/Client/Database"
  13. "PackageManager/Client/ProgressBar"
  14. "PackageManager/Color"
  15. "PackageManager/Variables"
  16. )
  17. var (
  18. fsStatusWG sync.WaitGroup
  19. FsWalkWG sync.WaitGroup
  20. )
  21. type FilesystemStatus struct {
  22. NewFiles []string
  23. PickedFiles []string
  24. ModifiedFiles []string
  25. MissingFiles []string
  26. }
  27. func ShowFilesystemDiff(root string) error {
  28. var (
  29. fsStatus FilesystemStatus
  30. picksBucket *bolt.Bucket
  31. pickedFiles []string
  32. err error
  33. )
  34. fsStatus, err = GetFilesystemDiff(root)
  35. if err != nil {
  36. return err
  37. }
  38. err = Database.FsDB.View(func(tx *bolt.Tx) error {
  39. picksBucket = tx.Bucket(Variables.FsHashPicksBucket)
  40. return picksBucket.ForEach(func(key, _ []byte) error {
  41. pickedFiles = append(pickedFiles, string(key))
  42. return nil
  43. })
  44. })
  45. if err != nil {
  46. return err
  47. }
  48. fmt.Println("New files:")
  49. PrintFilesOrLength(fsStatus.NewFiles, Color.Green)
  50. fmt.Println("Added files:")
  51. PrintFilesOrLength(pickedFiles, Color.Green)
  52. fmt.Println("Modified files:")
  53. PrintFilesOrLength(fsStatus.ModifiedFiles, Color.Warning)
  54. fmt.Println("Deleted files:")
  55. PrintFilesOrLength(fsStatus.MissingFiles, Color.Fatal)
  56. return nil
  57. }
  58. func GetFilesystemLength(root string) (int, error) {
  59. var (
  60. rootStat os.FileInfo
  61. fsCount int = 0
  62. err error
  63. )
  64. rootStat, err = os.Stat(root)
  65. if err != nil {
  66. return fsCount, err
  67. }
  68. if rootStat.IsDir() && root[len(root)-1:] != "/" {
  69. root = root + "/"
  70. }
  71. err = filepath.Walk(root, func(p string, i os.FileInfo, _ error) error {
  72. // Ignore path in Variables.PruneRegexPaths
  73. if i.IsDir() && matchAny(p, PruneRegex) {
  74. return filepath.SkipDir
  75. }
  76. // Ignore path in Variables.IgnoreRegexPaths
  77. if matchAny(p, IgnoreRegex) {
  78. return nil
  79. }
  80. if !i.Mode().IsRegular() && (i.Mode()&os.ModeSymlink == 0) {
  81. return nil
  82. }
  83. fsCount++
  84. return nil
  85. })
  86. return fsCount, err
  87. }
  88. func (fsStatus *FilesystemStatus) parseFile(indexBucket, picksBucket *bolt.Bucket, p string, bar *mpb.Bar) {
  89. var (
  90. newFileObject FileObject
  91. knownFileObject FileObject
  92. pick, known []byte
  93. err error
  94. )
  95. defer func() {
  96. bar.Increment()
  97. }()
  98. pick = picksBucket.Get([]byte(p))
  99. known = indexBucket.Get([]byte(p))
  100. if pick != nil {
  101. fsStatusWG.Wait()
  102. fsStatusWG.Add(1)
  103. fsStatus.PickedFiles = append(fsStatus.PickedFiles, p)
  104. fsStatusWG.Done()
  105. return
  106. }
  107. if known != nil {
  108. newFileObject, err = CreateFileObject(p)
  109. if err != nil {
  110. return
  111. }
  112. knownFileObject, err = FromBytes(known)
  113. if err != nil {
  114. return
  115. }
  116. err = newFileObject.IsDifferent(knownFileObject)
  117. if err != nil {
  118. fsStatusWG.Wait()
  119. fsStatusWG.Add(1)
  120. fsStatus.ModifiedFiles = append(fsStatus.ModifiedFiles, p)
  121. fsStatusWG.Done()
  122. }
  123. return
  124. }
  125. fsStatusWG.Wait()
  126. fsStatusWG.Add(1)
  127. fsStatus.NewFiles = append(fsStatus.NewFiles, p)
  128. fsStatusWG.Done()
  129. }
  130. func GetFilesystemDiff(root string) (FilesystemStatus, error) {
  131. var (
  132. fsStatus FilesystemStatus = FilesystemStatus{}
  133. sem *semaphore.Weighted
  134. picksBucket *bolt.Bucket
  135. indexBucket *bolt.Bucket
  136. rootStat os.FileInfo
  137. bar *mpb.Bar
  138. fsCount int
  139. poolSize int
  140. err error
  141. )
  142. poolSize = runtime.NumCPU()
  143. sem = semaphore.NewWeighted(int64(poolSize))
  144. rootStat, err = os.Stat(root)
  145. if err != nil {
  146. return fsStatus, err
  147. }
  148. if rootStat.IsDir() && root[len(root)-1:] != "/" {
  149. root = root + "/"
  150. }
  151. fsCount, err = GetFilesystemLength(root)
  152. if err != nil {
  153. return fsStatus, err
  154. }
  155. bar = ProgressBar.InitBar("Scanning...", fsCount)
  156. err = Database.FsDB.View(func(tx *bolt.Tx) error {
  157. picksBucket = tx.Bucket(Variables.FsHashPicksBucket)
  158. indexBucket = tx.Bucket(Variables.FsHashIndexBucket)
  159. filepath.Walk(root, func(p string, i os.FileInfo, _ error) error {
  160. // Ignore path in Variables.PruneRegexPaths
  161. if i.IsDir() && matchAny(p, PruneRegex) {
  162. return filepath.SkipDir
  163. }
  164. // Ignore path in Variables.IgnoreRegexPaths
  165. if matchAny(p, IgnoreRegex) {
  166. return nil
  167. }
  168. if !i.Mode().IsRegular() && (i.Mode()&os.ModeSymlink == 0) {
  169. return nil
  170. }
  171. FsWalkWG.Add(1)
  172. sem.Acquire(context.Background(), 1)
  173. go func() {
  174. fsStatus.parseFile(indexBucket, picksBucket, p, bar)
  175. sem.Release(1)
  176. FsWalkWG.Done()
  177. }()
  178. FsWalkWG.Wait()
  179. return nil
  180. })
  181. indexBucket.ForEach(func(k, v []byte) error {
  182. _, err = os.Lstat(string(k))
  183. if os.IsNotExist(err) {
  184. fsStatus.MissingFiles = append(fsStatus.MissingFiles, string(k))
  185. }
  186. return nil
  187. })
  188. return nil
  189. })
  190. return fsStatus, err
  191. }