Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize #95

Merged
merged 8 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,46 @@ issues:

# go generate introduces these
- path: expressions/scanner.go
linters: [deadcode, unused, varcheck]
linters: [deadcode, unused, varcheck, revive, stylecheck, gocritic, unconvert, gofumpt]
linters:
enable:
- gofmt
enable-all: true
disable:
- depguard
- exhaustruct
- varnamelen
- godox
- wsl
- wrapcheck
- gomnd
- gochecknoglobals
- exhaustive
- testpackage
- ireturn
- godot
- mnd
- nonamedreturns
- funlen
- gci
- nlreturn
- inamedparam
- lll
- paralleltest
- gocognit
- goconst
- cyclop
- dupword
- whitespace
- nolintlint
- nestif
- forcetypeassert
- interfacebloat
- revive
- gocyclo
- errname
- gosmopolitan
- maintidx

# Todo: re-add
- err113
- errorlint
fix: true
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Contributions:

* Fix array[nil] ([e39a1fe](https://github.com/osteele/liquid/commit/e39a1fe))
* Fix file not found tests for Windows ([068afef](https://github.com/osteele/liquid/commit/068afef))
* Restore m['str'] where m map[interface{}]interface{}
* Restore m['str'] where m map[any]any
([9852226](https://github.com/osteele/liquid/commit/9852226))

### Docs
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ generator.
```go
engine := liquid.NewEngine()
template := `<h1>{{ page.title }}</h1>`
bindings := map[string]interface{}{
bindings := map[string]any{
"page": map[string]string{
"title": "Introduction",
},
Expand Down Expand Up @@ -84,15 +84,15 @@ These features of Shopify Liquid aren't implemented:

Drops have a different design from the Shopify (Ruby) implementation. A Ruby
drop sets `liquid_attributes` to a list of attributes that are exposed to
Liquid. A Go drop implements `ToLiquid() interface{}`, that returns a proxy
Liquid. A Go drop implements `ToLiquid() any`, that returns a proxy
object. Conventionally, the proxy is a `map` or `struct` that defines the
exposed properties. See <http://godoc.org/github.com/osteele/liquid#Drop> for
additional information.

### Value Types

`Render` and friends take a `Bindings` parameter. This is a map of `string` to
`interface{}`, that associates template variable names with Go values.
`any`, that associates template variable names with Go values.

Any Go value can be used as a variable value. These values have special meaning:

Expand Down
12 changes: 6 additions & 6 deletions cmd/liquid/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (

// for testing
var (
stderr io.Writer = os.Stderr
stdout io.Writer = os.Stdout
stdin io.Reader = os.Stdin
exit func(int) = os.Exit
env func() []string = os.Environ
bindings map[string]interface{} = map[string]interface{}{}
stderr io.Writer = os.Stderr
stdout io.Writer = os.Stdout
stdin io.Reader = os.Stdin
exit func(int) = os.Exit
env func() []string = os.Environ
bindings map[string]any = map[string]any{}
strictVars bool
)

Expand Down
4 changes: 2 additions & 2 deletions cmd/liquid/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestMain(t *testing.T) {
stdin = os.Stdin
exit = os.Exit
env = os.Environ
bindings = map[string]interface{}{}
bindings = map[string]any{}
}()

exit = func(n int) {
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestMain(t *testing.T) {
main()
require.True(t, envCalled)
require.Equal(t, "Hello, World!", buf.String())
bindings = make(map[string]interface{})
bindings = make(map[string]any)

// filename
stdin = os.Stdin
Expand Down
4 changes: 2 additions & 2 deletions drops.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package liquid

// Drop indicates that the object will present to templates as its ToLiquid value.
type Drop interface {
ToLiquid() interface{}
ToLiquid() any
}

// FromDrop returns returns object.ToLiquid() if object's type implement this function;
// else the object itself.
func FromDrop(object interface{}) interface{} {
func FromDrop(object any) any {
switch object := object.(type) {
case Drop:
return object.ToLiquid()
Expand Down
18 changes: 9 additions & 9 deletions drops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

type dropTest struct{}

func (d dropTest) ToLiquid() interface{} { return "drop" }
func (d dropTest) ToLiquid() any { return "drop" }

func TestDrops(t *testing.T) {
require.Equal(t, "drop", FromDrop(dropTest{}))
Expand All @@ -20,22 +20,22 @@ func TestDrops(t *testing.T) {

type redConvertible struct{}

func (c redConvertible) ToLiquid() interface{} {
return map[string]interface{}{
func (c redConvertible) ToLiquid() any {
return map[string]any{
"color": "red",
}
}

func ExampleDrop_map() {
// type redConvertible struct{}
//
// func (c redConvertible) ToLiquid() interface{} {
// return map[string]interface{}{
// func (c redConvertible) ToLiquid() any {
// return map[string]any{
// "color": "red",
// }
// }
engine := NewEngine()
bindings := map[string]interface{}{
bindings := map[string]any{
"car": redConvertible{},
}
template := `{{ car.color }}`
Expand All @@ -49,7 +49,7 @@ func ExampleDrop_map() {

type car struct{ color, model string }

func (c car) ToLiquid() interface{} {
func (c car) ToLiquid() any {
return carDrop{c.model, c.color}
}

Expand All @@ -65,7 +65,7 @@ func (c carDrop) Drive() string {
func ExampleDrop_struct() {
// type car struct{ color, model string }
//
// func (c car) ToLiquid() interface{} {
// func (c car) ToLiquid() any {
// return carDrop{c.model, c.color}
// }
//
Expand All @@ -79,7 +79,7 @@ func ExampleDrop_struct() {
// }

engine := NewEngine()
bindings := map[string]interface{}{
bindings := map[string]any{
"car": car{"blue", "S85"},
}
template := `{{ car.color }} {{ car.Drive }} Model {{ car.Model }}`
Expand Down
2 changes: 1 addition & 1 deletion engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (e *Engine) RegisterBlock(name string, td Renderer) {
// * https://github.com/osteele/liquid/blob/main/filters/standard_filters.go
//
// * https://github.com/osteele/gojekyll/blob/master/filters/filters.go
func (e *Engine) RegisterFilter(name string, fn interface{}) {
func (e *Engine) RegisterFilter(name string, fn any) {
e.cfg.AddFilter(name, fn)
}

Expand Down
16 changes: 10 additions & 6 deletions engine_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package liquid
import (
"fmt"
"log"
"strconv"
"strings"

"github.com/osteele/liquid/render"
Expand All @@ -11,7 +12,7 @@ import (
func Example() {
engine := NewEngine()
source := `<h1>{{ page.title }}</h1>`
bindings := map[string]interface{}{
bindings := map[string]any{
"page": map[string]string{
"title": "Introduction",
},
Expand All @@ -27,18 +28,19 @@ func Example() {
func ExampleEngine_ParseAndRenderString() {
engine := NewEngine()
source := `{{ hello | capitalize | append: " Mundo" }}`
bindings := map[string]interface{}{"hello": "hola"}
bindings := map[string]any{"hello": "hola"}
out, err := engine.ParseAndRenderString(source, bindings)
if err != nil {
log.Fatalln(err)
}
fmt.Println(out)
// Output: Hola Mundo
}

func ExampleEngine_ParseTemplate() {
engine := NewEngine()
source := `{{ hello | capitalize | append: " Mundo" }}`
bindings := map[string]interface{}{"hello": "hola"}
bindings := map[string]any{"hello": "hola"}
tpl, err := engine.ParseString(source)
if err != nil {
log.Fatalln(err)
Expand All @@ -50,11 +52,12 @@ func ExampleEngine_ParseTemplate() {
fmt.Println(out)
// Output: Hola Mundo
}

func ExampleEngine_RegisterFilter() {
engine := NewEngine()
engine.RegisterFilter("has_prefix", strings.HasPrefix)
template := `{{ title | has_prefix: "Intro" }}`
bindings := map[string]interface{}{
bindings := map[string]any{
"title": "Introduction",
}
out, err := engine.ParseAndRenderString(template, bindings)
Expand All @@ -64,6 +67,7 @@ func ExampleEngine_RegisterFilter() {
fmt.Println(out)
// Output: true
}

func ExampleEngine_RegisterFilter_optional_argument() {
engine := NewEngine()
// func(a, b int) int) would default the second argument to zero.
Expand All @@ -74,7 +78,7 @@ func ExampleEngine_RegisterFilter_optional_argument() {
return a + b(1)
})
template := `10 + 1 = {{ m | inc }}; 20 + 5 = {{ n | inc: 5 }}`
bindings := map[string]interface{}{
bindings := map[string]any{
"m": 10,
"n": "20",
}
Expand Down Expand Up @@ -108,7 +112,7 @@ func ExampleEngine_RegisterBlock() {
return "", err
}
n := len(s)
return fmt.Sprint(n), nil
return strconv.Itoa(n), nil
})

template := `{% length %}abc{% endlength %}`
Expand Down
24 changes: 12 additions & 12 deletions engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ package liquid
import (
"bytes"
"encoding/json"
"fmt"
"io"
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

var emptyBindings = map[string]interface{}{}
var emptyBindings = map[string]any{}

// There's a lot more tests in the filters and tags sub-packages.
// This collects a minimal set for testing end-to-end.
Expand All @@ -21,18 +21,18 @@ var liquidTests = []struct{ in, expected string }{
{`{{ "upper" | upcase }}`, "UPPER"},
}

var testBindings = map[string]interface{}{
var testBindings = map[string]any{
"x": 123,
"ar": []string{"first", "second", "third"},
"page": map[string]interface{}{
"page": map[string]any{
"title": "Introduction",
},
}

func TestEngine_ParseAndRenderString(t *testing.T) {
engine := NewEngine()
for i, test := range liquidTests {
t.Run(fmt.Sprint(i+1), func(t *testing.T) {
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
out, err := engine.ParseAndRenderString(test.in, testBindings)
require.NoErrorf(t, err, test.in)
require.Equalf(t, test.expected, out, test.in)
Expand All @@ -51,7 +51,7 @@ func (c *capWriter) Write(bs []byte) (int, error) {
func TestEngine_ParseAndFRender(t *testing.T) {
engine := NewEngine()
for i, test := range liquidTests {
t.Run(fmt.Sprint(i+1), func(t *testing.T) {
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
wr := capWriter{}
err := engine.ParseAndFRender(&wr, []byte(test.in), testBindings)
require.NoErrorf(t, err, test.in)
Expand All @@ -61,8 +61,8 @@ func TestEngine_ParseAndFRender(t *testing.T) {
}

func TestEngine_ParseAndRenderString_ptr_to_hash(t *testing.T) {
params := map[string]interface{}{
"message": &map[string]interface{}{
params := map[string]any{
"message": &map[string]any{
"Text": "hello",
"jsonNumber": json.Number("123"),
},
Expand All @@ -77,7 +77,7 @@ func TestEngine_ParseAndRenderString_ptr_to_hash(t *testing.T) {
type testStruct struct{ Text string }

func TestEngine_ParseAndRenderString_struct(t *testing.T) {
params := map[string]interface{}{
params := map[string]any{
"message": testStruct{
Text: "hello",
},
Expand All @@ -103,7 +103,7 @@ func TestEngine_ParseAndRender_errors(t *testing.T) {
func BenchmarkEngine_Parse(b *testing.B) {
engine := NewEngine()
buf := new(bytes.Buffer)
for i := 0; i < 1000; i++ {
for range 1000 {
_, err := io.WriteString(buf, `if{% if true %}true{% elsif %}elsif{% else %}else{% endif %}`)
require.NoError(b, err)
_, err = io.WriteString(buf, `loop{% for item in array %}loop{% break %}{% endfor %}`)
Expand All @@ -115,7 +115,7 @@ func BenchmarkEngine_Parse(b *testing.B) {
}
s := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for range b.N {
_, err := engine.ParseTemplate(s)
require.NoError(b, err)
}
Expand All @@ -134,5 +134,5 @@ func TestEngine_ParseTemplateAndCache(t *testing.T) {
// ...and execute the second.
result, err := eng.ParseAndRender(templateB, Bindings{})
require.NoError(t, err)
require.Equal(t, string(result), "Foo, Bar")
require.Equal(t, "Foo, Bar", string(result))
}
Loading
Loading