From eb0c01dfa8bfbd3bc4bb09a5aca88437fff0d439 Mon Sep 17 00:00:00 2001 From: Christoph Witzko <github@christophwitzko.com> Date: Sun, 12 Jun 2022 17:39:52 +0200 Subject: [PATCH] feat: automatically detect and extract tar files --- pkg/plugin/discovery/download.go | 63 ++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/pkg/plugin/discovery/download.go b/pkg/plugin/discovery/download.go index ec317e3..062551a 100644 --- a/pkg/plugin/discovery/download.go +++ b/pkg/plugin/discovery/download.go @@ -1,10 +1,16 @@ package discovery import ( + "archive/tar" + "compress/gzip" "crypto/sha256" "encoding/hex" + "fmt" + "io" "os" "path" + "regexp" + "strings" "time" "github.com/cavaliergopher/grab/v3" @@ -44,9 +50,49 @@ func showDownloadProgressBar(name string, res *grab.Response) { <-done } +func extractFileFromTarGz(name, inputFile, outputFile string) error { + compressedFile, err := os.Open(inputFile) + if err != nil { + return err + } + defer compressedFile.Close() + + decompressedFile, err := gzip.NewReader(compressedFile) + if err != nil { + return err + } + defer decompressedFile.Close() + + tarReader := tar.NewReader(decompressedFile) + for { + header, err := tarReader.Next() + if err == io.EOF { + return fmt.Errorf("could not extract file") + } + if err != nil { + return err + } + if header.Typeflag == tar.TypeReg && strings.HasPrefix(header.Name, name) { + outFile, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY, 0755) + if err != nil { + return err + } + _, err = io.Copy(outFile, tarReader) + outFile.Close() + if err != nil { + return err + } + return nil + } + } +} + +var tgzRegexp = regexp.MustCompile(`^(.*)\.(tgz|tar\.gz)$`) + func downloadPlugin(pluginInfo *plugin.PluginInfo, downloadInfo *resolver.PluginDownloadInfo, showProgress bool) (string, error) { - targetPath := path.Join(pluginInfo.PluginPath, downloadInfo.Version, downloadInfo.FileName) - req, err := grab.NewRequest(targetPath, downloadInfo.URL) + versionDir := path.Join(pluginInfo.PluginPath, downloadInfo.Version) + targetFile := path.Join(versionDir, downloadInfo.FileName) + req, err := grab.NewRequest(targetFile, downloadInfo.URL) if err != nil { return "", err } @@ -65,8 +111,17 @@ func downloadPlugin(pluginInfo *plugin.PluginInfo, downloadInfo *resolver.Plugin if err := res.Err(); err != nil { return "", err } - if err := os.Chmod(res.Filename, 0755); err != nil { + + tgzMatch := tgzRegexp.FindStringSubmatch(downloadInfo.FileName) + if len(tgzMatch) > 2 { + outFile := path.Join(versionDir, tgzMatch[1]) + if err = extractFileFromTarGz(pluginInfo.Name, targetFile, outFile); err != nil { + return "", err + } + targetFile = outFile + } + if err := os.Chmod(targetFile, 0755); err != nil { return "", err } - return res.Filename, nil + return targetFile, nil } -- GitLab