easygen

package module
v4.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2019 License: MIT Imports: 12 Imported by: 0

README

easygen

MIT License GoDoc Go Report Card travis Status Codeship Status for go-easygen/easygen

TOC

easygen - Easy to use universal code/text generator

Command easygen is an easy to use universal code/text generator.

It can be used as a text or html generator for arbitrary purposes with arbitrary data and templates. It is a good GSL replacement, as it

  • is more easy to define driving data, in form of YML instead of XML
  • has more powerful template engine that based on Go template. You can also write your own function in Go to customize your template.

You can even use easygen as a generic Go template testing tool using the -ts commandline option, and much more.

Note this document is for easygen versions 4.0+. For historic versions check out the Different Versions section.

Usage

$ easygen
easygen version 4.0.0

Usage:
 easygen [flags] template_name [data_filename [data_filename...]]

Flags:

  -debug level
    	debugging level
  -ej extension
    	extension of json file (default ".json")
  -et extension
    	extension of template file (default ".tmpl")
  -ey extension
    	extension of yaml file (default ".yaml")
  -ts string
    	template string (in text)

data_filename(s): The name for the .yaml or .json data.
 - If omitted derive from the template_name.
 - Can have the extension or without it. If withot extension,
   will try .yaml first then .json
 - Can include the path as well.

template_name: The name for the template file.
 - Can have the extension or without it.
 - Can include the path as well.
 - Can be a comma-separated list giving many template files, in which case
   at least one data_filename must be given.

Flag defaults can be overridden by corresponding environment variable, e.g.:
  EASYGEN_EY=.yml EASYGEN_ET=.tpl easygen ...

Install

Install as Debian/Unbuntu package
apt install easygen
Install from source
go get github.com/go-easygen/easygen/...
ls -l $GOPATH/bin

You should find an easygen executable newly created in there.

Test

export PATH=$PATH:$GOPATH/bin

$ easygen $GOPATH/src/github.com/go-easygen/easygen/test/list0
The colors are: red, blue, white, .

cd $GOPATH/src/github.com/go-easygen/easygen

$ easygen test/list1 
The quoted colors are: "red", "blue", "white", .

$ easygen test/listfunc1 test/list0
red, blue, white.

And also check out the provided more examples in the Go Doc document.

Details

It can be used as a code generator, for example, command line parameter handling code generator, or anything that is structurally repetitive, like the following:

Ready to get started? Then check out Getting Started to start building your way to turn your data into any form, any way you want.

Command line flag handling code auto-generation

As explained above, one practical use of easygen is to auto-generating Go code for command line parameter handling, for both viper and cobra, and Go's built-in flag package.

easygen itself

Currently, easygen's command line parameter handling is built on top of Go's built-in flag package, and the handling code is entirely generated by easygen itself. Thus, showing how easygen is handling the command line parameters itself also means showing what functionality the auto-generated command line parameter handling code can do for you.

Currently, there are three tiers program parameters can be given:

  1. Default values defined within the program, so that program parameters can have meaningful defaults to start with
  2. Values defined in environment variables
  3. Values passed from command line

The latter will have higher priority and will override values defined formerly. I.e., the values from command line will override that in environment variables, which in turn override program defaults.

We will use the -ts, template string, as an example to illustrate. The program defaults is empty, which means using the .tmpl template file the same as the .yaml data file. We will override that first by environment variable, then from command line, illustrated in next section.

cli based

See,

A cookbook on how to jump-start a cli based command line handling program

The easygen usage

Command line

Check here for more on using easygen the command line tool.

The library

The easygen is a library as well as a command line tools. Not only it is super easy to use, it is super easy to extend as well.

The restructured easygen can now be a building block that people can easily extend, any extra functionalities, or extra feature that it depends on, or any external dependencies are now moved out to sub modules. Thus the library users can now pick and choose exactly what they want from the library.

  • The egVar package example shows how to add the variable name manipulation on top of the default library.
  • The egCal package example shows how to add the variable name manipulation and generic calculation functionalities, together with the default functions, all at the same time.

To put them all together, check out the easygen's main.go:

> cmd/easygen/main.go
package main

import (
	"flag"
	"os"

	"github.com/go-easygen/easygen"
	"github.com/go-easygen/easygen/egCal"
	"github.com/go-easygen/easygen/egVar"
)

//go:generate sh -v easygen.gen.sh

////////////////////////////////////////////////////////////////////////////
// Main

func main() {
	flag.Usage = Usage
	flag.Parse()

	// One mandatory non-flag arguments
	if flag.NArg() < 1 {
		Usage()
	}

	tmpl0 := easygen.NewTemplate().Customize()
	tmpl := tmpl0.Funcs(easygen.FuncDefs()).
		Funcs(egVar.FuncDefs()).Funcs(egCal.FuncDefs())

	args := flag.Args()
	if len(easygen.Opts.TemplateStr) > 0 {
		easygen.Process0(tmpl, os.Stdout, easygen.Opts.TemplateStr, args...)
	} else {
		easygen.Process(tmpl, os.Stdout, args...)
	}
}

It has been as simple as this up until version 3. I.e., it's quite simple to make use of easygen as a package.

Different Versions

The easygen has gone through four different versions whose API are a bit different between them.

To always stay at the latest version, import

"github.com/go-easygen/easygen"

in your Go code. However, to stay within a certain version, import the following package respectively to what you need:

To see the differences between them, check out

Author(s) & Contributor(s)

Tong SUN
suntong from cpan.org

Gerrit Renker
https://github.com/grrtrr

All patches welcome.

Documentation

Overview

Package easygen is an easy to use universal code/text generator library.

It can be used as a text or html generator for arbitrary purposes with arbitrary data and templates.

It can be used as a code generator, or anything that is structurally repetitive. Some command line parameter handling code generator are provided as examples, including the Go's built-in flag package, and the viper & cobra package.

Many examples have been provided to showcase its functionality, and different ways to use it.

Index

Examples

Constants

This section is empty.

Variables

View Source
var Opts = Options{ExtYaml: ".yaml", ExtJson: ".json", ExtTmpl: ".tmpl"}

Opts holds the actual values from the command line parameters

Functions

func Execute

func Execute(t Template, wr io.Writer, fileNameT string, m EgData) error

Execute will execute the Template on the given data map `m`.

Example

for standalone test, change package to `main` and the next func def to, func main() {

package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/go-easygen/easygen"
	"github.com/go-easygen/easygen/egCal"
	"github.com/go-easygen/easygen/egVar"
)

type variable struct {
	Name string
}

// for standalone test, change package to `main` and the next func def to,
// func main() {
func main() {
	easygen.Opts.Debug = 1

	tmpl0 := easygen.NewTemplate().Customize()
	tmpl := tmpl0.Funcs(easygen.FuncDefs()).Funcs(egVar.FuncDefs()).Funcs(egCal.FuncDefs())

	// define driving data of any tye
	v0 := variable{"some-init-method"}
	// https://godoc.org/github.com/go-easygen/easygen#Execute
	// provide full template file name with extension
	easygen.Execute(tmpl, os.Stdout, "test/var0.tmpl", v0)

	// Demo of using driving data of pure slice/array
	v1 := []string{"red", "blue", "white"}
	easygen.Execute(tmpl, os.Stdout, "test/list00.tmpl", v1)

	// Demo output to string
	var b strings.Builder
	easygen.Execute(tmpl, &b, "test/list00f.tmpl", v1)
	fmt.Print(b.String())

}

// To show the full code in GoDoc
type dummyExecute struct {
}
Output:

Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"
The colors are: red, blue, white, .
The colors are: red, blue, white.

func FuncDefs

func FuncDefs() template.FuncMap

FuncDefs returns the custom definition mapping for this specific package.

func IsExist

func IsExist(fileName string) bool

IsExist checks if the given file exist

func Process

func Process(t Template, wr io.Writer, fileNames ...string) error

Process will process the standard easygen input: the `fileName` is for both template and data file name, and produce output from the template according to the corresponding driving data. Process() is using the V3's calling convention and *only* works properly in V4+ in the case that there is only one fileName passed to it. If need to pass more files, use Process2() instead.

Example

for standalone test, change package to `main` and the next func def to, func main() {

package main

import (
	"os"

	"github.com/go-easygen/easygen"
	"github.com/go-easygen/easygen/egVar"
)

// for standalone test, change package to `main` and the next func def to,
// func main() {
func main() {
	tmpl0 := easygen.NewTemplate().Customize()
	tmpl := tmpl0.Funcs(easygen.FuncDefs()).Funcs(egVar.FuncDefs())
	tmplFileName := "test/var0"
	easygen.Process(tmpl, os.Stdout, tmplFileName)
	easygen.Process2(tmpl, os.Stdout, tmplFileName, tmplFileName)

	// To use Execute(), TemplateFileName has to be exact
	m := easygen.ReadDataFile(tmplFileName + ".yaml")
	easygen.Execute(tmpl, os.Stdout, tmplFileName+".tmpl", m)

}

// To show the full code in GoDoc
type dummy struct {
}
Output:

Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"
Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"
Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"

func Process0

func Process0(t Template, wr io.Writer, strTempl string, fileNames ...string) error

Process0 will produce output according to the driving data *without* a template file, using the string from strTempl as the template

Example

for standalone test, change package to `main` and the next func def to, func main() {

package main

import (
	"os"

	"github.com/go-easygen/easygen"
	"github.com/go-easygen/easygen/egCal"
	"github.com/go-easygen/easygen/egVar"
)

// for standalone test, change package to `main` and the next func def to,
// func main() {
func main() {
	tmpl0 := easygen.NewTemplate().Customize()
	tmpl := tmpl0.Funcs(easygen.FuncDefs()).Funcs(egVar.FuncDefs()).Funcs(egCal.FuncDefs())
	easygen.Process0(tmpl, os.Stdout,
		"{{.Name}}: {{clk2uc .Name}} {{clk2ss .Name}}\n"+
			"Cal: {{add 2 3}}, {{multiply 2 3}}, {{subtract 9 2}}, {{divide 24 3}}\n",
		"test/var0")

}

// To show the full code in GoDoc
type dummy0 struct {
}
Output:

some-init-method: SomeInitMethod SOME_INIT_METHOD
Cal: 5, 6, 7, 8
Example (List0StrTemplate)

Test string template with list0 data

package main

import (
	"os"
	"text/template"

	"github.com/go-easygen/easygen"
)

var tmpl *template.Template

func main() {
	// Equivalent testing on commandline:
	//   easygen -ts '{{range .Colors}}{{.}}, {{end}}' test/list0
	easygen.Process0(tmpl, os.Stdout,
		"{{range .Colors}}{{.}}, {{end}}", "test/list0")
}
Output:

red, blue, white,
Example (Split0)

Test the string split function in template

package main

import (
	"os"
	"text/template"

	"github.com/go-easygen/easygen"
)

var tmpl *template.Template

func main() {
	// Equivalent testing on commandline:
	//   easygen -ts '{{split .Colorlist}}' test/list0
	easygen.Process0(tmpl, os.Stdout,
		`{{split .Colorlist}}`, "test/list0")
}
Output:

[red blue white]
Example (Split1)

Test the string split function in template again

package main

import (
	"os"
	"text/template"

	"github.com/go-easygen/easygen"
)

var tmpl *template.Template

func main() {
	// Equivalent testing on commandline:
	//   easygen -ts '{{range ... {{end}}' test/list0
	easygen.Process0(tmpl, os.Stdout,
		`{{range (split .Colorlist)}}{{.}} {{end}}`, "test/list0")
}
Output:

red blue white
Example (StringsCmp)

Test string comparison in template

package main

import (
	"os"
	"text/template"

	"github.com/go-easygen/easygen"
)

var tmpl *template.Template

func main() {
	// Equivalent testing on commandline:
	//   easygen -ts '{{The {{if ... {{end}}.' test/strings0
	easygen.Process0(tmpl, os.Stdout,
		`The {{if eq .StrTest "-AB-axxb- HTML Html html"}}eq says Yea{{else}}eq says Nay{{end}} but {{if eqf .StrTest "-AB-axxb- HTML Html html"}}eqf says Yea{{else}}eqf says Nay{{end}}.`, "test/strings0")
}
Output:

The eq says Nay but eqf says Yea.

func Process1

func Process1(t Template, wr io.Writer, fileNameTempl string, fileName string) error

Process1 will process a *single* case where both template and data file names are given, and produce output according to the given template and driving data files, specified via fileNameTempl and fileName respectively. fileNameTempl is not a comma-separated string, but for a single template file.

func Process2

func Process2(t Template, wr io.Writer, fileNameTempl string, fileNames ...string) error

Process2 will process the case that *both* template and data file names are given, and produce output according to the given template and driving data files, specified via fileNameTempl and fileNames respectively. fileNameTempl can be a comma-separated string giving many template files

Example (Html)

Test HTML template with list1 data

package main

import (
	"os"
	"text/template"

	"github.com/go-easygen/easygen"
)

var tmpl *template.Template

func main() {
	// Equivalent testing on commandline:
	//   easygen -tf test/list1HTML test/list1
	easygen.Process2(tmpl, os.Stdout, "test/list1HTML", "test/list1")
}
Output:

The quoted colors are: &#34;red&#34;, &#34;blue&#34;, &#34;white&#34;, .

Types

type EgBase

type EgBase struct {
	*template.Template
}

EgBase -- EasyGen Template Base

func NewTemplate

func NewTemplate() *EgBase

NewTemplate returns a new Template for this specific package.

func (*EgBase) Customize

func (t *EgBase) Customize() *EgBase

Customize allows customization for this specific package.

type EgData

type EgData interface{}

EgData -- EasyGen driven Data

func ReadDataFile

func ReadDataFile(fileName string) EgData

ReadDataFile reads in the driving data from the given file, which can be optionally without the defined extension

Example

for standalone test, change package to `main` and the next func def to, func main() {

package main

import (
	"os"

	"github.com/go-easygen/easygen"
	"github.com/go-easygen/easygen/egVar"
)

func main() {
	tmplFileName := "test/var0"
	tmpl0 := easygen.NewTemplate().Customize()
	tmpl := tmpl0.Funcs(easygen.FuncDefs()).Funcs(egVar.FuncDefs())

	// To use Execute(), TemplateFileName has to be exact
	tmplFileNameFull := tmplFileName + ".tmpl"

	m := easygen.ReadDataFile(tmplFileName)
	easygen.Execute(tmpl, os.Stdout, tmplFileNameFull, m)

	easygen.Opts.Debug = 0
	m = easygen.ReadDataFile(tmplFileName + ".yaml")
	easygen.Execute(tmpl, os.Stdout, tmplFileNameFull, m)

	tmplFileName = "test/list0j"
	tmplFileNameFull = tmplFileName + ".tmpl"

	m = easygen.ReadDataFile(tmplFileName)
	easygen.Execute(tmpl, os.Stdout, tmplFileNameFull, m)

	m = easygen.ReadDataFile(tmplFileName + ".json")
	easygen.Execute(tmpl, os.Stdout, tmplFileNameFull, m)

}
Output:

Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"
Input: "some-init-method"
Output 1: "SomeInitMethod"
Output 2: "SOME_INIT_METHOD"
The colors are: red, blue, white, .
The colors are: red, blue, white, .

func ReadJsonFile

func ReadJsonFile(fileName string) EgData

ReadJsonFile reads given JSON file as EgData

func ReadYamlFile

func ReadYamlFile(fileName string) EgData

ReadYamlFile reads given YAML file as EgData

type FuncMap

type FuncMap map[string]interface{}

The FuncMap defined in easygen will shield the dependency of either text or html template, giving an implementation agnostic abstraction that will works for both cases.

type Options

type Options struct {
	TemplateStr string // template string (in text)
	ExtYaml     string // `extension` of yaml file
	ExtJson     string // `extension` of json file
	ExtTmpl     string // `extension` of template file
	Debug       int    // debugging `level`
}

The Options struct defines the structure to hold the commandline values

type Template

type Template interface {
	Execute(wr io.Writer, data interface{}) error
	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
	Parse(text string) (*template.Template, error)
	ParseFiles(filenames ...string) (*template.Template, error)
	Name() string
}

The Template defines the common ground for both text and html Template

Directories

Path Synopsis
cmd
easygen
Command easygen is an easy to use universal code/text generator.
Command easygen is an easy to use universal code/text generator.
Package egVar provides variable naming functionalities.
Package egVar provides variable naming functionalities.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL