func (i *Tar) Extract(r io.Reader, path string, depth int) error {

	depth--

	gz, err := gzip.NewReader(r)
	if err != nil {
		return err
	}
	defer gz.Close()

	tr := tar.NewReader(gz)

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

		if err == io.EOF {
			break // End of archive
		}
		if err != nil {
			return err
		}

		switch hdr.Typeflag {
		case tar.TypeSymlink:
		case tar.TypeReg:
			switch filepath.Ext(hdr.Name) {
			case ".tar":
				if depth > 0 {
					if err = i.Extract(tr, path, depth); err != nil {
						return err
					}
				}
			default:
				// fmt.Println(hdr.Name)
				var name string
				if hdr.Typeflag == tar.TypeSymlink {
					name = hdr.Linkname
				} else {
					name = hdr.Name
				}
				if strings.Contains(path, name) {
					// fmt.Println(name)
					// fmt.Println(filepath.Dir(name))
					// os.MkdirAll(filepath.Dir(name), os.ModePerm)
					f, err := os.OpenFile(filepath.Base(name), os.O_CREATE|os.O_RDWR, 0644)
					// f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, os.FileMode(hdr.Mode)) // TODO
					if err != nil {
						return err
					}
					if _, err := io.Copy(f, tr); err != nil {
						return err
					}
					f.Close()
					return nil
				}
			}
		}
	}

	return nil
	// return fmt.Errorf("did not find path: %s", path)
}
// Extract extracts a path from a tar.gz and can handle a set depth of nested tar.gz(s)
Extract extracts a path from a tar.gz and can handle a set depth of nested tar.gz(s)
// Extract extracts a path from a tar . gz and can handle a set depth of nested tar . gz ( s )
func (i *Tar) Extract(r io.Reader, path string, depth int) error {
	depth--
	gz, err := gzip.NewReader(r)
	if err != nil {
		return err
	}
	defer gz.Close()
	tr := tar.NewReader(gz)
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break 
		}
		if err != nil {
			return err
		}
		switch hdr.Typeflag {
		case tar.TypeSymlink:
		case tar.TypeReg:
			switch filepath.Ext(hdr.Name) {
			case ".tar":
				if depth > 0 {
					if err = i.Extract(tr, path, depth); err != nil {
						return err
					}
				}
			default:
				var name string
				if hdr.Typeflag == tar.TypeSymlink {
					name = hdr.Linkname
				} else {
					name = hdr.Name
				}
				if strings.Contains(path, name) {
					f, err := os.OpenFile(filepath.Base(name), os.O_CREATE|os.O_RDWR, 0644)
					if err != nil {
						return err
					}
					if _, err := io.Copy(f, tr); err != nil {
						return err
					}
					f.Close()
					return nil
				}
			}
		}
	}
	return nil
}
func ( i * Tar ) Extract ( r io . Reader , path string , depth int ) error { depth -- gz , err := gzip . NewReader ( r ) if err != nil { return err } defer gz . Close ( ) tr := tar . NewReader ( gz ) for { hdr , err := tr . Next ( ) if err == io . EOF { break } if err != nil { return err } switch hdr . Typeflag { case tar . TypeSymlink : case tar . TypeReg : switch filepath . Ext ( hdr . Name ) { case " " : if depth > 0 { if err = i . Extract ( tr , path , depth ) ; err != nil { return err } } default : var name string if hdr . Typeflag == tar . TypeSymlink { name = hdr . Linkname } else { name = hdr . Name } if strings . Contains ( path , name ) { f , err := os . OpenFile ( filepath . Base ( name ) , os . O_CREATE | os . O_RDWR , 0644 ) if err != nil { return err } if _ , err := io . Copy ( f , tr ) ; err != nil { return err } f . Close ( ) return nil } } } } return nil }
Extract extracts a path from a tar.gz and can handle a set depth of nested tar.gz(s)
Extract extracts a path from a tar . gz and can handle a set depth of nested tar . gz ( s )
// End of archive // fmt.Println(hdr.Name) // fmt.Println(name) // fmt.Println(filepath.Dir(name)) // os.MkdirAll(filepath.Dir(name), os.ModePerm) // f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, os.FileMode(hdr.Mode)) // TODO // return fmt.Errorf("did not find path: %s", path)