| package utils |
|
|
| import ( |
| "fmt" |
| "os" |
|
|
| "github.com/mholt/archiver/v3" |
| ) |
|
|
| func IsArchive(file string) bool { |
| uaIface, err := archiver.ByExtension(file) |
| if err != nil { |
| return false |
| } |
|
|
| _, ok := uaIface.(archiver.Unarchiver) |
| return ok |
| } |
|
|
| func ExtractArchive(archive, dst string) error { |
| uaIface, err := archiver.ByExtension(archive) |
| if err != nil { |
| return err |
| } |
|
|
| un, ok := uaIface.(archiver.Unarchiver) |
| if !ok { |
| return fmt.Errorf("format specified by source filename is not an archive format: %s (%T)", archive, uaIface) |
| } |
|
|
| mytar := &archiver.Tar{ |
| OverwriteExisting: true, |
| MkdirAll: true, |
| ImplicitTopLevelFolder: false, |
| ContinueOnError: true, |
| } |
|
|
| switch v := uaIface.(type) { |
| case *archiver.Tar: |
| uaIface = mytar |
| case *archiver.TarBrotli: |
| v.Tar = mytar |
| case *archiver.TarBz2: |
| v.Tar = mytar |
| case *archiver.TarGz: |
| v.Tar = mytar |
| case *archiver.TarLz4: |
| v.Tar = mytar |
| case *archiver.TarSz: |
| v.Tar = mytar |
| case *archiver.TarXz: |
| v.Tar = mytar |
| case *archiver.TarZstd: |
| v.Tar = mytar |
| } |
|
|
| err = archiver.Walk(archive, func(f archiver.File) error { |
| if f.FileInfo.Mode()&os.ModeSymlink != 0 { |
| return fmt.Errorf("archive contains a symlink") |
| } |
| return nil |
| }) |
|
|
| if err != nil { |
| return err |
| } |
|
|
| return un.Unarchive(archive, dst) |
| } |
|
|