Skip to content

Commit

Permalink
add untar function to polly
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljguarino committed Sep 18, 2023
1 parent 4dbf023 commit 6b3afba
Showing 1 changed file with 92 additions and 0 deletions.
92 changes: 92 additions & 0 deletions fs/tar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package fs

import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"os"
"path/filepath"
)

func Untar(dst string, r io.Reader) error {
gzr, err := gzip.NewReader(r)
if err != nil {
return err
}
defer gzr.Close()

tr := tar.NewReader(gzr)
madeDir := map[string]bool{}

for {
header, err := tr.Next()

switch {

// if no more files are found return
case err == io.EOF:
return nil

// return any other error
case err != nil:
return err

// if the header is nil, just skip it (not sure how this happens)
case header == nil:
continue
}

// the target location where the dir/file should be created
target := filepath.Join(dst, header.Name)
// the following switch could also be done using fi.Mode(), not sure if there
// a benefit of using one vs. the other.
// fi := header.FileInfo()

// check the file type
switch header.Typeflag {

// if its a dir and it doesn't exist create it
case tar.TypeDir:
if err := makeDir(target, madeDir); err != nil {
return err
}

// if it's a file create it
case tar.TypeReg:
if err := makeDir(filepath.Dir(target), madeDir); err != nil {
return err
}

f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
if err != nil {
fmt.Println("could not open file")
return err
}

// copy over contents
if _, err := io.Copy(f, tr); err != nil {
return err
}

// manually close here after each file operation; defering would cause each file close
// to wait until all operations have completed.
f.Close()
}
}
}

func makeDir(target string, made map[string]bool) error {
if made[target] {
return nil
}

if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, 0755); err != nil {
return err
}
}

made[target] = true
return nil
}

0 comments on commit 6b3afba

Please sign in to comment.