// Untar files from input channel and pass the result to the output channel. func Untar(opt Options) gonzo.Stage { return func(ctx context.Context, in <-chan gonzo.File, out chan<- gonzo.File) error { //Check patterns. pluck := len(opt.Pluck) > 0 if pluck { err := match.Good(opt.Pluck...) if err != nil { return err } } for { select { case file, ok := <-in: if !ok { return nil } context.WithValue(ctx, "archive", file.FileInfo().Name()).Debug("Untaring") tr := tar.NewReader(file) defer file.Close() // Iterate through the files in the archive. for { hdr, err := tr.Next() if err == io.EOF { // end of tar archive break } if err != nil { return err } name := strip(opt.StripComponenets, hdr.Name) if pluck && !match.Any(name, opt.Pluck...) { continue } context.WithValue(ctx, "file", name).Debug("Untaring") content := new(bytes.Buffer) n, err := content.ReadFrom(tr) if err != nil { return err } fs := gonzo.NewFile(ioutil.NopCloser(content), gonzo.FileInfoFrom(hdr.FileInfo())) fs.FileInfo().SetName(name) fs.FileInfo().SetSize(int64(n)) out <- fs } case <-ctx.Done(): return ctx.Err() } } } }
// Drop files that match at least one of te patterns. func Drop(patterns ...string) gonzo.Stage { return func(ctx context.Context, in <-chan gonzo.File, out chan<- gonzo.File) error { //Check patterns. err := match.Good(patterns...) if err != nil { return err } stage := Filter(func(file gonzo.File) bool { return !match.Any(file.FileInfo().Name(), patterns...) }) return stage(ctx, in, out) } }