package Archive import ( "archive/tar" "compress/gzip" "io" "os" "path/filepath" "strings" ) func Gzip(source, target string) error { var ( reader, writer *os.File archiver *gzip.Writer filename string e error ) reader, e = os.Open(source) if e != nil { return e } //filename = filepath.Base(source) //target = filepath.Join(target, fmt.Sprintf("%s.gz", filename)) writer, e = os.Create(target) if e != nil { return e } defer writer.Close() archiver = gzip.NewWriter(writer) archiver.Name = filename defer archiver.Close() _, e = io.Copy(archiver, reader) return e } func Tar(source, target string) error { var ( tarfile, file *os.File tarball *tar.Writer header *tar.Header e error ) tarfile, e = os.Create(target) if e != nil { return e } defer tarfile.Close() tarball = tar.NewWriter(tarfile) defer tarball.Close() return filepath.Walk(source, func(path string, info os.FileInfo, e error) error { if e != nil { return e } header, e = tar.FileInfoHeader(info, info.Name()) if e != nil { return e } // TODO change "/" to work cross platform header.Name = strings.TrimPrefix(strings.TrimPrefix(path, source), "/") if header.Name == "" { return nil } e = tarball.WriteHeader(header) if e != nil { return e } if info.IsDir() { return nil } file, e = os.Open(path) if e != nil { return e } defer file.Close() _, e = io.Copy(tarball, file) return e }) } func TarGzip(source, target string) error { var ( tarPath string = strings.ReplaceAll(target, ".gz", "") e error ) e = Tar(source, tarPath) if e != nil { return e } e = Gzip(tarPath, target) if e != nil { return e } return os.Remove(tarPath) }