ncw / gotemplate

Package based templating system for Go
MIT License
258 stars 28 forks source link

Make gotemplate be able to read more than one file for source template #9

Open ncw opened 9 years ago

ncw commented 9 years ago

In instantiate we check that only one go file is found for the template. This is an unecessary restriction. What we should do is either

// Instantiate the template package
func (t *template) instantiate() {
    logf("Substituting %q with %s(%s) into package %s", t.Package, t.Name, strings.Join(t.Args, ","), t.NewPackage)

    p, err := build.Default.Import(t.Package, t.Dir, build.ImportMode(0))
    if err != nil {
        fatalf("Import %s failed: %s", t.Package, err)
    }
    debugf("Dir = %#v", p.Dir)
    // FIXME CgoFiles ?
    debugf("Go files = %#v", p.GoFiles)

    if len(p.GoFiles) == 0 {
        fatalf("No go files found for package '%s'", t.Package)
    }
    // FIXME
    if len(p.GoFiles) != 1 {
        fatalf("Found more than one go file in '%s' - can only cope with 1 for the moment, sorry", t.Package)
    }

    templateFilePath := path.Join(p.Dir, p.GoFiles[0])
    t.parse(templateFilePath)
}
myitcv commented 7 years ago

Picking up this old issue 👍

Could we perhaps combine this with support for multiple templates per package?

Let's assume in a package we want to declare two templates:

// in package github.com/myitcv/allthethings
package allthethings

// template type Set(A)
// template type Ring(A)

It would then be relatively straightforward to group the package's *ast.File's by these special comments (with some basic handling for mismatched parameters etc)

Then using these templates we could do something like:

//go:generate gotemplate "github.com/myitcv/allthethings" StringSet(string) Set

I've added the template name as an additional parameter for backwards compatibility. Failing to supply a template name when referencing a package that contains multiple templates would be an error. Otherwise, if a package only contains a single template the template name would be optional.

I have to say I'm not entirely convinced of the need to support multiple files per template; I'm much more interested in multiple templates per package. So if you'd prefer I can split the latter into a separate issue.