func (a ByPath) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}
Swap the two values in the slice
package tpl
import (
	"fmt"
	"io"
	"io/ioutil"
	"path/filepath"
	"sort"
	"strings"
)
type template struct {
	path             string
	partialTemplates []Templater
}
func NewRootTemplate(path, osName string) Templater {
	rootTemplate := &template{}
	rootTemplate.path = path
	partials := make(map[string]*template)
	partialFiles := listPartialTemplatesFn(rootTemplate.Dir(), rootTemplate.BaseFilename())
	for _, f := range partialFiles {
		pt := &template{path: f}
		partials[pt.Filename()] = pt
	}
	partialFilesOS := listPartialTemplatesOSSpecificFn(rootTemplate.Dir(), rootTemplate.BaseFilename(), osName)
	for _, f := range partialFilesOS {
		pt := &template{path: f}
		partials[pt.Filename()] = pt
	}
	distinctPartials := []Templater{}
	for _, p := range partials {
		distinctPartials = append(distinctPartials, p)
	}
	sort.Sort(ByPath(distinctPartials))
	rootTemplate.partialTemplates = distinctPartials
	return rootTemplate
}
func (t *template) FullPath() string {
	return t.path
}
func (t *template) BaseFilename() string {
	ext := filepath.Ext(t.path)
	return strings.TrimSuffix(t.Filename(), ext)
}
func (t *template) Dir() string {
	dir, _ := filepath.Split(t.path)
	dir = strings.TrimSuffix(dir, "/")
	return dir
}
func (t *template) Filename() string {
	_, file := filepath.Split(t.path)
	return file
}
func (t *template) Content(buffer io.Writer) error {
	tpl, err := ioutil.ReadFile(t.path)
	if err != nil {
		return err
	}
	_, err = buffer.Write(tpl)
	if err != nil {
		return err
	}
	for _, pt := range t.partialTemplates {
		defineName := strings.TrimPrefix(pt.BaseFilename(), t.BaseFilename())
		defineName = strings.Replace(defineName, ".", "", -1)
		_, err = buffer.Write([]byte(fmt.Sprintf("\n{{define \"%s\"}}\n", defineName)))
		if err != nil {
			return err
		}
		err := pt.Content(buffer)
		if err != nil {
			return err
		}
		_, err = buffer.Write([]byte("\n{{end}}"))
		if err != nil {
			return err
		}
	}
	return nil
}
func (t *template) FindTemplate(path string) Templater {
	for _, pt := range t.partialTemplates {
		if pt.FullPath() == path {
			return pt
		}
	}
	return nil
}
func (t *template) ListTemplates() []Templater {
	return t.partialTemplates
}
var listPartialTemplatesFn = listPartialTemplates
var listPartialTemplatesOSSpecificFn = listPartialTemplatesOSSpecific
func listPartialTemplates(baseDir, baseFilename string) []string {
	return listFiles(fmt.Sprintf("%s/%s*.partial", baseDir, baseFilename))
}
func listPartialTemplatesOSSpecific(baseDir, baseFilename, osName string) []string {
	return listFiles(fmt.Sprintf("%s/%s/%s*.partial", baseDir, osName, baseFilename))
}
func listFiles(globPattern string) []string {
	templates, err := filepath.Glob(globPattern)
	if err != nil {
		panic(err)
	}
	sort.Strings(templates)
	return templates
}
type ByPath []Templater
func (a ByPath) Len() int {
	return len(a)
}