From 0aec53ae390d524a4e3a2765b99b29cceb582edc Mon Sep 17 00:00:00 2001 From: Jimmi Dyson Date: Tue, 7 Jun 2016 16:39:53 +0100 Subject: [PATCH] godep bump: github.com/evanphx/json-patch --- Godeps/Godeps.json | 2 +- .../github.com/evanphx/json-patch/README.md | 6 +- vendor/github.com/evanphx/json-patch/merge.go | 40 +++++-- vendor/github.com/evanphx/json-patch/patch.go | 111 +++++++++++++++--- 4 files changed, 134 insertions(+), 25 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9a9194490e..1b157affac 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -754,7 +754,7 @@ }, { "ImportPath": "github.com/evanphx/json-patch", - "Rev": "7dd4489c2eb6073e5a9d7746c3274c5b5f0387df" + "Rev": "465937c80b3c07a7c7ad20cc934898646a91c1de" }, { "ImportPath": "github.com/garyburd/redigo/internal", diff --git a/vendor/github.com/evanphx/json-patch/README.md b/vendor/github.com/evanphx/json-patch/README.md index 01bc590428..d0d826bacd 100644 --- a/vendor/github.com/evanphx/json-patch/README.md +++ b/vendor/github.com/evanphx/json-patch/README.md @@ -1,13 +1,13 @@ ## JSON-Patch -Provides the abiilty to modify and test a JSON according to a -[RFC6902 JSON patch](http://tools.ietf.org/html/rfc6902) and [RFC7386 JSON Merge Patch](https://tools.ietf.org/html/rfc7386). +Provides the ability to modify and test a JSON according to a +[RFC6902 JSON patch](http://tools.ietf.org/html/rfc6902) and [RFC7396 JSON Merge Patch](https://tools.ietf.org/html/rfc7396). *Version*: **1.0** [![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch) -[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=RFC7386)](https://travis-ci.org/evanphx/json-patch) +[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch) ### API Usage diff --git a/vendor/github.com/evanphx/json-patch/merge.go b/vendor/github.com/evanphx/json-patch/merge.go index ace10fd54e..330b9b528e 100644 --- a/vendor/github.com/evanphx/json-patch/merge.go +++ b/vendor/github.com/evanphx/json-patch/merge.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "reflect" + "strings" ) func merge(cur, patch *lazyNode) *lazyNode { @@ -27,6 +28,7 @@ func merge(cur, patch *lazyNode) *lazyNode { func mergeDocs(doc, patch *partialDoc) { for k, v := range *patch { + k := decodePatchKey(k) if v == nil { delete(*doc, k) } else { @@ -69,7 +71,7 @@ func pruneDocNulls(doc *partialDoc) *partialDoc { } func pruneAryNulls(ary *partialArray) *partialArray { - var newAry []*lazyNode + newAry := []*lazyNode{} for _, v := range *ary { if v != nil { @@ -218,6 +220,9 @@ func matchesValue(av, bv interface{}) bool { } } return true + case []interface{}: + bt := bv.([]interface{}) + return matchesArray(at, bt) } return false } @@ -226,15 +231,16 @@ func matchesValue(av, bv interface{}) bool { func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { into := map[string]interface{}{} for key, bv := range b { + escapedKey := encodePatchKey(key) av, ok := a[key] // value was added if !ok { - into[key] = bv + into[escapedKey] = bv continue } // If types have changed, replace completely if reflect.TypeOf(av) != reflect.TypeOf(bv) { - into[key] = bv + into[escapedKey] = bv continue } // Types are the same, compare values @@ -247,23 +253,23 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { return nil, err } if len(dst) > 0 { - into[key] = dst + into[escapedKey] = dst } case string, float64, bool: if !matchesValue(av, bv) { - into[key] = bv + into[escapedKey] = bv } case []interface{}: bt := bv.([]interface{}) if !matchesArray(at, bt) { - into[key] = bv + into[escapedKey] = bv } case nil: switch bv.(type) { case nil: // Both nil, fine. default: - into[key] = bv + into[escapedKey] = bv } default: panic(fmt.Sprintf("Unknown type:%T in key %s", av, key)) @@ -278,3 +284,23 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) { } return into, nil } + +// From http://tools.ietf.org/html/rfc6901#section-4 : +// +// Evaluation of each reference token begins by decoding any escaped +// character sequence. This is performed by first transforming any +// occurrence of the sequence '~1' to '/', and then transforming any +// occurrence of the sequence '~0' to '~'. + +var ( + rfc6901Encoder = strings.NewReplacer("~", "~0", "/", "~1") + rfc6901Decoder = strings.NewReplacer("~1", "/", "~0", "~") +) + +func decodePatchKey(k string) string { + return rfc6901Decoder.Replace(k) +} + +func encodePatchKey(k string) string { + return rfc6901Encoder.Replace(k) +} diff --git a/vendor/github.com/evanphx/json-patch/patch.go b/vendor/github.com/evanphx/json-patch/patch.go index 073e1b4314..8988da54bb 100644 --- a/vendor/github.com/evanphx/json-patch/patch.go +++ b/vendor/github.com/evanphx/json-patch/patch.go @@ -32,6 +32,7 @@ type partialArray []*lazyNode type container interface { get(key string) (*lazyNode, error) set(key string, val *lazyNode) error + add(key string, val *lazyNode) error remove(key string) error } @@ -42,7 +43,7 @@ func newLazyNode(raw *json.RawMessage) *lazyNode { func (n *lazyNode) MarshalJSON() ([]byte, error) { switch n.which { case eRaw: - return *n.raw, nil + return json.Marshal(n.raw) case eDoc: return json.Marshal(n.doc) case eAry: @@ -269,7 +270,7 @@ func findObject(pd *partialDoc, path string) (container, string) { for _, part := range parts { - next, ok := doc.get(part) + next, ok := doc.get(decodePatchKey(part)) if next == nil || ok != nil { return nil, "" @@ -290,7 +291,7 @@ func findObject(pd *partialDoc, path string) (container, string) { } } - return doc, key + return doc, decodePatchKey(key) } func (d *partialDoc) set(key string, val *lazyNode) error { @@ -298,11 +299,21 @@ func (d *partialDoc) set(key string, val *lazyNode) error { return nil } +func (d *partialDoc) add(key string, val *lazyNode) error { + (*d)[key] = val + return nil +} + func (d *partialDoc) get(key string) (*lazyNode, error) { return (*d)[key], nil } func (d *partialDoc) remove(key string) error { + _, ok := (*d)[key] + if !ok { + return fmt.Errorf("Unable to remove nonexistant key: %s", key) + } + delete(*d, key) return nil } @@ -314,7 +325,38 @@ func (d *partialArray) set(key string, val *lazyNode) error { } idx, err := strconv.Atoi(key) + if err != nil { + return err + } + sz := len(*d) + if idx+1 > sz { + sz = idx + 1 + } + + ary := make([]*lazyNode, sz) + + cur := *d + + copy(ary, cur) + + if idx >= len(ary) { + fmt.Printf("huh?: %#v[%d] %s, %s\n", ary, idx) + } + + ary[idx] = val + + *d = ary + return nil +} + +func (d *partialArray) add(key string, val *lazyNode) error { + if key == "-" { + *d = append(*d, val) + return nil + } + + idx, err := strconv.Atoi(key) if err != nil { return err } @@ -338,18 +380,25 @@ func (d *partialArray) get(key string) (*lazyNode, error) { return nil, err } + if idx >= len(*d) { + return nil, fmt.Errorf("Unable to access invalid index: %d", idx) + } + return (*d)[idx], nil } func (d *partialArray) remove(key string) error { idx, err := strconv.Atoi(key) - if err != nil { return err } cur := *d + if idx >= len(cur) { + return fmt.Errorf("Unable to remove invalid index: %d", idx) + } + ary := make([]*lazyNode, len(cur)-1) copy(ary[0:idx], cur[0:idx]) @@ -366,12 +415,10 @@ func (p Patch) add(doc *partialDoc, op operation) error { con, key := findObject(doc, path) if con == nil { - return fmt.Errorf("Missing container: %s", path) + return fmt.Errorf("jsonpatch add operation does not apply: doc is missing path: %s", path) } - con.set(key, op.value()) - - return nil + return con.add(key, op.value()) } func (p Patch) remove(doc *partialDoc, op operation) error { @@ -379,6 +426,10 @@ func (p Patch) remove(doc *partialDoc, op operation) error { con, key := findObject(doc, path) + if con == nil { + return fmt.Errorf("jsonpatch remove operation does not apply: doc is missing path: %s", path) + } + return con.remove(key) } @@ -387,9 +438,11 @@ func (p Patch) replace(doc *partialDoc, op operation) error { con, key := findObject(doc, path) - con.set(key, op.value()) + if con == nil { + return fmt.Errorf("jsonpatch replace operation does not apply: doc is missing path: %s", path) + } - return nil + return con.set(key, op.value()) } func (p Patch) move(doc *partialDoc, op operation) error { @@ -397,21 +450,29 @@ func (p Patch) move(doc *partialDoc, op operation) error { con, key := findObject(doc, from) - val, err := con.get(key) + if con == nil { + return fmt.Errorf("jsonpatch move operation does not apply: doc is missing from path: %s", from) + } + val, err := con.get(key) if err != nil { return err } - con.remove(key) + err = con.remove(key) + if err != nil { + return err + } path := op.path() con, key = findObject(doc, path) - con.set(key, val) + if con == nil { + return fmt.Errorf("jsonpatch move operation does not apply: doc is missing destination path: %s", path) + } - return nil + return con.set(key, val) } func (p Patch) test(doc *partialDoc, op operation) error { @@ -419,12 +480,24 @@ func (p Patch) test(doc *partialDoc, op operation) error { con, key := findObject(doc, path) + if con == nil { + return fmt.Errorf("jsonpatch test operation does not apply: is missing path: %s", path) + } + val, err := con.get(key) if err != nil { return err } + if val == nil { + if op.value().raw == nil { + return nil + } else { + return fmt.Errorf("Testing value %s failed", path) + } + } + if val.equal(op.value()) { return nil } @@ -461,6 +534,12 @@ func DecodePatch(buf []byte) (Patch, error) { // Apply mutates a JSON document according to the patch, and returns the new // document. func (p Patch) Apply(doc []byte) ([]byte, error) { + return p.ApplyIndent(doc, "") +} + +// ApplyIndent mutates a JSON document according to the patch, and returns the new +// document indented. +func (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) { pd := &partialDoc{} err := json.Unmarshal(doc, pd) @@ -492,5 +571,9 @@ func (p Patch) Apply(doc []byte) ([]byte, error) { } } + if indent != "" { + return json.MarshalIndent(pd, "", indent) + } + return json.Marshal(pd) }