This commit is contained in:
Gerasimos (Makis) Maropoulos 2021-01-09 05:41:20 +02:00
parent 72c2dafd2e
commit 8aedf6bc32
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
36 changed files with 99 additions and 130 deletions

View File

@ -231,7 +231,7 @@ func jsJquery211Js() (*asset, error) {
// It returns an error if the asset could not be found or // It returns an error if the asset could not be found or
// could not be loaded. // could not be loaded.
func Asset(name string) ([]byte, error) { func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1) cannonicalName := strings.ReplaceAll(name, "\\", "/")
if f, ok := _bindata[cannonicalName]; ok { if f, ok := _bindata[cannonicalName]; ok {
a, err := f() a, err := f()
if err != nil { if err != nil {

View File

@ -54,8 +54,8 @@ func (r resource) loadFromBase(dir string) string {
result := string(b) result := string(b)
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1) result = strings.ReplaceAll(result, "\n", "\r\n")
result = strings.Replace(result, "\r\r", "", -1) result = strings.ReplaceAll(result, "\r\r", "")
} }
return result return result
} }

View File

@ -55,7 +55,7 @@ func (r resource) loadFromBase(dir string) string {
result := string(b) result := string(b)
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1) result = strings.ReplaceAll(result, "\n", "\r\n")
} }
return result return result
} }

View File

@ -47,8 +47,8 @@ func (r resource) loadFromBase(dir string) string {
} }
result := string(b) result := string(b)
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1) result = strings.ReplaceAll(result, "\n", "\r\n")
result = strings.Replace(result, "\r\r", "", -1) result = strings.ReplaceAll(result, "\r\r", "")
} }
return result return result
} }

View File

@ -80,8 +80,8 @@ func beforeSave(ctx iris.Context, file *multipart.FileHeader) bool {
ip := ctx.RemoteAddr() ip := ctx.RemoteAddr()
// make sure you format the ip in a way // make sure you format the ip in a way
// that can be used for a file name (simple case): // that can be used for a file name (simple case):
ip = strings.Replace(ip, ".", "_", -1) ip = strings.ReplaceAll(ip, ".", "_")
ip = strings.Replace(ip, ":", "_", -1) ip = strings.ReplaceAll(ip, ":", "_")
// you can use the time.Now, to prefix or suffix the files // you can use the time.Now, to prefix or suffix the files
// based on the current time as well, as an exercise. // based on the current time as well, as an exercise.

2
cli.go
View File

@ -47,7 +47,7 @@ func injectLiveReload(r Party) (bool, error) {
path = filepath.Join(wd, path) path = filepath.Join(wd, path)
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
inFile, err := os.OpenFile(path, os.O_RDONLY, 0644) inFile, err := os.OpenFile(path, os.O_RDONLY, 0600)
if err != nil { if err != nil {
return false, err return false, err
} }

View File

@ -135,7 +135,7 @@ func expectTokenSlash(s string) (token, rest string) {
func expectQuality(s string) (q float64, rest string) { func expectQuality(s string) (q float64, rest string) {
switch { switch {
case len(s) == 0: case s == "":
return -1, "" return -1, ""
case s[0] == '0': case s[0] == '0':
q = 0 q = 0

View File

@ -102,7 +102,7 @@ func NewCompressWriter(w io.Writer, encoding string, level int) (cw CompressWrit
} }
cw = brotli.NewWriterLevel(w, level) cw = brotli.NewWriterLevel(w, level)
case SNAPPY: case SNAPPY:
cw = snappy.NewWriter(w) cw = snappy.NewBufferedWriter(w)
case S2: case S2:
cw = s2.NewWriter(w) cw = s2.NewWriter(w)
default: default:

View File

@ -1979,8 +1979,8 @@ func (ctx *Context) UploadFormFiles(destDirectory string, before ...func(*Contex
// which could lead to override existing system files // which could lead to override existing system files
// by ../../$file. // by ../../$file.
// Reported by Frank through security reports. // Reported by Frank through security reports.
file.Filename = strings.TrimLeft(file.Filename, "../") file.Filename = strings.ReplaceAll(file.Filename, "../", "")
file.Filename = strings.TrimLeft(file.Filename, "..\\") file.Filename = strings.ReplaceAll(file.Filename, "..\\", "")
for _, b := range before { for _, b := range before {
if !b(ctx, file) { if !b(ctx, file) {
@ -2859,10 +2859,8 @@ func (ctx *Context) CompressReader(enable bool) error {
return err return err
} }
ctx.request.Body = r ctx.request.Body = r
} else { } else if ok {
if ok { ctx.request.Body = cr.Src
ctx.request.Body = cr.Src
}
} }
return nil return nil
@ -3208,9 +3206,9 @@ func WriteJSON(writer io.Writer, v interface{}, options JSON, optimize bool) (in
} }
if options.UnescapeHTML { if options.UnescapeHTML {
result = bytes.Replace(result, ltHex, lt, -1) result = bytes.ReplaceAll(result, ltHex, lt)
result = bytes.Replace(result, gtHex, gt, -1) result = bytes.ReplaceAll(result, gtHex, gt)
result = bytes.Replace(result, andHex, and, -1) result = bytes.ReplaceAll(result, andHex, and)
} }
if prependSecure { if prependSecure {

View File

@ -41,7 +41,7 @@ func ProxyHandler(target *url.URL) *httputil.ReverseProxy {
if netutil.IsLoopbackHost(target.Host) { if netutil.IsLoopbackHost(target.Host) {
transport := &http.Transport{ transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // lint:ignore
} }
p.Transport = transport p.Transport = transport
} }

View File

@ -56,9 +56,9 @@ func (m myTestTask) OnServe(host TaskHost) {
if rans == exitAfterXRestarts { if rans == exitAfterXRestarts {
m.logger.Println("exit") m.logger.Println("exit")
ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second) ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
defer cancel()
_ = host.Supervisor.Shutdown(ctx) // total shutdown _ = host.Supervisor.Shutdown(ctx) // total shutdown
host.Supervisor.RestoreFlow() // free to exit (if shutdown) host.Supervisor.RestoreFlow() // free to exit (if shutdown)
cancel()
return return
} }

View File

@ -363,9 +363,6 @@ func (e Entry) UintDefault(def uint) (uint, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > uint64(maxValue) {
return def, e.notFound(reflect.Uint)
}
return uint(val), nil return uint(val), nil
case uint: case uint:
return vv, nil return vv, nil
@ -412,9 +409,6 @@ func (e Entry) Uint8Default(def uint8) (uint8, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > math.MaxUint8 {
return def, e.notFound(reflect.Uint8)
}
return uint8(val), nil return uint8(val), nil
case uint: case uint:
if vv > math.MaxUint8 { if vv > math.MaxUint8 {
@ -462,9 +456,6 @@ func (e Entry) Uint16Default(def uint16) (uint16, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > math.MaxUint16 {
return def, e.notFound(reflect.Uint16)
}
return uint16(val), nil return uint16(val), nil
case uint: case uint:
if vv > math.MaxUint16 { if vv > math.MaxUint16 {
@ -509,9 +500,6 @@ func (e Entry) Uint32Default(def uint32) (uint32, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > math.MaxUint32 {
return def, e.notFound(reflect.Uint32)
}
return uint32(val), nil return uint32(val), nil
case uint: case uint:
if vv > math.MaxUint32 { if vv > math.MaxUint32 {
@ -555,9 +543,6 @@ func (e Entry) Uint64Default(def uint64) (uint64, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > math.MaxUint64 {
return def, e.notFound(reflect.Uint64)
}
return uint64(val), nil return uint64(val), nil
case uint8: case uint8:
return uint64(vv), nil return uint64(vv), nil
@ -590,9 +575,6 @@ func (e Entry) Float32Default(key string, def float32) (float32, error) {
if err != nil { if err != nil {
return def, err return def, err
} }
if val > math.MaxFloat32 {
return def, e.notFound(reflect.Float32)
}
return float32(val), nil return float32(val), nil
case float32: case float32:
return vv, nil return vv, nil

View File

@ -442,9 +442,9 @@ func StripPrefix(prefix string, h context.Handler) context.Handler {
func toWebPath(systemPath string) string { func toWebPath(systemPath string) string {
// winos slash to slash // winos slash to slash
webpath := strings.Replace(systemPath, "\\", "/", -1) webpath := strings.ReplaceAll(systemPath, "\\", "/")
// double slashes to single // double slashes to single
webpath = strings.Replace(webpath, "//", "/", -1) webpath = strings.ReplaceAll(webpath, "//", "/")
return webpath return webpath
} }
@ -1013,7 +1013,7 @@ func cacheFiles(ctx stdContext.Context, fs http.FileSystem, names []string, comp
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
default: default:
break break // lint:ignore
} }
if alg == "brotli" { if alg == "brotli" {
@ -1218,7 +1218,7 @@ var _ http.File = (*dir)(nil)
// returns unorderded map of directories both reclusive and flat. // returns unorderded map of directories both reclusive and flat.
func findDirs(fs http.FileSystem, names []string) (map[string]*dir, error) { func findDirs(fs http.FileSystem, names []string) (map[string]*dir, error) {
dirs := make(map[string]*dir, 0) dirs := make(map[string]*dir)
for _, name := range names { for _, name := range names {
f, err := fs.Open(name) f, err := fs.Open(name)

View File

@ -19,7 +19,7 @@ func Param(name string) string {
// WildcardParam receives a parameter name prefixed with the WildcardParamStart symbol. // WildcardParam receives a parameter name prefixed with the WildcardParamStart symbol.
func WildcardParam(name string) string { func WildcardParam(name string) string {
if len(name) == 0 { if name == "" {
return "" return ""
} }
return prefix(name, WildcardParamStart) return prefix(name, WildcardParamStart)

View File

@ -378,7 +378,7 @@ func formatPath(path string) string {
var formattedParts []string var formattedParts []string
parts := strings.Split(path, "/") parts := strings.Split(path, "/")
for _, part := range parts { for _, part := range parts {
if len(part) == 0 { if part == "" {
continue continue
} }
if part[0] == startRune || part[0] == wildcardStartRune { if part[0] == startRune || part[0] == wildcardStartRune {
@ -566,7 +566,7 @@ func (r *Route) Trace(w io.Writer, stoppedIndex int) {
if stoppedIndex != -1 && stoppedIndex <= len(r.Handlers) { if stoppedIndex != -1 && stoppedIndex <= len(r.Handlers) {
if i <= stoppedIndex { if i <= stoppedIndex {
pio.WriteRich(w, " ✓", pio.Green) pio.WriteRich(w, " ✓", pio.Green)
} else { // } else {
// pio.WriteRich(w, " ✕", pio.Red, pio.Underline) // pio.WriteRich(w, " ✕", pio.Red, pio.Underline)
} }
} }

View File

@ -136,10 +136,7 @@ func (router *Router) buildMainHandlerWithFilters(routerFilters map[Party]*Filte
} }
if leftSlashLen == rightSlashLen { if leftSlashLen == rightSlashLen {
if len(left.Path) > len(right.Path) { return len(left.Path) > len(right.Path)
return true
}
return false
} }
return len(left.Path) > len(right.Path) return len(left.Path) > len(right.Path)

View File

@ -480,8 +480,6 @@ type View struct {
var _ Result = View{} var _ Result = View{}
const dotB = byte('.')
// Dispatch writes the template filename, template layout and (any) data to the client. // Dispatch writes the template filename, template layout and (any) data to the client.
// Completes the `Result` interface. // Completes the `Result` interface.
func (r View) Dispatch(ctx *context.Context) { // r as Response view. func (r View) Dispatch(ctx *context.Context) { // r as Response view.

View File

@ -125,7 +125,7 @@ func NewInsecure(t *testing.T, setters ...OptionSetter) *httpexpect.Expect {
setter.Set(conf) setter.Set(conf)
} }
transport := &http.Transport{ transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // lint:ignore
} }
testConfiguration := httpexpect.Config{ testConfiguration := httpexpect.Config{

View File

@ -115,12 +115,10 @@ func (loc *Locale) setString(c *Catalog, key string, value string, vars []Var, f
if err != nil { if err != nil {
return fmt.Errorf("<%s = %s>: %w", key, value, err) return fmt.Errorf("<%s = %s>: %w", key, value, err)
} }
} else { } else if err = c.Set(loc.tag, key, msgs...); err != nil {
// let's make normal keys direct fire: // let's make normal keys direct fire:
// renderer = &simpleRenderer{key, loc.Printer} // renderer = &simpleRenderer{key, loc.Printer}
if err = c.Set(loc.tag, key, msgs...); err != nil { return fmt.Errorf("<%s = %s>: %w", key, value, err)
return fmt.Errorf("<%s = %s>: %w", key, value, err)
}
} }
} }

View File

@ -1,11 +1,8 @@
package internal package internal
import ( import (
"reflect"
"regexp" "regexp"
"sort" "sort"
"golang.org/x/text/message/catalog"
) )
// Var represents a message variable. // Var represents a message variable.
@ -84,7 +81,7 @@ func getVars(loc *Locale, key string, src map[string]interface{}) []Var {
return vars return vars
} }
var unescapeVariableRegex = regexp.MustCompile("\\$\\{(.*?)}") var unescapeVariableRegex = regexp.MustCompile(`\$\{(.*?)}`)
func sortVars(text string, vars []Var) (newVars []Var) { func sortVars(text string, vars []Var) (newVars []Var) {
argth := 1 argth := 1
@ -122,6 +119,7 @@ func removeVarsDuplicates(elements []Var) (result []Var) {
return result return result
} }
/*
func removeMsgVarsDuplicates(elements []catalog.Message) (result []catalog.Message) { func removeMsgVarsDuplicates(elements []catalog.Message) (result []catalog.Message) {
seen := make(map[string]struct{}) seen := make(map[string]struct{})
@ -141,6 +139,7 @@ func removeMsgVarsDuplicates(elements []catalog.Message) (result []catalog.Messa
return return
} }
*/
func getCases(loc *Locale, src map[string]interface{}) []interface{} { func getCases(loc *Locale, src map[string]interface{}) []interface{} {
type PluralCase struct { type PluralCase struct {

View File

@ -142,7 +142,7 @@ func Default() *Application {
app.logger.Debugf(`Log level set to "debug"`) app.logger.Debugf(`Log level set to "debug"`)
// Register the accesslog middleware. // Register the accesslog middleware.
logFile, err := os.OpenFile("./access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) logFile, err := os.OpenFile("./access.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err == nil { if err == nil {
// Close the file on shutdown. // Close the file on shutdown.
app.ConfigureHost(func(su *Supervisor) { app.ConfigureHost(func(su *Supervisor) {

View File

@ -18,7 +18,7 @@ func Parse(fullpath string, paramTypes []ast.ParamType) ([]*ast.ParamStatement,
return nil, fmt.Errorf("empty parameter types") return nil, fmt.Errorf("empty parameter types")
} }
pathParts := strings.SplitN(fullpath, "/", -1) pathParts := strings.Split(fullpath, "/")
p := new(ParamParser) p := new(ParamParser)
statements := make([]*ast.ParamStatement, 0) statements := make([]*ast.ParamStatement, 0)
for i, s := range pathParts { for i, s := range pathParts {

View File

@ -337,7 +337,7 @@ func FileUnbuffered(path string) *AccessLog {
func mustOpenFile(path string) *os.File { func mustOpenFile(path string) *os.File {
// Note: we add os.RDWR in order to be able to read from it, // Note: we add os.RDWR in order to be able to read from it,
// some formatters (e.g. CSV) needs that. // some formatters (e.g. CSV) needs that.
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -1027,7 +1027,7 @@ func (ac *AccessLog) Print(ctx *context.Context,
// but let's don't coplicate things so much // but let's don't coplicate things so much
// as the end-developer can use a custom template. // as the end-developer can use a custom template.
func (ac *AccessLog) writeText(buf *bytes.Buffer, s string) { func (ac *AccessLog) writeText(buf *bytes.Buffer, s string) {
if len(s) == 0 { if s == "" {
if len(ac.Blank) == 0 { if len(ac.Blank) == 0 {
return return
} }

View File

@ -104,34 +104,29 @@ func TestAccessLogBroker(t *testing.T) {
go func() { go func() {
i := 0 i := 0
ln := broker.NewListener() ln := broker.NewListener()
for {
select {
case log, ok := <-ln:
if !ok {
if i != n {
for i < n {
wg.Done()
i++
}
}
t.Log("Log Listener Closed: interrupted") for log := range ln {
return lat := log.Latency
} t.Log(lat.String())
wg.Done()
if expected := time.Duration(i) * time.Second; expected != lat {
panic(fmt.Sprintf("expected latency: %s but got: %s", expected, lat))
}
time.Sleep(1350 * time.Millisecond)
if log.Latency != lat {
panic("expected logger to wait for notifier before release the log")
}
i++
}
lat := log.Latency if i != n {
t.Log(lat.String()) for i < n {
wg.Done() wg.Done()
if expected := time.Duration(i) * time.Second; expected != lat {
panic(fmt.Sprintf("expected latency: %s but got: %s", expected, lat))
}
time.Sleep(1350 * time.Millisecond)
if log.Latency != lat {
panic("expected logger to wait for notifier before release the log")
}
i++ i++
} }
} }
t.Log("Log Listener Closed: interrupted")
}() }()
time.Sleep(time.Second) time.Sleep(time.Second)
@ -258,18 +253,15 @@ func TestAccessLogSetOutput(t *testing.T) {
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
} }
switch i { if i == 5 {
case 5: if w != nil {
if w == nil { now := time.Now()
break ac.SetOutput(w)
} if withSlowClose {
end := time.Since(now)
now := time.Now() if end < time.Second {
ac.SetOutput(w) panic(fmt.Sprintf("[%s] [%d]: SetOutput should wait for previous Close. Expected to return a bit after %s but %s", name, i, time.Second, end))
if withSlowClose { }
end := time.Since(now)
if end < time.Second {
panic(fmt.Sprintf("[%s] [%d]: SetOutput should wait for previous Close. Expected to return a bit after %s but %s", name, i, time.Second, end))
} }
} }
} }

View File

@ -8,9 +8,7 @@ import (
) )
// CSV is a Formatter type for csv encoded logs. // CSV is a Formatter type for csv encoded logs.
type CSV struct { // TODO: change it to use csvutil. type CSV struct {
writer *csv.Writer
writerPool *sync.Pool writerPool *sync.Pool
ac *AccessLog ac *AccessLog

View File

@ -20,7 +20,7 @@ func TestCSV(t *testing.T) {
lat, _ := time.ParseDuration("1s") lat, _ := time.ParseDuration("1s")
print := func() { printFunc := func() {
ac.Print( ac.Print(
nil, nil,
lat, lat,
@ -39,8 +39,8 @@ func TestCSV(t *testing.T) {
} }
// print twice, the header should only be written once. // print twice, the header should only be written once.
print() printFunc()
print() printFunc()
expected := `Timestamp,Latency,Code,Method,Path,IP,Req Values,In,Out expected := `Timestamp,Latency,Code,Method,Path,IP,Req Values,In,Out
725864400000,1s,200,GET,/,::1,sleep=1s,573,81 725864400000,1s,200,GET,/,::1,sleep=1s,573,81

View File

@ -28,10 +28,6 @@ const (
DefaultCookieMaxAge = time.Hour DefaultCookieMaxAge = time.Hour
) )
// cookieExpireDelete may be set on Cookie.Expire for expiring the given cookie.
// Note that the MaxAge is set but we set Expires field in order to support very old browsers too.
var cookieExpireDelete = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
const ( const (
authorizationType = "Basic Authentication" authorizationType = "Basic Authentication"
authenticateHeaderKey = "WWW-Authenticate" authenticateHeaderKey = "WWW-Authenticate"
@ -480,7 +476,7 @@ func (b *BasicAuth) logout(ctx *context.Context) {
// If the custom user does // If the custom user does
// not implement the User interface, then extract from the request header (most common scenario): // not implement the User interface, then extract from the request header (most common scenario):
header := ctx.GetHeader(b.authorizationHeader) header := ctx.GetHeader(b.authorizationHeader)
fullUser, username, password, ok = decodeHeader(header) fullUser, _, _, ok = decodeHeader(header)
} }
if ok { // If it's authorized then try to lock and delete. if ok { // If it's authorized then try to lock and delete.

View File

@ -1,7 +1,7 @@
package requestid package requestid
import ( import (
"crypto/sha1" "crypto/sha256"
"encoding/hex" "encoding/hex"
"net/http/httputil" "net/http/httputil"
@ -102,7 +102,7 @@ func Get(ctx *context.Context) string {
// Hash returns the sha1 hash of the request. // Hash returns the sha1 hash of the request.
// It does not capture error, instead it returns an empty string. // It does not capture error, instead it returns an empty string.
func Hash(ctx *context.Context, includeBody bool) string { func Hash(ctx *context.Context, includeBody bool) string {
h := sha1.New() h := sha256.New() // sha1 fits here as well.
b, err := httputil.DumpRequest(ctx.Request(), includeBody) b, err := httputil.DumpRequest(ctx.Request(), includeBody)
if err != nil { if err != nil {
return "" return ""

View File

@ -56,15 +56,13 @@ func (g GRPC) Apply(c *ControllerActivator) {
path := path.Join(g.ServiceName, m.Name) path := path.Join(g.ServiceName, m.Name)
if g.Strict { if g.Strict {
c.app.Router.HandleMany(http.MethodPost, path, pre) c.app.Router.HandleMany(http.MethodPost, path, pre)
} else { } else if route := c.Handle(http.MethodPost, path, m.Name, pre); route != nil {
if route := c.Handle(http.MethodPost, path, m.Name, pre); route != nil { bckp := route.Description
bckp := route.Description route.Description = "gRPC"
route.Description = "gRPC" if g.Strict {
if g.Strict { route.Description += "-only"
route.Description += "-only"
}
route.Description += " " + bckp // e.g. "gRPC controller"
} }
route.Description += " " + bckp // e.g. "gRPC controller"
} }
} }

View File

@ -1,7 +1,6 @@
package sessions package sessions
import ( import (
"math"
"reflect" "reflect"
"strconv" "strconv"
"sync" "sync"
@ -327,9 +326,6 @@ func (s *Session) GetUint64(key string) (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
if val > math.MaxUint64 {
break
}
return uint64(val), nil return uint64(val), nil
case uint8: case uint8:
return uint64(vv), nil return uint64(vv), nil

View File

@ -39,7 +39,7 @@ func Ace(fs interface{}, extension string) *AceEngine {
s := &AceEngine{HTMLEngine: HTML(fs, extension), indent: ""} s := &AceEngine{HTMLEngine: HTML(fs, extension), indent: ""}
s.name = "Ace" s.name = "Ace"
funcs := make(map[string]interface{}, 0) funcs := make(map[string]interface{})
once := new(sync.Once) once := new(sync.Once)

View File

@ -143,6 +143,10 @@ func (s *AmberEngine) AddFunc(funcName string, funcBody interface{}) {
// Returns an error if something bad happens, user is responsible to catch it. // Returns an error if something bad happens, user is responsible to catch it.
func (s *AmberEngine) Load() error { func (s *AmberEngine) Load() error {
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error { return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info == nil || info.IsDir() { if info == nil || info.IsDir() {
return nil return nil
} }

View File

@ -213,6 +213,10 @@ func (s *DjangoEngine) RegisterTag(tagName string, fn TagParser) error {
// Returns an error if something bad happens, user is responsible to catch it. // Returns an error if something bad happens, user is responsible to catch it.
func (s *DjangoEngine) Load() error { func (s *DjangoEngine) Load() error {
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error { return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info == nil || info.IsDir() { if info == nil || info.IsDir() {
return nil return nil
} }

View File

@ -19,9 +19,10 @@ type HandlebarsEngine struct {
// files configuration // files configuration
rootDir string rootDir string
extension string extension string
assetFn func(name string) ([]byte, error) // for embedded, in combination with directory & extension // Not used anymore.
namesFn func() []string // for embedded, in combination with directory & extension // assetFn func(name string) ([]byte, error) // for embedded, in combination with directory & extension
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded. // namesFn func() []string // for embedded, in combination with directory & extension
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
// parser configuration // parser configuration
layout string layout string
rmu sync.RWMutex rmu sync.RWMutex

View File

@ -246,6 +246,10 @@ func (s *HTMLEngine) load() error {
} }
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error { return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info == nil || info.IsDir() { if info == nil || info.IsDir() {
return nil return nil
} }
@ -357,7 +361,7 @@ func (s *HTMLEngine) layoutFuncsFor(lt *template.Template, name string, binding
func (s *HTMLEngine) runtimeFuncsFor(t *template.Template, name string, binding interface{}) { func (s *HTMLEngine) runtimeFuncsFor(t *template.Template, name string, binding interface{}) {
funcs := template.FuncMap{ funcs := template.FuncMap{
"part": func(partName string) (template.HTML, error) { "part": func(partName string) (template.HTML, error) {
nameTemp := strings.Replace(name, s.extension, "", -1) nameTemp := strings.ReplaceAll(name, s.extension, "")
fullPartName := fmt.Sprintf("%s-%s", nameTemp, partName) fullPartName := fmt.Sprintf("%s-%s", nameTemp, partName)
result, err := s.executeTemplateBuf(fullPartName, binding) result, err := s.executeTemplateBuf(fullPartName, binding)
if err != nil { if err != nil {

View File

@ -222,6 +222,10 @@ func (l *jetLoader) Exists(name string) (string, bool) {
// Load should load the templates from a physical system directory or by an embedded one (assets/go-bindata). // Load should load the templates from a physical system directory or by an embedded one (assets/go-bindata).
func (s *JetEngine) Load() error { func (s *JetEngine) Load() error {
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error { return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info == nil || info.IsDir() { if info == nil || info.IsDir() {
return nil return nil
} }