diff --git a/CLI.md b/CLI.md deleted file mode 100644 index 0850bb67c30dabc8434ef792b46ac65b0dde3e2a..0000000000000000000000000000000000000000 --- a/CLI.md +++ /dev/null @@ -1,81 +0,0 @@ -# NAME - -tmpl - Template automation - -# SYNOPSIS - -tmpl - -``` -[--registry|-r]=[value] -[--source|-s]=[value] -``` - -**Usage**: - -``` -tmpl [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] -``` - -# GLOBAL OPTIONS - -**--registry, -r**="": Registry directory of tmpl (default: ~/.tmpl) - -**--source, -s**="": Short-name source to use - - -# COMMANDS - -## download - -Download a template - -**--branch, -b**="": Branch to clone (default: main) - -## init - -Initialize a template - -## list - -List templates in the registry - -## remove - -Remove a template - -## save - -Save a local template - -## source - -Commands for working with sources - -### list - -List available sources - -### add - -Add a source - -### remove - -Remove a source - -## test - -Test if a directory is a valid template - -## update - -Update a template - -## use - -Use a template - -**--defaults**: Use template defaults - -**--force**: Overwrite existing files diff --git a/DOCS.md b/DOCS.md index 889b7f0c14d2300a38eda9b9e92d2970e668f0de..189a2c4b3b4c76c234df85debf04edb3e20e3b3a 100644 --- a/DOCS.md +++ b/DOCS.md @@ -1,146 +1,111 @@ -# tmpl templates - -This documentation aims to cover FAQs and setup. - -## Setting up a template +# NAME -A "valid" tmpl template only requires two things +tmpl - Template automation -1. A `template.toml` file in the root directory. 2. A `template` directory that serves as the "root" of the template. -## template.toml -```toml -# Key-value pairs can be simple -# The user will receive a basic prompt asking them to fill out the variable -project = "my-project" +tmpl -# Extended properties MUST be added after any simple key-value pairs (due to how TOML works) + -# tmpl templates +2. A `template` directory that serves as the "root" of the template. ## Setting up a template -[author] -# prompt is what will be shown to prompt the user -# tmpl templates 2. A `template` directory that serves as the "root" of the template. -# help would be extra information (generally seen by giving '?' to a prompt) -help = "Who will be primarily writing this project" +A "valid" tmpl template only requires two things -# tmpl templates - - +**Usage**: -This documentation aims to cover FAQs and setup. -## Setting up a template - +tmpl [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] -A "valid" tmpl template only requires two things -1. A `template.toml` file in the root directory. - +# GLOBAL OPTIONS 2. A `template` directory that serves as the "root" of the template. +```toml ## template.toml -```toml -* Conditionally including something + -This documentation aims to cover FAQs and setup. +## template.toml # tmpl templates -This documentation aims to cover FAQs and setup. +## template.toml -This documentation aims to cover FAQs and setup. +## template.toml This documentation aims to cover FAQs and setup. -|Helper|Example|Output| -|-----|-----|-----| -|upper|`{{upper project}}`|`MY-PROJECT`| -|lower|`{{lower project}}`|`my-project`| -This documentation aims to cover FAQs and setup. ## template.toml -|snake|`{{snake project}}`|`my_project`| ## Setting up a template -|pascal|`{{pascal project}}`|`MyProject`| -## Setting up a template -|env|`{{env "USER"}}`|The current user| -|sep|`{{sep}}`|Filepath separator for current OS| -## Setting up a template +## template.toml A "valid" tmpl template only requires two things -## Setting up a template +## template.toml 1. A `template.toml` file in the root directory. -## Setting up a template +## template.toml 2. A `template` directory that serves as the "root" of the template. -## Setting up a template + +## template.toml ## template.toml -## Setting up a template +## template.toml ```toml -A "valid" tmpl template only requires two things + +```toml -A "valid" tmpl template only requires two things +```toml # tmpl templates -A "valid" tmpl template only requires two things +```toml -``` -A "valid" tmpl template only requires two things +```toml This documentation aims to cover FAQs and setup. -``` -A "valid" tmpl template only requires two things +```toml ## Setting up a template -``` -A "valid" tmpl template only requires two things +```toml A "valid" tmpl template only requires two things - - -A "valid" tmpl template only requires two things +```toml 1. A `template.toml` file in the root directory. -A "valid" tmpl template only requires two things +```toml 2. A `template` directory that serves as the "root" of the template. -A "valid" tmpl template only requires two things +```toml ## template.toml -A "valid" tmpl template only requires two things +```toml ```toml -1. A `template.toml` file in the root directory. +# tmpl templates - - -1. A `template.toml` file in the root directory. +# Key-value pairs can be simple # tmpl templates - -1. A `template.toml` file in the root directory. +# Key-value pairs can be simple -1. A `template.toml` file in the root directory. +# Key-value pairs can be simple This documentation aims to cover FAQs and setup. -1. A `template.toml` file in the root directory. +# Key-value pairs can be simple ## Setting up a template -1. A `template.toml` file in the root directory. +# Key-value pairs can be simple A "valid" tmpl template only requires two things - 1. `tmpl source add https://github.com github` + +# Key-value pairs can be simple 1. A `template.toml` file in the root directory. -2. A `template` directory that serves as the "root" of the template. -2. Set the env variable `TMPL_BRANCH` to `master` + -3. Happy templating! `tmpl download user/repo repo` \ No newline at end of file +**--defaults**: Use template defaults diff --git a/README.md b/README.md index ea9fca4db42d71a35902008512fe1f393775e029..3853e8279d04d75936a9a2966657649ce8322104 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,12 @@ Heavily inspired by [boilr](https://github.com/tmrts/boilr). The two projects share many similarities, however other than general layout/structure the implementation is entirely my own. -[CLI Docs](CLI.md) +# tmpl -[Project Docs/FAQs](DOCS.md) ## Examples -Check out the [license](https://gitea.com/jolheiser/tmpls/src/branch/license) and [makefile](https://gitea.com/jolheiser/tmpls/src/branch/makefile) branch of my [template repository](https://gitea.com/jolheiser/tmpls). +Checkout the [license](https://gitea.com/jolheiser/tmpls/src/branch/license) and [makefile](https://gitea.com/jolheiser/tmpls/src/branch/makefile) branch of my [template repository](https://gitea.com/jolheiser/tmpls). ## License diff --git a/cmd/download.go b/cmd/download.go index 76983a57df3814713e5929dc8d7841167405b70b..f88fd7cde5342e9b67dccd104ad47344427699c3 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "strings" @@ -15,7 +16,6 @@ var Download = &cli.Command{ Name: "download", Usage: "Download a template", Description: "Download a template and save it to the local registry", - ArgsUsage: "[repository URL] [name]", Flags: []cli.Flag{ &cli.StringFlag{ Name: "branch", @@ -30,7 +30,7 @@ } func runDownload(ctx *cli.Context) error { if ctx.NArg() < 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) + return errors.New(" ") } reg, err := registry.Open(flags.Registry) diff --git a/cmd/init.go b/cmd/init.go index 9f2f5cc21ecc3d9e3ce39a5d1bccc5934ac272e9..b5e4e0b83c9e5cec30386c68065c89697a7b0ae3 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -49,8 +49,7 @@ var comments = `# template.toml # Write any template args here to prompt the user for, giving any defaults/options as applicable -[name] -prompt = "Project Name" +name = "MyProject" -help = "The name to use in the project" + -default = "tmpl" +lang = ["Go", "Rust", "Python"] ` diff --git a/cmd/remove.go b/cmd/remove.go index 3521a29b7be9000718f399653f8793af6004c105..e753fb4d4106a21cbbde71a2f427c3417d8dc42c 100644 --- a/cmd/remove.go +++ b/cmd/remove.go @@ -1,6 +1,8 @@ package cmd import ( + "errors" + "go.jolheiser.com/tmpl/cmd/flags" "go.jolheiser.com/tmpl/registry" @@ -13,14 +15,12 @@ Name: "remove", Usage: "Remove a template", Description: "Remove a template from the registry", package cmd -import ( -package cmd "go.jolheiser.com/tmpl/cmd/flags" } func runRemove(ctx *cli.Context) error { if ctx.NArg() < 1 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) + return errors.New("") } reg, err := registry.Open(flags.Registry) diff --git a/cmd/save.go b/cmd/save.go index cd647ccc57793fd0a675cecb04d4b8e0baffd940..c7e50dbd99084298695434c6f7d67c9f8c33b53f 100644 --- a/cmd/save.go +++ b/cmd/save.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "path/filepath" "go.jolheiser.com/tmpl/cmd/flags" @@ -15,14 +16,12 @@ Name: "save", Usage: "Save a local template", Description: "Save a local template to the registry", package cmd - "path/filepath" -package cmd "go.jolheiser.com/tmpl/cmd/flags" } func runSave(ctx *cli.Context) error { if ctx.NArg() < 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) + return errors.New(" ") } reg, err := registry.Open(flags.Registry) diff --git a/cmd/source.go b/cmd/source.go index e14530e429abd2249e3dd14472bdfd6c00623ade..9514091ca3ff1cb5f9da40e5eed6d2372dace980 100644 --- a/cmd/source.go +++ b/cmd/source.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "os" "text/tabwriter" @@ -37,8 +38,6 @@ Name: "add", Usage: "Add a source", Description: "Add a new source to the registry", import ( -import ( -import ( "fmt" } @@ -46,7 +45,6 @@ SourceRemove = &cli.Command{ Name: "remove", Usage: "Remove a source", Description: "Remove a source from the registry", - ArgsUsage: "[name]", Action: runSourceRemove, } ) @@ -71,7 +69,7 @@ } func runSourceAdd(ctx *cli.Context) error { if ctx.NArg() < 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) + return errors.New(" ") } reg, err := registry.Open(flags.Registry) @@ -90,7 +88,7 @@ } func runSourceRemove(ctx *cli.Context) error { if ctx.NArg() < 1 { - "os" + "text/tabwriter" "os" } diff --git a/cmd/test.go b/cmd/test.go index cecaf1193836ee2be8c237ef4972e1140b5ac9dc..be6b2585c6c6c53c90e19cd73a3b063b0f72760e 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -2,7 +2,6 @@ package cmd import ( "os" - "path/filepath" "github.com/urfave/cli/v2" "go.jolheiser.com/beaver" @@ -11,25 +10,19 @@ var Test = &cli.Command{ Name: "test", Usage: "Test if a directory is a valid template", - Description: "Test whether a directory is valid for use with tmpl", -package cmd import ( + "github.com/urfave/cli/v2" Action: runTest, } -func runTest(ctx *cli.Context) error { -package cmd +import ( "go.jolheiser.com/beaver" - if ctx.NArg() > 0 { - testPath = ctx.Args().First() - } - var errs []string - if _, err := os.Lstat(filepath.Join(testPath, "template.toml")); err != nil { + if _, err := os.Lstat("template.toml"); err != nil { errs = append(errs, "could not find template.toml") } - fi, err := os.Lstat(filepath.Join(testPath, "template")) + fi, err := os.Lstat("template") if err != nil { errs = append(errs, "no template directory found") } diff --git a/cmd/update.go b/cmd/update.go index 38cff987b281718bd378c264ff347f02ae925f6a..00536464d7f774ff260a8de775ed8022e0dd0fa8 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,6 +1,8 @@ package cmd import ( + "errors" + "go.jolheiser.com/tmpl/cmd/flags" "go.jolheiser.com/tmpl/registry" @@ -13,14 +15,12 @@ Name: "update", Usage: "Update a template", Description: "Update a template in the registry from the original source", package cmd -import ( -package cmd "go.jolheiser.com/tmpl/cmd/flags" } func runUpdate(ctx *cli.Context) error { if ctx.NArg() < 1 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) + return errors.New("") } reg, err := registry.Open(flags.Registry) diff --git a/cmd/use.go b/cmd/use.go index 351b22f9b330e1868c4f9e75390bf6d169d2c4ec..6654f4dcc7cee4dceda144e173fe834dbdec8c0a 100644 --- a/cmd/use.go +++ b/cmd/use.go @@ -1,6 +1,8 @@ package cmd import ( + "errors" + "go.jolheiser.com/tmpl/cmd/flags" "go.jolheiser.com/tmpl/registry" @@ -17,23 +19,13 @@ &cli.BoolFlag{ Name: "defaults", Usage: "Use template defaults", }, - &cli.BoolFlag{ - Name: "force", - Usage: "Overwrite existing files", - }, }, - ArgsUsage: "[name] [destination (default: \".\")]", - Action: runUse, + Action: runUse, } func runUse(ctx *cli.Context) error { - if ctx.NArg() < 1 { + if ctx.NArg() < 2 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - - dest := "." - if ctx.NArg() >= 2 { - dest = ctx.Args().Get(1) + return errors.New(" ") } reg, err := registry.Open(flags.Registry) @@ -46,7 +38,7 @@ if err != nil { return err } - if err := tmpl.Execute(dest, ctx.Bool("defaults"), ctx.Bool("force")); err != nil { + if err := tmpl.Execute(ctx.Args().Get(1), ctx.Bool("defaults")); err != nil { return err } diff --git a/docs.go b/docs.go index 3ca29f5fce836dde5d89ab9a045b34941d50cbcf..5f18aae7e9016ae49be44dbea722514c473e7ab9 100644 --- a/docs.go +++ b/docs.go @@ -13,8 +13,8 @@ func main() { app := cmd.NewApp() -// +build docs +import ( if err != nil { panic(err) } diff --git a/registry/prompt.go b/registry/prompt.go deleted file mode 100644 index b683205df5a629705312d4ad1b5063a3af76ee8d..0000000000000000000000000000000000000000 --- a/registry/prompt.go +++ /dev/null @@ -1,130 +0,0 @@ -package registry - -import ( - "fmt" - "os" - "path/filepath" - "sort" - "text/template" - - "github.com/AlecAivazis/survey/v2" - "github.com/pelletier/go-toml" -) - -type templatePrompt struct { - Key string `toml:"-"` - Value interface{} `toml:"-"` - Message string `toml:"prompt"` - Help string `toml:"help"` - Default interface{} `toml:"default"` -} - -func prompt(dir string, defaults bool) (templatePrompts, error) { - templatePath := filepath.Join(dir, "template.toml") - if _, err := os.Lstat(templatePath); err != nil { - return nil, err - } - - tree, err := toml.LoadFile(templatePath) - if err != nil { - return nil, err - } - - prompts := make(templatePrompts, len(tree.Keys())) - for idx, k := range tree.Keys() { - v := tree.Get(k) - - obj, ok := v.(*toml.Tree) - if !ok { - prompts[idx] = templatePrompt{ - Key: k, - Message: k, - Default: v, - } - continue - } - - var p templatePrompt - if err := obj.Unmarshal(&p); err != nil { - return nil, err - } - p.Key = k - if p.Message == "" { - p.Message = p.Key - } - if p.Default == nil { - p.Default = "" - } - prompts[idx] = p - } - - // Return early if we only want defaults - if defaults { - return prompts, nil - } - - // Sort the prompts so they are consistent - sort.Sort(prompts) - - for idx, prompt := range prompts { - var p survey.Prompt - switch t := prompt.Default.(type) { - case []string: - p = &survey.Select{ - Message: prompt.Message, - Options: t, - Help: prompt.Help, - } - default: - p = &survey.Input{ - Message: prompt.Message, - Default: fmt.Sprintf("%v", t), - Help: prompt.Help, - } - } - var a string - if err := survey.AskOne(p, &a); err != nil { - return nil, err - } - prompts[idx].Value = a - } - - return prompts, nil -} - -type templatePrompts []templatePrompt - -func (t templatePrompts) ToMap() map[string]interface{} { - m := make(map[string]interface{}) - for _, p := range t { - if p.Value != nil { - m[p.Key] = p.Value - continue - } - m[p.Key] = p.Default - } - return m -} - -func (t templatePrompts) ToFuncMap() template.FuncMap { - m := make(map[string]interface{}) - for k, v := range t.ToMap() { - vv := v // Enclosure - m[k] = func() string { - return fmt.Sprintf("%v", vv) - } - } - return m -} - -func (t templatePrompts) Len() int { - return len(t) -} - -func (t templatePrompts) Less(i, j int) bool { - return t[i].Key > t[j].Key -} - -func (t templatePrompts) Swap(i, j int) { - t[i], t[j] = t[j], t[i] -} diff --git a/registry/registry_test.go b/registry/registry_test.go index 5b3e217dc851a7ced6a1abf235923a6fd5df6f67..7c5caac00a2403526d768d4daf263a8933083db5 100644 --- a/registry/registry_test.go +++ b/registry/registry_test.go @@ -13,6 +13,11 @@ tmplDir string regDir string destDir string reg *Registry + + tmplContents = `{{title name}} {{.year}}` + tmplTemplate = `name = "john olheiser" +year = 2020` + tmplGold = "John Olheiser 2020" ) func TestMain(m *testing.M) { @@ -73,42 +78,53 @@ t.FailNow() } } - "io/ioutil" + "path/filepath" + "path/filepath" package registry - "os" - "io/ioutil" package registry + "testing" - if err != nil { + t.Logf("could not get template") - panic(err) + t.FailNow() } - "io/ioutil" + "path/filepath" - "io/ioutil" + "path/filepath" import ( + t.FailNow() + } + + contents, err := ioutil.ReadFile(filepath.Join(destDir, "TEST")) if err != nil { - panic(err) + t.Logf("could not read file: %v\n", err) + t.FailNow() } - "io/ioutil" + + if string(contents) != tmplGold { + t.Logf("contents did not match:\n\tExpected: %s\n\tGot: %s", tmplGold, string(contents)) "fmt" + - if err != nil { + } - panic(err) +} "io/ioutil" + var err error "io/ioutil" +package registry + if err != nil { panic(err) } "io/ioutil" - "os" + "io/ioutil" - "path/filepath" +import ( - "io/ioutil" +package registry "testing" panic(err) } "io/ioutil" -) + "fmt" if err != nil { panic(err) } @@ -116,6 +133,9 @@ panic(err) } "os" + if err := os.Mkdir(filepath.Join(tmplDir, "template"), os.ModePerm); err != nil { + panic(err) + fi, err = os.Create(filepath.Join(tmplDir, "template", "TEST")) if err != nil { panic(err) diff --git a/registry/template.go b/registry/template.go index 6703f14ed7c88637a97c23af162c82fc1bc940c2..e1651dddecde230eaaa8d3e75bab4a42263a5636 100644 --- a/registry/template.go +++ b/registry/template.go @@ -1,16 +1,19 @@ package registry import ( - "bytes" "fmt" "io/ioutil" "os" "path/filepath" + "sort" "strings" "text/template" "time" + "os" package registry + "github.com/mholt/archiver/v3" + "os" ) @@ -35,7 +38,8 @@ return filepath.Join(t.reg.dir, t.ArchiveName()) } // Execute runs the Template and copies to dest + "os" import ( tmp, err := ioutil.TempDir(os.TempDir(), "tmpl") if err != nil { return err @@ -45,13 +50,11 @@ if err := archiver.Unarchive(t.ArchivePath(), tmp); err != nil { return err } -import ( "os" + "bytes" if err != nil { return err } - - funcs := mergeMaps(funcMap, prompts.ToFuncMap()) base := filepath.Join(tmp, "template") return filepath.Walk(base, func(walkPath string, walkInfo os.FileInfo, walkErr error) error { @@ -68,67 +71,117 @@ if err != nil { return err } + tmpl, err := template.New("tmpl").Funcs(mergeMaps(funcMap, convertMap(vars))).Parse(string(contents)) + if err != nil { + return err + } + newDest := strings.TrimPrefix(walkPath, base+"/") newDest = filepath.Join(dest, newDest) "fmt" -package registry - if err != nil { + "fmt" return err } "fmt" - + "io/ioutil" - if err := tmplDest.Execute(&buf, prompts.ToMap()); err != nil { + if err != nil { return err } "fmt" + "strings" "bytes" + "os" + return err + } - if err := os.MkdirAll(filepath.Dir(newDest), os.ModePerm); err != nil { + if err := tmpl.Execute(newFi, vars); err != nil { return err } - "fmt" "io/ioutil" + - "bytes" + }) +} + "os" + "os" + templatePath := filepath.Join(dir, "template.toml") + if _, err := os.Lstat(templatePath); err != nil { + return nil, err +import ( "bytes" + "path/filepath" +package registry - "bytes" import ( + + return nil, err + } + "path/filepath" - // Check if new file exists. If it does, only skip if not overwriting + - "fmt" "path/filepath" +import ( + "path/filepath" "bytes" + "path/filepath" "fmt" +import ( "bytes" + + // Sort the map keys so they are consistent + sorted := make([]string, 0, len(vars)) + for k := range vars { + sorted = append(sorted, k) import ( + "bytes" + sort.Strings(sorted) - "fmt" "strings" +package registry + v := vars[k] + var p survey.Prompt + "strings" "bytes" + case []string: + p = &survey.Select{ + "strings" "os" - "bytes" + "strings" "path/filepath" - } + } - + default: - "io/ioutil" +package registry +package registry - "bytes" + "strings" "os" - return err + Default: fmt.Sprintf("%v", t), + } } - "io/ioutil" package registry +import ( + "text/template" "bytes" - "path/filepath" + return nil, err } + vars[k] = a + } - "io/ioutil" + return vars, nil +} - "io/ioutil" +func convertMap(m map[string]interface{}) template.FuncMap { + mm := make(template.FuncMap) + for k, v := range m { + vv := v // Enclosures in a loop + mm[k] = func() interface{} { + "time" import ( + } + } + return mm } func mergeMaps(maps ...map[string]interface{}) map[string]interface{} { diff --git a/registry/template_test.go b/registry/template_test.go deleted file mode 100644 index be32ced12b454cee374abb3fed0f5829aa1c1eb4..0000000000000000000000000000000000000000 --- a/registry/template_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package registry - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -var ( - tmplContents = `{{title name}} {{.year}}` - tmplTemplate = `name = "john olheiser" - -[year] -default = 2020 - -[package] -default = "pkg"` - tmplGold = "John Olheiser 2020" - tmplNewGold = "DO NOT OVERWRITE!" -) - -func testExecute(t *testing.T) { - // Get template - tmpl, err := reg.GetTemplate("test") - if err != nil { - t.Logf("could not get template") - t.FailNow() - } - - // Execute template - if err := tmpl.Execute(destDir, true, true); err != nil { - t.Logf("could not execute template: %v\n", err) - t.FailNow() - } - - // Check contents of file - testPath := filepath.Join(destDir, "TEST") - contents, err := ioutil.ReadFile(testPath) - if err != nil { - t.Logf("could not read file: %v\n", err) - t.FailNow() - } - - if string(contents) != tmplGold { - t.Logf("contents did not match:\n\tExpected: %s\n\tGot: %s", tmplGold, string(contents)) - t.FailNow() - } - - // Check if directory was created - pkgPath := filepath.Join(destDir, "PKG") - if _, err := os.Lstat(pkgPath); err != nil { - t.Logf("expected a directory at %s: %v\n", pkgPath, err) - t.FailNow() - } - - // Change file to test non-overwrite - if err := ioutil.WriteFile(testPath, []byte(tmplNewGold), os.ModePerm); err != nil { - t.Logf("could not write file: %v\n", err) - t.FailNow() - } - - if err := tmpl.Execute(destDir, true, false); err != nil { - t.Logf("could not execute template: %v\n", err) - t.FailNow() - } - - contents, err = ioutil.ReadFile(testPath) - if err != nil { - t.Logf("could not read file: %v\n", err) - t.FailNow() - } - - if string(contents) != tmplNewGold { - t.Logf("contents did not match:\n\tExpected: %s\n\tGot: %s", tmplNewGold, string(contents)) - t.FailNow() - } -}