// Tar takes a source and variable writers and walks 'source' writing each file
// found to the tar writer
Tar takes a source and variable writers and walks 'source' writing each file
found to the tar writer
// Tar takes a source and variable writers and walks ' source ' writing each file // found to the tar writer
func Tar(src string, w io.Writer) error {
	if _, err := os.Stat(src); err != nil {
		return fmt.Errorf("unable to tar files: %w", err)
	}
	gzw := gzip.NewWriter(w)
	defer func(gzw *gzip.Writer) {
		if err := gzw.Close(); err != nil {
			logrus.Errorf("Error closing gzip writer: %v", err)
		}
	}(gzw)
	tw := tar.NewWriter(gzw)
	defer func(tw *tar.Writer) {
		if err := tw.Close(); err != nil {
			logrus.Errorf("Error closing tar writer: %v", err)
		}
	}(tw)
	if err := filepath.Walk(src, func(file string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !fi.Mode().IsRegular() {
			return nil
		}
		header, err := tar.FileInfoHeader(fi, fi.Name())
		if err != nil {
			return fmt.Errorf("creating tar file header: %w", err)
		}
		header.Name = strings.TrimPrefix(strings.Replace(file, src, "", -1), string(filepath.Separator))
		if err := tw.WriteHeader(header); err != nil {
			return fmt.Errorf("writing tar heeader: %w", err)
		}
		f, err := os.Open(file)
		if err != nil {
			return fmt.Errorf("opening file %s: %w", file, err)
		}
		if _, err := io.Copy(tw, f); err != nil {
			return fmt.Errorf("copying file content: %w", err)
		}
		if err = f.Close(); err != nil {
			return fmt.Errorf("closing file: %w", err)
		}
		return nil
	}); err != nil {
		return fmt.Errorf("walking path %s: %w", src, err)
	}
	return nil
}
func Tar ( src string , w io . Writer ) error { if _ , err := os . Stat ( src ) ; err != nil { return fmt . Errorf ( " " , err ) } gzw := gzip . NewWriter ( w ) defer func ( gzw * gzip . Writer ) { if err := gzw . Close ( ) ; err != nil { logrus . Errorf ( " " , err ) } } ( gzw ) tw := tar . NewWriter ( gzw ) defer func ( tw * tar . Writer ) { if err := tw . Close ( ) ; err != nil { logrus . Errorf ( " " , err ) } } ( tw ) if err := filepath . Walk ( src , func ( file string , fi os . FileInfo , err error ) error { if err != nil { return err } if ! fi . Mode ( ) . IsRegular ( ) { return nil } header , err := tar . FileInfoHeader ( fi , fi . Name ( ) ) if err != nil { return fmt . Errorf ( " " , err ) } header . Name = strings . TrimPrefix ( strings . Replace ( file , src , " " , - 1 ) , string ( filepath . Separator ) ) if err := tw . WriteHeader ( header ) ; err != nil { return fmt . Errorf ( " " , err ) } f , err := os . Open ( file ) if err != nil { return fmt . Errorf ( " " , file , err ) } if _ , err := io . Copy ( tw , f ) ; err != nil { return fmt . Errorf ( " " , err ) } if err = f . Close ( ) ; err != nil { return fmt . Errorf ( " " , err ) } return nil } ) ; err != nil { return fmt . Errorf ( " " , src , err ) } return nil }
Tar takes a source and variable writers and walks 'source' writing each file
found to the tar writer
Tar takes a source and variable writers and walks ' source ' writing each file found to the tar writer
// ensure the src actually exists before trying to tar it // walk path // return on any error // return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update) // create a new dir/file header // update the name to correctly reflect the desired destination when untaring // write the header // open files for taring // copy file data into tar writer // manually close here after each file operation; defering would cause each file close // to wait until all operations have completed.