package main import ( "archive/tar" "compress/gzip" "io" "os" "path/filepath" "strings" ) // From https://gist.github.com/mimoo/25fc9716e0f1353791f5908f94d6e726 // Modified to strip off top-level when compressing 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 err := filepath.Walk(src, func(file string, fi os.FileInfo, e 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) header.Name = strings.TrimPrefix(filepath.ToSlash(file), src+"/") // write header if err := tw.WriteHeader(header); err != nil { return err } // if not a dir, write file content if !fi.IsDir() { data, err := os.Open(file) if err != nil { return err } if _, err = io.Copy(tw, data); err != nil { return err } if err = data.Close(); err != nil { return err } } return nil }) if err != nil { return err } // produce tar if err := tw.Close(); err != nil { return err } // produce gzip if err := zr.Close(); err != nil { return err } // return nil }