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
2.9 KiB

3 years ago
  1. package Filesystem
  2. import (
  3. "bytes"
  4. "encoding/gob"
  5. "encoding/hex"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "os"
  10. "path/filepath"
  11. )
  12. var (
  13. // TODO: Where do I put this
  14. Data string
  15. )
  16. type Package struct {
  17. Name string
  18. Version string
  19. }
  20. type FileObject struct {
  21. FileMode os.FileMode
  22. Size int64
  23. Package Package
  24. Ref string
  25. Sha1 []byte
  26. }
  27. type ByName []Package
  28. func (f FileObject) IsLink() bool {
  29. return f.FileMode&os.ModeSymlink != 0
  30. }
  31. func (f FileObject) objFile() string {
  32. return filepath.Join(f.objDir(), hex.EncodeToString(f.Sha1))
  33. }
  34. func (f FileObject) objDir() string {
  35. return filepath.Join(Data, hex.EncodeToString(f.Sha1[:2]))
  36. }
  37. func (f FileObject) Reset(dst string) error {
  38. var e error
  39. if f.IsLink() {
  40. _, e = os.Lstat(dst)
  41. if !os.IsNotExist(e) {
  42. e = os.Remove(dst)
  43. if e != nil {
  44. return e
  45. }
  46. }
  47. e = os.Symlink(f.Ref, dst)
  48. if e != nil {
  49. return e
  50. }
  51. return nil
  52. }
  53. f.cp(f.objFile(), dst)
  54. e = os.Chmod(dst, f.FileMode)
  55. if e != nil {
  56. return e
  57. }
  58. return nil
  59. }
  60. func (f FileObject) Stov(src string) error {
  61. var e error
  62. if f.IsLink() {
  63. return nil
  64. }
  65. e = os.MkdirAll(f.objDir(), 0744)
  66. if e != nil {
  67. return e
  68. }
  69. f.cp(src, f.objFile())
  70. return nil
  71. }
  72. func (f FileObject) cp(src string, dst string) error {
  73. var (
  74. srcFile, dstFile *os.File
  75. e error
  76. )
  77. fmt.Println("cp ", src, dst)
  78. srcFile, e = os.Open(src)
  79. if e != nil {
  80. return e
  81. }
  82. defer srcFile.Close()
  83. dstFile, e = os.Create(dst)
  84. if e != nil {
  85. return e
  86. }
  87. defer dstFile.Close()
  88. _, e = io.Copy(dstFile, srcFile)
  89. if e != nil {
  90. return e
  91. }
  92. return dstFile.Sync()
  93. }
  94. func (f FileObject) IsDifferent(fn FileObject) error {
  95. if f.FileMode != fn.FileMode {
  96. return errors.New("Mode does not match")
  97. }
  98. if f.IsLink() {
  99. if f.Ref != fn.Ref {
  100. return errors.New("Ref does not match")
  101. }
  102. return nil
  103. }
  104. if f.Size != fn.Size {
  105. return errors.New("Size does not match")
  106. }
  107. if bytes.Compare(f.Sha1, fn.Sha1) != 0 {
  108. return errors.New("Sha1 does not match")
  109. }
  110. return nil
  111. }
  112. func CreateFileObject(f string) (FileObject, error) {
  113. var (
  114. fo FileObject
  115. fi os.FileInfo
  116. file *os.File
  117. e error
  118. )
  119. fi, e = os.Lstat(f)
  120. if e != nil {
  121. return fo, e
  122. }
  123. fo = FileObject{
  124. FileMode: fi.Mode(),
  125. Size: fi.Size(),
  126. }
  127. if fo.IsLink() {
  128. fo.Ref, e = os.Readlink(f)
  129. if e != nil {
  130. return fo, e
  131. }
  132. return fo, nil
  133. }
  134. file, e = os.Open(f)
  135. if e != nil {
  136. return fo, e
  137. }
  138. defer file.Close()
  139. io.Copy(sha1Hash, file)
  140. fo.Sha1 = sha1Hash.Sum(nil)
  141. return fo, nil
  142. }
  143. func (f FileObject) ToBytes() ([]byte, error) {
  144. var (
  145. encoder *gob.Encoder
  146. buf bytes.Buffer
  147. e error
  148. )
  149. encoder = gob.NewEncoder(&buf)
  150. e = encoder.Encode(f)
  151. return buf.Bytes(), e
  152. }
  153. func FromBytes(v []byte) (FileObject, error) {
  154. var (
  155. buf *bytes.Buffer
  156. decoder *gob.Decoder
  157. fo FileObject
  158. e error
  159. )
  160. buf = bytes.NewBuffer(v)
  161. decoder = gob.NewDecoder(buf)
  162. e = decoder.Decode(&fo)
  163. if e != nil {
  164. return fo, e
  165. }
  166. return fo, nil
  167. }