goderive

command module
v0.0.0-...-e3f2fdf Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2024 License: Apache-2.0 Imports: 37 Imported by: 1

README

goderive

Build Status Go Report Card GoDoc

goderive derives mundane golang functions that you do not want to maintain and keeps them up to date.

Watch the video

It does this by parsing your go code for functions, which are not implemented, and then generates these functions for you by deriving their implementations from the input parameter types.

Examples

In the following code the deriveEqual function will be spotted as a function that was not implemented (or was previously derived) and has a prefix deriveEqual.

package main

type MyStruct struct {
	Int64     int64
	StringPtr *string
}

func (this *MyStruct) Equal(that *MyStruct) bool {
	return deriveEqual(this, that)
}

goderive will then generate the following code in a derived.gen.go file in the same package:

func deriveEqual(this, that *MyStruct) bool {
	return (this == nil && that == nil) ||
		this != nil && that != nil &&
			this.Int64 == that.Int64 &&
			((this.StringPtr == nil && that.StringPtr == nil) ||
        (this.StringPtr != nil && that.StringPtr != nil && *(this.StringPtr) == *(that.StringPtr)))
}

Recursive Examples:

Set Examples:

Functional Examples:

Concurrency Examples:

Functions

Recursive Functions:

  • Equal
    • deriveEqual(T, T) bool
    • deriveEqual(T) func(T) bool
  • Compare
    • deriveCompare(T, T) int
    • deriveCompare(T) func(T) int
  • DeepCopy
    • deriveDeepCopy(dst *T, src *T)
    • deriveDeepCopy(dst []T, src []T)
    • deriveDeepCopy(dst map[A]B, src map[A]B)
  • Clone deriveClone(T) T
  • GoString deriveGoString(T) string
  • Hash deriveHash(T) uint64

Set Functions:

  • Keys deriveKeys(map[K]V) []K
  • Sort deriveSort([]T) []T
  • Unique deriveUnique([]T) []T
  • Set deriveSet([]T) map[T]struct{}
  • Min
    • deriveMin(list []T, default T) (min T)
    • deriveMin(T, T) T
  • Max
    • deriveMax(list []T, default T) (max T)
    • deriveMax(T, T) T
  • Contains deriveContains([]T, T) bool
  • Intersect
    • deriveIntersect(a, b []T) []T
    • deriveIntersect(a, b map[T]struct{}) map[T]struct{}
  • Union
    • deriveUnion(a, b []T) []T
    • deriveUnion(a, b map[T]struct{}) map[T]struct{}

Functional Functions:

  • Fmap
    • deriveFmap(func(A) B, []A) []B
    • deriveFmap(func(rune) B, string) []B
    • deriveFmap(func(A) B, func() (A, error)) (B, error)
    • deriveFmap(func(A) (B, error), func() (A, error)) (func() (B, error), error)
    • deriveFmap(func(A), func() (A, error)) error
    • deriveFmap(func(A) (B, c, d, ...), func() (A, error)) (func() (B, c, d, ...), error)
  • Join
    • deriveJoin([][]T) []T
    • deriveJoin([]string) string
    • deriveJoin(func() (T, error), error) func() (T, error)
    • deriveJoin(func() (T, ..., error), error) func() (T, ..., error)
  • Filter deriveFilter(pred func(T) bool, []T) []T
  • All deriveAll(pred func(T) bool, []T) bool
  • Any deriveAny(pred func(T) bool, []T) bool
  • TakeWhile deriveTakeWhile(pred func(T) bool, []T) []T
  • Flip deriveFlip(f func(A, B, ...) T) func(B, A, ...) T
  • Curry deriveCurry(f func(A, B, ...) T) func(A) func(B, ...) T
  • Uncurry deriveUncurry(f func(A) func(B, ...) T) func(A, B, ...) T
  • Tuple deriveTuple(A, B, ...) func() (A, B, ...)
  • Compose
    • deriveCompose(func() (A, error), func(A) (B, error)) func() (B, error)
    • deriveCompose(func(A) (B, error), func(B) (C, error)) func(A) (C, error)
    • deriveCompose(func(A...) (B..., error), func(B...) (C..., error)) func(A...) (C..., error)
    • deriveCompose(func(A...) (B..., error), ..., func(C...) (D..., error)) func(A...) (D..., error)
  • Mem
    • deriveMem(func(A...) (B...)) func(A...) (B...)
  • Traverse
    • deriveTraverse(func(A) (B, error), []A) ([]B, error)
  • ToError
    • deriveToError(error, func(A...) (B..., bool)) func(A...) (B..., error)
    • deriveToError(error, func() bool) func() error
  • Apply deriveApply(f func(...A, B) C, B) func(...A) C

Concurrency Functions:

  • Fmap
    • deriveFmap(func(A) B, <-chan A) <-chan B
  • Join
    • deriveJoin(<-chan <-chan T) <-chan T
    • deriveJoin(chan <-chan T) <-chan T
    • deriveJoin([]<-chan T) <-chan T
    • deriveJoin([]chan T) <-chan T
    • deriveJoin(chan T, chan T, ...) <-chan T
  • Pipeline
    • derivePipeline(func(A) <-chan B, func(B) <-chan C) func(A) <-chan C
  • Do
    • deriveDo(func() (A, error), func (B, error)) (A, B, error)
  • Dup
    • deriveDup(c <-chan T) (c1, c2 <-chan T)

When goderive walks over your code it is looking for a function that:

  • was not implemented (or was previously derived) and
  • has a predefined prefix.

Functions which have been previously derived will be regenerated to keep them up to date with the latest modifications to your types. This keeps these functions, which are truly mundane to write, maintainable.

For example when someone in your team adds a new field to a struct and forgets to update the CopyTo method. This problem is solved by goderive, by generating generated functions given the new types.

Function prefixes are by default deriveCamelCaseFunctionName, for example deriveEqual. These are customizable using command line flags.

You can derive functions for different types by using different suffixes with the same prefix. For example, if you wish to derive Equal for types MyStruct and MySecondStruct, name the functions deriveEqualMyStruct and deriveEqualMySecondStruct and goderive will derive both.

Let goderive edit your function names in your source code, by enabling autoname and dedup using the command line flags. These flags respectively make sure that your functions have unique names and that you don't generate multiple functions that do the same thing.

How to run

install the latest version of goderive globally using:

go install github.com/awalterschulze/goderive@latest

goderive can be run from the command line:

goderive ./...

, using the same path semantics as the go tool.

You can also run goderive using go generate

And you can customize specific function prefixes

Or you can customize all function prefixes

You can let goderive rename your functions using the -autoname and -dedup flags. If these flags are not used, goderive will not touch your code and rather return an error.

Customization

The derive package allows you to create your own code generator plugins, see all the current plugins for examples.

You can also create your own vanity binary. Including your own generators and/or customization of function prefixes, etc. This should be easy to figure out by looking at main.go

Inspired By

Users

These projects use goderive:

Please let us know if you are using goderive by opening an issue or a pull request that adds your project to the list.

Mentioned

Please let us know if you mention goderive in a blog post, talk or go experience report, so that we can add a link to our list.

Presentations

Documentation

Overview

Package main implements the goderive binary. This pulls in all the plugins, parses the flags and runs the generators using the derive library.

Directories

Path Synopsis
Package derive is the code generator library used by all plugins.
Package derive is the code generator library used by all plugins.
example
gogenerate
Example: gogenerate shows us how to call goderive using gogenerate instead of using a Makefile.
Example: gogenerate shows us how to call goderive using gogenerate instead of using a Makefile.
plugin/cmd/goderive-genreadme
goderive-genreadme replaces two blocks of go code in a Readme.md with the contents of a normal go file and the contents of a generated derived.gen.go file respectively.
goderive-genreadme replaces two blocks of go code in a Readme.md with the contents of a normal go file and the contents of a generated derived.gen.go file respectively.
pluginprefix
Example: pluginprefix shows how to defined a derived function that does not have to start with default "deriveEqual" prefix.
Example: pluginprefix shows how to defined a derived function that does not have to start with default "deriveEqual" prefix.
prefix
Example: prefix shows how to defined a derived function that does not have to start with default "deriveEqual" prefix.
Example: prefix shows how to defined a derived function that does not have to start with default "deriveEqual" prefix.
plugin
all
Package all contains the implementation of the all plugin, which generates the deriveAll function.
Package all contains the implementation of the all plugin, which generates the deriveAll function.
any
Package any contains the implementation of the any plugin, which generates the deriveAny function.
Package any contains the implementation of the any plugin, which generates the deriveAny function.
apply
Package apply contains the implementation of the apply plugin, which generates the deriveApply function.
Package apply contains the implementation of the apply plugin, which generates the deriveApply function.
clone
Package clone contains the implementation of the clone plugin, which generates the deriveClone function.
Package clone contains the implementation of the clone plugin, which generates the deriveClone function.
compare
Package compare contains the implementation of the compare plugin, which generates the deriveCompare function.
Package compare contains the implementation of the compare plugin, which generates the deriveCompare function.
compose
Package compose contains the implementation of the compose plugin, which generates the deriveCompose function.
Package compose contains the implementation of the compose plugin, which generates the deriveCompose function.
contains
Package contains contains the implementation of the contains plugin, which generates the deriveContains function.
Package contains contains the implementation of the contains plugin, which generates the deriveContains function.
curry
Package curry contains the implementation of the curry plugin, which generates the deriveCurry function.
Package curry contains the implementation of the curry plugin, which generates the deriveCurry function.
deepcopy
Package deepcopy contains the implementation of the deepcopy plugin, which generates the deriveDeepCopy function.
Package deepcopy contains the implementation of the deepcopy plugin, which generates the deriveDeepCopy function.
do
Package do contains the implementation of the do plugin, which generates the deriveDo function.
Package do contains the implementation of the do plugin, which generates the deriveDo function.
dup
Package dup contains the implementation of the dup plugin, which generates the deriveDup function.
Package dup contains the implementation of the dup plugin, which generates the deriveDup function.
equal
Package equal contains the implementation of the equal plugin, which generates the deriveEqual function.
Package equal contains the implementation of the equal plugin, which generates the deriveEqual function.
filter
Package filter contains the implementation of the filter plugin, which generates the deriveFilter function.
Package filter contains the implementation of the filter plugin, which generates the deriveFilter function.
flip
Package flip contains the implementation of the flip plugin, which generates the deriveFlip function.
Package flip contains the implementation of the flip plugin, which generates the deriveFlip function.
fmap
Package fmap contains the implementation of the fmap plugin, which generates the deriveFmap function.
Package fmap contains the implementation of the fmap plugin, which generates the deriveFmap function.
gostring
Package gostring contains the implementation of the gostring plugin, which generates the deriveGoString function.
Package gostring contains the implementation of the gostring plugin, which generates the deriveGoString function.
hash
Package hash contains the implementation of the hash plugin, which generates the deriveHash function.
Package hash contains the implementation of the hash plugin, which generates the deriveHash function.
intersect
Package intersect contains the implementation of the intersect plugin, which generates the deriveIntersect function.
Package intersect contains the implementation of the intersect plugin, which generates the deriveIntersect function.
join
Package join contains the implementation of the join plugin, which generates the deriveJoin function.
Package join contains the implementation of the join plugin, which generates the deriveJoin function.
keys
Package keys contains the implementation of the keys plugin, which generates the deriveKeys function.
Package keys contains the implementation of the keys plugin, which generates the deriveKeys function.
max
Package max contains the implementation of the max plugin, which generates the deriveMax function.
Package max contains the implementation of the max plugin, which generates the deriveMax function.
mem
Package mem contains the implementation of the mem plugin, which generates the deriveMem function.
Package mem contains the implementation of the mem plugin, which generates the deriveMem function.
min
Package min contains the implementation of the min plugin, which generates the deriveMin function.
Package min contains the implementation of the min plugin, which generates the deriveMin function.
pipeline
Package pipeline contains the implementation of the pipeline plugin, which generates the derivePipeline function.
Package pipeline contains the implementation of the pipeline plugin, which generates the derivePipeline function.
set
Package set contains the implementation of the set plugin, which generates the deriveSet function.
Package set contains the implementation of the set plugin, which generates the deriveSet function.
sort
Package sort contains the implementation of the sort plugin, which generates the deriveSort function.
Package sort contains the implementation of the sort plugin, which generates the deriveSort function.
takewhile
Package takewhile contains the implementation of the takewhile plugin, which generates the deriveTakeWhile function.
Package takewhile contains the implementation of the takewhile plugin, which generates the deriveTakeWhile function.
toerror
Package toerror contains the implementation of the toerror plugin, which generates the deriveToError function.
Package toerror contains the implementation of the toerror plugin, which generates the deriveToError function.
traverse
Package traverse contains the implementation of the traverse plugin, which generates the deriveTraverse function.
Package traverse contains the implementation of the traverse plugin, which generates the deriveTraverse function.
tuple
Package tuple contains the implementation of the tuple plugin, which generates the deriveTuple function.
Package tuple contains the implementation of the tuple plugin, which generates the deriveTuple function.
uncurry
Package uncurry contains the implementation of the uncurry plugin, which generates the deriveUncurry function.
Package uncurry contains the implementation of the uncurry plugin, which generates the deriveUncurry function.
union
Package union contains the implementation of the union plugin, which generates the deriveUnion function.
Package union contains the implementation of the union plugin, which generates the deriveUnion function.
unique
Package unique contains the implementation of the unique plugin, which generates the deriveUnique function.
Package unique contains the implementation of the unique plugin, which generates the deriveUnique function.
test

Jump to

Keyboard shortcuts

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