diff --git a/.gitignore b/.gitignore index 110f610..e96c5ed 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ # vendor/ pyrotic .vscode -# examples \ No newline at end of file +.idea +# examples diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/golinter.xml b/.idea/golinter.xml deleted file mode 100644 index 00b449d..0000000 --- a/.idea/golinter.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 8f6abd5..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pyrotic.iml b/.idea/pyrotic.iml index 5e764c4..7ee078d 100644 --- a/.idea/pyrotic.iml +++ b/.idea/pyrotic.iml @@ -1,9 +1,4 @@ - + - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index bf4d7d8..1cd24f3 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # pyrotic -code generator inspired by https://www.hygen.io/ for golang. +code generator inspired by https://plopjs.com/ & https://github.com/jondot/hygen for golang. ## Motivation -Why not use hygen? great question! I would recommend [hygen](https://www.hygen.io/) over this, however [hygen](https://www.hygen.io/) is written in js. +Why not use hygen? great question! I would recommend [plop](https://plopjs.com/) over this, however [plop](https://plopjs.com/) is written in js. This project is for people who want to use a code generator and not have to install node. Pyrotic also is specifically written to generate go code, all templates are parsed using go's builtin template parser and output is formatted using go's built in code formatter. @@ -75,38 +75,47 @@ pyrotic -s foo/bar generate cmd --name setup Formatter will pick up any of these variables within the `---` block and hydrate the metadata for the template. Any properties matching the signature will be added to the Meta property, for example `foo: bar` will be accessible by `{{ Meta.foo }}`. View more [examples](example/_templates). -| Property | Type | Default | Example | -| -------- | ---- | ------- | ------- | -| to: | string (path) | "" | src/lib/utils/readme.md | -| append: | bool | false | false | -| inject: | bool | false | false | -| before: | string | "" | type config struct | -| after: | string | "" | // commands | +| Property | Type | Default | Example | +|----------|---------------|---------|-------------------------| +| to: | string (path) | "" | src/lib/utils/readme.md | +| append: | bool | false | false | +| inject: | bool | false | false | +| before: | string | "" | type config struct | +| after: | string | "" | // commands | + + +### Variables within formater properties + +Tool's two-stage parser hydrates the data within the `---` blocks before parsing the template. + +| Property | Type | Default | Example | +|----------|---------------|---------|----------------------------------------------| +| to: | string (path) | "" | src/lib/{{ .Name }}/{{ Meta.readmeName }}.md | ### Using shared templates In some instances you will want to reuse some templates across multiple generators. This can be done by having a `shared` directory within the `_templates` directory. -Any templates that are declared in the [shared](example/_templates/shared/config.tmpl) directory will be loading along with the generator. [Reference](example/_templates/fakr/shared_config.tmpl) the shared template within your generator directory in order to inject / append / create file. +Any templates that are declared in the [shared](example/_templates/shared/config.tmpl) directory will be loading along with the generator. [Reference](example/_templates/fakr/shared_config.tmpl) the shared template within your generator directory to inject / append / create file. ## Built in template functions -ships with some already built in template funcs, some [examples](example/_templates/fakr/farkr_case.tmpl) - -| func name | description | code example | result | -| --------- | ----------- | ------------ | ------ | -| caseSnake | convert to snake case | {{ MetaData \| caseSnake }} | meta_data | -| caseKebab | convert to kebab case | {{ MetaData \| caseKebab }} | meta-data | -| casePascal | convert to pascal case | {{ meta_data \| casePascal }} | MetaData | -| caseLower | convert to lower case | {{ MetaData \| caseLower }} | metadata | -| caseTitle | convert to title case | {{ MetaData \| caseTitle }} | METADATA | -| caseCamel | convert to camel case | {{ MetaData \| caseCamel }} | metaData | -| splitByDelimiter | splits string by delimiter | {{ splitByDelimiter "long,list" "," }} | []string{"long" "list"} | -| splitAfterDelimiter | splits string after delimiter | {{ splitAfterDelimiter "a,long,list" "," }} | []string{"a," "long," "list"} | -| contains | checks if string contains substring | {{ contains "foobarbin" "bar" }} | true | -| hasPrefix | checks if string has the prefix | {{ contains "foobarbin" "foo" }} | true | -| hasSuffix | checks if string has the suffix | {{ contains "foobarbin" "bin" }} | true | +ships with some already built in template funcs, some [examples](example/_templates/fakr/fakr_case.tmpl) + +| func name | description | code example | result | +|---------------------|-------------------------------------|---------------------------------------------|-------------------------------| +| caseSnake | convert to snake case | {{ MetaData \| caseSnake }} | meta_data | +| caseKebab | convert to kebab case | {{ MetaData \| caseKebab }} | meta-data | +| casePascal | convert to pascal case | {{ meta_data \| casePascal }} | MetaData | +| caseLower | convert to lower case | {{ MetaData \| caseLower }} | metadata | +| caseTitle | convert to title case | {{ MetaData \| caseTitle }} | METADATA | +| caseCamel | convert to camel case | {{ MetaData \| caseCamel }} | metaData | +| splitByDelimiter | splits string by delimiter | {{ splitByDelimiter "long,list" "," }} | []string{"long" "list"} | +| splitAfterDelimiter | splits string after delimiter | {{ splitAfterDelimiter "a,long,list" "," }} | []string{"a," "long," "list"} | +| contains | checks if string contains substring | {{ contains "foobarbin" "bar" }} | true | +| hasPrefix | checks if string has the prefix | {{ contains "foobarbin" "foo" }} | true | +| hasSuffix | checks if string has the suffix | {{ contains "foobarbin" "bin" }} | true | we also provide some Inflections using [flect](https://github.com/gobuffalo/flect) diff --git a/go.mod b/go.mod index ca461a3..2bf033e 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,20 @@ module github.com/code-gorilla-au/pyrotic -go 1.24.4 +go 1.25.3 require ( github.com/code-gorilla-au/odize v1.3.4 github.com/gobuffalo/flect v1.0.3 github.com/mattn/go-isatty v0.0.20 github.com/spf13/cobra v1.10.1 - golang.org/x/text v0.30.0 + golang.org/x/text v0.31.0 ) require ( github.com/code-gorilla-au/env v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/joho/godotenv v1.5.1 // indirect - github.com/spf13/pflag v1.0.9 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/sys v0.32.0 // indirect + golang.org/x/sys v0.38.0 // indirect ) diff --git a/go.sum b/go.sum index 05cebc7..1bd5628 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 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= @@ -32,8 +34,12 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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= diff --git a/internal/commands/cmd_generate.go b/internal/commands/cmd_generate.go index 41578e7..2e70312 100644 --- a/internal/commands/cmd_generate.go +++ b/internal/commands/cmd_generate.go @@ -15,7 +15,7 @@ func generateCmd() *cobra.Command { return &cobra.Command{ Use: "generate --name ", Short: "Generate template", - Long: `Generate tempate by generator name. `, + Long: `Generate template by generator name. `, Run: generateFunc(), } } diff --git a/internal/engine/engine.go b/internal/engine/engine.go index 4cb2aa4..1c94403 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -47,19 +47,19 @@ func (c *Core) Generate(data Data) error { for _, item := range parsedOutput { switch item.Action { case parser.ActionAppend: - if err := c.fwr.AppendFile(item.To, item.Output); err != nil { + if err = c.fwr.AppendFile(item.To, item.Output); err != nil { log.Println("error appending file ", err) return err } case parser.ActionInject: - if err := c.fwr.InjectIntoFile(item.To, item.Output, writer.Inject{ + if err = c.fwr.InjectIntoFile(item.To, item.Output, writer.Inject{ Matcher: item.InjectMatcher, Clause: writer.InjectClause(item.InjectClause), }); err != nil { return err } default: - if err := c.fwr.WriteFile(item.To, item.Output, 0750); err != nil { + if err = c.fwr.WriteFile(item.To, item.Output, 0750); err != nil { log.Println("error writing to file ", err) return err } diff --git a/internal/parser/lexer.go b/internal/parser/lexer.go index 0c3109c..8e7ddf0 100644 --- a/internal/parser/lexer.go +++ b/internal/parser/lexer.go @@ -39,7 +39,7 @@ func parse(tmplName, tmpl string, data TemplateData, funcs template.FuncMap, sha log.Println(chalk.Red("error parsing metadata"), err) return hydratedData, err } - output, err := generateTemplate(tmplName, string(stringOutput), hydratedData, funcs, sharedTmpl) + output, err := generateTemplate(tmplName, stringOutput, hydratedData, funcs, sharedTmpl) if err != nil { log.Println(chalk.Red("error generating template"), err) return hydratedData, err @@ -49,7 +49,7 @@ func parse(tmplName, tmpl string, data TemplateData, funcs template.FuncMap, sha } func generateParseData(tmplName string, meta []string, data TemplateData, funcs template.FuncMap) (TemplateData, error) { - parsedMeta := []string{} + var parsedMeta []string for _, item := range meta { var buf bytes.Buffer @@ -59,11 +59,11 @@ func generateParseData(tmplName string, meta []string, data TemplateData, funcs return data, err } - if err := t.Execute(wr, data); err != nil { + if err = t.Execute(wr, data); err != nil { return data, fmt.Errorf("%w \n %s", err, item) } - if err := wr.Flush(); err != nil { + if err = wr.Flush(); err != nil { return data, err } @@ -88,10 +88,10 @@ func generateTemplate(tmplName, tmplOutput string, data TemplateData, funcs temp var buf bytes.Buffer wr := bufio.NewWriter(&buf) - if err := tmpl.Execute(wr, data); err != nil { + if err = tmpl.Execute(wr, data); err != nil { return nil, fmt.Errorf("%w \n %s", err, tmplOutput) } - if err := wr.Flush(); err != nil { + if err = wr.Flush(); err != nil { log.Printf(chalk.Red("error flushing writer: %s"), err) return buf.Bytes(), err } diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 9d0421d..d31f8df 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -70,7 +70,7 @@ func New(dirPath string, sharedPath string, fileSuffix string) (TemplateEngine, } func (te *TemplateEngine) Parse(data TemplateData) ([]TemplateData, error) { - result := []TemplateData{} + var result []TemplateData for name, tmpl := range te.templates { @@ -121,9 +121,9 @@ func withTemplates(dirPath string, fileSuffix string) (map[string]string, error) } func orderTemplateData(data []TemplateData) []TemplateData { - create := []TemplateData{} - inject := []TemplateData{} - app := []TemplateData{} + var create []TemplateData + var inject []TemplateData + var app []TemplateData for _, tmp := range data { switch tmp.Action { @@ -135,7 +135,7 @@ func orderTemplateData(data []TemplateData) []TemplateData { app = append(app, tmp) } } - result := []TemplateData{} + var result []TemplateData result = append(result, create...) result = append(result, inject...) result = append(result, app...)