{"id":13412965,"url":"https://github.com/awalterschulze/goderive","last_synced_at":"2025-05-14T10:09:55.337Z","repository":{"id":17276680,"uuid":"81609715","full_name":"awalterschulze/goderive","owner":"awalterschulze","description":"Derives and generates mundane golang functions that you do not want to maintain yourself","archived":false,"fork":false,"pushed_at":"2025-03-06T07:55:42.000Z","size":1060,"stargazers_count":1257,"open_issues_count":18,"forks_count":45,"subscribers_count":19,"default_branch":"main","last_synced_at":"2025-04-11T04:16:05.878Z","etag":null,"topics":["deriving","functional-programming","generator","generics","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/awalterschulze.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":"Contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-10T21:46:49.000Z","updated_at":"2025-03-18T06:54:31.000Z","dependencies_parsed_at":"2024-11-20T07:06:35.318Z","dependency_job_id":"e4715e75-78a9-4f39-856f-de5afe1eebd0","html_url":"https://github.com/awalterschulze/goderive","commit_stats":{"total_commits":380,"total_committers":16,"mean_commits":23.75,"dds":"0.12368421052631584","last_synced_commit":"0a721d5b1d722ae6ba0dddefa1200607ca3ece97"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalterschulze%2Fgoderive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalterschulze%2Fgoderive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalterschulze%2Fgoderive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awalterschulze%2Fgoderive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awalterschulze","download_url":"https://codeload.github.com/awalterschulze/goderive/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254120170,"owners_count":22017953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deriving","functional-programming","generator","generics","golang"],"created_at":"2024-07-30T20:01:31.681Z","updated_at":"2025-05-14T10:09:55.280Z","avatar_url":"https://github.com/awalterschulze.png","language":"Go","funding_links":[],"categories":["Relational Databases","Go","Generation and Generics","发电机","\u003cspan id=\"代和泛型-generation-and-generics\"\u003e代和泛型 Generation and Generics\u003c/span\u003e","Generators","代码生成与泛型"],"sub_categories":["Advanced Console UIs","检索及分析资料库","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","Search and Analytic Databases","Utility/Miscellaneous","SQL 查询语句构建库"],"readme":"# goderive\n\n[![Build Status](https://github.com/awalterschulze/goderive/actions/workflows/go.yaml/badge.svg?branch=master)](https://github.com/awalterschulze/goderive/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/awalterschulze/goderive)](https://goreportcard.com/report/github.com/awalterschulze/goderive)\n[![GoDoc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square.svg)](https://godoc.org/github.com/awalterschulze/goderive)\n\n`goderive` derives mundane golang functions that you do not want to maintain and keeps them up to date.\n\n\u003ca href=\"http://www.youtube.com/watch?feature=player_embedded\u0026v=qFYByoGFIUE\" target=\"_blank\"\u003e\n \u003cimg src=\"https://img.youtube.com/vi/qFYByoGFIUE/maxres2.jpg\" alt=\"Watch the video\" width=\"480\" border=\"10\" /\u003e\n\u003c/a\u003e\n\nIt 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.\n\n## Examples\n\nIn 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`.\n\n```go\npackage main\n\ntype MyStruct struct {\n\tInt64     int64\n\tStringPtr *string\n}\n\nfunc (this *MyStruct) Equal(that *MyStruct) bool {\n\treturn deriveEqual(this, that)\n}\n```\n\ngoderive will then generate the following code in a `derived.gen.go` file in the same package:\n\n```go\nfunc deriveEqual(this, that *MyStruct) bool {\n\treturn (this == nil \u0026\u0026 that == nil) ||\n\t\tthis != nil \u0026\u0026 that != nil \u0026\u0026\n\t\t\tthis.Int64 == that.Int64 \u0026\u0026\n\t\t\t((this.StringPtr == nil \u0026\u0026 that.StringPtr == nil) ||\n        (this.StringPtr != nil \u0026\u0026 that.StringPtr != nil \u0026\u0026 *(this.StringPtr) == *(that.StringPtr)))\n}\n```\n\nRecursive Examples:\n\n  - [Equal](https://github.com/awalterschulze/goderive/tree/master/example/plugin/equal)\n  - [Compare](https://github.com/awalterschulze/goderive/tree/master/example/plugin/compare)\n  - [DeepCopy](https://github.com/awalterschulze/goderive/tree/master/example/plugin/deepcopy)\n  - [GoString](https://github.com/awalterschulze/goderive/tree/master/example/plugin/gostring)\n  - [Hash](https://github.com/awalterschulze/goderive/tree/master/example/plugin/hash)\n\nSet Examples:\n\n  - [Keys](https://github.com/awalterschulze/goderive/tree/master/example/plugin/keys)\n  - [Sort](https://github.com/awalterschulze/goderive/tree/master/example/plugin/sort)\n  - [Unique](https://github.com/awalterschulze/goderive/tree/master/example/plugin/unique)\n  - [Set](https://github.com/awalterschulze/goderive/tree/master/example/plugin/set)\n  - [Min](https://github.com/awalterschulze/goderive/tree/master/example/plugin/min)\n  - [Max](https://github.com/awalterschulze/goderive/tree/master/example/plugin/max)\n  - [Contains](https://github.com/awalterschulze/goderive/tree/master/example/plugin/contains)\n  - [Intersect](https://github.com/awalterschulze/goderive/tree/master/example/plugin/intersect)\n  - [Union](https://github.com/awalterschulze/goderive/tree/master/example/plugin/union)\n\nFunctional Examples:\n\n  - [Compose](https://github.com/awalterschulze/goderive/tree/master/example/plugin/compose)\n  - [Mem](https://github.com/awalterschulze/goderive/tree/master/example/plugin/mem)\n  - [Traverse](https://github.com/awalterschulze/goderive/tree/master/example/plugin/traverse)\n  - [ToError](https://github.com/awalterschulze/goderive/tree/master/example/plugin/toerror)\n\nConcurrency Examples:\n\n  - [Pipeline](https://github.com/awalterschulze/goderive/tree/master/example/plugin/pipeline)\n  - [Do](https://github.com/awalterschulze/goderive/tree/master/example/plugin/do)\n\n## Functions\n\nRecursive Functions:\n\n  - [Equal](http://godoc.org/github.com/awalterschulze/goderive/plugin/equal)\n    - `deriveEqual(T, T) bool`\n    - `deriveEqual(T) func(T) bool`\n  - [Compare](http://godoc.org/github.com/awalterschulze/goderive/plugin/compare)\n    - `deriveCompare(T, T) int`\n    - `deriveCompare(T) func(T) int`\n  - [DeepCopy](http://godoc.org/github.com/awalterschulze/goderive/plugin/deepcopy)\n    - `deriveDeepCopy(dst *T, src *T)`\n    - `deriveDeepCopy(dst []T, src []T)`\n    - `deriveDeepCopy(dst map[A]B, src map[A]B)`\n  - [Clone](http://godoc.org/github.com/awalterschulze/goderive/plugin/clone) `deriveClone(T) T`\n  - [GoString](http://godoc.org/github.com/awalterschulze/goderive/plugin/gostring) `deriveGoString(T) string`\n  - [Hash](http://godoc.org/github.com/awalterschulze/goderive/plugin/hash) `deriveHash(T) uint64`\n\nFunctional Functions:\n\n  - [Fmap](http://godoc.org/github.com/awalterschulze/goderive/plugin/fmap)\n    - `deriveFmap(func(A) B, []A) []B`\n    - `deriveFmap(func(rune) B, string) []B`\n    - `deriveFmap(func(A) B, func() (A, error)) (B, error)`\n    - `deriveFmap(func(A) (B, error), func() (A, error)) (func() (B, error), error)`\n    - `deriveFmap(func(A), func() (A, error)) error`\n    - `deriveFmap(func(A) (B, c, d, ...), func() (A, error)) (func() (B, c, d, ...), error)`\n  - [Join](http://godoc.org/github.com/awalterschulze/goderive/plugin/join)\n    - `deriveJoin([][]T) []T`\n    - `deriveJoin([]string) string`\n    - `deriveJoin(func() (T, error), error) func() (T, error)`\n    - `deriveJoin(func() (T, ..., error), error) func() (T, ..., error)`\n  - [Flip](http://godoc.org/github.com/awalterschulze/goderive/plugin/flip) `deriveFlip(f func(A, B, ...) T) func(B, A, ...) T`\n  - [Curry](http://godoc.org/github.com/awalterschulze/goderive/plugin/curry) `deriveCurry(f func(A, B, ...) T) func(A) func(B, ...) T`\n  - [Uncurry](http://godoc.org/github.com/awalterschulze/goderive/plugin/uncurry) `deriveUncurry(f func(A) func(B, ...) T) func(A, B, ...) T`\n  - [Tuple](http://godoc.org/github.com/awalterschulze/goderive/plugin/tuple) `deriveTuple(A, B, ...) func() (A, B, ...)`\n  - [Compose](http://godoc.org/github.com/awalterschulze/goderive/plugin/compose)\n    - `deriveCompose(func() (A, error), func(A) (B, error)) func() (B, error)`\n    - `deriveCompose(func(A) (B, error), func(B) (C, error)) func(A) (C, error)`\n    - `deriveCompose(func(A...) (B..., error), func(B...) (C..., error)) func(A...) (C..., error)`\n    - `deriveCompose(func(A...) (B..., error), ..., func(C...) (D..., error)) func(A...) (D..., error)`\n  - [Mem](http://godoc.org/github.com/awalterschulze/goderive/plugin/mem)\n    - `deriveMem(func(A...) (B...)) func(A...) (B...)`\n  - [Traverse](http://godoc.org/github.com/awalterschulze/goderive/plugin/traverse)\n    - `deriveTraverse(func(A) (B, error), []A) ([]B, error)`\n  - [ToError](http://godoc.org/github.com/awalterschulze/goderive/plugin/toerror)\n    - `deriveToError(error, func(A...) (B..., bool)) func(A...) (B..., error)`\n    - `deriveToError(error, func() bool) func() error`\n  - [Apply](http://godoc.org/github.com/awalterschulze/goderive/plugin/apply) `deriveApply(f func(...A, B) C, B) func(...A) C`\n\nConcurrency Functions:\n  - [Fmap](http://godoc.org/github.com/awalterschulze/goderive/plugin/fmap)\n    - `deriveFmap(func(A) B, \u003c-chan A) \u003c-chan B`\n  - [Join](http://godoc.org/github.com/awalterschulze/goderive/plugin/join)\n    - `deriveJoin(\u003c-chan \u003c-chan T) \u003c-chan T`\n    - `deriveJoin(chan \u003c-chan T) \u003c-chan T`\n    - `deriveJoin([]\u003c-chan T) \u003c-chan T`\n    - `deriveJoin([]chan T) \u003c-chan T`\n    - `deriveJoin(chan T, chan T, ...) \u003c-chan T`\n  - [Pipeline](http://godoc.org/github.com/awalterschulze/goderive/plugin/pipeline)\n    - `derivePipeline(func(A) \u003c-chan B, func(B) \u003c-chan C) func(A) \u003c-chan C`\n  - [Do](http://godoc.org/github.com/awalterschulze/goderive/plugin/do)\n    - `deriveDo(func() (A, error), func (B, error)) (A, B, error)`\n  - [Dup](http://godoc.org/github.com/awalterschulze/goderive/plugin/dup)\n    - `deriveDup(c \u003c-chan T) (c1, c2 \u003c-chan T)`\n\nDeprecated in favour of generics:\n\n  - [Keys](http://godoc.org/github.com/awalterschulze/goderive/plugin/keys) `deriveKeys(map[K]V) []K`\n  - [Sort](http://godoc.org/github.com/awalterschulze/goderive/plugin/sort) `deriveSort([]T) []T`\n  - [Unique](http://godoc.org/github.com/awalterschulze/goderive/plugin/unique) `deriveUnique([]T) []T`\n  - [Set](http://godoc.org/github.com/awalterschulze/goderive/plugin/set) `deriveSet([]T) map[T]struct{}`\n  - [Min](http://godoc.org/github.com/awalterschulze/goderive/plugin/min)\n    - `deriveMin(list []T, default T) (min T)`\n    - `deriveMin(T, T) T`\n  - [Max](http://godoc.org/github.com/awalterschulze/goderive/plugin/max)\n    - `deriveMax(list []T, default T) (max T)`\n    - `deriveMax(T, T) T`\n  - [Contains](http://godoc.org/github.com/awalterschulze/goderive/plugin/contains) `deriveContains([]T, T) bool`\n  - [Intersect](http://godoc.org/github.com/awalterschulze/goderive/plugin/intersect)\n    - `deriveIntersect(a, b []T) []T`\n    - `deriveIntersect(a, b map[T]struct{}) map[T]struct{}`\n  - [Union](http://godoc.org/github.com/awalterschulze/goderive/plugin/union)\n    - `deriveUnion(a, b []T) []T`\n    - `deriveUnion(a, b map[T]struct{}) map[T]struct{}`\n  - [Filter](http://godoc.org/github.com/awalterschulze/goderive/plugin/filter) `deriveFilter(pred func(T) bool, []T) []T`\n  - [All](http://godoc.org/github.com/awalterschulze/goderive/plugin/all) `deriveAll(pred func(T) bool, []T) bool`\n  - [Any](http://godoc.org/github.com/awalterschulze/goderive/plugin/any) `deriveAny(pred func(T) bool, []T) bool`\n  - [TakeWhile](http://godoc.org/github.com/awalterschulze/goderive/plugin/takewhile) `deriveTakeWhile(pred func(T) bool, []T) []T`\n\nWhen goderive walks over your code it is looking for a function that:\n  - was not implemented (or was previously derived) and\n  - has a predefined prefix.\n\nFunctions 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.\n\nFor 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.\n\nFunction prefixes are by default `deriveCamelCaseFunctionName`, for example `deriveEqual`.\nThese are customizable using command line flags.\n\nYou 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.\n\nLet `goderive` edit your function names in your source code, by enabling `autoname` and `dedup` using the command line flags.\nThese flags respectively make sure that your functions have unique names and that you don't generate multiple functions that do the same thing.\n\n## How to run\n\ninstall the latest version of goderive globally using:\n\n`go install github.com/awalterschulze/goderive@latest`\n\ngoderive can be run from the command line:\n\n`goderive ./...`\n\n, using the same path semantics as the go tool.\n\n[You can also run goderive using go generate](https://github.com/awalterschulze/goderive/blob/master/example/gogenerate/example.go)\n\n[And you can customize specific function prefixes](https://github.com/awalterschulze/goderive/blob/master/example/pluginprefix/Makefile)\n\n[Or you can customize all function prefixes](https://github.com/awalterschulze/goderive/blob/master/example/prefix/Makefile)\n\nYou can let goderive rename your functions using the `-autoname` and `-dedup` flags.\nIf these flags are not used, goderive will not touch your code and rather return an error.\n\n## Customization\n\nThe derive package allows you to create your own code generator plugins, see all the current plugins for examples.\n\nYou can also create your own vanity binary.\nIncluding your own generators and/or customization of function prefixes, etc.\nThis should be easy to figure out by looking at [main.go](https://github.com/awalterschulze/goderive/blob/master/main.go)\n\n## Inspired By\n\n  - Haskell's deriving\n  - Robert Griesemer's talk [Prototype your design!](https://www.youtube.com/watch?v=vLxX3yZmw5Q)\n  - [go/types](https://golang.org/pkg/go/types/) standard library\n\n## Users\n\nThese projects use goderive:\n\n  - [DC/OS](https://github.com/dcos/dcos-cli/blob/af0434c0ca80cee7152a1880770dc878501b9ac5/pkg/httpclient/derived.gen.go)\n  - [katydid](https://github.com/katydid/katydid/blob/master/relapse/ast/derived.gen.go)\n  - [go-geom](https://github.com/twpayne/go-geom/blob/master/derived.gen.go)\n  - [gominikanren](https://github.com/awalterschulze/gominikanren/blob/master/micro/derived.gen.go)\n\nPlease let us know if you are using goderive by opening an issue or a pull request that adds your project to the list.\n\n## Mentioned\n\n  - [Monads for Go Programmers](https://medium.com/@awalterschulze/monads-for-go-programmers-6cda2b978cb1)\n  - [Golang Weekly](https://golangweekly.com/issues/174)\n  - [Reddit](https://www.reddit.com/r/programmingcirclejerk/comments/6vkkdw/this_is_what_goprogrammers_have_to_do_because/)\n  - [Generating `Equal` methods for Go structs with `goderive`](https://www.jvt.me/posts/2023/03/27/go-generate-equal-goderive/)\n\nPlease 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.\n\n## Presentations\n\n  - 2021-12: [goderive: Code generation with Gonads](https://www.youtube.com/watch?v=qFYByoGFIUE) - Go Cape Town meetup ([code examples](https://github.com/awalterschulze/goderive/blob/master/example/talk))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawalterschulze%2Fgoderive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawalterschulze%2Fgoderive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawalterschulze%2Fgoderive/lists"}