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,107 +1,79 @@ -# tmpl templates +# NAME -This documentation aims to cover FAQs and setup. +tmpl - Template automation -## Setting up a template +# SYNOPSIS -A "valid" tmpl template only requires two things +tmpl -1. A `template.toml` file in the root directory. -2. A `template` directory that serves as the "root" of the template. +``` +[--registry|-r]=[value] +[--source|-s]=[value] +``` -## template.toml +**Usage**: -```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 [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] +``` -# Extended properties MUST be added after any simple key-value pairs (due to how TOML works) +# GLOBAL OPTIONS -# The "key" is enclosed in braces -[author] -# prompt is what will be shown to prompt the user -prompt = "The name of the author of this project" -# help would be extra information (generally seen by giving '?' to a prompt) -help = "Who will be primarily writing this project" -# default is the "value" part of the simple pair. This could be a suggested value -default = "me" -``` +**--registry, -r**="": Registry directory of tmpl (default: ~/.tmpl) -## template directory +**--source, -s**="": Short-name source to use -This directory contains any and all files that are part of the template. -Everything in this directory (including paths and file names!) will be executed as a [Go template](https://golang.org/pkg/text/template/). +# COMMANDS -See the [documentation](https://golang.org/pkg/text/template/) for every available possibility, but some basic examples are... +## download -* A variable defined in template.toml (tmpl allows for keys to be called as a func or variable, whichever you prefer!) - * `{{project}}` or `{{.project}}` - * `{{author}}` or `{{.author}}` -* Conditionally including something - * `{{if eq project ""}} something... {{end}}` +Download a template -### template helpers +**--branch, -b**="": Branch to clone (default: main) -For a full list, see [helper.go](registry/helper.go) +## init -|Helper|Example|Output| -|-----|-----|-----| -|upper|`{{upper project}}`|`MY-PROJECT`| -|lower|`{{lower project}}`|`my-project`| -|title|`{{title project}}`|`My-Project`| -|snake|`{{snake project}}`|`my_project`| -|kebab|`{{kebab project}}`|`my-project`| -|pascal|`{{pascal project}}`|`MyProject`| -|camel|`{{camel project}}`|`myProject`| -|env|`{{env "USER"}}`|The current user| -|sep|`{{sep}}`|Filepath separator for current OS| -|time}|`{{time "01/02/2006"}}`|`11/21/2020` - The time according to the given [format](https://flaviocopes.com/go-date-time-format/)| +Initialize a template -## Sources +## list -tmpl was designed to work with any local or git-based template. Unfortunately, in contrast to boilr, this means -it cannot be used with `user/repo` notation out of the box. +List templates in the registry -However, you _can_ set up a source (and subsequent env variable) to make it easier to use your preferred source while -still allowing for others. +## remove -### Setting up a source +Remove a template -Let's set up a source for [Gitea](https://gitea.com) +## save -``` -tmpl source add https://gitea.com gitea -``` +Save a local template -To use it, either pass it in with the `--source` flag +## source -``` -tmpl --source gitea download jolheiser/tmpls tmpls -``` +Commands for working with sources -Or set it as the env variable `TMPL_SOURCE` +### list -## Using a different branch +List available sources -By default, tmpl will want to use a branch called `main` in your repository. +### add -If you are using another branch as your default, you can set it as the env variable `TMPL_BRANCH` +Add a source -Alternatively, you can specify on the command-line with the `--branch` flag of the `download` command +### remove -``` -tmpl --source gitea download --branch license jolheiser/tmpls license -``` -The above command would download the [license](https://gitea.com/jolheiser/tmpls/src/branch/license) template from `jolheiser/tmpls` +Remove a source -## Putting it all together +## test -I realize that many users will be using GitHub, and most will likely still be using the `master` branch. +Test if a directory is a valid template -1. Set up a source for GitHub - 1. `tmpl source add https://github.com github` - 2. Set the env variable `TMPL_SOURCE` to `github` -2. Set the env variable `TMPL_BRANCH` to `master` -3. Happy templating! `tmpl download user/repo repo` \ No newline at end of file +## update + +Update a template + +## use + +Use a template + +**--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,11 @@ 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) - -[Project Docs/FAQs](DOCS.md) +[CLI Docs](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" -help = "The name to use in the project" -default = "tmpl" +name = "MyProject" + +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" @@ -12,13 +14,12 @@ var Remove = &cli.Command{ Name: "remove", Usage: "Remove a template", Description: "Remove a template from the registry", - ArgsUsage: "[name]", Action: runRemove, } 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" @@ -14,13 +15,12 @@ var Save = &cli.Command{ Name: "save", Usage: "Save a local template", Description: "Save a local template to the registry", - ArgsUsage: "[path] [name]", Action: runSave, } 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" @@ -36,7 +37,6 @@ SourceAdd = &cli.Command{ Name: "add", Usage: "Add a source", Description: "Add a new source to the registry", - ArgsUsage: "[base URL] [name]", Action: runSourceAdd, } @@ -44,7 +44,6 @@ SourceRemove = &cli.Command{ Name: "remove", Usage: "Remove a source", Description: "Remove a source from the registry", - ArgsUsage: "[name]", Action: runSourceRemove, } ) @@ -69,7 +68,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) @@ -88,7 +87,7 @@ } func runSourceRemove(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/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,23 +10,17 @@ 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", - ArgsUsage: "[path (default: \".\")]", + Description: "Test whether the current directory is valid for use with tmpl", Action: runTest, } -func runTest(ctx *cli.Context) error { - testPath := "." - if ctx.NArg() > 0 { - testPath = ctx.Args().First() - } - +func runTest(_ *cli.Context) error { 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" @@ -12,13 +14,12 @@ var Update = &cli.Command{ Name: "update", Usage: "Update a template", Description: "Update a template in the registry from the original source", - ArgsUsage: "[name]", Action: runUpdate, } 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 { - return cli.ShowCommandHelp(ctx, ctx.Command.Name) - } - - dest := "." - if ctx.NArg() >= 2 { - dest = ctx.Args().Get(1) + if ctx.NArg() < 2 { + 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,7 +13,7 @@ func main() { app := cmd.NewApp() - fi, err := os.Create("CLI.md") + fi, err := os.Create("DOCS.md") 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,6 +78,30 @@ t.FailNow() } } +func testExecute(t *testing.T) { + tmpl, err := reg.GetTemplate("test") + if err != nil { + t.Logf("could not get template") + t.FailNow() + } + + if err := tmpl.Execute(destDir, true); err != nil { + t.Logf("could not execute template: %v\n", err) + t.FailNow() + } + + contents, err := ioutil.ReadFile(filepath.Join(destDir, "TEST")) + 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() + } +} + func setupTemplate() { var err error tmplDir, err = ioutil.TempDir(os.TempDir(), "tmpl") @@ -93,20 +122,10 @@ if err := fi.Close(); err != nil { panic(err) } - // Template directories - pkgPath := filepath.Join(tmplDir, "template", "{{upper package}}") - if err := os.MkdirAll(pkgPath, os.ModePerm); err != nil { - panic(err) - } - fi, err = os.Create(filepath.Join(pkgPath, ".keep")) - if err != nil { + // Template file + if err := os.Mkdir(filepath.Join(tmplDir, "template"), os.ModePerm); err != nil { panic(err) } - if err := fi.Close(); err != nil { - panic(err) - } - - // Template file 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,18 @@ package registry import ( - "bytes" "fmt" "io/ioutil" "os" "path/filepath" + "sort" "strings" "text/template" "time" + "github.com/AlecAivazis/survey/v2" "github.com/mholt/archiver/v3" + "github.com/pelletier/go-toml" ) // Template is a tmpl project @@ -34,7 +36,7 @@ return filepath.Join(t.reg.dir, t.ArchiveName()) } // Execute runs the Template and copies to dest -func (t *Template) Execute(dest string, defaults, overwrite bool) error { +func (t *Template) Execute(dest string, defaults bool) error { tmp, err := ioutil.TempDir(os.TempDir(), "tmpl") if err != nil { return err @@ -45,12 +47,10 @@ if err := archiver.Unarchive(t.ArchivePath(), tmp); err != nil { return err } - prompts, err := prompt(tmp, defaults) + vars, err := prompt(tmp, defaults) 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 { @@ -67,19 +67,13 @@ if err != nil { return err } - newDest := strings.TrimPrefix(walkPath, base+"/") - newDest = filepath.Join(dest, newDest) - - tmplDest, err := template.New("dest").Funcs(funcs).Parse(newDest) + tmpl, err := template.New("tmpl").Funcs(mergeMaps(funcMap, convertMap(vars))).Parse(string(contents)) if err != nil { return err } - var buf bytes.Buffer - if err := tmplDest.Execute(&buf, prompts.ToMap()); err != nil { - return err - } - newDest = buf.String() + newDest := strings.TrimPrefix(walkPath, base+"/") + newDest = filepath.Join(dest, newDest) if err := os.MkdirAll(filepath.Dir(newDest), os.ModePerm); err != nil { return err @@ -89,27 +83,77 @@ oldFi, err := os.Lstat(walkPath) if err != nil { return err } - - // Check if new file exists. If it does, only skip if not overwriting - if _, err := os.Lstat(newDest); err == nil && !overwrite { - return nil - } - newFi, err := os.OpenFile(newDest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, oldFi.Mode()) if err != nil { return err } - tmplContents, err := template.New("tmpl").Funcs(funcs).Parse(string(contents)) - if err != nil { - return err - } - if err := tmplContents.Execute(newFi, prompts.ToMap()); err != nil { + if err := tmpl.Execute(newFi, vars); err != nil { return err } return newFi.Close() }) +} + +func prompt(dir string, defaults bool) (map[string]interface{}, 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 + } + vars := tree.ToMap() + + // Return early if we only want defaults + if defaults { + return vars, nil + } + + // Sort the map keys so they are consistent + sorted := make([]string, 0, len(vars)) + for k := range vars { + sorted = append(sorted, k) + } + sort.Strings(sorted) + + for _, k := range sorted { + v := vars[k] + var p survey.Prompt + switch t := v.(type) { + case []string: + p = &survey.Select{ + Message: k, + Options: t, + } + default: + p = &survey.Input{ + Message: k, + Default: fmt.Sprintf("%v", t), + } + } + var a string + if err := survey.AskOne(p, &a); err != nil { + return nil, err + } + vars[k] = a + } + + return vars, nil +} + +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{} { + return fmt.Sprintf("%v", vv) + } + } + 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() - } -}