func getTemplateOrExitError(ctx *cli.Context) (string, error) {
	templateName := ctx.GlobalString("template")
	if strings.Contains(templateName, ".") == false {
		data, err := Asset(filepath.Join(templateAssetFolderName, templateName) + ".html")
		if err != nil {
			return "", cli.NewExitError(err.Error(), 1)
		}
		return string(data), nil
	}
	if !util.FileExists(templateName) {
		s := fmt.Sprintf("Template file %s does not exist\n", templateName)
		return "", cli.NewExitError(s, 1)
	}
	data, err := ioutil.ReadFile(templateName)
	if err != nil {
		return "", cli.NewExitError(err.Error(), 1)
	}
	return string(data), nil
}
getTemplateOrExitError gets the template, if the templatename doesnt contain
a dot, from the internal assets. if it contains a dot it is treated as a user
defined template and is treated like a path to the file.
it returns the template as a string
package main
import (
	"bufio"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
	"gopkg.in/urfave/cli.v1"
	"github.com/jubalh/gontributions/gontrib"
	"github.com/jubalh/gontributions/util"
	"github.com/jubalh/gontributions/vcs/mediawiki"
	"github.com/jubalh/gontributions/vcs/obs"
)
type Summary struct {
	TotalContributions int
	ProjectCount       int
}
type TemplateFill struct {
	Contributions []gontrib.Contribution
	Summary       Summary
}
const (
	templateAssetFolderName = "templates"
)
func loadConfig(filename string) (gontribs gontrib.Configuration, err error) {
	file, err := os.OpenFile(filename, os.O_RDONLY, 0660)
	if err != nil {
		return
	}
	decoder := json.NewDecoder(file)
	err = decoder.Decode(&gontribs)
	return
}
func putdate() string {
	return time.Now().Local().Format("2006-01-02")
}
func fillTemplate(contributions []gontrib.Contribution, tempContent string, writer io.Writer) {
	tf := TemplateFill{Contributions: contributions}
	for _, contribution := range contributions {
		tf.Summary.TotalContributions += contribution.Count
	}
	tf.Summary.ProjectCount = len(contributions)
	funcMap := template.FuncMap{
		"putdate": putdate,
	}
	t, err := template.New("string-template").Funcs(funcMap).Parse(tempContent)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	err = t.Execute(writer, tf)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
func main() {
	app := cli.NewApp()
	app.Name = "gontributions"
	app.Usage = "contributions lister"
	app.Author = "Michael Vetter"
	app.Version = "v0.5.2"
	app.Email = "jubalh@openmailbox.org"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config",
			Value: "gontrib.json",
			Usage: "Set which config file to use",
		},
		cli.StringFlag{
			Name:  "template",
			Value: "default",
			Usage: "Set which template to use. If it contains a dot it will be treated as a path to a user defined template. No dot means using an internal template",
		},
		cli.StringFlag{
			Name:  "output",
			Value: "output.html",
			Usage: "Define name of the generated HTMl file",
		},
		cli.BoolFlag{
			Name:  "no-pull",
			Usage: "Don't update VCS repositories",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:   "exconf",
			Usage:  "Show an example configuration file",
			Action: cmdExconf,
		},
		{
			Name:   "list-templates",
			Usage:  "List all built-in templates",
			Action: cmdListTemplates,
		},
		{
			Name:   "show-template",
			Usage:  "Display the content of a template",
			Action: cmdShowTemplate,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "name",
					Value: "default",
					Usage: "Display the content of a template",
				},
			},
		},
	}
	app.Action = run
	err := app.Run(os.Args)
	if err != nil {
		fmt.Println(err.Error())
	}
}