• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

mergo-0.3.5/H08-Jun-2018-

.gitignoreH A D06-Oct-2020492

.travis.ymlH A D06-Oct-2020200

CODE_OF_CONDUCT.mdH A D06-Oct-20203.1 KiB

LICENSEH A D06-Oct-20201.5 KiB

README.mdH A D06-Oct-20208.1 KiB

doc.goH A D06-Oct-2020978

map.goH A D06-Oct-20205.2 KiB

merge.goH A D06-Oct-20206.6 KiB

mergo.goH A D06-Oct-20202.8 KiB

README.md

1# Mergo
2
3A helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.
4
5Also a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.
6
7## Status
8
9It is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc](https://github.com/imdario/mergo#mergo-in-the-wild).
10
11[![GoDoc][3]][4]
12[![GoCard][5]][6]
13[![Build Status][1]][2]
14[![Coverage Status][7]][8]
15[![Sourcegraph][9]][10]
16
17[1]: https://travis-ci.org/imdario/mergo.png
18[2]: https://travis-ci.org/imdario/mergo
19[3]: https://godoc.org/github.com/imdario/mergo?status.svg
20[4]: https://godoc.org/github.com/imdario/mergo
21[5]: https://goreportcard.com/badge/imdario/mergo
22[6]: https://goreportcard.com/report/github.com/imdario/mergo
23[7]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master
24[8]: https://coveralls.io/github/imdario/mergo?branch=master
25[9]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg
26[10]: https://sourcegraph.com/github.com/imdario/mergo?badge
27
28### Latest release
29
30[Release v0.3.4](https://github.com/imdario/mergo/releases/tag/v0.3.4).
31
32### Important note
33
34Please keep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2) Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). An optional/variadic argument has been added, so it won't break existing code.
35
36If you were using Mergo **before** April 6th 2015, please check your project works as intended after updating your local copy with ```go get -u github.com/imdario/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause (I hope it won't!) in existing projects after the change (release 0.2.0).
37
38### Donations
39
40If Mergo is useful to you, consider buying me a coffee, a beer or making a monthly donation so I can keep building great free software. :heart_eyes:
41
42<a href='https://ko-fi.com/B0B58839' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
43[![Beerpay](https://beerpay.io/imdario/mergo/badge.svg)](https://beerpay.io/imdario/mergo)
44[![Beerpay](https://beerpay.io/imdario/mergo/make-wish.svg)](https://beerpay.io/imdario/mergo)
45<a href="https://liberapay.com/dario/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
46
47### Mergo in the wild
48
49- [moby/moby](https://github.com/moby/moby)
50- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)
51- [vmware/dispatch](https://github.com/vmware/dispatch)
52- [Shopify/themekit](https://github.com/Shopify/themekit)
53- [imdario/zas](https://github.com/imdario/zas)
54- [matcornic/hermes](https://github.com/matcornic/hermes)
55- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)
56- [kataras/iris](https://github.com/kataras/iris)
57- [michaelsauter/crane](https://github.com/michaelsauter/crane)
58- [go-task/task](https://github.com/go-task/task)
59- [sensu/uchiwa](https://github.com/sensu/uchiwa)
60- [ory/hydra](https://github.com/ory/hydra)
61- [sisatech/vcli](https://github.com/sisatech/vcli)
62- [dairycart/dairycart](https://github.com/dairycart/dairycart)
63- [projectcalico/felix](https://github.com/projectcalico/felix)
64- [resin-os/balena](https://github.com/resin-os/balena)
65- [go-kivik/kivik](https://github.com/go-kivik/kivik)
66- [Telefonica/govice](https://github.com/Telefonica/govice)
67- [supergiant/supergiant](supergiant/supergiant)
68- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)
69- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)
70- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)
71- [EagerIO/Stout](https://github.com/EagerIO/Stout)
72- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)
73- [russross/canvasassignments](https://github.com/russross/canvasassignments)
74- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)
75- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)
76- [divshot/gitling](https://github.com/divshot/gitling)
77- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)
78- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)
79- [elwinar/rambler](https://github.com/elwinar/rambler)
80- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)
81- [jfbus/impressionist](https://github.com/jfbus/impressionist)
82- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)
83- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)
84- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)
85- [thoas/picfit](https://github.com/thoas/picfit)
86- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)
87- [jnuthong/item_search](https://github.com/jnuthong/item_search)
88- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)
89
90## Installation
91
92    go get github.com/imdario/mergo
93
94    // use in your .go code
95    import (
96        "github.com/imdario/mergo"
97    )
98
99## Usage
100
101You can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are not considered zero values](https://golang.org/ref/spec#The_zero_value) either. Also maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).
102
103```go
104if err := mergo.Merge(&dst, src); err != nil {
105    // ...
106}
107```
108
109Also, you can merge overwriting values using the transformer `WithOverride`.
110
111```go
112if err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {
113    // ...
114}
115```
116
117Additionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.
118
119```go
120if err := mergo.Map(&dst, srcMap); err != nil {
121    // ...
122}
123```
124
125Warning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.
126
127More information and examples in [godoc documentation](http://godoc.org/github.com/imdario/mergo).
128
129### Nice example
130
131```go
132package main
133
134import (
135	"fmt"
136	"github.com/imdario/mergo"
137)
138
139type Foo struct {
140	A string
141	B int64
142}
143
144func main() {
145	src := Foo{
146		A: "one",
147		B: 2,
148	}
149	dest := Foo{
150		A: "two",
151	}
152	mergo.Merge(&dest, src)
153	fmt.Println(dest)
154	// Will print
155	// {two 2}
156}
157```
158
159Note: if test are failing due missing package, please execute:
160
161    go get gopkg.in/yaml.v2
162
163### Transformers
164
165Transformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?
166
167```go
168package main
169
170import (
171	"fmt"
172	"github.com/imdario/mergo"
173        "reflect"
174        "time"
175)
176
177type timeTransfomer struct {
178}
179
180func (t timeTransfomer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
181	if typ == reflect.TypeOf(time.Time{}) {
182		return func(dst, src reflect.Value) error {
183			if dst.CanSet() {
184				isZero := dst.MethodByName("IsZero")
185				result := isZero.Call([]reflect.Value{})
186				if result[0].Bool() {
187					dst.Set(src)
188				}
189			}
190			return nil
191		}
192	}
193	return nil
194}
195
196type Snapshot struct {
197	Time time.Time
198	// ...
199}
200
201func main() {
202	src := Snapshot{time.Now()}
203	dest := Snapshot{}
204	mergo.Merge(&dest, src, mergo.WithTransformers(timeTransfomer{}))
205	fmt.Println(dest)
206	// Will print
207	// { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }
208}
209```
210
211
212## Contact me
213
214If I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)
215
216## About
217
218Written by [Dario Castañé](http://dario.im).
219
220## License
221
222[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).
223