|
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) |
|
} |
|
|