gosingl

command module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2023 License: BSD-3-Clause Imports: 19 Imported by: 0

README

Gosingle

gosingle generate module level singleton based on the chosen structure or interface (map slice or array defined as type also supported).

Installation

go get github.com/alh1m1k/gosingle

Usage

The generator does not generate any initialization code, only declaration. Use module level init() or any other way to properly initialize singleton.

By default, generator recursively inspect target structure or interface as well as it composition members. It seek for exported field function, exported methods and then wrap it with module level proxy function.

Global singleton variable may be hidden via lower case variable name. Variable type (pointer or value) currently defined by target type (for interfaces) or rcv type of the first exported method and not 100% accurate. See todo and sources for more information.

Collision detector for function name and signature currently not 100% accurate (See todo and sources), it keept the first collided function into output instead of dropping it all.

Composition member of field type may be excluded from inspect via tag `singl:"ignore"'

Filename for output file has template <package>/<target>_singleton.go and can be changed via --suffix or --filepath.

File suffix _test.go and _singleton.go are excluded from analyze.

Path to source files a resolved via build.Default.Import(pkg, ".", build.FindOnly) be careful with path and naming

All scalar type and all composite type are supported, as well as it's mixing and types decl are supported.

Generator will rename all _ or anonymous function parameter to p0, p1 ...pn in order to generate valid function call

With the following structure in the executor.go file :

package queryExecutor

import (
	"context"
	"database/sql"
	"errors"
)

type QueryExecutor struct {
    One, Two string
}

// todo add opt contenxt param
func (receiver *QueryExecutor) Prepare(sqlStatement string) (context.Context, error) {
    return nil, nil
}

func (receiver *QueryExecutor) Query(sqlStatement any, params ...any) (*sql.Rows, error) {
    return nil, nil
}

func (receiver *QueryExecutor) Execute(sqlStatement any, params ...any) (sql.Result, error) {
    return nil, nil
}

func (receiver *QueryExecutor) WithSql(ctx context.Context, sqlStatement string, params ...any) context.Context {
    return nil
}

func (receiver *QueryExecutor) WithPrepare(ctx context.Context, sql *sql.Stmt) context.Context {
	return ctx
}

func (receiver *QueryExecutor) prepareContext(ctx context.Context) (*sql.Stmt, []any, error) {
    return nil, nil, nil
}

func (receiver *QueryExecutor) prepare(context context.Context, sqlStatement string) (*sql.Stmt, error) {
    return nil, nil
}

func (receiver *QueryExecutor) run(sqlStatement any, done finalizer, params ...any) (any, error) {
    return nil, nil
}

if you run :

$ gosingle github.com/me/queryExecutor QueryExecutor

you will have this output :

// Code generated by <git repo>. DO NOT EDIT.
package queryExecutor

import (
	"context"
	"database/sql"
	"errors"
)

var Instance *QueryExecutor

func Prepare(sqlStatement string) (context.Context, error) {
	return Instance.Prepare(sqlStatement)
}

func Query(sqlStatement any, params ...any) (*sql.Rows, error) {
	return Instance.Query(sqlStatement, params...)
}

func Execute(sqlStatement any, params ...any) (sql.Result, error) {
	return Instance.Execute(sqlStatement, params...)
}

func WithSql(ctx context.Context, sqlStatement string, params ...any) context.Context {
	return Instance.WithSql(ctx, sqlStatement, params...)
}

func WithPrepare(ctx context.Context, sql *sql.Stmt) context.Context {
	return Instance.WithPrepare(ctx, sql)
}

just add the -w flag (or use other file related flag such as --suffix, --filepath) to write it to queryExecutor_singleton.go.

Flags

--PKG        package to walk to
--TARGET     structure or interface that will be use as module singleton
--variable   singleton instance (module variable) "Instance" by default
--comment    code generated by <git repo>. DO NOT EDIT.
--suffix     suffix of generated file "_singleton.go"
--filepath   path for generated file --suffix will be ignored
--deep       recursive deep

Status

Package in ready state. All basic functionality are implemented. It has test coverage, but has lack of usage in real cases. So it can be broken, but not entirely :) Generic currently not supported as it not trivial to convert struct[T] to func[T]

Dependencies

The two main dependencies are :

  • dave/jennifer: an awesome library for writing go code
  • mow.cli : a cli command utility (probably will be dropped)

Inspired by

TODO

Checker must be improved to better handle function collision (check function signature instead of parameters count), that is needed to distinguish between a collision with an interface and with another composition method, as behavior is quite different. Singleton variable decl must be delayed until first method appear to determinate rcv type (pointer or value). Currently not 100% accurate, but works in most cases.

  • composition
  • interface
  • generics
  • tags (ignore)
  • test coverage & testing
  • ambiguous function detector
  • later variable decl
  • drop custom cli

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
test
arraySliceType
Code generated by <git repo>.
Code generated by <git repo>.
arrayTarget
Code generated by <git repo>.
Code generated by <git repo>.
callbackType
random comment
random comment
composition
Code generated by <git repo>.
Code generated by <git repo>.
deep
Code generated by <git repo>.
Code generated by <git repo>.
empty
Code generated by <git repo>.
Code generated by <git repo>.
interfaceType
Code generated by <git repo>.
Code generated by <git repo>.
mapTarget
Code generated by <git repo>.
Code generated by <git repo>.
mapType
Code generated by <git repo>.
Code generated by <git repo>.
sliceTarget
Code generated by <git repo>.
Code generated by <git repo>.
split
Code generated by <git repo>.
Code generated by <git repo>.

Jump to

Keyboard shortcuts

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