Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / evanphx / json-patch / README.md
1 # JSON-Patch
2 `jsonpatch` is a library which provides functionallity for both applying
3 [RFC6902 JSON patches](http://tools.ietf.org/html/rfc6902) against documents, as
4 well as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396).
5
6 [![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch)
7 [![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch)
8 [![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch)
9
10 # Get It!
11
12 **Latest and greatest**: 
13 ```bash
14 go get -u github.com/evanphx/json-patch
15 ```
16
17 **Stable Versions**:
18 * Version 4: `go get -u gopkg.in/evanphx/json-patch.v4`
19
20 (previous versions below `v3` are unavailable)
21
22 # Use It!
23 * [Create and apply a merge patch](#create-and-apply-a-merge-patch)
24 * [Create and apply a JSON Patch](#create-and-apply-a-json-patch)
25 * [Comparing JSON documents](#comparing-json-documents)
26 * [Combine merge patches](#combine-merge-patches)
27
28
29 # Configuration
30
31 There is a single global configuration variable `jsonpatch.SupportNegativeIndices'. This
32 defaults to `true` and enables the non-standard practice of allowing negative indices
33 to mean indices starting at the end of an array. This functionality can be disabled
34 by setting `jsonpatch.SupportNegativeIndices = false`.
35
36 ## Create and apply a merge patch
37 Given both an original JSON document and a modified JSON document, you can create
38 a [Merge Patch](https://tools.ietf.org/html/rfc7396) document. 
39
40 It can describe the changes needed to convert from the original to the 
41 modified JSON document.
42
43 Once you have a merge patch, you can apply it to other JSON documents using the
44 `jsonpatch.MergePatch(document, patch)` function.
45
46 ```go
47 package main
48
49 import (
50         "fmt"
51
52         jsonpatch "github.com/evanphx/json-patch"
53 )
54
55 func main() {
56         // Let's create a merge patch from these two documents...
57         original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
58         target := []byte(`{"name": "Jane", "age": 24}`)
59
60         patch, err := jsonpatch.CreateMergePatch(original, target)
61         if err != nil {
62                 panic(err)
63         }
64
65         // Now lets apply the patch against a different JSON document...
66
67         alternative := []byte(`{"name": "Tina", "age": 28, "height": 3.75}`)
68         modifiedAlternative, err := jsonpatch.MergePatch(alternative, patch)
69
70         fmt.Printf("patch document:   %s\n", patch)
71         fmt.Printf("updated alternative doc: %s\n", modifiedAlternative)
72 }
73 ```
74
75 When ran, you get the following output:
76
77 ```bash
78 $ go run main.go
79 patch document:   {"height":null,"name":"Jane"}
80 updated tina doc: {"age":28,"name":"Jane"}
81 ```
82
83 ## Create and apply a JSON Patch
84 You can create patch objects using `DecodePatch([]byte)`, which can then 
85 be applied against JSON documents.
86
87 The following is an example of creating a patch from two operations, and
88 applying it against a JSON document.
89
90 ```go
91 package main
92
93 import (
94         "fmt"
95
96         jsonpatch "github.com/evanphx/json-patch"
97 )
98
99 func main() {
100         original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
101         patchJSON := []byte(`[
102                 {"op": "replace", "path": "/name", "value": "Jane"},
103                 {"op": "remove", "path": "/height"}
104         ]`)
105
106         patch, err := jsonpatch.DecodePatch(patchJSON)
107         if err != nil {
108                 panic(err)
109         }
110
111         modified, err := patch.Apply(original)
112         if err != nil {
113                 panic(err)
114         }
115
116         fmt.Printf("Original document: %s\n", original)
117         fmt.Printf("Modified document: %s\n", modified)
118 }
119 ```
120
121 When ran, you get the following output:
122
123 ```bash
124 $ go run main.go
125 Original document: {"name": "John", "age": 24, "height": 3.21}
126 Modified document: {"age":24,"name":"Jane"}
127 ```
128
129 ## Comparing JSON documents
130 Due to potential whitespace and ordering differences, one cannot simply compare
131 JSON strings or byte-arrays directly. 
132
133 As such, you can instead use `jsonpatch.Equal(document1, document2)` to 
134 determine if two JSON documents are _structurally_ equal. This ignores
135 whitespace differences, and key-value ordering.
136
137 ```go
138 package main
139
140 import (
141         "fmt"
142
143         jsonpatch "github.com/evanphx/json-patch"
144 )
145
146 func main() {
147         original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
148         similar := []byte(`
149                 {
150                         "age": 24,
151                         "height": 3.21,
152                         "name": "John"
153                 }
154         `)
155         different := []byte(`{"name": "Jane", "age": 20, "height": 3.37}`)
156
157         if jsonpatch.Equal(original, similar) {
158                 fmt.Println(`"original" is structurally equal to "similar"`)
159         }
160
161         if !jsonpatch.Equal(original, different) {
162                 fmt.Println(`"original" is _not_ structurally equal to "similar"`)
163         }
164 }
165 ```
166
167 When ran, you get the following output:
168 ```bash
169 $ go run main.go
170 "original" is structurally equal to "similar"
171 "original" is _not_ structurally equal to "similar"
172 ```
173
174 ## Combine merge patches
175 Given two JSON merge patch documents, it is possible to combine them into a 
176 single merge patch which can describe both set of changes.
177
178 The resulting merge patch can be used such that applying it results in a
179 document structurally similar as merging each merge patch to the document
180 in succession. 
181
182 ```go
183 package main
184
185 import (
186         "fmt"
187
188         jsonpatch "github.com/evanphx/json-patch"
189 )
190
191 func main() {
192         original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
193
194         nameAndHeight := []byte(`{"height":null,"name":"Jane"}`)
195         ageAndEyes := []byte(`{"age":4.23,"eyes":"blue"}`)
196
197         // Let's combine these merge patch documents...
198         combinedPatch, err := jsonpatch.MergeMergePatches(nameAndHeight, ageAndEyes)
199         if err != nil {
200                 panic(err)
201         }
202
203         // Apply each patch individual against the original document
204         withoutCombinedPatch, err := jsonpatch.MergePatch(original, nameAndHeight)
205         if err != nil {
206                 panic(err)
207         }
208
209         withoutCombinedPatch, err = jsonpatch.MergePatch(withoutCombinedPatch, ageAndEyes)
210         if err != nil {
211                 panic(err)
212         }
213
214         // Apply the combined patch against the original document
215
216         withCombinedPatch, err := jsonpatch.MergePatch(original, combinedPatch)
217         if err != nil {
218                 panic(err)
219         }
220
221         // Do both result in the same thing? They should!
222         if jsonpatch.Equal(withCombinedPatch, withoutCombinedPatch) {
223                 fmt.Println("Both JSON documents are structurally the same!")
224         }
225
226         fmt.Printf("combined merge patch: %s", combinedPatch)
227 }
228 ```
229
230 When ran, you get the following output:
231 ```bash
232 $ go run main.go
233 Both JSON documents are structurally the same!
234 combined merge patch: {"age":4.23,"eyes":"blue","height":null,"name":"Jane"}
235 ```
236
237 # CLI for comparing JSON documents
238 You can install the commandline program `json-patch`.
239
240 This program can take multiple JSON patch documents as arguments, 
241 and fed a JSON document from `stdin`. It will apply the patch(es) against 
242 the document and output the modified doc.
243
244 **patch.1.json**
245 ```json
246 [
247     {"op": "replace", "path": "/name", "value": "Jane"},
248     {"op": "remove", "path": "/height"}
249 ]
250 ```
251
252 **patch.2.json**
253 ```json
254 [
255     {"op": "add", "path": "/address", "value": "123 Main St"},
256     {"op": "replace", "path": "/age", "value": "21"}
257 ]
258 ```
259
260 **document.json**
261 ```json
262 {
263     "name": "John",
264     "age": 24,
265     "height": 3.21
266 }
267 ```
268
269 You can then run:
270
271 ```bash
272 $ go install github.com/evanphx/json-patch/cmd/json-patch
273 $ cat document.json | json-patch -p patch.1.json -p patch.2.json
274 {"address":"123 Main St","age":"21","name":"Jane"}
275 ```
276
277 # Help It!
278 Contributions are welcomed! Leave [an issue](https://github.com/evanphx/json-patch/issues)
279 or [create a PR](https://github.com/evanphx/json-patch/compare).
280
281
282 Before creating a pull request, we'd ask that you make sure tests are passing
283 and that you have added new tests when applicable.
284
285 Contributors can run tests using:
286
287 ```bash
288 go test -cover ./...
289 ```
290
291 Builds for pull requests are tested automatically 
292 using [TravisCI](https://travis-ci.org/evanphx/json-patch).