func/vendor/github.com/evanphx/json-patch
knative-automation 6b8cccbbf9
upgrade to latest dependencies (#1269)
bumping github.com/prometheus/common 2af6d03...49b3603:
  > 49b3603 Improve OAuth2 user agent handling (# 391)
  > c5e1b60 config: ignore deprecated warning in tests (# 389)
  > b86ea81 OAuth2: Respect disable keepalives option; Implement close idle connections (# 390)
  > cdc09f0 Merge pull request # 387 from roidelapluie/useragent
  > d75e027 Merge pull request # 388 from simonpasquier/fix-tls-tests-for-go-1.18
  > db0284d Fix comment
  > 26d4974 Add more mimetypes (# 385)
  > aeda642 Update to Go 1.18
  > 2d0de85 Use full roundtripper
  > 627089d Set minimum version for go to 1.16 (# 372)
  > 5ab1c85 config: fix testdata for Go 1.18
  > 316097c Use WithUserAgent
  > 3763a1d TLS config: Enable selection of min TLS version (# 375)
  > 99a1aca add User-Agent header to oauth2 requests
  > 0c7319a Remove comment about PROMETHEUS_COMMON_DISABLE_HTTP2 env var because it is no longer true
  > 840c039 Use path.Clean to clean sigv4 path.
  > ffd0efb Deduplicate slashes for sigv4 signature
  > 902cb39 Merge pull request # 365 from prometheus/superq/bump_sigv4
  > 2c24277 Merge pull request # 362 from prometheus/repo_sync
  > 910a9df Update sigv4 modules
  > f6b0912 Merge pull request # 353 from prometheus/superq/bump_go
  > e457c0a Update common Prometheus files
  > 0e1254b Merge pull request # 359 from prometheus/repo_sync
  > 3c43b4d Update build/test
  > 252ff6f Make HTTP2 user visible
  > 809633a Update common Prometheus files
  > 00591a3 circleci: Test with go 1.17 (# 347)
  > 0762b59 Add proxy_url support for oauth2
  > f57586d circleci: add test-assets and style jobs
  > 1871a70 assets: add file system layer for zipped embed assets
  > ce7006e Update common Prometheus files (# 344)
  > 88ce30c Update common Prometheus files (# 340)
  > 88f1636 Remove github.com/pkg/errors dependency (# 338)
bumping contrib.go.opencensus.io/exporter/prometheus f3a7283...e6b6b80:
  > e6b6b80 Merge pull request # 30 from bogdandrutu/updatedeps
  > aaaf212 Merge pull request # 28 from wincus/update-prometheus
  > 75046ad Upgrade all deps to lastest
  > bf25aba update prometheus golang client
bumping golang.org/x/net 0bcc04d...f2f64eb:
  > f2f64eb http2: Send WindowUpdates when remaining bytes are below a threshold
  > ca03788 dns/dnsmessage: remove unnecessary []byte conversions
  > 0081b4b http2/h2c: propagate HTTP/1 server configuration to HTTP/2
  > f8f703f http2: accept HEAD requests with a body
  > bea034e all: remove redundant type conversion
  > 1e95f45 http/httpproxy: remove comment on https proxy precedance
  > f3363e0 http2: handle server errors after sending GOAWAY
  > 83b083e internal/socket: add missing import to zos-s390x file
  > b0a4917 dns/dnsmessage: use exported MustNewName in example
  > 3211cb9 nettest: fix Unix socket test on macOS
  > 4c34ddd http2: delete multipart form tempfiles after ServeHTTP returns
  > 1d4ff48 http2: add DialTLSContext to Transport
  > 13a9a73 http2: fix conn flow control when stream closes on bad content-length
  > 07c6da5 dns/dnsmessage: add AD and CD bits support
  > f428fae all: add FreeBSD riscv64 support
  > a33c5aa route: import syscall rather than golang.org/x/sys/unix
  > 7431dee lif: import syscall rather than golang.org/x/sys/unix

Signed-off-by: Knative Automation <automation@knative.team>

Signed-off-by: Knative Automation <automation@knative.team>
2022-10-12 05:44:51 +00:00
..
v5 chore(deps): update Knative dependencies to v1.4 @dsimansk (#1194) 2022-08-25 16:32:19 +00:00
.gitignore Update to latest Tekton release (#935) 2022-04-01 14:44:45 +00:00
LICENSE Vendor dependencies (#531) 2021-09-16 04:42:39 -07:00
README.md Update Knative dependencies to v1.0 (0.27) (#833) 2022-02-16 12:15:40 -08:00
errors.go Vendor dependencies (#531) 2021-09-16 04:42:39 -07:00
merge.go Update Knative dependencies to v1.0 (0.27) (#833) 2022-02-16 12:15:40 -08:00
patch.go upgrade to latest dependencies (#1269) 2022-10-12 05:44:51 +00:00

README.md

JSON-Patch

jsonpatch is a library which provides functionality for both applying RFC6902 JSON patches against documents, as well as for calculating & applying RFC7396 JSON merge patches.

GoDoc Build Status Report Card

Get It!

Latest and greatest:

go get -u github.com/evanphx/json-patch/v5

Stable Versions:

  • Version 5: go get -u gopkg.in/evanphx/json-patch.v5
  • Version 4: go get -u gopkg.in/evanphx/json-patch.v4

(previous versions below v3 are unavailable)

Use It!

Configuration

  • There is a global configuration variable jsonpatch.SupportNegativeIndices. This defaults to true and enables the non-standard practice of allowing negative indices to mean indices starting at the end of an array. This functionality can be disabled by setting jsonpatch.SupportNegativeIndices = false.

  • There is a global configuration variable jsonpatch.AccumulatedCopySizeLimit, which limits the total size increase in bytes caused by "copy" operations in a patch. It defaults to 0, which means there is no limit.

These global variables control the behavior of jsonpatch.Apply.

An alternative to jsonpatch.Apply is jsonpatch.ApplyWithOptions whose behavior is controlled by an options parameter of type *jsonpatch.ApplyOptions.

Structure jsonpatch.ApplyOptions includes the configuration options above and adds two new options: AllowMissingPathOnRemove and EnsurePathExistsOnAdd.

When AllowMissingPathOnRemove is set to true, jsonpatch.ApplyWithOptions will ignore remove operations whose path points to a non-existent location in the JSON document. AllowMissingPathOnRemove defaults to false which will lead to jsonpatch.ApplyWithOptions returning an error when hitting a missing path on remove.

When EnsurePathExistsOnAdd is set to true, jsonpatch.ApplyWithOptions will make sure that add operations produce all the path elements that are missing from the target object.

Use jsonpatch.NewApplyOptions to create an instance of jsonpatch.ApplyOptions whose values are populated from the global configuration variables.

Create and apply a merge patch

Given both an original JSON document and a modified JSON document, you can create a Merge Patch document.

It can describe the changes needed to convert from the original to the modified JSON document.

Once you have a merge patch, you can apply it to other JSON documents using the jsonpatch.MergePatch(document, patch) function.

package main

import (
	"fmt"

	jsonpatch "github.com/evanphx/json-patch"
)

func main() {
	// Let's create a merge patch from these two documents...
	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
	target := []byte(`{"name": "Jane", "age": 24}`)

	patch, err := jsonpatch.CreateMergePatch(original, target)
	if err != nil {
		panic(err)
	}

	// Now lets apply the patch against a different JSON document...

	alternative := []byte(`{"name": "Tina", "age": 28, "height": 3.75}`)
	modifiedAlternative, err := jsonpatch.MergePatch(alternative, patch)

	fmt.Printf("patch document:   %s\n", patch)
	fmt.Printf("updated alternative doc: %s\n", modifiedAlternative)
}

When ran, you get the following output:

$ go run main.go
patch document:   {"height":null,"name":"Jane"}
updated alternative doc: {"age":28,"name":"Jane"}

Create and apply a JSON Patch

You can create patch objects using DecodePatch([]byte), which can then be applied against JSON documents.

The following is an example of creating a patch from two operations, and applying it against a JSON document.

package main

import (
	"fmt"

	jsonpatch "github.com/evanphx/json-patch"
)

func main() {
	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
	patchJSON := []byte(`[
		{"op": "replace", "path": "/name", "value": "Jane"},
		{"op": "remove", "path": "/height"}
	]`)

	patch, err := jsonpatch.DecodePatch(patchJSON)
	if err != nil {
		panic(err)
	}

	modified, err := patch.Apply(original)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Original document: %s\n", original)
	fmt.Printf("Modified document: %s\n", modified)
}

When ran, you get the following output:

$ go run main.go
Original document: {"name": "John", "age": 24, "height": 3.21}
Modified document: {"age":24,"name":"Jane"}

Comparing JSON documents

Due to potential whitespace and ordering differences, one cannot simply compare JSON strings or byte-arrays directly.

As such, you can instead use jsonpatch.Equal(document1, document2) to determine if two JSON documents are structurally equal. This ignores whitespace differences, and key-value ordering.

package main

import (
	"fmt"

	jsonpatch "github.com/evanphx/json-patch"
)

func main() {
	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)
	similar := []byte(`
		{
			"age": 24,
			"height": 3.21,
			"name": "John"
		}
	`)
	different := []byte(`{"name": "Jane", "age": 20, "height": 3.37}`)

	if jsonpatch.Equal(original, similar) {
		fmt.Println(`"original" is structurally equal to "similar"`)
	}

	if !jsonpatch.Equal(original, different) {
		fmt.Println(`"original" is _not_ structurally equal to "different"`)
	}
}

When ran, you get the following output:

$ go run main.go
"original" is structurally equal to "similar"
"original" is _not_ structurally equal to "different"

Combine merge patches

Given two JSON merge patch documents, it is possible to combine them into a single merge patch which can describe both set of changes.

The resulting merge patch can be used such that applying it results in a document structurally similar as merging each merge patch to the document in succession.

package main

import (
	"fmt"

	jsonpatch "github.com/evanphx/json-patch"
)

func main() {
	original := []byte(`{"name": "John", "age": 24, "height": 3.21}`)

	nameAndHeight := []byte(`{"height":null,"name":"Jane"}`)
	ageAndEyes := []byte(`{"age":4.23,"eyes":"blue"}`)

	// Let's combine these merge patch documents...
	combinedPatch, err := jsonpatch.MergeMergePatches(nameAndHeight, ageAndEyes)
	if err != nil {
		panic(err)
	}

	// Apply each patch individual against the original document
	withoutCombinedPatch, err := jsonpatch.MergePatch(original, nameAndHeight)
	if err != nil {
		panic(err)
	}

	withoutCombinedPatch, err = jsonpatch.MergePatch(withoutCombinedPatch, ageAndEyes)
	if err != nil {
		panic(err)
	}

	// Apply the combined patch against the original document

	withCombinedPatch, err := jsonpatch.MergePatch(original, combinedPatch)
	if err != nil {
		panic(err)
	}

	// Do both result in the same thing? They should!
	if jsonpatch.Equal(withCombinedPatch, withoutCombinedPatch) {
		fmt.Println("Both JSON documents are structurally the same!")
	}

	fmt.Printf("combined merge patch: %s", combinedPatch)
}

When ran, you get the following output:

$ go run main.go
Both JSON documents are structurally the same!
combined merge patch: {"age":4.23,"eyes":"blue","height":null,"name":"Jane"}

CLI for comparing JSON documents

You can install the commandline program json-patch.

This program can take multiple JSON patch documents as arguments, and fed a JSON document from stdin. It will apply the patch(es) against the document and output the modified doc.

patch.1.json

[
    {"op": "replace", "path": "/name", "value": "Jane"},
    {"op": "remove", "path": "/height"}
]

patch.2.json

[
    {"op": "add", "path": "/address", "value": "123 Main St"},
    {"op": "replace", "path": "/age", "value": "21"}
]

document.json

{
    "name": "John",
    "age": 24,
    "height": 3.21
}

You can then run:

$ go install github.com/evanphx/json-patch/cmd/json-patch
$ cat document.json | json-patch -p patch.1.json -p patch.2.json
{"address":"123 Main St","age":"21","name":"Jane"}

Help It!

Contributions are welcomed! Leave an issue or create a PR.

Before creating a pull request, we'd ask that you make sure tests are passing and that you have added new tests when applicable.

Contributors can run tests using:

go test -cover ./...

Builds for pull requests are tested automatically using TravisCI.