Skip to content

Instantly share code, notes, and snippets.

@jovandeginste
Created May 31, 2022 11:51
Show Gist options
  • Save jovandeginste/09103dac4b9dff8577513a119fb2a7d9 to your computer and use it in GitHub Desktop.
Save jovandeginste/09103dac4b9dff8577513a119fb2a7d9 to your computer and use it in GitHub Desktop.
package main
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"path/filepath"
)
func main() {
var files []string
root := "./data/"
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
panic(err)
}
if info.IsDir() {
return nil
}
files = append(files, path)
os.Stderr.WriteString("Adding file: " + path + "\n")
return nil
})
if err != nil {
panic(err)
}
file := os.Stdout
err = createArchive(files, file)
if err != nil {
panic(err)
}
os.Stderr.WriteString("Done!\n")
}
func createArchive(files []string, buf io.Writer) error {
// Create new Writers for gzip and tar
// These writers are chained. Writing to the tar writer will
// write to the gzip writer which in turn will write to
// the "buf" writer
gw := gzip.NewWriter(buf)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
// Iterate over files and add them to the tar archive
for _, file := range files {
err := addToArchive(tw, file)
if err != nil {
return err
}
}
return nil
}
func addToArchive(tw *tar.Writer, filename string) error {
// Open the file which will be written into the archive
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
// Get FileInfo about our file providing file size, mode, etc.
info, err := file.Stat()
if err != nil {
return err
}
// Create a tar Header from the FileInfo data
header, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
// Use full path as name (FileInfoHeader only takes the basename)
// If we don't do this the directory strucuture would
// not be preserved
// https://golang.org/src/archive/tar/common.go?#L626
header.Name = filename
// Write file header to the tar archive
err = tw.WriteHeader(header)
if err != nil {
return err
}
// Copy file content to tar archive
_, err = io.Copy(tw, file)
if err != nil {
return err
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment