77 lines
1.5 KiB
Go
77 lines
1.5 KiB
Go
package targz
|
|
|
|
import (
|
|
"archive/tar"
|
|
"compress/gzip"
|
|
"io"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Package packages the directory src into dst.
|
|
// onCopy, when not nil, is called for each file being copied into the archive.
|
|
func Package(dst, src string, onCopy func(rel string, src string)) (count int64, err error) {
|
|
// create the target archive
|
|
archive, err := os.Create(dst)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer archive.Close()
|
|
|
|
// create a gzip writer
|
|
zipHandle := gzip.NewWriter(archive)
|
|
defer zipHandle.Close()
|
|
|
|
// create a tar writer
|
|
tarHandle := tar.NewWriter(zipHandle)
|
|
defer tarHandle.Close()
|
|
|
|
// and walk through it!
|
|
err = filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// determine the relative path
|
|
var relpath string
|
|
relpath, err = filepath.Rel(src, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if onCopy != nil {
|
|
onCopy(relpath, path)
|
|
}
|
|
|
|
// create a file info header!
|
|
tInfo, err := tar.FileInfoHeader(info, relpath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tInfo.Name = filepath.ToSlash(relpath)
|
|
|
|
// write it!
|
|
if err := tarHandle.WriteHeader(tInfo); err != nil {
|
|
return err
|
|
}
|
|
|
|
// a directory => no more writing required
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
// open the file
|
|
handle, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer handle.Close()
|
|
|
|
// and copy it into the archive
|
|
ccount, err := io.Copy(tarHandle, handle)
|
|
count += ccount
|
|
return err
|
|
})
|
|
return
|
|
}
|