From 5e64024c1dcc23300ad3c00b8b0cb72f0db22ade Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:28:07 -0500 Subject: [PATCH 1/6] task: removing deps and updating to go 1.22 --- .github/FUNDING.yml | 4 - README.md | 15 ++-- SHOULDERS.md | 35 -------- ast/ast.go | 2 +- ast/ast_test.go | 4 +- ast/return_statement.go | 2 +- comments_test.go | 6 +- compiler.go | 6 +- context.go | 6 +- context_test.go | 2 +- error_test.go | 2 +- escape_test.go | 2 +- example_test.go | 2 +- for_test.go | 28 +++---- forms.go | 18 ----- functions_test.go | 6 +- go.mod | 20 +++-- go.sum | 68 ++-------------- hashes_test.go | 2 +- helper_context.go | 68 ++++++++++++++++ helpers.go | 78 +----------------- helpers/content/content.go | 17 ++++ helpers/content/for.go | 30 +++++++ helpers/content/for_test.go | 41 ++++++++++ helpers/content/of.go | 35 ++++++++ helpers/content/of_test.go | 50 ++++++++++++ helpers/debug/debug.go | 27 +++++++ helpers/debug/debug_test.go | 26 ++++++ helpers/debug/inspect.go | 10 +++ helpers/debug/inspect_test.go | 17 ++++ helpers/encoders/encoders.go | 18 +++++ helpers/encoders/json.go | 16 ++++ helpers/encoders/json_test.go | 44 ++++++++++ helpers/encoders/raw.go | 8 ++ helpers/encoders/raw_test.go | 13 +++ helpers/env/env.go | 46 +++++++++++ helpers/env/env_test.go | 1 + helpers/escapes/escapes.go | 17 ++++ helpers/escapes/html.go | 19 +++++ helpers/escapes/html_test.go | 41 ++++++++++ helpers/escapes/js.go | 6 ++ helpers/hctx/context.go | 20 +++++ helpers/hctx/map.go | 18 +++++ helpers/hctx/map_test.go | 38 +++++++++ helpers/helpers.go | 39 +++++++++ helpers/helptest/context.go | 90 +++++++++++++++++++++ helpers/inflections/inflections.go | 55 +++++++++++++ helpers/iterators/between.go | 7 ++ helpers/iterators/group_by.go | 64 +++++++++++++++ helpers/iterators/group_by_test.go | 59 ++++++++++++++ helpers/iterators/iterator.go | 6 ++ helpers/iterators/iterators.go | 21 +++++ helpers/iterators/range.go | 21 +++++ helpers/iterators/until.go | 7 ++ helper_map.go => helpers/map.go | 21 +++-- helpers/meta/len.go | 17 ++++ helpers/meta/len_test.go | 27 +++++++ helpers/meta/meta.go | 17 ++++ helpers/paths/path_for.go | 113 ++++++++++++++++++++++++++ helpers/paths/path_for_test.go | 68 ++++++++++++++++ helpers/paths/paths.go | 15 ++++ helpers/text/text.go | 15 ++++ helpers/text/truncate.go | 31 +++++++ helpers/text/truncate_test.go | 53 ++++++++++++ helpers_test.go | 3 +- if_test.go | 2 +- iterators_test.go | 2 +- lexer/lexer.go | 2 +- lexer/lexer_test.go | 6 +- line_number_test.go | 10 +-- markdown_helper.go | 20 ----- markdown_helper_test.go | 26 ------ math_test.go | 2 +- numbers_test.go | 2 +- parser/parser.go | 6 +- parser/parser_test.go | 4 +- parser/precedences.go | 2 +- partial_helper.go | 7 -- partial_helper_test.go | 125 +---------------------------- plush.go | 2 +- plush_test.go | 2 +- quotes_test.go | 2 +- return_exit_test.go | 2 +- script_test.go | 2 +- struct_test.go | 2 +- template.go | 6 +- template_test.go | 2 +- time_test.go | 2 +- user_function.go | 2 +- variables_test.go | 2 +- variadic_test.go | 2 +- 91 files changed, 1462 insertions(+), 465 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 SHOULDERS.md delete mode 100644 forms.go create mode 100644 helper_context.go create mode 100644 helpers/content/content.go create mode 100644 helpers/content/for.go create mode 100644 helpers/content/for_test.go create mode 100644 helpers/content/of.go create mode 100644 helpers/content/of_test.go create mode 100644 helpers/debug/debug.go create mode 100644 helpers/debug/debug_test.go create mode 100644 helpers/debug/inspect.go create mode 100644 helpers/debug/inspect_test.go create mode 100644 helpers/encoders/encoders.go create mode 100644 helpers/encoders/json.go create mode 100644 helpers/encoders/json_test.go create mode 100644 helpers/encoders/raw.go create mode 100644 helpers/encoders/raw_test.go create mode 100644 helpers/env/env.go create mode 100644 helpers/env/env_test.go create mode 100644 helpers/escapes/escapes.go create mode 100644 helpers/escapes/html.go create mode 100644 helpers/escapes/html_test.go create mode 100644 helpers/escapes/js.go create mode 100644 helpers/hctx/context.go create mode 100644 helpers/hctx/map.go create mode 100644 helpers/hctx/map_test.go create mode 100644 helpers/helpers.go create mode 100644 helpers/helptest/context.go create mode 100644 helpers/inflections/inflections.go create mode 100644 helpers/iterators/between.go create mode 100644 helpers/iterators/group_by.go create mode 100644 helpers/iterators/group_by_test.go create mode 100644 helpers/iterators/iterator.go create mode 100644 helpers/iterators/iterators.go create mode 100644 helpers/iterators/range.go create mode 100644 helpers/iterators/until.go rename helper_map.go => helpers/map.go (82%) create mode 100644 helpers/meta/len.go create mode 100644 helpers/meta/len_test.go create mode 100644 helpers/meta/meta.go create mode 100644 helpers/paths/path_for.go create mode 100644 helpers/paths/path_for_test.go create mode 100644 helpers/paths/paths.go create mode 100644 helpers/text/text.go create mode 100644 helpers/text/truncate.go create mode 100644 helpers/text/truncate_test.go delete mode 100644 markdown_helper.go delete mode 100644 markdown_helper_test.go diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 65b45f1..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: markbates -patreon: buffalo diff --git a/README.md b/README.md index 62d17d1..f2997d7 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Plush [![Standard Test](https://github.com/gobuffalo/plush/actions/workflows/standard-go-test.yml/badge.svg)](https://github.com/gobuffalo/plush/actions/workflows/standard-go-test.yml) -[![Go Reference](https://pkg.go.dev/badge/github.com/gobuffalo/plush/v4.svg)](https://pkg.go.dev/github.com/gobuffalo/plush/v4) +[![Go Reference](https://pkg.go.dev/badge/github.com/gobuffalo/plush/v5.svg)](https://pkg.go.dev/github.com/gobuffalo/plush/v5) Plush is the templating system that [Go](http://golang.org) both needs _and_ deserves. Powerful, flexible, and extendable, Plush is there to make writing your templates that much easier. @@ -207,8 +207,8 @@ for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { if (i > 0) { continue } - return v -} + return v +} ``` You can terminate the for loop with `break`: @@ -217,8 +217,8 @@ for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { if (i > 5) { break } - return v -} + return v +} ``` The values inside the `()` part of the statement are the names you wish to give to the key (or index) and the value of the expression. The `expression` can be an array, map, or iterator type. @@ -294,9 +294,9 @@ fmt.Print(s) // output: 45 ``` -## Helpers +## Default helpers -For a full list, and documentation of, all the Helpers included in Plush, see [`github.com/gobuffalo/helpers`](https://godoc.org/github.com/gobuffalo/helpers). +Plush ships with a comprehensive list of helpers to make your life easier. For more info check the helpers package. ### Custom Helpers @@ -350,4 +350,3 @@ This package absolutely 100% could not have been written without the help of Tho Not only did the book make understanding the process of writing lexers, parsers, and asts, but it also provided the basis for the syntax of Plush itself. If you have yet to read Thorsten's book, I can't recommend it enough. Please go and buy it! - diff --git a/SHOULDERS.md b/SHOULDERS.md deleted file mode 100644 index 327644e..0000000 --- a/SHOULDERS.md +++ /dev/null @@ -1,35 +0,0 @@ -# Plush Stands on the Shoulders of Giants - -Plush does not try to reinvent the wheel! Instead, it uses the already great wheels developed by the Go community and puts them all together in the best way possible. Without these giants, this project would not be possible. Please make sure to check them out and thank them for all of their hard work. - -Thank you to the following **GIANTS**: - -* [github.com/aymerick/douceur](https://godoc.org/github.com/aymerick/douceur) -* [github.com/davecgh/go-spew](https://godoc.org/github.com/davecgh/go-spew) -* [github.com/fatih/structs](https://godoc.org/github.com/fatih/structs) -* [github.com/gobuffalo/flect](https://godoc.org/github.com/gobuffalo/flect) -* [github.com/gobuffalo/github_flavored_markdown](https://godoc.org/github.com/gobuffalo/github_flavored_markdown) -* [github.com/gobuffalo/helpers](https://godoc.org/github.com/gobuffalo/helpers) -* [github.com/gobuffalo/tags/v3](https://godoc.org/github.com/gobuffalo/tags/v3) -* [github.com/gobuffalo/validate/v3](https://godoc.org/github.com/gobuffalo/validate/v3) -* [github.com/gofrs/uuid](https://godoc.org/github.com/gofrs/uuid) -* [github.com/gorilla/css](https://godoc.org/github.com/gorilla/css) -* [github.com/kr/pretty](https://godoc.org/github.com/kr/pretty) -* [github.com/kr/pty](https://godoc.org/github.com/kr/pty) -* [github.com/kr/text](https://godoc.org/github.com/kr/text) -* [github.com/microcosm-cc/bluemonday](https://godoc.org/github.com/microcosm-cc/bluemonday) -* [github.com/pmezard/go-difflib](https://godoc.org/github.com/pmezard/go-difflib) -* [github.com/sergi/go-diff](https://godoc.org/github.com/sergi/go-diff) -* [github.com/sourcegraph/annotate](https://godoc.org/github.com/sourcegraph/annotate) -* [github.com/sourcegraph/syntaxhighlight](https://godoc.org/github.com/sourcegraph/syntaxhighlight) -* [github.com/stretchr/objx](https://godoc.org/github.com/stretchr/objx) -* [github.com/stretchr/testify](https://godoc.org/github.com/stretchr/testify) -* [golang.org/x/net](https://godoc.org/golang.org/x/net) -* [golang.org/x/sync](https://godoc.org/golang.org/x/sync) -* [golang.org/x/sys](https://godoc.org/golang.org/x/sys) -* [golang.org/x/term](https://godoc.org/golang.org/x/term) -* [golang.org/x/text](https://godoc.org/golang.org/x/text) -* [golang.org/x/tools](https://godoc.org/golang.org/x/tools) -* [gopkg.in/check.v1](https://godoc.org/gopkg.in/check.v1) -* [gopkg.in/yaml.v2](https://godoc.org/gopkg.in/yaml.v2) -* [gopkg.in/yaml.v3](https://godoc.org/gopkg.in/yaml.v3) diff --git a/ast/ast.go b/ast/ast.go index 7f7775a..dce4450 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -1,6 +1,6 @@ package ast -import "github.com/gobuffalo/plush/v4/token" +import "github.com/gobuffalo/plush/v5/token" type TokenAble struct { token.Token diff --git a/ast/ast_test.go b/ast/ast_test.go index 9d43053..ee75544 100644 --- a/ast/ast_test.go +++ b/ast/ast_test.go @@ -3,8 +3,8 @@ package ast_test import ( "testing" - "github.com/gobuffalo/plush/v4/ast" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/token" "github.com/stretchr/testify/require" ) diff --git a/ast/return_statement.go b/ast/return_statement.go index 372b25b..ab30eb1 100644 --- a/ast/return_statement.go +++ b/ast/return_statement.go @@ -3,7 +3,7 @@ package ast import ( "bytes" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/token" ) type ReturnStatement struct { diff --git a/comments_test.go b/comments_test.go index 07d9fff..7cfeca8 100644 --- a/comments_test.go +++ b/comments_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) @@ -32,12 +32,12 @@ func Test_BlockComment(t *testing.T) { r := require.New(t) input := map[string]string{ "test1": ` - <%# this is + <%# this is a block comment %> Hi `, "test2": ` - <% <%# this is + <% <%# this is a block comment %> %> Hi`, } diff --git a/compiler.go b/compiler.go index d796396..27c68ad 100644 --- a/compiler.go +++ b/compiler.go @@ -3,7 +3,7 @@ package plush import ( "fmt" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/token" "html/template" "reflect" @@ -11,8 +11,8 @@ import ( "strings" "time" - "github.com/gobuffalo/helpers/hctx" - "github.com/gobuffalo/plush/v4/ast" + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/helpers/hctx" ) type ErrUnknownIdentifier struct { diff --git a/context.go b/context.go index 338fe4d..df96406 100644 --- a/context.go +++ b/context.go @@ -4,7 +4,7 @@ import ( "context" "sync" - "github.com/gobuffalo/helpers/hctx" + "github.com/gobuffalo/plush/v5/helpers/hctx" ) var _ context.Context = &Context{} @@ -85,7 +85,7 @@ func NewContextWith(data map[string]interface{}) *Context { moot: &sync.Mutex{}, } - for k, v := range Helpers.helpers { + for k, v := range Helpers.All() { if !c.Has(k) { c.Set(k, v) } @@ -105,7 +105,7 @@ func NewContextWithOuter(data map[string]interface{}, out *Context) *Context { moot: &sync.Mutex{}, } - for k, v := range Helpers.helpers { + for k, v := range Helpers.All() { if !c.Has(k) && !c.outer.Has(k) { c.Set(k, v) } diff --git a/context_test.go b/context_test.go index 3d4644e..621c1a7 100644 --- a/context_test.go +++ b/context_test.go @@ -6,7 +6,7 @@ import ( "golang.org/x/sync/errgroup" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/error_test.go b/error_test.go index ce06ee8..aa3b239 100644 --- a/error_test.go +++ b/error_test.go @@ -6,7 +6,7 @@ import ( "errors" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/escape_test.go b/escape_test.go index 67926ef..99ebc0e 100644 --- a/escape_test.go +++ b/escape_test.go @@ -4,7 +4,7 @@ import ( "html/template" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/example_test.go b/example_test.go index a6a9f87..145e9a3 100644 --- a/example_test.go +++ b/example_test.go @@ -5,7 +5,7 @@ import ( "html/template" "log" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" ) // ExampleRender using `if`, `for`, `else`, functions, etc... diff --git a/for_test.go b/for_test.go index 933b9f0..36bb765 100644 --- a/for_test.go +++ b/for_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) @@ -43,13 +43,13 @@ func Test_Render_For_Array_Continue(t *testing.T) { input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { %>Start<% if (v == 1 || v ==3 || v == 5 || v == 7 || v == 9) { - - + + %>Odd<% continue } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -60,13 +60,13 @@ func Test_Render_For_Array_Continue(t *testing.T) { func Test_Render_For_Array_WithNoOutput(t *testing.T) { r := require.New(t) input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { - + if (v == 1 || v == 2 || v ==3 || v == 4|| v == 5 || v == 6 || v == 7 || v == 8 || v == 9 || v == 10) { continue } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -79,7 +79,7 @@ func Test_Render_For_Array_WithoutContinue(t *testing.T) { input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { if (v == 1 || v ==3 || v == 5 || v == 7 || v == 9) { } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -91,7 +91,7 @@ func Test_Render_For_Array_ContinueNoControl(t *testing.T) { r := require.New(t) input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { continue - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -104,13 +104,13 @@ func Test_Render_For_Array_Break_String(t *testing.T) { input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { %>Start<% if (v == 5) { - - + + %>Odd<% break } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -124,7 +124,7 @@ func Test_Render_For_Array_WithBreakFirstValue(t *testing.T) { if (v == 1 || v ==3 || v == 5 || v == 7 || v == 9) { break } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -139,7 +139,7 @@ func Test_Render_For_Array_WithBreakFirstValueWithReturn(t *testing.T) { %><%=v%><% break } - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) @@ -150,7 +150,7 @@ func Test_Render_For_Array_Break(t *testing.T) { r := require.New(t) input := `<%= for (i,v) in [1, 2, 3,4,5,6,7,8,9,10] { break - return v + return v } %>` s, err := plush.Render(input, plush.NewContext()) diff --git a/forms.go b/forms.go deleted file mode 100644 index bc2207b..0000000 --- a/forms.go +++ /dev/null @@ -1,18 +0,0 @@ -package plush - -import ( - "github.com/gobuffalo/helpers/forms" - "github.com/gobuffalo/helpers/forms/bootstrap" -) - -// FormHelper is deprecated use github.com/gobuffalo/helpers/forms#Form instead. -var FormHelper = forms.Form - -// FormForHelper is deprecated use github.com/gobuffalo/helpers/forms#FormFor instead. -var FormForHelper = forms.FormFor - -// BootstrapFormHelper is deprecated use github.com/gobuffalo/helpers/forms/bootstrap#Form instead. -var BootstrapFormHelper = bootstrap.Form - -// BootstrapFormForHelper is deprecated use github.com/gobuffalo/helpers/forms/bootstrap#FormFor instead. -var BootstrapFormForHelper = bootstrap.FormFor diff --git a/functions_test.go b/functions_test.go index 573dcb7..f01c0da 100644 --- a/functions_test.go +++ b/functions_test.go @@ -6,7 +6,7 @@ import ( "html/template" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) @@ -152,7 +152,7 @@ func Test_Render_Function_With_Backticks_And_Quotes(t *testing.T) { papers.updated_at, papers.id, papers.name, - ( setweight(to_tsvector(papers.name::text), 'A'::"char") || + ( setweight(to_tsvector(papers.name::text), 'A'::"char") || setweight(to_tsvector(papers.author_name), 'B'::"char") ) || setweight(to_tsvector(papers.description), 'C'::"char") AS paper_vector @@ -171,7 +171,7 @@ func Test_Render_Function_With_Backticks_And_Quotes(t *testing.T) { papers.updated_at, papers.id, papers.name, - ( setweight(to_tsvector(papers.name::text), 'A'::"char") || + ( setweight(to_tsvector(papers.name::text), 'A'::"char") || setweight(to_tsvector(papers.author_name), 'B'::"char") ) || setweight(to_tsvector(papers.description), 'C'::"char") AS paper_vector diff --git a/go.mod b/go.mod index d6bf27b..3a6dc12 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,19 @@ -module github.com/gobuffalo/plush/v4 +module github.com/gobuffalo/plush/v5 -go 1.16 +go 1.22 require ( - github.com/gobuffalo/github_flavored_markdown v1.1.4 - github.com/gobuffalo/helpers v0.6.7 + github.com/gobuffalo/flect v1.0.2 github.com/gobuffalo/tags/v3 v3.1.4 - github.com/stretchr/testify v1.8.4 - golang.org/x/sync v0.3.0 + github.com/stretchr/testify v1.9.0 + golang.org/x/sync v0.8.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/kr/pretty v0.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a04042b..19a8d56 100644 --- a/go.sum +++ b/go.sum @@ -1,89 +1,35 @@ -github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= -github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/gobuffalo/flect v0.3.0 h1:erfPWM+K1rFNIQeRPdeEXxo8yFr/PO17lhRnS8FUrtk= github.com/gobuffalo/flect v0.3.0/go.mod h1:5pf3aGnsvqvCj50AVni7mJJF8ICxGZ8HomberC3pXLE= -github.com/gobuffalo/github_flavored_markdown v1.1.3/go.mod h1:IzgO5xS6hqkDmUh91BW/+Qxo/qYnvfzoz3A7uLkg77I= -github.com/gobuffalo/github_flavored_markdown v1.1.4 h1:WacrEGPXUDX+BpU1GM/Y0ADgMzESKNWls9hOTG1MHVs= -github.com/gobuffalo/github_flavored_markdown v1.1.4/go.mod h1:Vl9686qrVVQou4GrHRK/KOG3jCZOKLUqV8MMOAYtlso= -github.com/gobuffalo/helpers v0.6.7 h1:C9CedoRSfgWg2ZoIkVXgjI5kgmSpL34Z3qdnzpfNVd8= -github.com/gobuffalo/helpers v0.6.7/go.mod h1:j0u1iC1VqlCaJEEVkZN8Ia3TEzfj/zoXANqyJExTMTA= +github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= +github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gobuffalo/tags/v3 v3.1.4 h1:X/ydLLPhgXV4h04Hp2xlbI2oc5MDaa7eub6zw8oHjsM= github.com/gobuffalo/tags/v3 v3.1.4/go.mod h1:ArRNo3ErlHO8BtdA0REaZxijuWnWzF6PUXngmMXd2I0= -github.com/gobuffalo/validate/v3 v3.3.3 h1:o7wkIGSvZBYBd6ChQoLxkz2y1pfmhbI4jNJYh6PuNJ4= github.com/gobuffalo/validate/v3 v3.3.3/go.mod h1:YC7FsbJ/9hW/VjQdmXPvFqvRis4vrRYFxr69WiNZw6g= -github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= -github.com/microcosm-cc/bluemonday v1.0.22 h1:p2tT7RNzRdCi0qmwxG+HbqD6ILkmwter1ZwVZn1oTxA= -github.com/microcosm-cc/bluemonday v1.0.22/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d h1:yKm7XZV6j9Ev6lojP2XaIshpT4ymkqhMeSghO5Ps00E= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e h1:qpG93cPwA5f7s/ZPBJnGOYQNK/vKsaDaseuKT5Asee8= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hashes_test.go b/hashes_test.go index 8d13cf6..269247f 100644 --- a/hashes_test.go +++ b/hashes_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/helper_context.go b/helper_context.go new file mode 100644 index 0000000..d3c5e2b --- /dev/null +++ b/helper_context.go @@ -0,0 +1,68 @@ +package plush + +import ( + "fmt" + "strings" + + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +var _ hctx.HelperContext = &HelperContext{} + +// HelperContext is an optional last argument to helpers +// that provides the current context of the call, and access +// to an optional "block" of code that can be executed from +// within the helper. +type HelperContext struct { + hctx.Context + compiler *compiler + block *ast.BlockStatement +} + +const helperContextKind = "HelperContext" + +// Render a string with the current context +func (h HelperContext) Render(s string) (string, error) { + return Render(s, h.Context) +} + +// HasBlock returns true if a block is associated with the helper function +func (h HelperContext) HasBlock() bool { + return h.block != nil +} + +// Block executes the block of template associated with +// the helper, think the block inside of an "if" or "each" +// statement. +func (h HelperContext) Block() (string, error) { + return h.BlockWith(h.Context) +} + +// BlockWith executes the block of template associated with +// the helper, think the block inside of an "if" or "each" +// statement, but with it's own context. +func (h HelperContext) BlockWith(hc hctx.Context) (string, error) { + ctx, ok := hc.(*Context) + if !ok { + return "", fmt.Errorf("expected *Context, got %T", hc) + } + + octx := h.compiler.ctx + defer func() { h.compiler.ctx = octx }() + h.compiler.ctx = ctx + + if h.block == nil { + return "", fmt.Errorf("no block defined") + } + + i, err := h.compiler.evalBlockStatement(h.block) + if err != nil { + return "", err + } + + bb := &strings.Builder{} + h.compiler.write(bb, i) + + return bb.String(), nil +} diff --git a/helpers.go b/helpers.go index 94a2505..8df5c6b 100644 --- a/helpers.go +++ b/helpers.go @@ -1,87 +1,15 @@ package plush import ( - "fmt" - "strings" - "sync" - - "github.com/gobuffalo/helpers" - "github.com/gobuffalo/helpers/forms" - "github.com/gobuffalo/helpers/forms/bootstrap" - "github.com/gobuffalo/helpers/hctx" - "github.com/gobuffalo/plush/v4/ast" + "github.com/gobuffalo/plush/v5/helpers" ) // Helpers contains all of the default helpers for // These will be available to all templates. You should add // any custom global helpers to this list. -var Helpers = HelperMap{ - moot: &sync.Mutex{}, -} +var Helpers = helpers.NewMap(map[string]interface{}{}) func init() { + Helpers.AddMany(helpers.Base) Helpers.Add("partial", PartialHelper) - Helpers.AddMany(helpers.ALL()) - Helpers.Add(forms.FormKey, bootstrap.Form) - Helpers.Add(forms.FormForKey, bootstrap.FormFor) - Helpers.Add("form_for", bootstrap.FormFor) -} - -var _ hctx.HelperContext = &HelperContext{} - -// HelperContext is an optional last argument to helpers -// that provides the current context of the call, and access -// to an optional "block" of code that can be executed from -// within the helper. -type HelperContext struct { - hctx.Context - compiler *compiler - block *ast.BlockStatement -} - -const helperContextKind = "HelperContext" - -// Render a string with the current context -func (h HelperContext) Render(s string) (string, error) { - return Render(s, h.Context) -} - -// HasBlock returns true if a block is associated with the helper function -func (h HelperContext) HasBlock() bool { - return h.block != nil -} - -// Block executes the block of template associated with -// the helper, think the block inside of an "if" or "each" -// statement. -func (h HelperContext) Block() (string, error) { - return h.BlockWith(h.Context) -} - -// BlockWith executes the block of template associated with -// the helper, think the block inside of an "if" or "each" -// statement, but with it's own context. -func (h HelperContext) BlockWith(hc hctx.Context) (string, error) { - ctx, ok := hc.(*Context) - if !ok { - return "", fmt.Errorf("expected *Context, got %T", hc) - } - - octx := h.compiler.ctx - defer func() { h.compiler.ctx = octx }() - h.compiler.ctx = ctx - - if h.block == nil { - return "", fmt.Errorf("no block defined") - } - - i, err := h.compiler.evalBlockStatement(h.block) - if err != nil { - return "", err - } - - bb := &strings.Builder{} - h.compiler.write(bb, i) - - return bb.String(), nil } diff --git a/helpers/content/content.go b/helpers/content/content.go new file mode 100644 index 0000000..ab2a0e9 --- /dev/null +++ b/helpers/content/content.go @@ -0,0 +1,17 @@ +package content + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + OfKey = "contentOf" + ForKey = "contentFor" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + OfKey: ContentOf, + ForKey: ContentFor, + } +} diff --git a/helpers/content/for.go b/helpers/content/for.go new file mode 100644 index 0000000..da9ced8 --- /dev/null +++ b/helpers/content/for.go @@ -0,0 +1,30 @@ +package content + +import ( + "html/template" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// ContentFor stores a block of templating code to be re-used later in the template +// via the contentOf helper. +// An optional map of values can be passed to contentOf, +// which are made available to the contentFor block. +/* + <% contentFor("buttons") { %> + + <% } %> +*/ +func ContentFor(name string, help hctx.HelperContext) { + help.Set("contentFor:"+name, func(data hctx.Map) (template.HTML, error) { + hctx := help.New() + for k, v := range data { + hctx.Set(k, v) + } + body, err := help.BlockWith(hctx) + if err != nil { + return "", err + } + return template.HTML(body), nil + }) +} diff --git a/helpers/content/for_test.go b/helpers/content/for_test.go new file mode 100644 index 0000000..6791618 --- /dev/null +++ b/helpers/content/for_test.go @@ -0,0 +1,41 @@ +package content + +import ( + "errors" + "testing" + + "github.com/gobuffalo/plush/v5/helpers/hctx" + "github.com/gobuffalo/plush/v5/helpers/helptest" + "github.com/stretchr/testify/require" +) + +func Test_ContentFor(t *testing.T) { + r := require.New(t) + + in := "" + hc := helptest.NewContext() + hc.BlockContextFn = func(c hctx.Context) (string, error) { + return in, nil + } + + cf := hc.New().(*helptest.HelperContext) + ContentFor("buttons", hc) + s, err := ContentOf("buttons", hctx.Map{}, cf) + r.NoError(err) + r.Contains(s, in) +} + +func Test_ContentFor_Fail(t *testing.T) { + r := require.New(t) + + hc := helptest.NewContext() + hc.BlockContextFn = func(c hctx.Context) (string, error) { + return "", errors.New("nope") + } + + cf := hc.New().(*helptest.HelperContext) + ContentFor("buttons", hc) + s, err := ContentOf("buttons", hctx.Map{}, cf) + r.Error(err) + r.Empty(s) +} diff --git a/helpers/content/of.go b/helpers/content/of.go new file mode 100644 index 0000000..6bfe5a9 --- /dev/null +++ b/helpers/content/of.go @@ -0,0 +1,35 @@ +package content + +import ( + "errors" + "html/template" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// ContentOf retrieves a stored block for templating and renders it. +// You can pass an optional map of fields that will be set. +/* + <%= contentOf("buttons") %> + <%= contentOf("buttons", {"label": "Click me"}) %> +*/ +func ContentOf(name string, data hctx.Map, help hctx.HelperContext) (template.HTML, error) { + fn, ok := help.Value("contentFor:" + name).(func(data hctx.Map) (template.HTML, error)) + if !ok { + if !help.HasBlock() { + return template.HTML(""), errors.New("missing contentOf block: " + name) + } + + hc := help.New() + for k, v := range data { + hc.Set(k, v) + } + body, err := help.BlockWith(hc) + if err != nil { + return template.HTML(""), err + } + + return template.HTML(body), nil + } + return fn(data) +} diff --git a/helpers/content/of_test.go b/helpers/content/of_test.go new file mode 100644 index 0000000..9c3d23f --- /dev/null +++ b/helpers/content/of_test.go @@ -0,0 +1,50 @@ +package content + +import ( + "html/template" + "testing" + + "github.com/gobuffalo/plush/v5/helpers/hctx" + "github.com/gobuffalo/plush/v5/helpers/helptest" + "github.com/stretchr/testify/require" +) + +func Test_ContentOf_MissingBlock(t *testing.T) { + r := require.New(t) + + cf := helptest.NewContext() + s, err := ContentOf("buttons", hctx.Map{}, cf) + r.Error(err) + r.Empty(s) +} + +func Test_ContentOf_MissingBlock_DefaultBlock(t *testing.T) { + r := require.New(t) + + cf := helptest.NewContext() + cf.BlockContextFn = func(hctx.Context) (string, error) { + return "default", nil + } + + s, err := ContentOf("buttons", hctx.Map{}, cf) + r.NoError(err) + r.Equal(s, template.HTML("default")) +} + +func Test_ContentOf(t *testing.T) { + r := require.New(t) + + cf := helptest.NewContext() + cf.BlockContextFn = func(hctx.Context) (string, error) { + return "default", nil + } + + name := "testing" + cf.Set("contentFor:"+name, func(data hctx.Map) (template.HTML, error) { + return template.HTML("body"), nil + }) + + s, err := ContentOf(name, hctx.Map{}, cf) + r.NoError(err) + r.Equal(s, template.HTML("body")) +} diff --git a/helpers/debug/debug.go b/helpers/debug/debug.go new file mode 100644 index 0000000..0bd5d0d --- /dev/null +++ b/helpers/debug/debug.go @@ -0,0 +1,27 @@ +package debug + +import ( + "fmt" + "html/template" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// Keys to be used in templates for the functions in this package. +const ( + DebugKey = "debug" + InspectKey = "inspect" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + DebugKey: Debug, + InspectKey: Inspect, + } +} + +// Debug by verbosely printing out using 'pre' tags. +func Debug(v interface{}) template.HTML { + return template.HTML(fmt.Sprintf("
%s
", Inspect(v))) +} diff --git a/helpers/debug/debug_test.go b/helpers/debug/debug_test.go new file mode 100644 index 0000000..3b6cedf --- /dev/null +++ b/helpers/debug/debug_test.go @@ -0,0 +1,26 @@ +package debug + +import ( + "fmt" + "html/template" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Debug(t *testing.T) { + table := []struct { + in interface{} + out string + }{ + {"foo", "foo"}, + } + + for _, tt := range table { + t.Run(fmt.Sprint(tt.in), func(st *testing.T) { + r := require.New(st) + out := fmt.Sprintf("
%s
", tt.out) + r.Equal(template.HTML(out), Debug(tt.in)) + }) + } +} diff --git a/helpers/debug/inspect.go b/helpers/debug/inspect.go new file mode 100644 index 0000000..cdf72a5 --- /dev/null +++ b/helpers/debug/inspect.go @@ -0,0 +1,10 @@ +package debug + +import ( + "fmt" +) + +// Inspect the interface using the `%+v` formatter +func Inspect(v interface{}) string { + return fmt.Sprintf("%+v", v) +} diff --git a/helpers/debug/inspect_test.go b/helpers/debug/inspect_test.go new file mode 100644 index 0000000..277ebc5 --- /dev/null +++ b/helpers/debug/inspect_test.go @@ -0,0 +1,17 @@ +package debug + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Inspect(t *testing.T) { + r := require.New(t) + s := struct { + Name string + }{"Ringo"} + + o := Inspect(s) + r.Contains(o, "Ringo") +} diff --git a/helpers/encoders/encoders.go b/helpers/encoders/encoders.go new file mode 100644 index 0000000..dd7d7d0 --- /dev/null +++ b/helpers/encoders/encoders.go @@ -0,0 +1,18 @@ +package encoders + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + ToJSONKey = "toJSON" + RawKey = "raw" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + "json": ToJSON, + RawKey: Raw, + ToJSONKey: ToJSON, + } +} diff --git a/helpers/encoders/json.go b/helpers/encoders/json.go new file mode 100644 index 0000000..ba6a679 --- /dev/null +++ b/helpers/encoders/json.go @@ -0,0 +1,16 @@ +package encoders + +import ( + "encoding/json" + "html/template" +) + +// ToJSON marshals the interface{} and returns it +// as template.HTML +func ToJSON(v interface{}) (template.HTML, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + return template.HTML(b), nil +} diff --git a/helpers/encoders/json_test.go b/helpers/encoders/json_test.go new file mode 100644 index 0000000..a6869ba --- /dev/null +++ b/helpers/encoders/json_test.go @@ -0,0 +1,44 @@ +package encoders + +import ( + "fmt" + "html/template" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_ToJSON(t *testing.T) { + x := struct { + A string + B int + C bool + }{"A", 42, true} + + f := func() {} + + table := []struct { + in interface{} + out string + err bool + }{ + {"foo", `"foo"`, false}, + {[]string{"foo", "bar"}, `["foo","bar"]`, false}, + {x, `{"A":"A","B":42,"C":true}`, false}, + {nil, "null", false}, + {f, "", true}, + } + + for _, tt := range table { + t.Run(fmt.Sprint(tt.in), func(st *testing.T) { + r := require.New(st) + h, err := ToJSON(tt.in) + if tt.err { + r.Error(err) + return + } + r.NoError(err) + r.Equal(template.HTML(tt.out), h) + }) + } +} diff --git a/helpers/encoders/raw.go b/helpers/encoders/raw.go new file mode 100644 index 0000000..7765f3d --- /dev/null +++ b/helpers/encoders/raw.go @@ -0,0 +1,8 @@ +package encoders + +import "html/template" + +// Raw converts a `string` to a `template.HTML` +func Raw(s string) template.HTML { + return template.HTML(s) +} diff --git a/helpers/encoders/raw_test.go b/helpers/encoders/raw_test.go new file mode 100644 index 0000000..550f96c --- /dev/null +++ b/helpers/encoders/raw_test.go @@ -0,0 +1,13 @@ +package encoders + +import ( + "html/template" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Raw(t *testing.T) { + r := require.New(t) + r.Equal(template.HTML("A"), Raw("A")) +} diff --git a/helpers/env/env.go b/helpers/env/env.go new file mode 100644 index 0000000..6ee4f60 --- /dev/null +++ b/helpers/env/env.go @@ -0,0 +1,46 @@ +package env + +import ( + "fmt" + "os" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// Keys to be used in templates for the functions in this package. +const ( + EnvKey = "env" + EnvOrKey = "envOr" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + EnvKey: Env, + EnvOrKey: EnvOr, + } +} + +// Env will return the specified environment variable, +// or an error if it can not be found +// +// <%= env("GOPATH") %> +func Env(key string) (string, error) { + s := os.Getenv(key) + if len(s) == 0 { + return "", fmt.Errorf("could not find ENV %q", key) + } + return s, nil +} + +// Env will return the specified environment variable, +// or the second argument, if not found +// +// <%= envOr("GOPATH", "~/go") %> +func EnvOr(key string, def string) string { + s := os.Getenv(key) + if len(s) == 0 { + return def + } + return s +} diff --git a/helpers/env/env_test.go b/helpers/env/env_test.go new file mode 100644 index 0000000..13a09ae --- /dev/null +++ b/helpers/env/env_test.go @@ -0,0 +1 @@ +package env diff --git a/helpers/escapes/escapes.go b/helpers/escapes/escapes.go new file mode 100644 index 0000000..07db895 --- /dev/null +++ b/helpers/escapes/escapes.go @@ -0,0 +1,17 @@ +package escapes + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + JSEscapeKey = "jsEscape" + HTMLEscapeKey = "htmlEscape" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + JSEscapeKey: JSEscape, + HTMLEscapeKey: HTMLEscape, + } +} diff --git a/helpers/escapes/html.go b/helpers/escapes/html.go new file mode 100644 index 0000000..7ee9d74 --- /dev/null +++ b/helpers/escapes/html.go @@ -0,0 +1,19 @@ +package escapes + +import ( + "html/template" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// HTMLEscape will escape a string for HTML +func HTMLEscape(s string, help hctx.HelperContext) (string, error) { + var err error + if help.HasBlock() { + s, err = help.Block() + } + if err != nil { + return "", err + } + return template.HTMLEscapeString(s), nil +} diff --git a/helpers/escapes/html_test.go b/helpers/escapes/html_test.go new file mode 100644 index 0000000..219972a --- /dev/null +++ b/helpers/escapes/html_test.go @@ -0,0 +1,41 @@ +package escapes + +import ( + "errors" + "html/template" + "testing" + + "github.com/gobuffalo/plush/v5/helpers/helptest" + "github.com/stretchr/testify/require" +) + +func Test_HTMLEscape(t *testing.T) { + r := require.New(t) + + in := `foo` + hc := helptest.NewContext() + s, err := HTMLEscape(in, hc) + r.NoError(err) + r.Equal(template.HTMLEscapeString(in), s) +} + +func Test_HTMLEscape_Block(t *testing.T) { + r := require.New(t) + + in := `foo` + hc := helptest.NewContext() + hc.BlockFn = func() (string, error) { + return in, nil + } + s, err := HTMLEscape("", hc) + r.NoError(err) + r.Equal(template.HTMLEscapeString(in), s) + + hc2 := helptest.NewContext() + hc2.BlockFn = func() (string, error) { + return "", errors.New("nope") + } + s2, err2 := HTMLEscape("", hc2) + r.Error(err2) + r.Empty(s2) +} diff --git a/helpers/escapes/js.go b/helpers/escapes/js.go new file mode 100644 index 0000000..1bf2faa --- /dev/null +++ b/helpers/escapes/js.go @@ -0,0 +1,6 @@ +package escapes + +import "html/template" + +// JSEscape will escape a string for Javascript +var JSEscape = template.JSEscapeString diff --git a/helpers/hctx/context.go b/helpers/hctx/context.go new file mode 100644 index 0000000..548a661 --- /dev/null +++ b/helpers/hctx/context.go @@ -0,0 +1,20 @@ +package hctx + +import ( + "context" +) + +type Context interface { + context.Context + New() Context + Has(key string) bool + Set(key string, value interface{}) +} + +type HelperContext interface { + Context + Block() (string, error) + BlockWith(Context) (string, error) + HasBlock() bool + Render(s string) (string, error) +} diff --git a/helpers/hctx/map.go b/helpers/hctx/map.go new file mode 100644 index 0000000..e62f27f --- /dev/null +++ b/helpers/hctx/map.go @@ -0,0 +1,18 @@ +package hctx + +// Map is a standard map[string]interface{} +// for use throughout the helper packages. +type Map map[string]interface{} + +// Merge creates a single Map from any +// number of Maps. Latter key/value pairs +// will overwrite earlier pairs. +func Merge(maps ...Map) Map { + mx := map[string]interface{}{} + for _, m := range maps { + for k, v := range m { + mx[k] = v + } + } + return mx +} diff --git a/helpers/hctx/map_test.go b/helpers/hctx/map_test.go new file mode 100644 index 0000000..59b3dde --- /dev/null +++ b/helpers/hctx/map_test.go @@ -0,0 +1,38 @@ +package hctx + +import ( + "reflect" + "testing" +) + +func TestMerge(t *testing.T) { + map1 := Map{ + "Test": 1, + "Take": 2, + } + map2 := Map{ + "Testing": '1', + "Taking": "2", + } + mapM := Map{ + "Test": 1, + "Take": 2, + "Testing": '1', + "Taking": "2", + } + tests := []struct { + name string + maps []Map + want Map + }{ + {"good single", []Map{map1}, map1}, + {"good together", []Map{map1, map2}, mapM}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Merge(tt.maps...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Merge() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/helpers/helpers.go b/helpers/helpers.go new file mode 100644 index 0000000..769e474 --- /dev/null +++ b/helpers/helpers.go @@ -0,0 +1,39 @@ +package helpers + +import ( + "github.com/gobuffalo/plush/v5/helpers/content" + "github.com/gobuffalo/plush/v5/helpers/debug" + "github.com/gobuffalo/plush/v5/helpers/encoders" + "github.com/gobuffalo/plush/v5/helpers/env" + "github.com/gobuffalo/plush/v5/helpers/escapes" + "github.com/gobuffalo/plush/v5/helpers/hctx" + "github.com/gobuffalo/plush/v5/helpers/inflections" + "github.com/gobuffalo/plush/v5/helpers/iterators" + "github.com/gobuffalo/plush/v5/helpers/meta" + "github.com/gobuffalo/plush/v5/helpers/paths" + "github.com/gobuffalo/plush/v5/helpers/text" +) + +var Content = content.New() +var Debug = debug.New() +var Encoders = encoders.New() +var Env = env.New() +var Escapes = escapes.New() +var Inflections = inflections.New() +var Iterators = iterators.New() +var Meta = meta.New() +var Paths = paths.New() +var Text = text.New() + +var Base = hctx.Merge( + Content, + Debug, + Encoders, + Env, + Escapes, + Inflections, + Iterators, + Meta, + Paths, + Text, +) diff --git a/helpers/helptest/context.go b/helpers/helptest/context.go new file mode 100644 index 0000000..96a36de --- /dev/null +++ b/helpers/helptest/context.go @@ -0,0 +1,90 @@ +package helptest + +import ( + "context" + "errors" + "sync" + + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +var _ hctx.HelperContext = NewContext() + +func NewContext() *HelperContext { + return &HelperContext{ + Context: context.Background(), + } +} + +type HelperContext struct { + context.Context + data sync.Map + BlockFn func() (string, error) + BlockContextFn func(hctx.Context) (string, error) + RenderFn func(string) (string, error) +} + +func (f HelperContext) New() hctx.Context { + fhc := NewContext() + fhc.Context = f.Context + f.data.Range(func(k, v interface{}) bool { + fhc.data.Store(k, v) + return true + }) + fhc.BlockFn = f.BlockFn + fhc.BlockContextFn = f.BlockContextFn + fhc.RenderFn = f.RenderFn + return fhc +} + +func (f HelperContext) Data() sync.Map { + var m sync.Map + f.data.Range(func(k, v interface{}) bool { + m.Store(k, v) + return true + }) + + return m +} + +func (f HelperContext) Value(key interface{}) interface{} { + v, ok := f.data.Load(key) + if ok { + return v + } + return f.Context.Value(key) +} + +func (f *HelperContext) Set(key string, value interface{}) { + f.data.Store(key, value) +} + +func (f HelperContext) Block() (string, error) { + if f.BlockFn == nil { + return "", errors.New("no block given") + } + return f.BlockFn() +} + +func (f HelperContext) BlockWith(c hctx.Context) (string, error) { + if f.BlockContextFn == nil { + return "", errors.New("no block given") + } + return f.BlockContextFn(c) +} + +func (f HelperContext) HasBlock() bool { + return f.BlockFn != nil || f.BlockContextFn != nil +} + +func (f HelperContext) Render(s string) (string, error) { + if f.RenderFn == nil { + return "", errors.New("render is not available") + } + return f.RenderFn(s) +} + +// Has checks the existence of the key in the context. +func (c HelperContext) Has(key string) bool { + return c.Value(key) != nil +} diff --git a/helpers/inflections/inflections.go b/helpers/inflections/inflections.go new file mode 100644 index 0000000..5b7ba3d --- /dev/null +++ b/helpers/inflections/inflections.go @@ -0,0 +1,55 @@ +package inflections + +import ( + "strings" + + "github.com/gobuffalo/flect" + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// Keys to be used in templates for the functions in this package. +const ( + CamelizeKey = "camelize" + CapitalizeKey = "capitalize" + DasherizeKey = "dasherize" + OrdinalizeKey = "ordinalize" + PluralizeKey = "pluralize" + SingularizeKey = "singularize" + UnderscoreKey = "underscore" + UpcaseKey = "upcase" + DowncaseKey = "downcase" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + CamelizeKey: Camelize, + "camelize_down_first": Camelize, // Deprecated + CapitalizeKey: Capitalize, + DasherizeKey: Dasherize, + OrdinalizeKey: Ordinalize, + PluralizeKey: Pluralize, + SingularizeKey: Singularize, + UnderscoreKey: Underscore, + DowncaseKey: Downcase, + UpcaseKey: Upcase, + + // "asciffy": Asciify, + // "humanize": Humanize, + // "parameterize": Parameterize, + // "pluralize_with_size": PluralizeWithSize, + // "tableize": Tableize, + // "typeify": Typeify, + } +} + +var Upcase = strings.ToUpper +var Downcase = strings.ToLower +var Camelize = flect.Camelize +var Pascalize = flect.Pascalize +var Capitalize = flect.Capitalize +var Dasherize = flect.Dasherize +var Ordinalize = flect.Ordinalize +var Pluralize = flect.Pluralize +var Singularize = flect.Singularize +var Underscore = flect.Underscore diff --git a/helpers/iterators/between.go b/helpers/iterators/between.go new file mode 100644 index 0000000..613b402 --- /dev/null +++ b/helpers/iterators/between.go @@ -0,0 +1,7 @@ +package iterators + +// Between will iterate up to, but not including `b` +// Between(0,10) // 0,1,2,3,4,5,6,7,8,9 +func Between(a, b int) Iterator { + return &ranger{pos: a, end: b - 1} +} diff --git a/helpers/iterators/group_by.go b/helpers/iterators/group_by.go new file mode 100644 index 0000000..d9ed9a2 --- /dev/null +++ b/helpers/iterators/group_by.go @@ -0,0 +1,64 @@ +package iterators + +import ( + "errors" + "fmt" + "reflect" +) + +// GroupBy creates an iterator of groups or sub-slices of the underlying +// Array or Slice entered where each group is of length +// Len(underlying) / size. If Len(underlying) == size it will +// return an iterator with only a single group. +func GroupBy(size int, underlying interface{}) (Iterator, error) { + if size <= 0 { + return nil, errors.New("size must be greater than zero") + } + u := reflect.Indirect(reflect.ValueOf(underlying)) + + group := []reflect.Value{} + switch u.Kind() { + case reflect.Array, reflect.Slice: + if u.Len() == size { + return &groupBy{ + group: []reflect.Value{u}, + }, nil + } + + groupSize := u.Len() / size + if u.Len()%size != 0 { + groupSize++ + } + + pos := 0 + for pos < u.Len() { + e := pos + groupSize + if e > u.Len() { + e = u.Len() + } + group = append(group, u.Slice(pos, e)) + pos += groupSize + } + default: + return nil, fmt.Errorf("can not use %T in groupBy", underlying) + } + g := &groupBy{ + group: group, + } + return g, nil +} + +type groupBy struct { + pos int + group []reflect.Value +} + +// Next returns the next group from the GroupBy +func (g *groupBy) Next() interface{} { + if g.pos >= len(g.group) { + return nil + } + v := g.group[g.pos] + g.pos++ + return v.Interface() +} diff --git a/helpers/iterators/group_by_test.go b/helpers/iterators/group_by_test.go new file mode 100644 index 0000000..f685070 --- /dev/null +++ b/helpers/iterators/group_by_test.go @@ -0,0 +1,59 @@ +package iterators + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_GroupBy(t *testing.T) { + r := require.New(t) + g, err := GroupBy(2, []string{"a", "b", "c", "d", "e"}) + r.NoError(err) + g1 := g.Next() + r.Equal([]string{"a", "b", "c"}, g1) + g2 := g.Next() + r.Equal([]string{"d", "e"}, g2) + r.Nil(g.Next()) +} + +func Test_GroupBy_Exact(t *testing.T) { + r := require.New(t) + g, err := GroupBy(2, []string{"a", "b"}) + r.NoError(err) + g1 := g.Next() + r.Equal([]string{"a", "b"}, g1) + r.Nil(g.Next()) +} + +func Test_GroupBy_Pointer(t *testing.T) { + r := require.New(t) + g, err := GroupBy(2, &[]string{"a", "b", "c", "d", "e"}) + r.NoError(err) + g1 := g.Next() + r.Equal([]string{"a", "b", "c"}, g1) + g2 := g.Next() + r.Equal([]string{"d", "e"}, g2) + r.Nil(g.Next()) +} + +func Test_GroupBy_SmallGroup(t *testing.T) { + r := require.New(t) + g, err := GroupBy(1, []string{"a", "b", "c", "d", "e"}) + r.NoError(err) + g1 := g.Next() + r.Equal([]string{"a", "b", "c", "d", "e"}, g1) + r.Nil(g.Next()) +} + +func Test_GroupBy_NonGroupable(t *testing.T) { + r := require.New(t) + _, err := GroupBy(1, 1) + r.Error(err) +} + +func Test_GroupBy_ZeroSize(t *testing.T) { + r := require.New(t) + _, err := GroupBy(0, []string{"a"}) + r.Error(err) +} diff --git a/helpers/iterators/iterator.go b/helpers/iterators/iterator.go new file mode 100644 index 0000000..7962f3e --- /dev/null +++ b/helpers/iterators/iterator.go @@ -0,0 +1,6 @@ +package iterators + +// Iterator type can be implemented and used by the `for` command to build loops in templates +type Iterator interface { + Next() interface{} +} diff --git a/helpers/iterators/iterators.go b/helpers/iterators/iterators.go new file mode 100644 index 0000000..cef2507 --- /dev/null +++ b/helpers/iterators/iterators.go @@ -0,0 +1,21 @@ +package iterators + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + RangeKey = "range" + BetweenKey = "between" + UntilKey = "until" + GroupByKey = "groupBy" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + RangeKey: Range, + BetweenKey: Between, + UntilKey: Until, + GroupByKey: GroupBy, + } +} diff --git a/helpers/iterators/range.go b/helpers/iterators/range.go new file mode 100644 index 0000000..8e11a35 --- /dev/null +++ b/helpers/iterators/range.go @@ -0,0 +1,21 @@ +package iterators + +// Range creates an Iterator that will +// iterate numbers from a to b, including b. +func Range(a, b int) Iterator { + return &ranger{pos: a - 1, end: b} +} + +type ranger struct { + pos int + end int +} + +// Next returns the next number in the Range or nil +func (r *ranger) Next() interface{} { + if r.pos < r.end { + r.pos++ + return r.pos + } + return nil +} diff --git a/helpers/iterators/until.go b/helpers/iterators/until.go new file mode 100644 index 0000000..51744e4 --- /dev/null +++ b/helpers/iterators/until.go @@ -0,0 +1,7 @@ +package iterators + +// Until will iterate up to, but not including `a` +// Until(3) // 0,1,2 +func Until(a int) Iterator { + return &ranger{pos: -1, end: a - 1} +} diff --git a/helper_map.go b/helpers/map.go similarity index 82% rename from helper_map.go rename to helpers/map.go index 191b755..28c43b5 100644 --- a/helper_map.go +++ b/helpers/map.go @@ -1,8 +1,6 @@ -package plush +package helpers -import ( - "sync" -) +import "sync" // HelperMap holds onto helpers and validates they are properly formed. type HelperMap struct { @@ -11,18 +9,13 @@ type HelperMap struct { } // NewHelperMap containing all of the "default" helpers from "plush.Helpers". -func NewHelperMap() (HelperMap, error) { +func NewMap(helpers map[string]interface{}) HelperMap { hm := HelperMap{ - helpers: map[string]interface{}{}, + helpers: helpers, moot: &sync.Mutex{}, } - err := hm.AddMany(Helpers.Helpers()) - if err != nil { - return hm, err - } - - return hm, nil + return hm } // Add a new helper to the map. New Helpers will be validated to ensure they @@ -56,3 +49,7 @@ func (h *HelperMap) AddMany(helpers map[string]interface{}) error { func (h HelperMap) Helpers() map[string]interface{} { return h.helpers } + +func (h HelperMap) All() map[string]interface{} { + return h.helpers +} diff --git a/helpers/meta/len.go b/helpers/meta/len.go new file mode 100644 index 0000000..253d25d --- /dev/null +++ b/helpers/meta/len.go @@ -0,0 +1,17 @@ +package meta + +import ( + "reflect" +) + +// Len returns the length of v +func Len(v interface{}) int { + if v == nil { + return 0 + } + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Ptr { + rv = rv.Elem() + } + return rv.Len() +} diff --git a/helpers/meta/len_test.go b/helpers/meta/len_test.go new file mode 100644 index 0000000..fc886e0 --- /dev/null +++ b/helpers/meta/len_test.go @@ -0,0 +1,27 @@ +package meta + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Len(t *testing.T) { + table := []struct { + in interface{} + out int + }{ + {"foo", 3}, + {[]string{"a", "b"}, 2}, + {nil, 0}, + {map[string]int{"a": 1, "b": 2, "c": 3, "d": 4}, 4}, + } + + for _, tt := range table { + t.Run(fmt.Sprint(tt.in), func(st *testing.T) { + r := require.New(st) + r.Equal(Len(tt.in), tt.out) + }) + } +} diff --git a/helpers/meta/meta.go b/helpers/meta/meta.go new file mode 100644 index 0000000..490be16 --- /dev/null +++ b/helpers/meta/meta.go @@ -0,0 +1,17 @@ +package meta + +import ( + "github.com/gobuffalo/plush/v5/helpers/hctx" +) + +// Keys to be used in templates for the functions in this package. +const ( + LenKey = "len" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + LenKey: Len, + } +} diff --git a/helpers/paths/path_for.go b/helpers/paths/path_for.go new file mode 100644 index 0000000..a9919ce --- /dev/null +++ b/helpers/paths/path_for.go @@ -0,0 +1,113 @@ +package paths + +import ( + "errors" + "fmt" + "html/template" + "net/url" + "path" + "reflect" + "strings" + + "github.com/gobuffalo/flect/name" +) + +type Pathable interface { + ToPath() string +} + +type Paramable interface { + ToParam() string +} + +// PathFor takes an `interface{}`, or a `slice` of them, +// and tries to convert it to a `/foos/{id}` style URL path. +// Rules: +// * if `string` it is returned as is +// * if `Pathable` the `ToPath` method is returned +// * if `slice` or an `array` each element is run through the helper then joined +// * if `struct` the name of the struct, pluralized is used for the name +// * if `Paramable` the `ToParam` method is used to fill the `{id}` slot +// * if `struct.Slug` the slug is used to fill the `{id}` slot of the URL +// * if `struct.ID` the ID is used to fill the `{id}` slot of the URL +func PathFor(in interface{}) (string, error) { + if in == nil { + return "", errors.New("can not calculate path to nil") + } + + switch s := in.(type) { + case string: + return join(s), nil + case template.HTML: + return join(string(s)), nil + case Pathable: + return join(s.ToPath()), nil + } + + ni, err := name.Interface(in) + if err != nil { + return "", err + } + + rv := reflect.Indirect(reflect.ValueOf(in)) + + to := rv.Type() + k := to.Kind() + switch k { + case reflect.Struct: + f := rv.FieldByName("Slug") + if f.IsValid() { + return byField(ni, f) + } + f = rv.FieldByName("ID") + if f.IsValid() { + return byField(ni, f) + } + case reflect.Slice, reflect.Array: + var paths []string + for i := 0; i < rv.Len(); i++ { + xrv := rv.Index(i) + s, err := PathFor(xrv.Interface()) + if err != nil { + return "", err + } + paths = append(paths, s) + } + return join(paths...), nil + } + + if s, ok := in.(Paramable); ok { + return join(ni.URL().String(), s.ToParam()), nil + } + + return "", fmt.Errorf("could not convert %T to path", in) +} + +func byField(ni name.Ident, f reflect.Value) (string, error) { + ii := f.Interface() + if ii == nil { + return "", nil + } + + zero := reflect.DeepEqual(ii, reflect.Zero(reflect.TypeOf(ii)).Interface()) + if zero { + return join(ni.URL().String()), nil + } + return join(ni.URL().String(), fmt.Sprint(ii)), nil +} + +func join(s ...string) string { + //In case is a full valid url it will return the same url without modification + if len(s) == 1 { + if _, err := url.ParseRequestURI(s[0]); err == nil { + return s[0] + } + } + + p := path.Join(s...) + if !strings.HasPrefix(p, "/") { + p = "/" + p + } + + return p +} diff --git a/helpers/paths/path_for_test.go b/helpers/paths/path_for_test.go new file mode 100644 index 0000000..064822f --- /dev/null +++ b/helpers/paths/path_for_test.go @@ -0,0 +1,68 @@ +package paths + +import ( + "html/template" + "testing" + + "github.com/stretchr/testify/require" +) + +type Car struct { + ID int +} + +type boat struct { + Slug string +} + +type plane struct{} + +func (plane) ToParam() string { + return "aeroplane" +} + +type truck struct{} + +func (truck) ToPath() string { + return "/a/truck" +} + +type BadCar struct { + IDs int +} + +func Test_PathFor(t *testing.T) { + table := []struct { + in interface{} + out string + err bool + }{ + {Car{1}, "/cars/1", false}, + {Car{}, "/cars", false}, + {&Car{}, "/cars", false}, + {boat{"titanic"}, "/boats/titanic", false}, + {plane{}, "/planes/aeroplane", false}, + {truck{}, "/a/truck", false}, + {[]interface{}{truck{}, plane{}}, "/a/truck/planes/aeroplane", false}, + {"foo", "/foo", false}, + {template.HTML("foo"), "/foo", false}, + {map[int]int{}, "", true}, + {nil, "", true}, + {[]interface{}{truck{}, nil}, "", true}, + {BadCar{}, "", true}, + {"https://www.google.com", "https://www.google.com", false}, + } + + for _, tt := range table { + t.Run(tt.out, func(st *testing.T) { + r := require.New(st) + s, err := PathFor(tt.in) + if tt.err { + r.Error(err) + return + } + r.NoError(err) + r.Equal(tt.out, s) + }) + } +} diff --git a/helpers/paths/paths.go b/helpers/paths/paths.go new file mode 100644 index 0000000..bc8220b --- /dev/null +++ b/helpers/paths/paths.go @@ -0,0 +1,15 @@ +package paths + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + PathForKey = "pathFor" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + PathForKey: PathFor, + } +} diff --git a/helpers/text/text.go b/helpers/text/text.go new file mode 100644 index 0000000..e9c9f16 --- /dev/null +++ b/helpers/text/text.go @@ -0,0 +1,15 @@ +package text + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Keys to be used in templates for the functions in this package. +const ( + TruncateKey = "truncate" +) + +// New returns a map of the helpers within this package. +func New() hctx.Map { + return hctx.Map{ + TruncateKey: Truncate, + } +} diff --git a/helpers/text/truncate.go b/helpers/text/truncate.go new file mode 100644 index 0000000..4127a45 --- /dev/null +++ b/helpers/text/truncate.go @@ -0,0 +1,31 @@ +package text + +import "github.com/gobuffalo/plush/v5/helpers/hctx" + +// Truncate will try to return a string that is no longer +// than `size`, which defaults to 50. If given +// a `trail` option the returned string will have +// that appended at the end, while still trying to make +// sure that the returned string is no longer than +// `size` characters long. However, if `trail` is longer +// than or equal to `size`, `trail` will be returned +// completely as is. Defaults to a `trail` of `...`. +func Truncate(s string, opts hctx.Map) string { + if opts["size"] == nil { + opts["size"] = 50 + } + if opts["trail"] == nil { + opts["trail"] = "..." + } + runesS := []rune(s) + size := opts["size"].(int) + if len(runesS) <= size { + return s + } + trail := opts["trail"].(string) + runesTrail := []rune(trail) + if len(runesTrail) >= size { + return trail + } + return string(runesS[:size-len(runesTrail)]) + trail +} diff --git a/helpers/text/truncate_test.go b/helpers/text/truncate_test.go new file mode 100644 index 0000000..2f6f68b --- /dev/null +++ b/helpers/text/truncate_test.go @@ -0,0 +1,53 @@ +package text + +import ( + "testing" + + "github.com/gobuffalo/plush/v5/helpers/hctx" + "github.com/stretchr/testify/require" +) + +func Test_Truncate(t *testing.T) { + var runesS []rune + var runesX []rune + + r := require.New(t) + x := "世界uFHyyImKUMhSkSolLqgqevKQNZUjpSZokrGbZqnUrUnWrTDwi" + s := Truncate(x, hctx.Map{}) + runesS = []rune(s) + r.Equal(len(runesS), 50) + r.Equal("...", string(runesS[47:])) + + s = Truncate(x, hctx.Map{ + "size": 10, + }) + runesS = []rune(s) + r.Equal(len(runesS), 10) + r.Equal("...", string(runesS[7:])) + + s = Truncate(x, hctx.Map{ + "size": 10, + "trail": "世界re", + }) + runesS = []rune(s) + r.Equal(len(runesS), 10) + r.Equal("世界re", string(runesS[6:])) + + // Case size < len(trail) + s = Truncate(x, hctx.Map{ + "size": 3, + "trail": "世界re", + }) + runesS = []rune(s) + r.Equal(len(runesS), 4) + r.Equal("世界re", s) + + // Case size >= len(string) + s = Truncate(x, hctx.Map{ + "size": len(x), + }) + runesS = []rune(s) + runesX = []rune(x) + r.Equal(len(runesS), len(runesX)) + r.Equal(string(runesX[48:]), string(runesS[48:])) +} diff --git a/helpers_test.go b/helpers_test.go index 28a2426..2b01e37 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) @@ -34,5 +34,4 @@ func Test_Helpers_WithoutData(t *testing.T) { r.NoError(err) r.Equal(tt.E, s) } - } diff --git a/if_test.go b/if_test.go index 5343663..656dcb3 100644 --- a/if_test.go +++ b/if_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/iterators_test.go b/iterators_test.go index 3c8a792..e281dcf 100644 --- a/iterators_test.go +++ b/iterators_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/lexer/lexer.go b/lexer/lexer.go index 1f4a0eb..dc2390e 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -3,7 +3,7 @@ package lexer import ( "strings" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/token" ) // Lexer moves through the source input and tokenizes its content diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go index 90329a2..542665b 100644 --- a/lexer/lexer_test.go +++ b/lexer/lexer_test.go @@ -3,8 +3,8 @@ package lexer_test import ( "testing" - "github.com/gobuffalo/plush/v4/lexer" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/lexer" + "github.com/gobuffalo/plush/v5/token" "github.com/stretchr/testify/require" ) @@ -30,7 +30,7 @@ func Test_NextToken_Simple(t *testing.T) { func Test_NextToken_SkipLineComments(t *testing.T) { r := require.New(t) - input := `<%= + input := `<%= # comment 1 # another line comment diff --git a/line_number_test.go b/line_number_test.go index 3915f2b..bd665bb 100644 --- a/line_number_test.go +++ b/line_number_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) @@ -63,10 +63,10 @@ func Test_LineNumberErrors_InsideForLoop(t *testing.T) { func Test_LineNumberErrors_MissingKeyword(t *testing.T) { r := require.New(t) input := ` - - - - + + + + <%= (n) in numbers { %> <%= n %> <% } %> diff --git a/markdown_helper.go b/markdown_helper.go deleted file mode 100644 index f36d1fc..0000000 --- a/markdown_helper.go +++ /dev/null @@ -1,20 +0,0 @@ -package plush - -import ( - "html/template" - - "github.com/gobuffalo/github_flavored_markdown" -) - -// Markdown converts the string into HTML using GitHub flavored markdown. -func MarkdownHelper(body string, help HelperContext) (template.HTML, error) { - var err error - if help.HasBlock() { - body, err = help.Block() - if err != nil { - return "", err - } - } - b := github_flavored_markdown.Markdown([]byte(body)) - return template.HTML(b), err -} diff --git a/markdown_helper_test.go b/markdown_helper_test.go deleted file mode 100644 index 2e95b62..0000000 --- a/markdown_helper_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package plush_test - -import ( - "testing" - - "github.com/gobuffalo/plush/v4" - "github.com/stretchr/testify/require" -) - -func Test_MarkdownHelper(t *testing.T) { - r := require.New(t) - input := `<%= markdown(m) %>` - ctx := plush.NewContext() - ctx.Set("m", "# H1") - s, err := plush.Render(input, ctx) - r.NoError(err) - r.Contains(s, "H1") -} - -func Test_MarkdownHelper_WithBlock(t *testing.T) { - r := require.New(t) - input := `<%= markdown("") { return "# H2" } %>` - s, err := plush.Render(input, plush.NewContext()) - r.NoError(err) - r.Contains(s, "H2") -} diff --git a/math_test.go b/math_test.go index 25a8ca3..aec0d17 100644 --- a/math_test.go +++ b/math_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/numbers_test.go b/numbers_test.go index e37a228..35874f3 100644 --- a/numbers_test.go +++ b/numbers_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/parser/parser.go b/parser/parser.go index b72051e..7875b00 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -5,9 +5,9 @@ import ( "strconv" "strings" - "github.com/gobuffalo/plush/v4/ast" - "github.com/gobuffalo/plush/v4/lexer" - "github.com/gobuffalo/plush/v4/token" + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/lexer" + "github.com/gobuffalo/plush/v5/token" ) type ( diff --git a/parser/parser_test.go b/parser/parser_test.go index 057fee7..89ede5d 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/gobuffalo/plush/v4/ast" - "github.com/gobuffalo/plush/v4/parser" + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/parser" "github.com/stretchr/testify/require" ) diff --git a/parser/precedences.go b/parser/precedences.go index d519849..0ee3429 100644 --- a/parser/precedences.go +++ b/parser/precedences.go @@ -1,6 +1,6 @@ package parser -import "github.com/gobuffalo/plush/v4/token" +import "github.com/gobuffalo/plush/v5/token" const ( _ int = iota diff --git a/partial_helper.go b/partial_helper.go index fff2c0f..44750f3 100644 --- a/partial_helper.go +++ b/partial_helper.go @@ -5,8 +5,6 @@ import ( "html/template" "path/filepath" "strings" - - "github.com/gobuffalo/github_flavored_markdown" ) // PartialFeeder is callback function should implemented on application side. @@ -37,11 +35,6 @@ func PartialHelper(name string, data map[string]interface{}, help HelperContext) return "", err } - if strings.HasSuffix(name, ".md") { - part = string(github_flavored_markdown.Markdown([]byte(part))) - part = strings.TrimSuffix(part, "\n") - } - if ct, ok := help.Value("contentType").(string); ok { ext := filepath.Ext(name) if strings.Contains(ct, "javascript") && ext != ".js" && ext != "" { diff --git a/partial_helper_test.go b/partial_helper_test.go index 5a4a365..38f269e 100644 --- a/partial_helper_test.go +++ b/partial_helper_test.go @@ -2,11 +2,10 @@ package plush_test import ( "fmt" - "strings" "testing" - "github.com/gobuffalo/helpers/hctx" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" + "github.com/gobuffalo/plush/v5/helpers/hctx" "github.com/stretchr/testify/require" ) @@ -277,126 +276,6 @@ func Test_PartialHelper_Javascript_With_HTML_Partial(t *testing.T) { r.Equal(`alert('\u003Cdiv\u003E\\u003Cspan\\u003EFORM\\u003C/span\\u003E\u003C/div\u003E');`, string(html)) } -func Test_PartialHelper_Markdown(t *testing.T) { - r := require.New(t) - - name := "index.md" - data := map[string]interface{}{} - help := plush.HelperContext{Context: plush.NewContext()} - help.Set("contentType", "text/markdown") - help.Set("partialFeeder", func(string) (string, error) { - return "`test`", nil - }) - - md, err := plush.PartialHelper(name, data, help) - r.NoError(err) - r.Equal(`

test

`, strings.TrimSpace(string(md))) -} - -func Test_PartialHelper_Markdown_With_Layout(t *testing.T) { - r := require.New(t) - - name := "index.md" - data := map[string]interface{}{ - "layout": "container.html", - } - help := plush.HelperContext{Context: plush.NewContext()} - help.Set("partialFeeder", func(name string) (string, error) { - if name == data["layout"] { - return `This is a <%= yield %>`, nil - } - return `**test**`, nil - }) - - html, err := plush.PartialHelper(name, data, help) - r.NoError(err) - r.Equal("This is a

test

", string(html)) -} - -func Test_PartialHelper_Markdown_With_Layout_Reversed(t *testing.T) { - r := require.New(t) - - name := "index.html" - data := map[string]interface{}{ - "layout": "container.md", - } - help := plush.HelperContext{Context: plush.NewContext()} - help.Set("partialFeeder", func(name string) (string, error) { - if name == data["layout"] { - return `This *is* a <%= yield %>`, nil - } - return `test`, nil - }) - - html, err := plush.PartialHelper(name, data, help) - r.NoError(err) - r.Equal(`

This is a test

`, strings.TrimSpace(string(html))) -} - -func Test_PartialHelpers_Markdown_With_Nested_CodeBlock(t *testing.T) { - // for https://github.com/gobuffalo/plush/issues/82 - r := require.New(t) - - main := `<%= partial("outer.md") %>` - outer := `Some text - -<%= partial("inner.md") %> -` - inner := "```go\n" + `if true { - fmt.Println() -}` + "\n```" - - help := plush.HelperContext{Context: plush.NewContext()} - help.Set("contentType", "text/markdown") - help.Set("partialFeeder", func(name string) (string, error) { - if name == "outer.md" { - return outer, nil - } - return inner, nil - }) - - html, err := plush.Render(main, help) - r.NoError(err) - r.Equal(`

Some text

- -
if true {
-    fmt.Println()
-}
-
`, string(html)) -} - -func Test_PartialHelpers_With_Indentation(t *testing.T) { - r := require.New(t) - - main := `
-
- <%= partial("dummy.md") %> -
-
` - partial := "```go\n" + - "if true {\n" + - " fmt.Println()\n" + - "}\n" + - "```" - - ctx := plush.NewContext() - ctx.Set("partialFeeder", func(string) (string, error) { - return partial, nil - }) - - html, err := plush.Render(main, ctx) - r.NoError(err) - r.Equal(`
-
-
if true {
-    fmt.Println()
-}
-
-
-
`, - string(html)) -} - func Test_PartialHelper_NoDefaultHelperOverride(t *testing.T) { r := require.New(t) diff --git a/plush.go b/plush.go index 0b1f164..6579c11 100644 --- a/plush.go +++ b/plush.go @@ -7,7 +7,7 @@ import ( "io/ioutil" "sync" - "github.com/gobuffalo/helpers/hctx" + "github.com/gobuffalo/plush/v5/helpers/hctx" ) // DefaultTimeFormat is the default way of formatting a time.Time type. diff --git a/plush_test.go b/plush_test.go index 363a930..18186fe 100644 --- a/plush_test.go +++ b/plush_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/quotes_test.go b/quotes_test.go index 80a9440..a298e05 100644 --- a/quotes_test.go +++ b/quotes_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/return_exit_test.go b/return_exit_test.go index 7f48a23..e34ff49 100644 --- a/return_exit_test.go +++ b/return_exit_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/script_test.go b/script_test.go index 96cbdad..17eb792 100644 --- a/script_test.go +++ b/script_test.go @@ -5,7 +5,7 @@ import ( "fmt" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/struct_test.go b/struct_test.go index 3fb8df1..cc60a19 100644 --- a/struct_test.go +++ b/struct_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/template.go b/template.go index 8ab5f89..1fdd7c3 100644 --- a/template.go +++ b/template.go @@ -1,10 +1,10 @@ package plush import ( - "github.com/gobuffalo/helpers/hctx" - "github.com/gobuffalo/plush/v4/ast" + "github.com/gobuffalo/plush/v5/ast" + "github.com/gobuffalo/plush/v5/helpers/hctx" - "github.com/gobuffalo/plush/v4/parser" + "github.com/gobuffalo/plush/v5/parser" ) // Template represents an input and helpers to be used diff --git a/template_test.go b/template_test.go index 647d61a..0e6f13f 100644 --- a/template_test.go +++ b/template_test.go @@ -5,7 +5,7 @@ import ( "golang.org/x/sync/errgroup" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/time_test.go b/time_test.go index 1ab0b63..c01b3bd 100644 --- a/time_test.go +++ b/time_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) diff --git a/user_function.go b/user_function.go index 2a41629..3342cf9 100644 --- a/user_function.go +++ b/user_function.go @@ -4,7 +4,7 @@ import ( "bytes" "strings" - "github.com/gobuffalo/plush/v4/ast" + "github.com/gobuffalo/plush/v5/ast" ) type userFunction struct { diff --git a/variables_test.go b/variables_test.go index 7aed31d..7bcf22e 100644 --- a/variables_test.go +++ b/variables_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/gobuffalo/tags/v3" "github.com/stretchr/testify/require" ) diff --git a/variadic_test.go b/variadic_test.go index 2bc8ff5..8705d2a 100644 --- a/variadic_test.go +++ b/variadic_test.go @@ -3,7 +3,7 @@ package plush_test import ( "testing" - "github.com/gobuffalo/plush/v4" + "github.com/gobuffalo/plush/v5" "github.com/stretchr/testify/require" ) From cc5cea7aa125641046bb06d07ff943cb481654be Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:35:02 -0500 Subject: [PATCH 2/6] task: updating the action to use go 1.22 --- .github/workflows/standard-go-test.yml | 47 +++++++++++++++++++++++--- .github/workflows/standard-stale.yml | 29 +++++++++++++--- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/.github/workflows/standard-go-test.yml b/.github/workflows/standard-go-test.yml index 9788981..da36dda 100644 --- a/.github/workflows/standard-go-test.yml +++ b/.github/workflows/standard-go-test.yml @@ -2,11 +2,48 @@ name: Standard Test on: push: - branches: [ main ] + branches: [main] pull_request: jobs: - call-standard-test: - name: Test - uses: gobuffalo/.github/.github/workflows/go-test.yml@v1 - secrets: inherit + dependency-review: + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Dependency Review + uses: actions/dependency-review-action@v1 + + standard-go-test: + name: go${{ matrix.go-version }}/${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + go-version: + - "1.22" + os: + - "ubuntu-latest" + - "macos-latest" + - "windows-latest" + + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: ${{ matrix.go-version }} + + - name: Test + if: ${{ matrix.os != 'windows-latest' }} + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: 0 + run: | + go test -v -p 1 -race -cover -tags "sqlite,integration" ./... + + - name: Short Test + if: ${{ matrix.os == 'windows-latest' }} + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: 0 + run: | + go test -v -p 1 -tags "sqlite,integration" ./... diff --git a/.github/workflows/standard-stale.yml b/.github/workflows/standard-stale.yml index 59a79c4..44267f0 100644 --- a/.github/workflows/standard-stale.yml +++ b/.github/workflows/standard-stale.yml @@ -5,7 +5,28 @@ on: - cron: "30 1 * * *" jobs: - call-standard-autocloser: - name: Autocloser - uses: gobuffalo/.github/.github/workflows/stale.yml@v1 - secrets: inherit + stale: + runs-on: ubuntu-latest + permissions: + issues: write # for actions/stale to close stale issues + pull-requests: write # for actions/stale to close stale PRs + + steps: + - uses: actions/stale@v6 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-issue-stale: 30 + days-before-issue-close: 7 + days-before-pr-stale: 45 + days-before-pr-close: 7 + stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment. Otherwise, this will be closed in 7 days." + stale-pr-message: "This PR is stale because it has been open 45 days with no activity. Remove stale label or comment. Otherwise, this will be closed in 7 days." + close-issue-message: "This issue was closed because it has been stalled for 30+7 days with no activity." + close-pr-message: "This PR was closed because it has been stalled for 45+7 days with no activity." + stale-issue-label: "stale" + stale-pr-label: "stale" + close-issue-label: "s: closed" + close-pr-label: "s: closed" + exempt-issue-labels: "bug,security,s: accepted,s: blocked,s: hold" + exempt-pr-labels: "bug,security,s: accepted,s: blocked,s: hold" + exempt-all-milestones: true From 46ecbaa8d1b905d526c496a28b6d2c84ba05b486 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:38:24 -0500 Subject: [PATCH 3/6] task: adding go 1.21 and Go 1.23rc --- .github/workflows/standard-go-test.yml | 4 +++- go.mod | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/standard-go-test.yml b/.github/workflows/standard-go-test.yml index da36dda..785cd7c 100644 --- a/.github/workflows/standard-go-test.yml +++ b/.github/workflows/standard-go-test.yml @@ -20,7 +20,9 @@ jobs: strategy: matrix: go-version: + - "1.21" - "1.22" + - "1.23rc2" os: - "ubuntu-latest" - "macos-latest" @@ -30,7 +32,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} diff --git a/go.mod b/go.mod index 3a6dc12..a7b7869 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/gobuffalo/plush/v5 -go 1.22 +go 1.21 require ( github.com/gobuffalo/flect v1.0.2 From 7866617ecfa63ac52bc8e0e5e8a5a64a4d05d4a4 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:40:26 -0500 Subject: [PATCH 4/6] trying 1.23 with new syntax --- .github/workflows/standard-go-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/standard-go-test.yml b/.github/workflows/standard-go-test.yml index 785cd7c..818e29d 100644 --- a/.github/workflows/standard-go-test.yml +++ b/.github/workflows/standard-go-test.yml @@ -22,7 +22,7 @@ jobs: go-version: - "1.21" - "1.22" - - "1.23rc2" + - "1.23-rc.2" os: - "ubuntu-latest" - "macos-latest" From 7b4459ab7515a28bcb3004313efaa39b1717cda3 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:41:09 -0500 Subject: [PATCH 5/6] task: giving up on 1.23 for now --- .github/workflows/standard-go-test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/standard-go-test.yml b/.github/workflows/standard-go-test.yml index 818e29d..8bf8bb2 100644 --- a/.github/workflows/standard-go-test.yml +++ b/.github/workflows/standard-go-test.yml @@ -22,7 +22,6 @@ jobs: go-version: - "1.21" - "1.22" - - "1.23-rc.2" os: - "ubuntu-latest" - "macos-latest" From 9a4f75ec561874c386d1949e1420cb7bce65666b Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 6 Aug 2024 09:43:11 -0500 Subject: [PATCH 6/6] task: checkout action to v4 --- .github/workflows/standard-go-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/standard-go-test.yml b/.github/workflows/standard-go-test.yml index 8bf8bb2..6a24ccd 100644 --- a/.github/workflows/standard-go-test.yml +++ b/.github/workflows/standard-go-test.yml @@ -10,7 +10,7 @@ jobs: if: ${{ github.event_name == 'pull_request' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Dependency Review uses: actions/dependency-review-action@v1