func Discover(f *os.File) (Extractor, error) {
	typ, err := filetype.MatchReader(f)
	if err != nil {
		return nil, errors.Wrap(err, "failed to match file type")
	}
	// Rewind after filetype matching
	_, err = f.Seek(0, io.SeekStart)
	if err != nil {
		return nil, errors.Wrap(err, "failed to rewind temp file")
	}

	switch typ {
	case matchers.TypeZip:
		return new(zip.Archive), nil

	case matchers.TypeGz:
		gr, err := gzip.NewReader(f)
		if err != nil {
			return nil, errors.Wrap(err, "failed to create gzip reader")
		}
		defer gr.Close()

		t, err := filetype.MatchReader(gr)
		if err != nil {
			return nil, errors.Wrap(err, "failed to detect type inside gzip")
		}

		if t != matchers.TypeTar {
			return nil, errors.Wrap(err, "unsupported archive inside gzip, expected tar.gz")
		}

		return new(targz.Archive), nil
	case matchers.TypeElf: // matchers.TypeMachO
		return new(direct.File), nil
	default:
		return nil, fmt.Errorf("unsupported filetype %v", typ)
	}
}
// Discover determine extractor by source file type
Discover determine extractor by source file type
// Discover determine extractor by source file type
func Discover(f *os.File) (Extractor, error) {
	typ, err := filetype.MatchReader(f)
	if err != nil {
		return nil, errors.Wrap(err, "failed to match file type")
	}
	_, err = f.Seek(0, io.SeekStart)
	if err != nil {
		return nil, errors.Wrap(err, "failed to rewind temp file")
	}
	switch typ {
	case matchers.TypeZip:
		return new(zip.Archive), nil
	case matchers.TypeGz:
		gr, err := gzip.NewReader(f)
		if err != nil {
			return nil, errors.Wrap(err, "failed to create gzip reader")
		}
		defer gr.Close()
		t, err := filetype.MatchReader(gr)
		if err != nil {
			return nil, errors.Wrap(err, "failed to detect type inside gzip")
		}
		if t != matchers.TypeTar {
			return nil, errors.Wrap(err, "unsupported archive inside gzip, expected tar.gz")
		}
		return new(targz.Archive), nil
	case matchers.TypeElf: 
		return new(direct.File), nil
	default:
		return nil, fmt.Errorf("unsupported filetype %v", typ)
	}
}
func Discover ( f * os . File ) ( Extractor , error ) { typ , err := filetype . MatchReader ( f ) if err != nil { return nil , errors . Wrap ( err , " " ) } _ , err = f . Seek ( 0 , io . SeekStart ) if err != nil { return nil , errors . Wrap ( err , " " ) } switch typ { case matchers . TypeZip : return new ( zip . Archive ) , nil case matchers . TypeGz : gr , err := gzip . NewReader ( f ) if err != nil { return nil , errors . Wrap ( err , " " ) } defer gr . Close ( ) t , err := filetype . MatchReader ( gr ) if err != nil { return nil , errors . Wrap ( err , " " ) } if t != matchers . TypeTar { return nil , errors . Wrap ( err , " " ) } return new ( targz . Archive ) , nil case matchers . TypeElf : return new ( direct . File ) , nil default : return nil , fmt . Errorf ( " " , typ ) } }
Discover determine extractor by source file type
Discover determine extractor by source file type
// Rewind after filetype matching // matchers.TypeMachO