func (m *Main) Run() error {
	if len(m.Paths) == 0 {
		return errors.New("path required")
	}
	for _, path := range m.Paths {
		if err := m.process(path); err != nil {
			return err
		}
	}
	return nil
}
Run executes the program.
package main
import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"text/template"
	"github.com/Masterminds/sprig"
	"github.com/dustin/go-humanize/english"
)
const Extension = ".tmpl"
func main() {
	m := NewMain()
	if err := m.ParseFlags(os.Args[1:]); err != nil {
		fmt.Fprintln(m.Stderr, err)
		os.Exit(2)
	}
	if err := m.Run(); err != nil {
		fmt.Fprintln(m.Stderr, err)
		os.Exit(1)
	}
}
type Main struct {
	Paths []string
	NoHeader   bool
	OutputPath string
	Data interface{}
	OS interface {
		Stat(filename string) (os.FileInfo, error)
	}
	FileReadWriter interface {
		ReadFile(filename string) ([]byte, error)
		WriteFile(filename string, data []byte, perm os.FileMode) error
	}
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}
func NewMain() *Main {
	return &Main{
		OS:             &mainOS{},
		FileReadWriter: &fileReadWriter{},
		Stdin:  os.Stdin,
		Stdout: os.Stdout,
		Stderr: os.Stderr,
	}
}
func (m *Main) ParseFlags(args []string) error {
	fs := flag.NewFlagSet("tmp", flag.ContinueOnError)
	fs.SetOutput(m.Stderr)
	data := fs.String("data", "", "json data")
	fs.BoolVar(&m.NoHeader, "no-header", false, "hide warning header")
	fs.StringVar(&m.OutputPath, "o", "", "output file")
	if err := fs.Parse(args); err != nil {
		return err
	}
	if *data != "" {
		buf := []byte(*data)
		if strings.HasPrefix(*data, "@") {
			b, err := m.FileReadWriter.ReadFile(strings.TrimPrefix(*data, "@"))
			if err != nil {
				return err
			}
			buf = b
		}
		if err := json.Unmarshal(buf, &m.Data); err != nil {
			return err
		}
	}
	m.Paths = fs.Args()
	return nil
}