"runtime/trace": {"L0", "context", "fmt"},
"text/tabwriter": {"L2"},
- "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
- "testing/iotest": {"L2", "log"},
- "testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
- "internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
- "internal/lazyregexp": {"L2", "OS", "regexp"},
+ "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
+ "testing/iotest": {"L2", "log"},
+ "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.
// 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 (
"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
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 {
--- /dev/null
+// 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
+}