From a37fadc3ba0d338aba0292a172962950bd8faa26 Mon Sep 17 00:00:00 2001 From: John Beisley Date: Sat, 14 Aug 2021 10:17:22 +0100 Subject: [PATCH] Factor code template into a file. This allows code regeneration without rebuilding the generator binary. --- cmd/goupnpdcpgen/dcp.go | 13 ++------- cmd/goupnpdcpgen/goupnpdcpgen.go | 28 ++++++++++++++++--- dcps/av1/gen.go | 2 +- .../codetemplate.go => dcps/dcps.gotemplate | 14 +--------- dcps/internetgateway1/gen.go | 2 +- dcps/internetgateway2/gen.go | 2 +- dcps/ocf/internetgateway2/gen.go | 2 +- 7 files changed, 32 insertions(+), 31 deletions(-) rename cmd/goupnpdcpgen/codetemplate.go => dcps/dcps.gotemplate (95%) diff --git a/cmd/goupnpdcpgen/dcp.go b/cmd/goupnpdcpgen/dcp.go index bebee34..c1e8045 100644 --- a/cmd/goupnpdcpgen/dcp.go +++ b/cmd/goupnpdcpgen/dcp.go @@ -7,10 +7,10 @@ import ( "os" "sort" "strings" + "text/template" "github.com/huin/goupnp" "github.com/huin/goupnp/scpd" - "github.com/huin/goutil/codegen" ) // DCP collects together information about a UPnP Device Control Protocol. @@ -86,20 +86,13 @@ func (dcp *DCP) processDeviceFile(file *zip.File) error { return mainErr } -func (dcp *DCP) writeCode(outFile string, useGofmt bool) error { +func (dcp *DCP) writeCode(outFile string, codeTmpl *template.Template) error { packageFile, err := os.Create(outFile) if err != nil { return err } var output io.WriteCloser = packageFile - if useGofmt { - if output, err = codegen.NewGofmtWriteCloser(output); err != nil { - packageFile.Close() - return err - } - } - - if err = packageTmpl.Execute(output, dcp); err != nil { + if err = codeTmpl.Execute(output, dcp); err != nil { output.Close() return err } diff --git a/cmd/goupnpdcpgen/goupnpdcpgen.go b/cmd/goupnpdcpgen/goupnpdcpgen.go index 68b9dd4..89fb1cf 100644 --- a/cmd/goupnpdcpgen/goupnpdcpgen.go +++ b/cmd/goupnpdcpgen/goupnpdcpgen.go @@ -6,7 +6,9 @@ import ( "fmt" "log" "os" + "os/exec" "path/filepath" + "text/template" ) var ( @@ -22,15 +24,23 @@ func main() { useGofmt = flag.Bool("gofmt", true, "Pass the generated code through gofmt. "+ "Disable this if debugging code generation and needing to see the generated code "+ "prior to being passed through gofmt.") + codeTmplFile = flag.String("code_tmpl_file", "", "Path to Go template to generate code from.") ) flag.Parse() - if err := run(*dcpName, *specsDir, *useGofmt); err != nil { + if err := run(*dcpName, *specsDir, *useGofmt, *codeTmplFile); err != nil { log.Fatal(err) } } -func run(dcpName, specsDir string, useGofmt bool) error { +func run(dcpName, specsDir string, useGofmt bool, codeTmplFile string) error { + codeTmpl, err := template.New(filepath.Base(codeTmplFile)).Funcs(template.FuncMap{ + "base": filepath.Base, + }).ParseFiles(codeTmplFile) + if err != nil { + return fmt.Errorf("error parsing template from file: %w", err) + } + if err := os.MkdirAll(specsDir, os.ModePerm); err != nil { return fmt.Errorf("could not create specs-dir %q: %v", specsDir, err) } @@ -47,12 +57,22 @@ func run(dcpName, specsDir string, useGofmt bool) error { return fmt.Errorf("error processing spec %s: %v", metadata.Name, err) } - if err := dcp.writeCode(filepath.Base(metadata.Name)+".go", useGofmt); err != nil { + filename := filepath.Base(metadata.Name) + ".go" + if err := dcp.writeCode(filename, codeTmpl); err != nil { return fmt.Errorf("error writing package %q: %v", dcp.Metadata.Name, err) } - return nil + if !useGofmt { + return nil + } + + return gofmt(filename) } return fmt.Errorf("could not find DCP with name %q", dcpName) } + +func gofmt(filename string) error { + cmd := exec.Command("gofmt", "-w", filename) + return cmd.Run() +} diff --git a/dcps/av1/gen.go b/dcps/av1/gen.go index 4c9e66b..b65b371 100644 --- a/dcps/av1/gen.go +++ b/dcps/av1/gen.go @@ -1,2 +1,2 @@ -//go:generate goupnpdcpgen -dcp_name av1 +//go:generate goupnpdcpgen -dcp_name av1 -code_tmpl_file ../dcps.gotemplate package av1 diff --git a/cmd/goupnpdcpgen/codetemplate.go b/dcps/dcps.gotemplate similarity index 95% rename from cmd/goupnpdcpgen/codetemplate.go rename to dcps/dcps.gotemplate index d7eadb5..45d3efa 100644 --- a/cmd/goupnpdcpgen/codetemplate.go +++ b/dcps/dcps.gotemplate @@ -1,15 +1,4 @@ -package main - -import ( - "html/template" - "path/filepath" -) - -var templateFuncs = template.FuncMap{ - "base": filepath.Base, -} - -var packageTmpl = template.Must(template.New("package").Funcs(templateFuncs).Parse(`{{$name := .Metadata.Name}} +{{$name := .Metadata.Name -}} // Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}. // {{if .DocURLs}} // This DCP is documented in detail at: {{range .DocURLs}} @@ -172,4 +161,3 @@ func (client *{{$srvIdent}}) {{.Name}}({{range $winargs -}} {{define "argstruct"}}struct {{"{"}} {{range .}}{{.Name}} string {{end}}{{"}"}}{{end}} -`)) diff --git a/dcps/internetgateway1/gen.go b/dcps/internetgateway1/gen.go index 2b146a3..e6af2bb 100644 --- a/dcps/internetgateway1/gen.go +++ b/dcps/internetgateway1/gen.go @@ -1,2 +1,2 @@ -//go:generate goupnpdcpgen -dcp_name internetgateway1 +//go:generate goupnpdcpgen -dcp_name internetgateway1 -code_tmpl_file ../dcps.gotemplate package internetgateway1 diff --git a/dcps/internetgateway2/gen.go b/dcps/internetgateway2/gen.go index 752058b..88f8d77 100644 --- a/dcps/internetgateway2/gen.go +++ b/dcps/internetgateway2/gen.go @@ -1,2 +1,2 @@ -//go:generate goupnpdcpgen -dcp_name internetgateway2 +//go:generate goupnpdcpgen -dcp_name internetgateway2 -code_tmpl_file ../dcps.gotemplate package internetgateway2 diff --git a/dcps/ocf/internetgateway2/gen.go b/dcps/ocf/internetgateway2/gen.go index 151d327..ec4a1f2 100644 --- a/dcps/ocf/internetgateway2/gen.go +++ b/dcps/ocf/internetgateway2/gen.go @@ -1,2 +1,2 @@ -//go:generate goupnpdcpgen -dcp_name ocf/internetgateway2 +//go:generate goupnpdcpgen -dcp_name ocf/internetgateway2 -code_tmpl_file ../../dcps.gotemplate package internetgateway2