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.

204 lines
3.4 KiB

  1. package Archive
  2. import (
  3. "archive/tar"
  4. "bufio"
  5. "bytes"
  6. "compress/gzip"
  7. "io"
  8. "io/fs"
  9. "os"
  10. "path/filepath"
  11. )
  12. func ExtractArchive(source, target string) error {
  13. var (
  14. inFile *os.File
  15. gzipReader *gzip.Reader
  16. tarReader *tar.Reader
  17. err error
  18. )
  19. inFile, err = os.Open(source)
  20. if err != nil {
  21. return err
  22. }
  23. defer inFile.Close()
  24. gzipReader, err = gzip.NewReader(inFile)
  25. if err != nil {
  26. return err
  27. }
  28. defer gzipReader.Close()
  29. tarReader = tar.NewReader(gzipReader)
  30. return extractFromArchive(tarReader, target)
  31. }
  32. func extractFromArchive(tarReader *tar.Reader, target string) error {
  33. var (
  34. header *tar.Header
  35. info fs.FileInfo
  36. file *os.File
  37. path, basePath string
  38. err error
  39. )
  40. for {
  41. header, err = tarReader.Next()
  42. if err == io.EOF {
  43. break
  44. }
  45. if err != nil {
  46. return err
  47. }
  48. path = filepath.Join(target, header.Name)
  49. info = header.FileInfo()
  50. if filepath.Base(info.Name()) == "manifest.yml" {
  51. continue
  52. }
  53. if info.IsDir() {
  54. err = os.MkdirAll(path, info.Mode())
  55. if err != nil {
  56. return err
  57. }
  58. continue
  59. }
  60. basePath, err = filepath.Abs(filepath.Dir(path))
  61. if err != nil {
  62. return err
  63. }
  64. _, err = os.Stat(basePath)
  65. if os.IsNotExist(err) {
  66. err = os.MkdirAll(basePath, info.Mode())
  67. if err != nil {
  68. return err
  69. }
  70. }
  71. file, err = os.OpenFile(path, os.O_CREATE|os.O_RDWR, info.Mode())
  72. if err != nil {
  73. return err
  74. }
  75. _, err = io.Copy(file, tarReader)
  76. if err != nil {
  77. return err
  78. }
  79. file.Close()
  80. }
  81. return nil
  82. }
  83. func ExtractManifestFile(source string) (string, error) {
  84. var (
  85. inFile *os.File
  86. gzipReader *gzip.Reader
  87. tarReader *tar.Reader
  88. err error
  89. )
  90. inFile, err = os.Open(source)
  91. if err != nil {
  92. return "", err
  93. }
  94. defer inFile.Close()
  95. gzipReader, err = gzip.NewReader(inFile)
  96. if err != nil {
  97. return "", err
  98. }
  99. defer gzipReader.Close()
  100. tarReader = tar.NewReader(gzipReader)
  101. return extractManifestFromArchive(tarReader)
  102. }
  103. func extractManifestFromArchive(tarReader *tar.Reader) (string, error) {
  104. var (
  105. header *tar.Header
  106. info fs.FileInfo
  107. manifestWriter *bufio.Writer
  108. manifestBytes bytes.Buffer
  109. err error
  110. )
  111. for {
  112. header, err = tarReader.Next()
  113. if err == io.EOF {
  114. break
  115. }
  116. if err != nil {
  117. return manifestBytes.String(), err
  118. }
  119. info = header.FileInfo()
  120. if filepath.Base(info.Name()) != "manifest.yml" {
  121. continue
  122. }
  123. manifestWriter = bufio.NewWriter(&manifestBytes)
  124. _, err = io.Copy(manifestWriter, tarReader)
  125. if err != nil {
  126. return manifestBytes.String(), err
  127. }
  128. }
  129. return manifestBytes.String(), nil
  130. }
  131. func GetPackageFilePaths(source string) ([]string, error) {
  132. var (
  133. inFile *os.File
  134. gzipReader *gzip.Reader
  135. tarReader *tar.Reader
  136. info os.FileInfo
  137. header *tar.Header
  138. pkgFiles []string
  139. err error
  140. )
  141. inFile, err = os.Open(source)
  142. if err != nil {
  143. return pkgFiles, err
  144. }
  145. defer inFile.Close()
  146. gzipReader, err = gzip.NewReader(inFile)
  147. if err != nil {
  148. return pkgFiles, err
  149. }
  150. defer gzipReader.Close()
  151. tarReader = tar.NewReader(gzipReader)
  152. for {
  153. header, err = tarReader.Next()
  154. if err == io.EOF {
  155. break
  156. }
  157. if err != nil {
  158. return pkgFiles, err
  159. }
  160. info = header.FileInfo()
  161. if filepath.Base(info.Name()) == "manifest.yml" {
  162. continue
  163. }
  164. pkgFiles = append(pkgFiles, header.Name)
  165. }
  166. return pkgFiles, nil
  167. }