1
0
mirror of https://github.com/golang/go synced 2024-09-25 15:10:11 -06:00

internal/lazytemplate: add a lazy template wrapper

Similar to internal/lazyregexp, this will allow removing unnecessary
work from init functions with trivial refactors, thanks to sync.Once.

Copy the structure. The only major difference is that a template also
carries a name.

For #29382.

Change-Id: I65d096dc2e2072b310bf59a814cd62669856b5b5
Reviewed-on: https://go-review.googlesource.com/c/164337
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Daniel Martí 2019-02-27 22:02:51 +00:00
parent 8e8abf368d
commit bd23e84b73
3 changed files with 65 additions and 5 deletions

View File

@ -199,6 +199,7 @@ var pkgDeps = map[string][]string{
"testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
"internal/lazyregexp": {"L2", "OS", "regexp"},
"internal/lazytemplate": {"L2", "OS", "text/template"},
// L4 is defined as L3+fmt+log+time, because in general once
// you're using L3 packages, use of fmt, log, or time is not a big deal.

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package lazyregexp is a thin wrapper over regexp, allowing the use of global
// regexp variables without forcing them to be compiled at init.
package lazyregexp
import (
@ -11,6 +13,8 @@ import (
"sync"
)
// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be
// compiled the first time it is needed.
type Regexp struct {
str string
once sync.Once
@ -61,6 +65,9 @@ func (r *Regexp) SubexpNames() []string {
var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
// New creates a new lazy regexp, delaying the compiling work until it is first
// needed. If the code is being run as part of tests, the regexp compiling will
// happen immediately.
func New(str string) *Regexp {
lr := &Regexp{str: str}
if inTest {

View File

@ -0,0 +1,52 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package lazytemplate is a thin wrapper over text/template, allowing the use
// of global template variables without forcing them to be parsed at init.
package lazytemplate
import (
"io"
"os"
"strings"
"sync"
"text/template"
)
// Template is a wrapper around text/template.Template, where the underlying
// template will be parsed the first time it is needed.
type Template struct {
name, text string
once sync.Once
tmpl *template.Template
}
func (r *Template) tp() *template.Template {
r.once.Do(r.build)
return r.tmpl
}
func (r *Template) build() {
r.tmpl = template.Must(template.New(r.name).Parse(r.text))
r.name, r.text = "", ""
}
func (r *Template) Execute(w io.Writer, data interface{}) error {
return r.tp().Execute(w, data)
}
var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test")
// New creates a new lazy template, delaying the parsing work until it is first
// needed. If the code is being run as part of tests, the template parsing will
// happen immediately.
func New(name, text string) *Template {
lt := &Template{name: name, text: text}
if inTest {
// In tests, always parse the templates early.
lt.tp()
}
return lt
}