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
	}
}
Beispiel #2
0
// 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
	}
}
Beispiel #3
0
// 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
	}
}
Beispiel #4
0
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
}