New Upstream Release - easygen
Ready changes
Summary
Merged new upstream version: 5.2.1 (was: 5.1.9).
Resulting package
Built on 2022-12-14T13:58 (took 4m4s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases easygenapt install -t fresh-releases golang-github-go-easygen-easygen-dev
Lintian Result
Diff
diff --git a/.all-contributorsrc b/.all-contributorsrc
index abc924f..d151d6b 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -2,7 +2,7 @@
"files": [
"README.md",
"README.beg.e.md",
- "README.end.e.md"
+ "README.end2.e.md"
],
"imageSize": 100,
"commit": false,
diff --git a/.gitignore b/.gitignore
index 76b5f2c..f9f78f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ _testmain.go
*.prof
*~
+.idea/
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 0320726..3444ff0 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -19,6 +19,9 @@ builds:
goarch:
- amd64
- arm64
+ ignore:
+ - goos: windows
+ goarch: arm64
# Path to main.go file or main package.
# Notice: when used with `gomod.proxy`, this must be a package.
diff --git a/README.end.e.md b/README.end.e.md
index 425a493..1f34563 100644
--- a/README.end.e.md
+++ b/README.end.e.md
@@ -29,7 +29,7 @@ rmdir -v {{.Name}}_*_linux_amd64
### Distro package
-- Packages available for Linux distros are
+- [Packages available for Linux distros](https://cloudsmith.io/~suntong/repos/repo/packages/) are
* [Alpine Linux](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-alpine)
* [Debian](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-deb)
* [RedHat](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-rpm)
@@ -69,29 +69,3 @@ Tong SUN
_Powered by_ [**WireFrame**](https://github.com/go-easygen/wireframe)
[![PoweredBy WireFrame](https://github.com/go-easygen/wireframe/blob/master/PoweredBy-WireFrame-Y.svg)](http://godoc.org/github.com/go-easygen/wireframe)
the _one-stop wire-framing solution_ for Go cli based projects, from _init_ to _deploy_.
-
-## Contributors β¨
-
-Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
-
-<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
-<!-- prettier-ignore-start -->
-<!-- markdownlint-disable -->
-<table>
- <tr>
- <td align="center"><a href="https://github.com/suntong"><img src="https://avatars.githubusercontent.com/u/422244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>suntong</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Code">π»</a> <a href="#ideas-suntong" title="Ideas, Planning, & Feedback">π€</a> <a href="#design-suntong" title="Design">π¨</a> <a href="#data-suntong" title="Data">π£</a> <a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Tests">β οΈ</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Asuntong" title="Bug reports">π</a> <a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Documentation">π</a> <a href="#blog-suntong" title="Blogposts">π</a> <a href="#example-suntong" title="Examples">π‘</a> <a href="#tutorial-suntong" title="Tutorials">β
</a> <a href="#tool-suntong" title="Tools">π§</a> <a href="#platform-suntong" title="Packaging/porting to new platform">π¦</a> <a href="https://github.com/go-easygen/easygen/pulls?q=is%3Apr+reviewed-by%3Asuntong" title="Reviewed Pull Requests">π</a> <a href="#question-suntong" title="Answering Questions">π¬</a> <a href="#maintenance-suntong" title="Maintenance">π§</a> <a href="#infra-suntong" title="Infrastructure (Hosting, Build-Tools, etc)">π</a></td>
- <td align="center"><a href="http://gerrit.sdf.org/"><img src="https://avatars.githubusercontent.com/u/5132989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gerrit Renker</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=grrtrr" title="Code">π»</a> <a href="#ideas-grrtrr" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Agrrtrr" title="Bug reports">π</a> <a href="#userTesting-grrtrr" title="User Testing">π</a> <a href="#talk-grrtrr" title="Talks">π’</a> <a href="#content-grrtrr" title="Content">π</a> <a href="#blog-grrtrr" title="Blogposts">π</a></td>
- <td align="center"><a href="https://github.com/bruston"><img src="https://avatars.githubusercontent.com/u/3519911?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benjamin Ruston</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=bruston" title="Code">π»</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Abruston" title="Bug reports">π</a> <a href="#userTesting-bruston" title="User Testing">π</a></td>
- <td align="center"><a href="https://github.com/sanjaymsh"><img src="https://avatars.githubusercontent.com/u/66668807?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sanjaymsh</b></sub></a><br /><a href="#platform-sanjaymsh" title="Packaging/porting to new platform">π¦</a></td>
- <td align="center"><a href="https://wiki.debian.org/AnthonyFok"><img src="https://avatars.githubusercontent.com/u/1274764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anthony Fok</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aanthonyfok" title="Bug reports">π</a> <a href="https://github.com/go-easygen/easygen/pulls?q=is%3Apr+reviewed-by%3Aanthonyfok" title="Reviewed Pull Requests">π</a> <a href="#maintenance-anthonyfok" title="Maintenance">π§</a> <a href="#userTesting-anthonyfok" title="User Testing">π</a></td>
- <td align="center"><a href="https://github.com/ghost"><img src="https://avatars.githubusercontent.com/u/10137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Deleted user</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aghost" title="Bug reports">π</a> <a href="#ideas-ghost" title="Ideas, Planning, & Feedback">π€</a> <a href="#userTesting-ghost" title="User Testing">π</a></td>
- <td align="center"><a href="https://github.com/romz-pl"><img src="https://avatars.githubusercontent.com/u/32552206?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zbigniew Romanowski</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aromz-pl" title="Bug reports">π</a> <a href="#ideas-romz-pl" title="Ideas, Planning, & Feedback">π€</a> <a href="#userTesting-romz-pl" title="User Testing">π</a></td>
- </tr>
-</table>
-
-<!-- markdownlint-restore -->
-<!-- prettier-ignore-end -->
-
-<!-- ALL-CONTRIBUTORS-LIST:END -->
-
-This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
diff --git a/README.end2.e.md b/README.end2.e.md
new file mode 100644
index 0000000..62e2c1b
--- /dev/null
+++ b/README.end2.e.md
@@ -0,0 +1,26 @@
+
+## Contributors β¨
+
+Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
+
+<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
+<!-- prettier-ignore-start -->
+<!-- markdownlint-disable -->
+<table>
+ <tr>
+ <td align="center"><a href="https://github.com/suntong"><img src="https://avatars.githubusercontent.com/u/422244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>suntong</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Code">π»</a> <a href="#ideas-suntong" title="Ideas, Planning, & Feedback">π€</a> <a href="#design-suntong" title="Design">π¨</a> <a href="#data-suntong" title="Data">π£</a> <a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Tests">β οΈ</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Asuntong" title="Bug reports">π</a> <a href="https://github.com/go-easygen/easygen/commits?author=suntong" title="Documentation">π</a> <a href="#blog-suntong" title="Blogposts">π</a> <a href="#example-suntong" title="Examples">π‘</a> <a href="#tutorial-suntong" title="Tutorials">β
</a> <a href="#tool-suntong" title="Tools">π§</a> <a href="#platform-suntong" title="Packaging/porting to new platform">π¦</a> <a href="https://github.com/go-easygen/easygen/pulls?q=is%3Apr+reviewed-by%3Asuntong" title="Reviewed Pull Requests">π</a> <a href="#question-suntong" title="Answering Questions">π¬</a> <a href="#maintenance-suntong" title="Maintenance">π§</a> <a href="#infra-suntong" title="Infrastructure (Hosting, Build-Tools, etc)">π</a></td>
+ <td align="center"><a href="http://gerrit.sdf.org/"><img src="https://avatars.githubusercontent.com/u/5132989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gerrit Renker</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=grrtrr" title="Code">π»</a> <a href="#ideas-grrtrr" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Agrrtrr" title="Bug reports">π</a> <a href="#userTesting-grrtrr" title="User Testing">π</a> <a href="#talk-grrtrr" title="Talks">π’</a> <a href="#content-grrtrr" title="Content">π</a> <a href="#blog-grrtrr" title="Blogposts">π</a></td>
+ <td align="center"><a href="https://github.com/bruston"><img src="https://avatars.githubusercontent.com/u/3519911?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benjamin Ruston</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/commits?author=bruston" title="Code">π»</a> <a href="https://github.com/go-easygen/easygen/issues?q=author%3Abruston" title="Bug reports">π</a> <a href="#userTesting-bruston" title="User Testing">π</a></td>
+ <td align="center"><a href="https://github.com/sanjaymsh"><img src="https://avatars.githubusercontent.com/u/66668807?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sanjaymsh</b></sub></a><br /><a href="#platform-sanjaymsh" title="Packaging/porting to new platform">π¦</a></td>
+ <td align="center"><a href="https://wiki.debian.org/AnthonyFok"><img src="https://avatars.githubusercontent.com/u/1274764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anthony Fok</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aanthonyfok" title="Bug reports">π</a> <a href="https://github.com/go-easygen/easygen/pulls?q=is%3Apr+reviewed-by%3Aanthonyfok" title="Reviewed Pull Requests">π</a> <a href="#maintenance-anthonyfok" title="Maintenance">π§</a> <a href="#userTesting-anthonyfok" title="User Testing">π</a></td>
+ <td align="center"><a href="https://github.com/ghost"><img src="https://avatars.githubusercontent.com/u/10137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Deleted user</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aghost" title="Bug reports">π</a> <a href="#ideas-ghost" title="Ideas, Planning, & Feedback">π€</a> <a href="#userTesting-ghost" title="User Testing">π</a></td>
+ <td align="center"><a href="https://github.com/romz-pl"><img src="https://avatars.githubusercontent.com/u/32552206?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zbigniew Romanowski</b></sub></a><br /><a href="https://github.com/go-easygen/easygen/issues?q=author%3Aromz-pl" title="Bug reports">π</a> <a href="#ideas-romz-pl" title="Ideas, Planning, & Feedback">π€</a> <a href="#userTesting-romz-pl" title="User Testing">π</a></td>
+ </tr>
+</table>
+
+<!-- markdownlint-restore -->
+<!-- prettier-ignore-end -->
+
+<!-- ALL-CONTRIBUTORS-LIST:END -->
+
+This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
diff --git a/README.md b/README.md
index 031c21a..d0642a1 100644
--- a/README.md
+++ b/README.md
@@ -136,7 +136,7 @@ rmdir -v easygen_*_linux_amd64
### Distro package
-- Packages available for Linux distros are
+- [Packages available for Linux distros](https://cloudsmith.io/~suntong/repos/repo/packages/) are
* [Alpine Linux](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-alpine)
* [Debian](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-deb)
* [RedHat](https://cloudsmith.io/~suntong/repos/repo/setup/#formats-rpm)
diff --git a/cmd/easygen/main.go b/cmd/easygen/main.go
index 265c876..70a001a 100644
--- a/cmd/easygen/main.go
+++ b/cmd/easygen/main.go
@@ -41,8 +41,8 @@ import (
var (
progname = "easygen"
- version = "5.1.9"
- date = "2021-12-31"
+ version = "5.2.1"
+ date = "2022-07-10"
)
////////////////////////////////////////////////////////////////////////////
diff --git a/cmd/easygen/main_test.go b/cmd/easygen/main_test.go
index dff19c5..15306b8 100644
--- a/cmd/easygen/main_test.go
+++ b/cmd/easygen/main_test.go
@@ -72,6 +72,7 @@ func TestExec(t *testing.T) {
testEasygen(t, "list1", "list1")
testEasygen(t, "listfunc1", "listfunc1")
testEasygen(t, "listfunc2", "listfunc2")
+ testEasygen(t, "tf-calc", "tf-calc")
//Test Basic Json Functions
testEasygen(t, "list0j", "list0j")
diff --git a/debian/changelog b/debian/changelog
index 3e00428..c03be88 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+easygen (5.2.1-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 14 Dec 2022 13:55:10 -0000
+
easygen (5.1.9-2) unstable; urgency=medium
* Team Upload.
diff --git a/t_strings_test.go b/t_strings_test.go
index dabaf6a..57f872c 100644
--- a/t_strings_test.go
+++ b/t_strings_test.go
@@ -183,6 +183,22 @@ func TestStringManipulation(t *testing.T) {
// "a PEACH",
// },
// == my added strings functions
+ {
+ `{{ indent 2 "a" }}`,
+ "a",
+ },
+ {
+ `{{ indent 2 "a\nb\nc" }}`,
+ "a\n b\n c",
+ },
+ {
+ `{{ pindent 2 "a" }}`,
+ " a",
+ },
+ {
+ `{{ pindent 2 "a\nb\nc" }}`,
+ " a\n b\n c",
+ },
{
`{{ coalesce "a" }}`,
"a",
@@ -211,6 +227,11 @@ func TestStringManipulation(t *testing.T) {
`{{ coalesce .StrEmpty "Something else" }}`,
"Something else",
},
+ // The following failed the template.Execute before but now fixed
+ {
+ `{{ coalesce .StrNone "Not exist" }}`,
+ "Not exist",
+ },
}
testStringManipulation(t, testData)
diff --git a/template.go b/template.go
index da9fc3c..b56afd6 100644
--- a/template.go
+++ b/template.go
@@ -156,8 +156,8 @@ var egFuncMap = FuncMap{
"stringsTrimSpace": strings.TrimSpace,
"stringsTrimSuffix": strings.TrimSuffix,
// aliases
- "eqf": strings.EqualFold,
- "split": strings.Fields,
+ "eqf": strings.EqualFold,
+ "split": strings.Fields,
"sprintf": fmt.Sprintf,
// == standard regexp function definitions
@@ -178,12 +178,16 @@ var egFuncMap = FuncMap{
// == my added functions
"ENV": os.Getenv,
"substr": Substr,
+ "indent": Indent,
+ "pindent": PIndent,
"coalesce": Coalesce,
"quote4shell": Quote4shell,
"iterate": Iterate,
"argsa": ArgsA,
"argsm": ArgsM,
+ "add": Add,
+ "minus": Minus,
"minus1": Minus1,
"date": Date,
"timestamp": Timestamp,
diff --git a/test/commandlineEnv.ref b/test/commandlineEnv.ref
new file mode 100644
index 0000000..4214664
--- /dev/null
+++ b/test/commandlineEnv.ref
@@ -0,0 +1,36 @@
+package main
+
+// import "github.com/caarlos0/env"
+
+//////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+
+/*
+
+Custom environment settings:
+
+- **EVD_HOST**: Host address (string="localhost")
+- **EVD_PORT**: Listening port (int="80")
+- **EVD_FRCE**: Force start (bool)
+- **EVD_VERB**: Verbose mode (higher numbers increase the verbosity) (int)
+
+*/
+
+type envConfig struct {
+ Host string `env:"EVD_HOST" envDefault:"localhost"` // Host address
+ Port int `env:"EVD_PORT" envDefault:"80"` // Listening port
+ Force bool `env:"EVD_FRCE"` // Force start
+ Verbose int `env:"EVD_VERB"` // Verbose mode (higher numbers increase the verbosity)
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Global variables definitions
+
+// var (
+// progname = "evdemo"
+// version = "0.1.0"
+// date = "2022-01-30"
+
+// e envConfig
+// )
diff --git a/test/commandlineEnv.tmpl b/test/commandlineEnv.tmpl
new file mode 100644
index 0000000..26630d1
--- /dev/null
+++ b/test/commandlineEnv.tmpl
@@ -0,0 +1,39 @@
+package {{$.PackageName}}
+
+// import "github.com/caarlos0/env"
+
+//////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+
+/*{{- $prefix := .Prefix}}
+
+Custom environment settings:
+{{range .Options}}
+- **{{$prefix}}
+{{- if .EVar}}{{.EVar}}
+{{- else}}{{clk2ss .Name}}
+{{- end}}**: {{.Usage}} ({{.Type}}{{- if .Value}}="{{.Value}}"{{end}})
+{{- end}}
+
+*/
+
+type envConfig struct { {{- range .Options}}
+ {{.Name}} {{.Type}} `env:"{{$prefix}}
+{{- if .EVar}}{{.EVar}}
+{{- else}}{{clk2ss .Name}}
+{{- end}}"
+{{- if .Value}} envDefault:"{{.Value}}"{{end}}` // {{.Usage}}
+{{- end}}
+}
+
+////////////////////////////////////////////////////////////////////////////
+// Global variables definitions
+
+// var (
+// progname = "{{.Name}}"
+// version = "0.1.0"
+// date = "{{ date "I" }}"
+
+// e envConfig
+// )
diff --git a/test/commandlineEnv.yaml b/test/commandlineEnv.yaml
new file mode 100644
index 0000000..af8e38c
--- /dev/null
+++ b/test/commandlineEnv.yaml
@@ -0,0 +1,35 @@
+# program name, name for the executable
+# ProgramName: redo
+# Authors: Myself <me@mine.org>
+
+#
+PackageName: main
+
+Name: evdemo
+# Desc: "global option redo"
+# Text: Redo global option via automatic code-gen
+
+# prefix string before every environment variable
+Prefix: EVD_
+
+Options:
+ - Name: Host
+ Type: string
+ Usage: Host address
+ Value: localhost
+
+ - Name: Port
+ Type: int
+ Usage: Listening port
+ Value: 80
+
+ - Name: Force
+ Type: bool
+ EVar: FRCE
+ Usage: Force start
+
+ - Name: Verbose
+ Type: int
+ EVar: VERB
+ Usage: Verbose mode (higher numbers increase the verbosity)
+ Value: 0
diff --git a/test/commandlineGoFlags.header.tmpl b/test/commandlineGoFlags.header.tmpl
new file mode 100644
index 0000000..66cb210
--- /dev/null
+++ b/test/commandlineGoFlags.header.tmpl
@@ -0,0 +1,7 @@
+{{- define "header" -}}
+////////////////////////////////////////////////////////////////////////////
+// Program: {{.Name}}
+// Purpose: {{.Desc}}
+// Authors: {{or .Authors "Author"}} (c) {{date "Y4"}}, All rights reserved
+////////////////////////////////////////////////////////////////////////////
+{{- end}}
diff --git a/test/commandlineGoFlags.ityped.tmpl b/test/commandlineGoFlags.ityped.tmpl
new file mode 100644
index 0000000..90bbc81
--- /dev/null
+++ b/test/commandlineGoFlags.ityped.tmpl
@@ -0,0 +1,27 @@
+{{- define "type_struct" -}}
+// The {{.typeName}} type defines all the configurable options from cli.
+{{.Prefix}}type {{.typeName}} struct { {{- range .Options}}
+{{- if eq .Name "Args" }}
+{{$.Prefix}}
+{{$.Prefix}} {{.Args}}
+{{- else }}{{$f := stringsSplit .Flag ","}}{{ $flen := len $f }}
+{{$.Prefix}} {{.Name}} {{.Type}} `
+{{- if gt $flen 1}}short:"{{index $f 0}}" long:"{{index $f 1}}"
+{{- else}}
+ {{- if le ((index $f 0) | len) 1 }}short:"{{index $f 0}}"
+ {{- else}}long:"{{index $f 0}}"{{end}}
+{{- end}}
+{{- if .EnvV}} env:"{{printf "%s_%s" (clk2ss $.ProgramName) (clk2ss .Name)}}"{{end}} description:"{{.Usage}}"
+{{- if .Value}} default:"{{.Value}}"{{end}}
+{{- if .Choices}}{{range .Choices}} choice:"{{.}}"{{end}}{{end}}
+{{- if .Required}} required:"true"{{end}}`{{end}}
+{{- end}}
+{{- if .Verbose}}
+{{$.Prefix}} Verbflg func() `short:"v" long:"verbose" description:"Verbose mode (Multiple -v options increase the verbosity)"`
+{{$.Prefix}} Verbose int
+{{- end}}
+{{- if .Version}}
+{{$.Prefix}} Version func() `short:"V" long:"version" description:"Show program version and exit"`
+{{- end}}
+{{$.Prefix -}} }
+{{- end}}
diff --git a/test/commandlineGoFlags.ref b/test/commandlineGoFlags.ref
new file mode 100644
index 0000000..b6ec334
--- /dev/null
+++ b/test/commandlineGoFlags.ref
@@ -0,0 +1,263 @@
+
+
+// redo - global option redo
+//
+// Redo global option via automatic code-gen
+
+package main
+
+////////////////////////////////////////////////////////////////////////////
+// Program: redo
+// Purpose: global option redo
+// Authors: Myself <me@mine.org> (c) 2022, All rights reserved
+////////////////////////////////////////////////////////////////////////////
+
+import (
+// "fmt"
+// "os"
+
+// "github.com/go-easygen/go-flags"
+)
+
+// Template for main starts here
+
+//////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+////////////////////////////////////////////////////////////////////////////
+// Global variables definitions
+
+// var (
+// progname = "redo"
+// version = "0.1.0"
+// date = "2022-02-07"
+
+// // opts store all the configurable options
+// opts optsT
+// )
+//
+// var parser = flags.NewParser(&opts, flags.Default)
+
+////////////////////////////////////////////////////////////////////////////
+// Function definitions
+
+// Function main
+// func main() {
+// opts.Version = showVersion
+// opts.Verbflg = func() {
+// opts.Verbose++
+// }
+//
+// if _, err := parser.Parse(); err != nil {
+// fmt.Println()
+// parser.WriteHelp(os.Stdout)
+// os.Exit(1)
+// }
+// fmt.Println()
+// //DoRedo()
+// }
+//
+// func showVersion() {
+// fmt.Fprintf(os.Stderr, "redo - global option redo, version %s\n", version)
+// fmt.Fprintf(os.Stderr, "Built on %s\n", date)
+// fmt.Fprintf(os.Stderr, "Copyright (C) 2022, Myself <me@mine.org>\n\n")
+// fmt.Fprintf(os.Stderr, "Redo global option via automatic code-gen\n")
+// os.Exit(0)
+// }
+// Template for main ends here
+
+// DoRedo implements the business logic of command `redo`
+// func DoRedo() error {
+// return nil
+// }
+
+// Template for type define starts here
+
+// The optsT type defines all the configurable options from cli.
+type optsT struct {
+ Host string `short:"H" long:"host" env:"REDO_HOST" description:"Host address" default:"localhost"`
+ Port int `short:"p" long:"port" env:"REDO_PORT" description:"Listening port" default:"80"`
+ Force bool `short:"f" long:"force" env:"REDO_FORCE" description:"Force start"`
+ Verbflg func() `short:"v" long:"verbose" description:"Verbose mode (Multiple -v options increase the verbosity)"`
+ Verbose int
+ Version func() `short:"V" long:"version" description:"Show program version and exit"`
+}
+// Template for type define ends here
+
+
+// Template for "build" CLI handling starts here
+////////////////////////////////////////////////////////////////////////////
+// Program: redo
+// Purpose: global option redo
+// Authors: Myself <me@mine.org> (c) 2022, All rights reserved
+////////////////////////////////////////////////////////////////////////////
+
+// package main
+
+// import (
+// "fmt"
+// "os"
+//
+// "github.com/go-easygen/go-flags/clis"
+// )
+
+// *** Sub-command: build ***
+
+////////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+// The BuildCommand type defines all the configurable options from cli.
+// type BuildCommand struct {
+// Dir string `long:"dir" description:"source code root dir" default:"./"`
+// }
+
+//
+// var buildCommand BuildCommand
+//
+// func init() {
+// parser.AddCommand("build",
+// "Build the network application",
+// "Usage:\n redo build [Options] Arch(i386|amd64)",
+// &buildCommand)
+// }
+//
+// func (x *BuildCommand) Execute(args []string) error {
+// fmt.Fprintf(os.Stderr, "Build the network application\n")
+// // fmt.Fprintf(os.Stderr, "Copyright (C) 2022, Myself <me@mine.org>\n\n")
+// clis.Setup("redo::build", opts.Verbose)
+// clis.Verbose(1, "Doing Build, with %+v, %+v", opts, args)
+// fmt.Println(x.Dir)
+// return x.Exec(args)
+// }
+//
+// Exec implements the business logic of command `build`
+// func (x *BuildCommand) Exec(args []string) error {
+// // err := ...
+// // clis.WarnOn("Build, Exec", err)
+// // or,
+// // clis.AbortOn("Build, Exec", err)
+// return nil
+// }
+// Template for "build" CLI handling ends here
+
+// Template for "install" CLI handling starts here
+////////////////////////////////////////////////////////////////////////////
+// Program: redo
+// Purpose: global option redo
+// Authors: Myself <me@mine.org> (c) 2022, All rights reserved
+////////////////////////////////////////////////////////////////////////////
+
+// package main
+
+// import (
+// "fmt"
+// "os"
+//
+// "github.com/go-easygen/go-flags/clis"
+// )
+
+// *** Sub-command: install ***
+
+////////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+// The InstallCommand type defines all the configurable options from cli.
+// type InstallCommand struct {
+// Dir string `short:"d" description:"source code root dir" default:"./"`
+// Suffix string `long:"suffix" description:"source file suffix" default:".go,.c,.s"`
+// }
+
+//
+// var installCommand InstallCommand
+//
+// func init() {
+// parser.AddCommand("install",
+// "Install the network application",
+// "The add command adds a file to the repository. Use -a to add all files",
+// &installCommand)
+// }
+//
+// func (x *InstallCommand) Execute(args []string) error {
+// fmt.Fprintf(os.Stderr, "Install the network application\n")
+// // fmt.Fprintf(os.Stderr, "Copyright (C) 2022, Myself <me@mine.org>\n\n")
+// clis.Setup("redo::install", opts.Verbose)
+// clis.Verbose(1, "Doing Install, with %+v, %+v", opts, args)
+// fmt.Println(x.Dir, x.Suffix)
+// return x.Exec(args)
+// }
+//
+// Exec implements the business logic of command `install`
+// func (x *InstallCommand) Exec(args []string) error {
+// // err := ...
+// // clis.WarnOn("Install, Exec", err)
+// // or,
+// // clis.AbortOn("Install, Exec", err)
+// return nil
+// }
+// Template for "install" CLI handling ends here
+
+// Template for "publish" CLI handling starts here
+////////////////////////////////////////////////////////////////////////////
+// Program: redo
+// Purpose: global option redo
+// Authors: Myself <me@mine.org> (c) 2022, All rights reserved
+////////////////////////////////////////////////////////////////////////////
+
+// package main
+
+// import (
+// "fmt"
+// "os"
+//
+// "github.com/go-easygen/go-flags/clis"
+// )
+
+// *** Sub-command: publish ***
+
+////////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+// The PublishCommand type defines all the configurable options from cli.
+// type PublishCommand struct {
+// Dir string `short:"d" long:"dir" description:"publish dir" required:"true"`
+// Suffix []string `short:"s" long:"suffix" description:"source file suffix for publish" choice:".go" choice:".c" choice:".h"`
+// Out string `short:"o" long:"out" description:"output filename"`
+//
+// // Example of positional arguments
+// Args struct {
+// ID string
+// Num int
+// Rest []string
+// } `positional-args:"yes" required:"yes"`
+// }
+
+//
+// var publishCommand PublishCommand
+//
+// func init() {
+// parser.AddCommand("publish",
+// "Publish the network application",
+// "Publish the built network application to central repo",
+// &publishCommand)
+// }
+//
+// func (x *PublishCommand) Execute(args []string) error {
+// fmt.Fprintf(os.Stderr, "Publish the network application\n")
+// // fmt.Fprintf(os.Stderr, "Copyright (C) 2022, Myself <me@mine.org>\n\n")
+// clis.Setup("redo::publish", opts.Verbose)
+// clis.Verbose(1, "Doing Publish, with %+v, %+v", opts, args)
+// fmt.Println(x.Dir, x.Suffix, x.Out, x.Args)
+// return x.Exec(args)
+// }
+//
+// Exec implements the business logic of command `publish`
+// func (x *PublishCommand) Exec(args []string) error {
+// // err := ...
+// // clis.WarnOn("Publish, Exec", err)
+// // or,
+// // clis.AbortOn("Publish, Exec", err)
+// return nil
+// }
+// Template for "publish" CLI handling ends here
+
+
diff --git a/test/commandlineGoFlags.tmpl b/test/commandlineGoFlags.tmpl
new file mode 100644
index 0000000..7a5d2f4
--- /dev/null
+++ b/test/commandlineGoFlags.tmpl
@@ -0,0 +1,128 @@
+// {{.Name}} - {{.Desc}}
+//
+// {{.Text}}
+
+package {{$.PackageName}}
+
+{{template "header" $ }}
+
+import (
+// "fmt"
+// "os"
+
+// "github.com/go-easygen/go-flags"
+)
+
+// Template for main starts here
+
+//////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+////////////////////////////////////////////////////////////////////////////
+// Global variables definitions
+
+// var (
+// progname = "{{.Name}}"
+// version = "0.1.0"
+// date = "{{ date "I" }}"
+
+// // opts store all the configurable options
+// opts optsT
+// )
+//
+// var parser = flags.NewParser(&opts, flags.Default)
+
+////////////////////////////////////////////////////////////////////////////
+// Function definitions
+
+// Function main
+// func main() {
+{{- if .Version }}
+// opts.Version = showVersion
+{{- end }}
+{{- if .Verbose }}
+// opts.Verbflg = func() {
+// opts.Verbose++
+// }
+{{- end }}
+//
+// if _, err := parser.Parse(); err != nil {
+// fmt.Println()
+// parser.WriteHelp(os.Stdout)
+// os.Exit(1)
+// }
+// fmt.Println()
+// //Do{{stringsTitle .Name}}()
+// }
+//
+{{- if .Version }}
+// func showVersion() {
+// fmt.Fprintf(os.Stderr, "{{.Name}} - {{.Desc}}, version %s\n", version)
+// fmt.Fprintf(os.Stderr, "Built on %s\n", date)
+// fmt.Fprintf(os.Stderr, "Copyright (C) {{ date "Y4" }}, {{or $.Authors "The Author(s) <they@their.org>"}}\n\n")
+// fmt.Fprintf(os.Stderr, "{{.Text}}\n")
+// os.Exit(0)
+// }
+{{- end }}
+// Template for main ends here
+
+// Do{{stringsTitle .Name}} implements the business logic of command `{{.Name}}`
+// func Do{{stringsTitle .Name}}() error {
+// return nil
+// }
+
+// Template for type define starts here
+
+{{template "type_struct" argsm "ProgramName" .ProgramName "Options" .Options "Verbose" .Verbose "Version" .Version "typeName" "optsT" "Prefix" "" }}
+// Template for type define ends here
+
+{{range .Command}}
+// Template for "{{.Name}}" CLI handling starts here
+{{template "header" $ }}
+
+// package {{$.PackageName}}
+
+// import (
+// "fmt"
+// "os"
+//
+// "github.com/go-easygen/go-flags/clis"
+// )
+
+// *** Sub-command: {{.Name}} ***
+
+////////////////////////////////////////////////////////////////////////////
+// Constant and data type/structure definitions
+
+{{template "type_struct" argsm "ProgramName" $.ProgramName "Options" .Options "typeName" (print (stringsTitle .Name) "Command") "Prefix" "// " }}
+
+//
+// var {{.Name}}Command {{stringsTitle .Name}}Command
+//
+// func init() {
+// parser.AddCommand("{{.Name}}",
+// "{{.Desc}}",
+// "{{.Text}}",
+// &{{.Name}}Command)
+// }
+//
+// func (x *{{stringsTitle .Name}}Command) Execute(args []string) error {
+// fmt.Fprintf(os.Stderr, "{{.Desc}}\n")
+// // fmt.Fprintf(os.Stderr, "Copyright (C) {{ date "Y4" }}, {{or $.Authors "The Author(s) <they@their.org>"}}\n\n")
+// clis.Setup("{{$.Name}}::{{.Name}}", opts.Verbose)
+// clis.Verbose(1, "Doing {{stringsTitle .Name}}, with %+v, %+v", opts, args)
+// {{$opts := .Options}}fmt.Println({{range $i, $opt := .Options}}x.{{$opt.Name}}{{if lt $i ($opts | len | minus1)}}, {{end}}{{end}})
+// return x.Exec(args)
+// }
+//
+// Exec implements the business logic of command `{{.Name}}`
+// func (x *{{stringsTitle .Name}}Command) Exec(args []string) error {
+// // err := ...
+// // clis.WarnOn("{{stringsTitle .Name}}, Exec", err)
+// // or,
+// // clis.AbortOn("{{stringsTitle .Name}}, Exec", err)
+// return nil
+// }
+// Template for "{{.Name}}" CLI handling ends here
+{{end}}
+
diff --git a/test/commandlineGoFlags.yaml b/test/commandlineGoFlags.yaml
new file mode 100644
index 0000000..8ff2642
--- /dev/null
+++ b/test/commandlineGoFlags.yaml
@@ -0,0 +1,102 @@
+# program name, name for the executable
+ProgramName: redo
+Authors: Myself <me@mine.org>
+
+# For the complete demo, refer to the finished code at
+# https://github.com/suntong/lang/tree/master/lang/Go/src/sys/go-flags/wireframed
+# and the wiki at
+# https://github.com/go-easygen/easygen/issues/46
+#
+PackageName: main
+
+Name: redo
+Desc: "global option redo"
+Text: Redo global option via automatic code-gen
+Verbose: true
+Version: true
+
+Options:
+ - Name: Host
+ Type: string
+ Flag: H,host
+ EnvV: true
+ Usage: Host address
+ Value: localhost
+
+ - Name: Port
+ Type: int
+ Flag: p,port
+ EnvV: true
+ Usage: Listening port
+ Value: 80
+
+ - Name: Force
+ Type: bool
+ Flag: f,force
+ EnvV: true
+ Usage: Force start
+
+
+Command:
+
+ - Name: build
+ Desc: "Build the network application"
+ Text: 'Usage:\n redo build [Options] Arch(i386|amd64)'
+
+ Options:
+ - Name: Dir
+ Type: string
+ Flag: dir
+ Value: "./"
+ Usage: source code root dir
+
+ - Name: install
+ Desc: "Install the network application"
+ Text: 'The add command adds a file to the repository. Use -a to add all files'
+
+ Options:
+ - Name: Dir
+ Type: string
+ Flag: d
+ Value: "./"
+ Usage: source code root dir
+
+ - Name: Suffix
+ Type: string
+ Flag: suffix
+ Value: ".go,.c,.s"
+ Usage: "source file suffix"
+
+ - Name: publish
+ Desc: Publish the network application
+ Text: Publish the built network application to central repo
+
+ Options:
+ - Name: Dir
+ Type: string
+ Flag: 'd,dir'
+ Usage: publish dir
+ Required: true
+
+ - Name: Suffix
+ Type: '[]string'
+ Flag: s,suffix
+ Usage: "source file suffix for publish"
+ Choices:
+ - .go
+ - .c
+ - .h
+
+ - Name: Out
+ Type: string
+ Flag: o,out
+ Usage: "output filename"
+
+ - Name: Args
+ Args: |-
+ // Example of positional arguments
+ // Args struct {
+ // ID string
+ // Num int
+ // Rest []string
+ // } `positional-args:"yes" required:"yes"`
diff --git a/test/nested_demo_argsm_opt.tmpl b/test/nested_demo_argsm_opt.tmpl
new file mode 100644
index 0000000..682db92
--- /dev/null
+++ b/test/nested_demo_argsm_opt.tmpl
@@ -0,0 +1,23 @@
+{{define "type_struct" -}}
+
+// The {{.typeName}} type defines all the configurable options from cli.
+type {{.typeName}} struct { {{- range .Options}}
+{{- if eq .Name "Args" }}
+
+ {{.Args}}
+{{- else }}{{$f := stringsSplit .Flag ","}}{{ $flen := len $f }}
+ {{.Name}} {{.Type}} `short:"{{index $f 0}}"{{if gt $flen 1}} long:"{{index $f 1}}"{{end}}{{if .EnvV}} env:"{{printf "%s_%s" (clk2ss $.ProgramName) (clk2ss .Name)}}"{{end}} description:"{{.Usage}}"{{if .Value}} default:"{{.Value}}"{{end}}`{{end}}
+{{- end}}
+{{- if .Verbose}}
+ Verbflg func() `short:"v" long:"verbose" description:"Verbose mode (Multiple -v options increase the verbosity)"`
+ Verbose uint
+{{end}}
+{{- end -}}
+
+{{range .Command}}
+////////////////////////////////////////////////////////////////////////////
+// {{.Name}}
+
+{{template "type_struct" argsm "Options" .Options "typeName" (print (stringsTitle .Name) "Command") }}
+}
+{{end}}
diff --git a/test/nested_demo_argsm_opt.yaml b/test/nested_demo_argsm_opt.yaml
new file mode 100644
index 0000000..85ec7aa
--- /dev/null
+++ b/test/nested_demo_argsm_opt.yaml
@@ -0,0 +1,36 @@
+Command:
+
+ - Name: publish
+ Desc: "Publish application"
+ Text: 'Publish the network application"'
+
+ Options:
+ - Name: Dir
+ Type: string
+ Flag: '*d,dir'
+ Usage: publish dir
+
+ - Name: Suffix
+ Type: string
+ Flag: suffix
+ Value: ".go,.c,.s"
+ Usage: "source file suffix"
+
+ - Name: Out
+ Type: string
+ Flag: o,out
+ Usage: "output filename"
+
+ - Name: List
+ Type: bool
+ Flag: l,list
+ Usage: "list all sub commands"
+
+ - Name: Args
+ Args: |
+ // Example of positional arguments
+ Args struct {
+ ID string
+ Num int
+ Rest []string
+ "} `positional-args:"yes" required:"yes"`"
diff --git a/test/tf-calc.ref b/test/tf-calc.ref
new file mode 100644
index 0000000..be3a1f4
--- /dev/null
+++ b/test/tf-calc.ref
@@ -0,0 +1,5 @@
+some-init-method
+5 5
+5 5
+3 3 2 2
+8
diff --git a/test/tf-calc.tmpl b/test/tf-calc.tmpl
new file mode 100644
index 0000000..60fabb5
--- /dev/null
+++ b/test/tf-calc.tmpl
@@ -0,0 +1,5 @@
+{{.Name}}
+{{6 | minus1}} {{minus1 6}}
+{{6 | minus 1}} {{minus 1 6}}
+{{5 | minus 2}} {{minus 2 5}} {{5 | minus 3}} {{minus 3 5}}
+{{add 2 6}}
diff --git a/test/tf-calc.yaml b/test/tf-calc.yaml
new file mode 120000
index 0000000..042f49b
--- /dev/null
+++ b/test/tf-calc.yaml
@@ -0,0 +1 @@
+listfunc2.yaml
\ No newline at end of file
diff --git a/tf-calc.go b/tf-calc.go
index 5f23e9d..78db730 100644
--- a/tf-calc.go
+++ b/tf-calc.go
@@ -45,6 +45,9 @@ func ArgsM(kvs ...interface{}) (map[string]interface{}, error) {
//==========================================================================
// template function for calculations
+func Add(b, a int) int { return a + b }
+func Minus(b, a int) int { return a - b }
+
// By Caleb Spare @gmail.com
// https://groups.google.com/d/msg/golang-nuts/gzAyBLAeUbU/LwgomgxcjQ8J
diff --git a/tf-strings.go b/tf-strings.go
index fdf4a3a..3e48f0e 100644
--- a/tf-strings.go
+++ b/tf-strings.go
@@ -150,11 +150,25 @@ func RegexpSplit(s string, regExp string, n int) []string {
////////////////////////////////////////////////////////////////////////////
// Misc
+// Indent will indent the following lines according to the specified spaces
+func Indent(spaces int, v string) string {
+ pad := strings.Repeat(" ", spaces)
+ return strings.Replace(v, "\n", "\n"+pad, -1)
+}
+
+// PIndent will indent all lines according to the specified spaces
+func PIndent(spaces int, v string) string {
+ pad := strings.Repeat(" ", spaces)
+ return pad + Indent(spaces, v)
+}
+
// Coalesce function takes two or more string arguments and returns the first argument that is not empty.
// The result is empty only if all the arguments are empty.
-func Coalesce(s ...string) string {
- for _, str := range s {
- if len(str) != 0 && str != "<no value>" {
+func Coalesce(s ...interface{}) string {
+ // https://go.dev/play/p/C2-f7B0eCwx
+ for _, v := range s {
+ str := fmt.Sprint(v)
+ if len(str) != 0 && str != "<nil>" {
return str
}
}