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.

151 lines
2.5 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. e error
  18. )
  19. inFile, e = os.Open(source)
  20. if e != nil {
  21. return e
  22. }
  23. defer inFile.Close()
  24. gzipReader, e = gzip.NewReader(inFile)
  25. defer gzipReader.Close()
  26. tarReader = tar.NewReader(gzipReader)
  27. return extractFromArchive(tarReader, target)
  28. }
  29. func extractFromArchive(tarReader *tar.Reader, target string) error {
  30. var (
  31. header *tar.Header
  32. info fs.FileInfo
  33. file *os.File
  34. path, basePath string
  35. e error
  36. )
  37. for {
  38. header, e = tarReader.Next()
  39. if e == io.EOF {
  40. break
  41. }
  42. if e != nil {
  43. return e
  44. }
  45. path = filepath.Join(target, header.Name)
  46. info = header.FileInfo()
  47. if filepath.Base(info.Name()) == "manifest.yml" {
  48. continue
  49. }
  50. if info.IsDir() {
  51. e = os.MkdirAll(path, info.Mode())
  52. if e != nil {
  53. return e
  54. }
  55. continue
  56. }
  57. basePath, e = filepath.Abs(filepath.Dir(path))
  58. if e != nil {
  59. return e
  60. }
  61. _, e = os.Stat(basePath)
  62. if os.IsNotExist(e) {
  63. e = os.MkdirAll(basePath, info.Mode())
  64. if e != nil {
  65. return e
  66. }
  67. }
  68. file, e = os.OpenFile(path, os.O_CREATE|os.O_RDWR, info.Mode())
  69. if e != nil {
  70. return e
  71. }
  72. defer file.Close()
  73. _, e = io.Copy(file, tarReader)
  74. if e != nil {
  75. return e
  76. }
  77. }
  78. return nil
  79. }
  80. func ExtractManifestFile(source string) (string, error) {
  81. var (
  82. inFile *os.File
  83. gzipReader *gzip.Reader
  84. tarReader *tar.Reader
  85. e error
  86. )
  87. inFile, e = os.Open(source)
  88. if e != nil {
  89. return "", e
  90. }
  91. defer inFile.Close()
  92. gzipReader, e = gzip.NewReader(inFile)
  93. defer gzipReader.Close()
  94. tarReader = tar.NewReader(gzipReader)
  95. return extractManifestFromArchive(tarReader)
  96. }
  97. func extractManifestFromArchive(tarReader *tar.Reader) (string, error) {
  98. var (
  99. header *tar.Header
  100. info fs.FileInfo
  101. manifestWriter *bufio.Writer
  102. manifestBytes bytes.Buffer
  103. e error
  104. )
  105. for {
  106. header, e = tarReader.Next()
  107. if e == io.EOF {
  108. break
  109. }
  110. if e != nil {
  111. return manifestBytes.String(), e
  112. }
  113. info = header.FileInfo()
  114. if filepath.Base(info.Name()) != "manifest.yml" {
  115. continue
  116. }
  117. manifestWriter = bufio.NewWriter(&manifestBytes)
  118. _, e = io.Copy(manifestWriter, tarReader)
  119. if e != nil {
  120. return manifestBytes.String(), e
  121. }
  122. }
  123. return manifestBytes.String(), nil
  124. }