package archive import ( "archive/tar" "compress/gzip" "io" "os" "strings" makeshift "git.towk2.me/towk/makeshift/pkg" ) func Create(filenames []string, buf io.Writer, hooks []makeshift.Hook) error { // Create new Writers for gzip and tar // These writers are chained. Writing to the tar writer will // write to the gzip writer which in turn will write to // the "buf" writer gw := gzip.NewWriter(buf) defer gw.Close() tw := tar.NewWriter(gw) defer tw.Close() // Iterate over files and add them to the tar archive for _, filename := range filenames { err := addToArchive(tw, filename, hooks) if err != nil { return err } } return nil } func Expand(path string) error { return nil } func addToArchive(tw *tar.Writer, filename string, hooks []makeshift.Hook) error { var ( hook makeshift.Hook file *os.File data any err error ) // open file to write to archive file, err = os.Open(filename) if err != nil { return err } defer file.Close() // run pre-hooks to modify the contents of the file // before archiving using plugins for _, hook := range hooks { err = hook.Run() if err != nil { return err } } // get FileInfo for file size, mode, etc. info, err := file.Stat() if err != nil { return err } // skip file if it's a directory if info.IsDir() { return nil } // create a tar Header from the FileInfo data header, err := tar.FileInfoHeader(info, info.Name()) if err != nil { return err } // use full path as name (FileInfoHeader only takes the basename) to // preserve directory structure // see for more info: https://golang.org/src/archive/tar/common.go?#L626 header.Name = filename // Write file header to the tar archive err = tw.WriteHeader(header) if err != nil { return err } // take the contents from the last hook and update files hook = hooks[len(hooks)-1] data, err = hook.Data.Get("out") if err != nil { return err } // copy file content to tar archive _, err = io.Copy(tw, strings.NewReader(data.(string))) if err != nil { return err } return nil }