Last active
January 28, 2017 01:45
-
-
Save sdomino/53225245f5a8f577c202 to your computer and use it in GitHub Desktop.
Chaining io.Writers in Go: https://medium.com/@skdomino/writing-on-the-train-chaining-io-writers-in-go-1b39e07f71c9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"archive/tar" | |
"compress/gzip" | |
"crypto/md5" | |
"fmt" | |
"io" | |
"os" | |
"path/filepath" | |
"sync" | |
api "github.com/pagodabox/nanobox-api-client" | |
) | |
// | |
var tw *tar.Writer | |
// | |
func main() { | |
// | |
h := md5.New() | |
// | |
pr, pw := io.Pipe() | |
// | |
mw := io.MultiWriter(h, pw) | |
// | |
gzw := gzip.NewWriter(mw) | |
// | |
tw = tar.NewWriter(gzw) | |
// | |
wg := &sync.WaitGroup{} | |
wg.Add(1) | |
// | |
go func() { | |
// defer is LIFO | |
defer pw.Close() | |
defer gzw.Close() | |
defer tw.Close() | |
for _, pf := range release.ProjectFiles { | |
if stat, err := os.Stat(pf); err == nil { | |
// if its a directory, walk the directory taring each file | |
if stat.Mode().IsDir() { | |
if err := filepath.Walk(pf, tarDir); err != nil { | |
fmt.Println("ERROR", err) | |
} | |
// if its a file tar it | |
} else { | |
tarFile(pf) | |
} | |
} | |
} | |
wg.Done() | |
}() | |
obj := &Object{} | |
// upload tarball | |
if err := api.DoRawRequest(obj, "POST", "/server/uploads", pr, nil); err != nil { | |
fmt.Println("ERROR", err) | |
} | |
wg.Wait() | |
defer pr.Close() | |
} | |
// tarDir | |
func tarDir(path string, fi os.FileInfo, err error) error { | |
if fi.Mode().IsDir() { | |
return nil | |
} | |
return tarFile(path) | |
} | |
// tarFile | |
func tarFile(path string) error { | |
// open the file/dir... | |
f, err := os.Open(path) | |
if err != nil { | |
return err | |
} | |
defer f.Close() | |
// stat the file | |
if fi, err := f.Stat(); err == nil { | |
// create header for this file | |
header := &tar.Header{ | |
Name: path, | |
Size: fi.Size(), | |
Mode: int64(fi.Mode()), | |
ModTime: fi.ModTime(), | |
} | |
// write the header to the tarball archive | |
if err := tw.WriteHeader(header); err != nil { | |
return err | |
} | |
// copy the file data to the tarball | |
if _, err := io.Copy(tw, f); err != nil { | |
return err | |
} | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment