From c8f4ba7f45e3f043a65eb0290fc970ddc35cab08 Mon Sep 17 00:00:00 2001 From: Mike Farah Date: Wed, 18 Oct 2023 12:36:52 +1100 Subject: [PATCH] Removing copier lib --- pkg/yqlib/context.go | 40 ++++++++++++------------------ pkg/yqlib/context_test.go | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 pkg/yqlib/context_test.go diff --git a/pkg/yqlib/context.go b/pkg/yqlib/context.go index d2dc656b..aaa80da6 100644 --- a/pkg/yqlib/context.go +++ b/pkg/yqlib/context.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - "github.com/jinzhu/copier" logging "gopkg.in/op/go-logging.v1" ) @@ -58,13 +57,19 @@ func (n *Context) SetVariable(name string, value *list.List) { func (n *Context) ChildContext(results *list.List) Context { clone := Context{DontAutoCreate: n.DontAutoCreate, datetimeLayout: n.datetimeLayout} clone.Variables = make(map[string]*list.List) - if len(n.Variables) > 0 { - err := copier.Copy(&clone.Variables, n.Variables) - if err != nil { - log.Error("Error cloning context :(") - panic(err) + for variableKey, originalValueList := range n.Variables { + + variableCopyList := list.New() + for el := originalValueList.Front(); el != nil; el = el.Next() { + // note that we dont make a copy of the candidate node + // this is so the 'ref' operator can work correctly. + clonedNode := el.Value.(*CandidateNode) + variableCopyList.PushBack(clonedNode) } + + clone.Variables[variableKey] = variableCopyList } + clone.MatchingNodes = results return clone } @@ -78,31 +83,18 @@ func (n *Context) ToString() string { } func (n *Context) DeepClone() Context { - clone := Context{} - err := copier.Copy(&clone, n) - // copier doesn't do lists properly for some reason - clone.MatchingNodes = list.New() + + clonedContent := list.New() for el := n.MatchingNodes.Front(); el != nil; el = el.Next() { clonedNode := el.Value.(*CandidateNode).Copy() - clone.MatchingNodes.PushBack(clonedNode) + clonedContent.PushBack(clonedNode) } - if err != nil { - log.Error("Error cloning context :(") - panic(err) - } - return clone + return n.ChildContext(clonedContent) } func (n *Context) Clone() Context { - clone := Context{} - err := copier.Copy(&clone, n) - - if err != nil { - log.Error("Error cloning context :(") - panic(err) - } - return clone + return n.ChildContext(n.MatchingNodes) } func (n *Context) ReadOnlyClone() Context { diff --git a/pkg/yqlib/context_test.go b/pkg/yqlib/context_test.go new file mode 100644 index 00000000..13ec0e2f --- /dev/null +++ b/pkg/yqlib/context_test.go @@ -0,0 +1,51 @@ +package yqlib + +import ( + "container/list" + "testing" + + "github.com/mikefarah/yq/v4/test" +) + +func TestChildContext(t *testing.T) { + + expectedOriginal := make(map[string]*list.List) + expectedOriginal["dog"] = list.New() + expectedOriginal["dog"].PushBack(&CandidateNode{Value: "woof"}) + + originalVariables := make(map[string]*list.List) + originalVariables["dog"] = list.New() + originalVariables["dog"].PushBack(&CandidateNode{Value: "woof"}) + + original := Context{ + DontAutoCreate: true, + datetimeLayout: "cat", + Variables: originalVariables, + } + + newResults := list.New() + newResults.PushBack(&CandidateNode{Value: "bar"}) + + clone := original.ChildContext(newResults) + test.AssertResultComplex(t, originalVariables, clone.Variables) + + clone.Variables["dog"].PushBack("bark") + // ensure this is a separate copy + test.AssertResultComplex(t, 1, originalVariables["dog"].Len()) + +} + +func TestChildContextNoVariables(t *testing.T) { + + original := Context{ + DontAutoCreate: true, + datetimeLayout: "cat", + } + + newResults := list.New() + newResults.PushBack(&CandidateNode{Value: "bar"}) + + clone := original.ChildContext(newResults) + test.AssertResultComplex(t, make(map[string]*list.List), clone.Variables) + +}