<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"sync"
	"text/template"

	dep "github.com/hashicorp/consul-template/dependency"
)

// Template is the Go representation of a Consul Template template on disk.
type Template struct {
	sync.Mutex

	// The path to this Template on disk.
	Path string

	// The internal list of dependencies for this Template.
	dependencies []dep.Dependency

	// contents is string contents for this file from disk
	contents string
}

// NewTemplate creates and parses a new Consul Template template at the given
// path. If the template does not exist, an error is returned. During
// initialization, the template is read and is parsed for dependencies. Any
// errors that occur are returned.
func NewTemplate(path string) (*Template, error) {
	template := &Template{Path: path}
	if err := template.init(); err != nil {
		return nil, err
	}

	return template, nil
}

//
func (t *Template) Execute(brain *Brain) ([]dep.Dependency, []byte, error) {
	usedMap := make(map[string]dep.Dependency)
	missingMap := make(map[string]dep.Dependency)
	name := filepath.Base(t.Path)
	funcs := funcMap(brain, usedMap, missingMap)

	tmpl, err := template.New(name).Funcs(funcs).Parse(t.contents)
	if err != nil {
		return nil, nil, fmt.Errorf("template: %s", err)
	}

	// TODO: accept an io.Writer instead
	buff := new(bytes.Buffer)
	if err := tmpl.Execute(buff, nil); err != nil {
		return nil, nil, fmt.Errorf("template: %s", err)
	}

	// Lock because we are about to update the internal state of this template,
	// which could be happening concurrently...
	t.Lock()
	defer t.Unlock()

	// Update this list of this template's dependencies
	var used []dep.Dependency
	for _, dep := range usedMap {
		used = append(used, dep)
	}
	t.dependencies = used

	// Compile the list of missing dependencies
	var missing []dep.Dependency<commit_msg>Update documentation in Template<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"sync"
	"text/template"

	dep "github.com/hashicorp/consul-template/dependency"
)

type Template struct {
	sync.Mutex

	// Path is the path to this template on disk.
	Path string

	// dependencies is the internal list of dependencies,
	dependencies []dep.Dependency

	// contents is string contents for this file when read from disk.
	contents string
}

// NewTemplate creates and parses a new Consul Template template at the given
// path. If the template does not exist, an error is returned. During
// initialization, the template is read and is parsed for dependencies. Any
// errors that occur are returned.
func NewTemplate(path string) (*Template, error) {
	template := &Template{Path: path}
	if err := template.init(); err != nil {
		return nil, err
	}

	return template, nil
}

// Execute evaluates this template in the context of the given brain. The first
// return value is a slice of missing dependencies that were encountered
// during evaluation. If there are any missing dependencies found, it should be
// considered unsafe to write the resulting contents to disk. The second return
// value is the contents of the template as-rendered. This value may not be the
// final resulting template if there are any missing dependencies. The last
// return value is any error that occurred while evaluating the template.
func (t *Template) Execute(brain *Brain) ([]dep.Dependency, []byte, error) {
	usedMap := make(map[string]dep.Dependency)
	missingMap := make(map[string]dep.Dependency)
	name := filepath.Base(t.Path)
	funcs := funcMap(brain, usedMap, missingMap)

	tmpl, err := template.New(name).Funcs(funcs).Parse(t.contents)
	if err != nil {
		return nil, nil, fmt.Errorf("template: %s", err)
	}

	// TODO: accept an io.Writer instead
	buff := new(bytes.Buffer)
	if err := tmpl.Execute(buff, nil); err != nil {
		return nil, nil, fmt.Errorf("template: %s", err)
	}

	// Lock because we are about to update the internal state of this template,
	// which could be happening concurrently...
	t.Lock()
	defer t.Unlock()

	// Update this list of this template's dependencies
	var used []dep.Dependency
	for _, dep := range usedMap {
		used = append(used, dep)
	}
	t.dependencies = used

	// Compile the list of missing dependencies
	var missing []dep.Dependency
{'fraction_non_alphanumeric': 0.10762751520823584, 'fraction_numerical': 0.0, 'mean_word_length': 3.8801369863013697, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1242302', 'n_tokens_mistral': 1293, 'n_tokens_neox': 1247, 'n_words': 505}