import (
"archive/tar"
"fmt"
"io"
"os"
"errors"
)
// ExtractTar extract tar
func ExtractTar(stream io.Reader, name string) error {
tarReader := tar.NewReader(stream)
for true {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("extract tar next failed: %w", err)
}
switch header.Typeflag {
case tar.TypeDir:
if err := os.Mkdir(header.Name, 0750); err != nil {
return fmt.Errorf("extract tar mkdir: %w", err)
}
case tar.TypeReg:
outFile, err := os.Create(name)
if err != nil {
return fmt.Errorf("extract tar create: %w", err)
}
defer outFile.Close()
if _, err := io.Copy(outFile, tarReader); err != nil {
return fmt.Errorf("extract tar copy failed: %w", err)
}
default:
return errors.New(fmt.Sprintf("extract tar: unknown type: %v in %s", header.Typeflag, header.Name))
}
}
return nil
}