Skip to content

Metronlab/genius

Repository files navigation

Genius

A golang generative framework that palliate the lack of generic in go.

Supported commands

Use genius $COMMAND --help to see usage on each possibilities

genius tmpl

tmpl bring goland template framework to go code itself using tmpl specs and data files in various format.

Command tmpl is a complete rework of original influxdata framework for generate golang code. It removes support for .json comments which is an unsafe / non ide proof way to derive json specification but add YAML support to allow adding comments on data feeding the generation. Original licence is maintained here.

Features

  • run go fmt over generated code at code gen
  • support several format for data:
    • json
    • yaml
    • toml
  • With option -v support command line defined values as a key value pair
  • With option -i can run goimports command at generation to correct missing import paths
  • With option -dry or better with environment GENIUS_DRY=true allow comparing result with targeted file instead of generating it again. Wich can be useful in continuous integration logics

Getting started

Getting started is inspired by example subdirectory.

After installing genius with go get or go install, use a go generate directive:

package yourpackage

//go:generate genius tmpl -data=YOUR_DEFINITIONS.json NAME_OF_YOUR_GO_FILE_TO_GENERATE.gen.go.tmpl

Your YOUR_DEFINITIONS.json should look like so:

[
	{
		"name":"float64"
	},
	{
		"name":"int"
	}
]

Write the tmpl file in NAME_OF_YOUR_GO_FILE_TO_GENERATE.gen.go.tmpl, all golang tmpl directive are allowed:

package yourpackage

import (
	"fmt"
	"reflect"
	"github.com/spf13/cast"
)

func ConvertToReflectKind(kind reflect.Kind, value interface{}) {
	switch kind {
		{{range .Data}} // range against the provided definitions
		{{ $Type := print .name | stringsTitle }}
		case reflect.{{ $Type }}:
			fmt.Println("{{ .name }}", cast.To{{ $Type }}(value))
		{{end}}
		default:
			panic(fmt.Errorf("unhandled type %v", kind))
	}
}

Generated code in NAME_OF_YOUR_GO_FILE_TO_GENERATE.gen.go will look like:

// Code generated by NAME_OF_YOUR_GO_FILE_TO_GENERATE.gen.go.tmpl. DO NOT EDIT.

package yourpackage

import (
	"fmt"
	"github.com/spf13/cast"
	"reflect"
)

func ConvertToReflectKind(kind reflect.Kind, value interface{}) {
	switch kind {

	case reflect.Float64:
		fmt.Println("float64", cast.ToFloat64(value))

	case reflect.Int:
		fmt.Println("int", cast.ToInt(value))

	default:
		panic(fmt.Errorf("unhandled type %v", kind))
	}
}