Factor code template into a file.

This allows code regeneration without rebuilding the generator binary.
This commit is contained in:
John Beisley 2021-08-14 10:17:22 +01:00 committed by Huin
parent 0668181616
commit a37fadc3ba
7 changed files with 32 additions and 31 deletions

View File

@ -7,10 +7,10 @@ import (
"os" "os"
"sort" "sort"
"strings" "strings"
"text/template"
"github.com/huin/goupnp" "github.com/huin/goupnp"
"github.com/huin/goupnp/scpd" "github.com/huin/goupnp/scpd"
"github.com/huin/goutil/codegen"
) )
// DCP collects together information about a UPnP Device Control Protocol. // DCP collects together information about a UPnP Device Control Protocol.
@ -86,20 +86,13 @@ func (dcp *DCP) processDeviceFile(file *zip.File) error {
return mainErr 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) packageFile, err := os.Create(outFile)
if err != nil { if err != nil {
return err return err
} }
var output io.WriteCloser = packageFile var output io.WriteCloser = packageFile
if useGofmt { if err = codeTmpl.Execute(output, dcp); err != nil {
if output, err = codegen.NewGofmtWriteCloser(output); err != nil {
packageFile.Close()
return err
}
}
if err = packageTmpl.Execute(output, dcp); err != nil {
output.Close() output.Close()
return err return err
} }

View File

@ -6,7 +6,9 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"text/template"
) )
var ( var (
@ -22,15 +24,23 @@ func main() {
useGofmt = flag.Bool("gofmt", true, "Pass the generated code through gofmt. "+ useGofmt = flag.Bool("gofmt", true, "Pass the generated code through gofmt. "+
"Disable this if debugging code generation and needing to see the generated code "+ "Disable this if debugging code generation and needing to see the generated code "+
"prior to being passed through gofmt.") "prior to being passed through gofmt.")
codeTmplFile = flag.String("code_tmpl_file", "", "Path to Go template to generate code from.")
) )
flag.Parse() flag.Parse()
if err := run(*dcpName, *specsDir, *useGofmt); err != nil { if err := run(*dcpName, *specsDir, *useGofmt, *codeTmplFile); err != nil {
log.Fatal(err) 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 { if err := os.MkdirAll(specsDir, os.ModePerm); err != nil {
return fmt.Errorf("could not create specs-dir %q: %v", specsDir, err) 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) 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 fmt.Errorf("error writing package %q: %v", dcp.Metadata.Name, err)
} }
if !useGofmt {
return nil return nil
} }
return gofmt(filename)
}
return fmt.Errorf("could not find DCP with name %q", dcpName) 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()
}

View File

@ -1,2 +1,2 @@
//go:generate goupnpdcpgen -dcp_name av1 //go:generate goupnpdcpgen -dcp_name av1 -code_tmpl_file ../dcps.gotemplate
package av1 package av1

View File

@ -1,15 +1,4 @@
package main {{$name := .Metadata.Name -}}
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}}
// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}. // Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}.
// {{if .DocURLs}} // {{if .DocURLs}}
// This DCP is documented in detail at: {{range .DocURLs}} // This DCP is documented in detail at: {{range .DocURLs}}
@ -172,4 +161,3 @@ func (client *{{$srvIdent}}) {{.Name}}({{range $winargs -}}
{{define "argstruct"}}struct {{"{"}} {{define "argstruct"}}struct {{"{"}}
{{range .}}{{.Name}} string {{range .}}{{.Name}} string
{{end}}{{"}"}}{{end}} {{end}}{{"}"}}{{end}}
`))

View File

@ -1,2 +1,2 @@
//go:generate goupnpdcpgen -dcp_name internetgateway1 //go:generate goupnpdcpgen -dcp_name internetgateway1 -code_tmpl_file ../dcps.gotemplate
package internetgateway1 package internetgateway1

View File

@ -1,2 +1,2 @@
//go:generate goupnpdcpgen -dcp_name internetgateway2 //go:generate goupnpdcpgen -dcp_name internetgateway2 -code_tmpl_file ../dcps.gotemplate
package internetgateway2 package internetgateway2

View File

@ -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 package internetgateway2