From 09ef963ca3a2776b4de20ab90977b4cc29a98ee1 Mon Sep 17 00:00:00 2001 From: Louis Seubert Date: Sun, 20 Oct 2024 14:55:16 +0200 Subject: [PATCH] wip: needs tests --- cache.go | 6 +-- cache/tar.go | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/main.go | 18 ++++++++ 3 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 cache/tar.go diff --git a/cache.go b/cache.go index 6fca1f5..f3a17da 100644 --- a/cache.go +++ b/cache.go @@ -3,7 +3,7 @@ package sdk import "git.geekeey.de/actions/sdk/cache" func (c *Action) Cache() *cache.Client { - c.env("ACTIONS_CACHE_URL") - c.env("ACTIONS_RUNTIME_TOKEN") - return cache.New("", "") + token := c.env("ACTIONS_RUNTIME_TOKEN") + url := c.env("ACTIONS_CACHE_URL") + return cache.New(token, url) } diff --git a/cache/tar.go b/cache/tar.go new file mode 100644 index 0000000..8899812 --- /dev/null +++ b/cache/tar.go @@ -0,0 +1,115 @@ +package cache + +import ( + "archive/tar" + "compress/gzip" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +// Tar takes a source and variable writers and walks 'source' writing each file +// found to the tar writer; the purpose for accepting multiple writers is to allow +// for multiple outputs (for example a file, or md5 hash) +func Tar(src string, writers ...io.Writer) error { + if _, err := os.Stat(src); err != nil { + return fmt.Errorf("unable to tar files - %v", err.Error()) + } + + mw := io.MultiWriter(writers...) + + gzw := gzip.NewWriter(mw) + defer gzw.Close() + + tw := tar.NewWriter(gzw) + defer tw.Close() + + // walk path + return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + if !fi.Mode().IsRegular() { + return nil + } + + header, err := tar.FileInfoHeader(fi, fi.Name()) + if err != nil { + return err + } + + // update the name to correctly reflect the desired destination when untaring + header.Name = strings.TrimPrefix(strings.Replace(file, src, "", -1), string(filepath.Separator)) + + if err := tw.WriteHeader(header); err != nil { + return err + } + + f, err := os.Open(file) + if err != nil { + return err + } + + if _, err := io.Copy(tw, f); err != nil { + f.Close() + return err + } + + f.Close() + + return nil + }) +} + +// Untar takes a destination path and a reader; a tar reader loops over the tarfile +// creating the file structure at 'dst' along the way, and writing any files +func Untar(dst string, r io.Reader) error { + + gzr, err := gzip.NewReader(r) + if err != nil { + return err + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + + for { + header, err := tr.Next() + + if errors.Is(err, io.EOF) || header == nil { + break + } + if err != nil { + return err + } + + target := filepath.Join(dst, header.Name) + + switch header.Typeflag { + + // if its a dir and it doesn't exist create it + case tar.TypeDir: + if _, err := os.Stat(target); err != nil { + if err := os.MkdirAll(target, 0755); err != nil { + return err + } + } + + // if it's a file create it + case tar.TypeReg: + f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) + if err != nil { + return err + } + if _, err := io.Copy(f, tr); err != nil { + return err + } + f.Close() + } + } + return nil +} diff --git a/cmd/main.go b/cmd/main.go index ebb54e0..69ceabc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,11 +1,29 @@ package main import ( + "context" + "os" + "git.geekeey.de/actions/sdk" + "git.geekeey.de/actions/sdk/cache" ) func main() { a := sdk.New() a.AddMask("hello") a.WithFieldsSlice("foo=bar", "biz=baz").Debugf("hello world") + blob, err := a.Cache().Load(context.Background(), "example") + if err != nil { + panic(err) + } + cache.Tar("./foo") + f, err := os.Open("") + if err != nil { + panic(err) + } + a.Cache().Save(context.Background(), "", cache.NewFileBlob(f)) + entry := blob.Download(context.Background()) + if entry == nil { + return + } }