// Copyright 2024 Matthew Rich . All rights reserved. package target import ( _ "context" _ "encoding/json" _ "fmt" _ "gopkg.in/yaml.v3" "net/url" "path/filepath" "decl/internal/resource" "compress/gzip" "archive/tar" _ "regexp" "os" "io" "log" "log/slog" ) type Tar struct { Path string `yaml:"path" json:"path"` Gzip bool `yaml:"gzip" json:"gzip"` } func NewTar() *Tar { return &Tar{ Gzip: false } } func init() { TargetTypes.Register([]string{"tar"}, func(u *url.URL) DocTarget { t := NewTar() t.Path,_ = filepath.Abs(filepath.Join(u.Hostname(), u.Path)) return t }) TargetTypes.Register([]string{"tar.gz", "tgz"}, func(u *url.URL) DocTarget { t := NewTar() if u.Scheme == "file" { fileAbsolutePath, _ := filepath.Abs(filepath.Join(u.Hostname(), u.RequestURI())) t.Path = fileAbsolutePath } else { t.Path = filepath.Join(u.Hostname(), u.Path) } t.Gzip = true return t }) } func (t *Tar) Type() string { return "tar" } func (t *Tar) EmitResources(documents []*resource.Document, filter resource.ResourceSelector) error { file, fileErr := os.Create(t.Path) if fileErr != nil { return fileErr } var fileWriter io.WriteCloser if t.Gzip { fileWriter = gzip.NewWriter(file) } else { fileWriter = file } tarWriter := tar.NewWriter(fileWriter) defer func() { tarWriter.Close() fileWriter.Close() file.Close() }() for _,document := range documents { for _,res := range document.Filter(func(d *resource.Declaration) bool { return d.Type == "file" }) { var f *resource.File = res.Attributes.(*resource.File) slog.Info("Tar.EmitResources", "file", f) hdr, fiErr := tar.FileInfoHeader(f.FileInfo(), "") slog.Info("Tar.EmitResources", "header", hdr, "err", fiErr) if err := tarWriter.WriteHeader(hdr); err != nil { log.Fatal(err) } if _, err := tarWriter.Write([]byte(f.Content)); err != nil { log.Fatal(err) } } } return nil }