93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
|
package tar
|
||
|
|
||
|
import (
|
||
|
"archive/tar"
|
||
|
"bytes"
|
||
|
"compress/gzip"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func Compress(source, dest string) error {
|
||
|
// tar + gzip
|
||
|
var buf bytes.Buffer
|
||
|
_ = compress(source, &buf)
|
||
|
|
||
|
// write the .tar.gzip
|
||
|
fileToWrite, err := os.OpenFile(dest, os.O_CREATE|os.O_RDWR, 0666)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
_, err = io.Copy(fileToWrite, &buf)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func compress(src string, buf io.Writer) error {
|
||
|
// tar > gzip > buf
|
||
|
zr := gzip.NewWriter(buf)
|
||
|
tw := tar.NewWriter(zr)
|
||
|
|
||
|
// walk through every file in the folder
|
||
|
filepath.Walk(src, func(file string, fi os.FileInfo, err error) error {
|
||
|
|
||
|
// generate tar header
|
||
|
header, err := tar.FileInfoHeader(fi, file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// must provide real name
|
||
|
// (see https://golang.org/src/archive/tar/common.go?#L626)
|
||
|
|
||
|
srcWithSlash := src
|
||
|
if !strings.HasSuffix(src, string(filepath.Separator)) {
|
||
|
srcWithSlash = src + string(filepath.Separator)
|
||
|
}
|
||
|
header.Name = strings.ReplaceAll(file, srcWithSlash, "")
|
||
|
if header.Name == src || len(strings.TrimSpace(header.Name)) == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// @todo This is a quick hack to speed up whole repo uploads
|
||
|
// https://github.com/micro/micro/pull/956
|
||
|
if !fi.IsDir() && !strings.HasSuffix(header.Name, ".go") &&
|
||
|
!strings.HasSuffix(header.Name, ".mod") &&
|
||
|
!strings.HasSuffix(header.Name, ".sum") {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// write header
|
||
|
if err := tw.WriteHeader(header); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if fi.IsDir() {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// if not a dir, write file content
|
||
|
|
||
|
data, err := os.Open(file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if _, err := io.Copy(tw, data); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
})
|
||
|
|
||
|
// produce tar
|
||
|
if err := tw.Close(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
// produce gzip
|
||
|
if err := zr.Close(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
//
|
||
|
return nil
|
||
|
}
|