diff --git a/README.md b/README.md index 1b5f9a6..8b6998c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ It supports a functional API for defining tags and filters. On the one hand, thi - [Contribute](#contribute) - [Setup](#setup) - [Workflow](#workflow) + - [Style Guide](#style-guide) - [Working on the Parser and Lexer](#working-on-the-parser-and-lexer) - [References](#references) - [Attribution](#attribution) @@ -91,6 +92,12 @@ godoc -http=:6060& open http://localhost:6060/pkg/github.com/osteele/liquid/ ``` +### Style Guide + +`make test` and `make lint` should pass. + +The cyclomatic complexity checks on generated functions, hand-written parsers, and some of the generic interpreter functions, have been disabled (via `nolint: gocyclo`). IMO this check isn't appropriate for those classes of functions. This isn't a license to disable cyclomatic complexity or lint in general willy nilly. + ### Working on the Parser and Lexer To work on the lexer, install Ragel. On macOS: `brew install ragel`. diff --git a/chunks/chunk.go b/chunks/chunk.go index 720dafd..e54b51e 100644 --- a/chunks/chunk.go +++ b/chunks/chunk.go @@ -36,13 +36,13 @@ type SourceInfo struct { func (c Chunk) String() string { switch c.Type { case TextChunkType: - return fmt.Sprintf("%s{%#v}", c.Type, c.Source) + return fmt.Sprintf("%v{%#v}", c.Type, c.Source) case TagChunkType: - return fmt.Sprintf("%s{Tag:%#v, Args:%#v}", c.Type, c.Name, c.Args) + return fmt.Sprintf("%v{Tag:%#v, Args:%#v}", c.Type, c.Name, c.Args) case ObjChunkType: - return fmt.Sprintf("%s{%#v}", c.Type, c.Args) + return fmt.Sprintf("%v{%#v}", c.Type, c.Args) default: - return fmt.Sprintf("%s{%#v}", c.Type, c.Source) + return fmt.Sprintf("%v{%#v}", c.Type, c.Source) } } diff --git a/chunks/parser.go b/chunks/parser.go index 0eb0f02..73497f7 100644 --- a/chunks/parser.go +++ b/chunks/parser.go @@ -12,7 +12,7 @@ func (s Settings) Parse(source string) (ASTNode, error) { } // Parse creates an AST from a sequence of Chunks. -func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) { +func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) { // nolint: gocyclo // a stack of control tag state, for matching nested {%if}{%endif%} etc. type frame struct { cd *controlTagDefinition // saved local ccd @@ -104,6 +104,7 @@ func (s Settings) parseChunks(chunks []Chunk) (ASTNode, error) { return root, nil } +// nolint: gocyclo func (s Settings) evaluateBuilders(n ASTNode) error { switch n := n.(type) { case *ASTControlTag: diff --git a/expressions/context.go b/expressions/context.go index 2237083..a047b5e 100644 --- a/expressions/context.go +++ b/expressions/context.go @@ -4,7 +4,7 @@ package expressions type Context interface { Get(string) interface{} Set(string, interface{}) - Filters() *FilterDictionary + Filters() *filterDictionary } type context struct { @@ -13,15 +13,15 @@ type context struct { } type Settings struct { - filters *FilterDictionary + filters *filterDictionary } func NewSettings() Settings { - return Settings{NewFilterDictionary()} + return Settings{newFilterDictionary()} } func (s Settings) AddFilter(name string, fn interface{}) { - s.filters.AddFilter(name, fn) + s.filters.addFilter(name, fn) } // NewContext makes a new expression evaluation context. @@ -29,7 +29,7 @@ func NewContext(vars map[string]interface{}, s Settings) Context { return &context{vars, s} } -func (c *context) Filters() *FilterDictionary { +func (c *context) Filters() *filterDictionary { return c.filters } diff --git a/expressions/filters.go b/expressions/filters.go index 9e52907..8a51628 100644 --- a/expressions/filters.go +++ b/expressions/filters.go @@ -23,16 +23,16 @@ func (e UndefinedFilter) Error() string { type valueFn func(Context) interface{} -type FilterDictionary struct { +type filterDictionary struct { filters map[string]interface{} } -func NewFilterDictionary() *FilterDictionary { - return &FilterDictionary{map[string]interface{}{}} +func newFilterDictionary() *filterDictionary { + return &filterDictionary{map[string]interface{}{}} } -// AddFilter defines a filter. -func (d *FilterDictionary) AddFilter(name string, fn interface{}) { +// addFilter defines a filter. +func (d *filterDictionary) addFilter(name string, fn interface{}) { rf := reflect.ValueOf(fn) switch { case rf.Kind() != reflect.Func: @@ -53,7 +53,7 @@ func isClosureInterfaceType(t reflect.Type) bool { return closureType.ConvertibleTo(t) && !interfaceType.ConvertibleTo(t) } -func (d *FilterDictionary) runFilter(ctx Context, f valueFn, name string, params []valueFn) interface{} { +func (d *filterDictionary) runFilter(ctx Context, f valueFn, name string, params []valueFn) interface{} { filter, ok := d.filters[name] if !ok { panic(UndefinedFilter(name)) diff --git a/expressions/scanner.go b/expressions/scanner.go index 8576cf5..7ffddff 100644 --- a/expressions/scanner.go +++ b/expressions/scanner.go @@ -1,7 +1,7 @@ //line scanner.rl:1 -// Adapted from https://github.com/mhamrah/thermostat package expressions +// Adapted from https://github.com/mhamrah/thermostat import "fmt" import "strconv" diff --git a/expressions/scanner.rl b/expressions/scanner.rl index 084777c..27c23ab 100644 --- a/expressions/scanner.rl +++ b/expressions/scanner.rl @@ -1,5 +1,4 @@ package expressions -// Adapted from https://github.com/mhamrah/thermostat import "fmt" import "strconv" diff --git a/filters/filters.go b/filters/filters.go index 3500c3e..abe2171 100644 --- a/filters/filters.go +++ b/filters/filters.go @@ -19,7 +19,7 @@ import ( ) // AddStandardFilters defines the standard Liquid filters. -func AddStandardFilters(settings expressions.Settings) { +func AddStandardFilters(settings expressions.Settings) { // nolint: gocyclo // values settings.AddFilter("default", func(value, defaultValue interface{}) interface{} { if value == nil || value == false || generics.IsEmpty(value) { diff --git a/generics/compare.go b/generics/compare.go index 1734cf4..56ae76f 100644 --- a/generics/compare.go +++ b/generics/compare.go @@ -10,7 +10,7 @@ var ( ) // Equal returns a bool indicating whether a == b after conversion. -func Equal(a, b interface{}) bool { +func Equal(a, b interface{}) bool { // nolint: gocyclo if a == nil || b == nil { return a == b } @@ -59,7 +59,7 @@ func Less(a, b interface{}) bool { } } -func joinKind(a, b reflect.Kind) reflect.Kind { +func joinKind(a, b reflect.Kind) reflect.Kind { // nolint: gocyclo if a == b { return a } diff --git a/generics/convert.go b/generics/convert.go index f477a09..8ee3546 100644 --- a/generics/convert.go +++ b/generics/convert.go @@ -23,7 +23,7 @@ func conversionError(modifier string, value interface{}, typ reflect.Type) error // Convert value to the type. This is a more aggressive conversion, that will // recursively create new map and slice values as necessary. It doesn't // handle circular references. -func Convert(value interface{}, target reflect.Type) (interface{}, error) { +func Convert(value interface{}, target reflect.Type) (interface{}, error) { // nolint: gocyclo r := reflect.ValueOf(value) if r.Type().ConvertibleTo(target) { return r.Convert(target).Interface(), nil