func Compile(conf Config) gonzo.Stage { return func(ctx context.Context, in <-chan gonzo.File, out chan<- gonzo.File) error { b := cache{conf, make(map[string]gonzo.File)} for file := range in { path := file.FileInfo().Name() ctx.Infof("Adding %s", path) b.Files[path] = file defer file.Close() //Close files AFTER we have build our package. } buff := new(bytes.Buffer) err := cacheTemplate.Execute(buff, b) if err != nil { ctx.Error(err) return err } fi := gonzo.NewFileInfo() fi.SetName(b.Name) fi.SetSize(int64(buff.Len())) sf := gonzo.NewFile(ioutil.NopCloser(buff), fi) out <- sf return nil } }
// A build stage creates a new Package and adds all the files coming through the channel to // the package and returns the result of build as a File on the output channel. func Build(config Config) gonzo.Stage { return func(ctx context.Context, files <-chan gonzo.File, out chan<- gonzo.File) error { ctx, cancel := context.WithCancel(ctx) res := resources.New() res.Config = resources.Config(config) var err error buff := &bytes.Buffer{} for { select { case file, ok := <-files: if !ok { goto BUILD } if file.FileInfo().IsDir() { continue } path, _ := filepath.Rel(file.FileInfo().Base(), file.FileInfo().Name()) res.Add(filepath.ToSlash(path), file) ctx.Infof("Adding %s", path) defer func(path string) { ctx.Debug("Closing %s", path) file.Close() //Close files AFTER we have build our package. }(path) case <-ctx.Done(): err = ctx.Err() goto BUILD } } BUILD: if err != nil { return err } ctx.Debug("Runnig build...") err = res.Build(buff) if err != nil { cancel() return err } path := fmt.Sprintf(FilenameFormat, strings.ToLower(config.Var)) sf := gonzo.NewFile(ioutil.NopCloser(buff), gonzo.NewFileInfo()) sf.FileInfo().SetName(path) sf.FileInfo().SetSize(int64(buff.Len())) out <- sf return nil } }
// Concatenates all the files from the input channel // and passes them to output channel with the given name. func Concat(ctx context.Context, name string) gonzo.Stage { return func(ctx context.Context, files <-chan gonzo.File, out chan<- gonzo.File) error { var ( size int64 bigfile = new(bytes.Buffer) ) err := func() error { for { select { case f, ok := <-files: if !ok { return nil } ctx.Infof( "Adding %s to %s", filepath.Join(f.FileInfo().Base(), f.FileInfo().Name()), name, ) n, err := bigfile.ReadFrom(f) if err != nil { return err } bigfile.WriteRune('\n') size += n + 1 f.Close() case <-ctx.Done(): return ctx.Err() } } }() if err != nil { return err } file := gonzo.NewFile(ioutil.NopCloser(bigfile), gonzo.NewFileInfo()) file.FileInfo().SetSize(size) file.FileInfo().SetName(name) out <- file return nil } }
func get(ctx context.Context, client *http.Client, url string) (gonzo.File, error) { resp, err := ctxhttp.Get(ctx, client, url) if err != nil { return nil, err } if resp.StatusCode < 200 || resp.StatusCode > 399 { return nil, fmt.Errorf("%s (%s)", resp.Status, url) } _, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition")) name, ok := params["filename"] if !ok || err != nil { name = path.Base(url) } file := gonzo.NewFile(resp.Body, gonzo.NewFileInfo()) file.FileInfo().SetName(name) file.FileInfo().SetSize(resp.ContentLength) return file, nil }