<commit_before>// vagrant implements the packer.PostProcessor interface and adds a
// post-processor that turns artifacts of known builders into Vagrant
// boxes.
package vagrant

import (
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/packer"
	"log"
	"text/template"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":  "aws",
	"mitchellh.virtualbox": "virtualbox",
	"mitchellh.vmware":     "vmware",
}

type Config struct {
	OutputPath string `mapstructure:"output"`
}

type PostProcessor struct {
	config     Config
	premade    map[string]packer.PostProcessor
	rawConfigs []interface{}
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	// Store the raw configs for usage later
	p.rawConfigs = raws

	for _, raw := range raws {
		err := mapstructure.Decode(raw, &p.config)
		if err != nil {
			return err
		}
	}

	ppExtraConfig := make(map[string]interface{})
	if p.config.OutputPath == "" {
		p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
		ppExtraConfig["output"] = p.config.OutputPath
	}

	_, err := template.New("output").Parse(p.config.OutputPath)
	if err != nil {
		return fmt.Errorf("output invalid template: %s", err)
	}

	// Store the extra configuration for post-processors
	p.rawConfigs = append(p.rawConfigs, ppExtraConfig)

	// TODO(mitchellh): Properly handle multiple raw configs
	var mapConfig map[string]interface{}
	if err := mapstructure.Decode(raws[0], &mapConfig); err != nil {
		return err
	}
<commit_msg>post-processor/vagrant: fix output ConfigTemplate validation [GH-324]<commit_after>// vagrant implements the packer.PostProcessor interface and adds a
// post-processor that turns artifacts of known builders into Vagrant
// boxes.
package vagrant

import (
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/common"
	"github.com/mitchellh/packer/packer"
	"log"
)

var builtins = map[string]string{
	"mitchellh.amazonebs":  "aws",
	"mitchellh.virtualbox": "virtualbox",
	"mitchellh.vmware":     "vmware",
}

type Config struct {
	common.PackerConfig `mapstructure:",squash"`

	OutputPath string `mapstructure:"output"`
}

type PostProcessor struct {
	config     Config
	premade    map[string]packer.PostProcessor
	rawConfigs []interface{}
}

func (p *PostProcessor) Configure(raws ...interface{}) error {
	// Store the raw configs for usage later
	p.rawConfigs = raws

	md, err := common.DecodeConfig(&p.config, raws...)
	if err != nil {
		return err
	}

	tpl, err := packer.NewConfigTemplate()
	if err != nil {
		return err
	}
	tpl.UserVars = p.config.PackerUserVars

	// Accumulate any errors
	errs := common.CheckUnusedConfig(md)

	ppExtraConfig := make(map[string]interface{})
	if p.config.OutputPath == "" {
		p.config.OutputPath = "packer_{{ .BuildName }}_{{.Provider}}.box"
		ppExtraConfig["output"] = p.config.OutputPath
	}

	//	_, err := template.New("output").Parse(p.config.OutputPath)
	if err := tpl.Validate(p.config.OutputPath); err != nil {
		errs = packer.MultiErrorAppend(
			errs, fmt.Errorf("Error parsing output template: %s", err))
		return errs
	}

	// Store the extra configuration for post-processors
	p.rawConfigs = append(p.rawConfigs, ppExtraConfig)

	// TODO(mitchellh): Properly handle multiple raw configs
	var mapConfig map[string]interface{}
	if err := mapstructure.Decode(raws[0], &mapConfig); err != nil {
		return err
	}

{'fraction_non_alphanumeric': 0.1346153846153846, 'fraction_numerical': 0.0014792899408284023, 'mean_word_length': 4.341232227488152, 'pattern_counts': {'":': 6, '<': 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': '7576224', 'n_tokens_mistral': 1175, 'n_tokens_neox': 1131, 'n_words': 276}