From 43b5e1e652e890f527ee615f203064db71bb96ae Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 18 Jun 2018 12:20:38 +0900 Subject: [PATCH] Add support for "orb.yml" case to merge contents under the parent This case occurs only under the following situations: * we're on a leaf node that is a file AND * it's siblings are all _only_ directories We'll probably need to tweak this a little in the case we want to support merging other files at this level of the tree. `usage.yml` maybe one such case. This change also identified a case where this type of file, let's call it the "root file" can appear at the top-level of a tree. In this case the contents of the root file are nested under a key by the same name of the path which we started. At the moment, this means in our tests we'd add a key named after the temporary file path we constructed for our test environment. :/ --- filetree/filetree.go | 26 ++++++++++++++++++++------ filetree/filetree_test.go | 23 ++++++++--------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/filetree/filetree.go b/filetree/filetree.go index 4d27e91b8..b502e7c28 100644 --- a/filetree/filetree.go +++ b/filetree/filetree.go @@ -1,12 +1,12 @@ package filetree import ( - "encoding/json" "fmt" "io/ioutil" "os" "path/filepath" + "github.com/mitchellh/mapstructure" yaml "gopkg.in/yaml.v2" ) @@ -34,11 +34,12 @@ func (n Node) marshalParent() (interface{}, error) { return tree, err } - if len(child.siblings()) > 0 { - result := make(map[string]interface{}) - merge, _ := json.Marshal(c) - json.Unmarshal(merge, &result) - tree[child.Parent.Info.Name()] = result + if len(child.siblings()) > 0 && child.onlyFile() { + find := make(map[string]interface{}) + if err := mapstructure.Decode(c, &find); err != nil { + panic(err) + } + tree[child.Parent.Info.Name()] = find } else { tree[child.Info.Name()] = c } @@ -47,6 +48,19 @@ func (n Node) marshalParent() (interface{}, error) { return tree, nil } +// Returns true/false if this node is the only file of it's siblings +func (n Node) onlyFile() bool { + if n.Info.IsDir() { + return false + } + for _, v := range n.siblings() { + if v.Info.IsDir() { + return true + } + } + return false +} + func (n Node) siblings() []*Node { siblings := []*Node{} for _, child := range n.Parent.Children { diff --git a/filetree/filetree_test.go b/filetree/filetree_test.go index 1ed158924..710b9dec4 100644 --- a/filetree/filetree_test.go +++ b/filetree/filetree_test.go @@ -30,15 +30,13 @@ var _ = Describe("filetree", func() { }) Describe("NewTree", func() { - var rootFile, subDir, subDirFile, emptyDir string + var subDir, subDirFile, emptyDir string BeforeEach(func() { - rootFile = filepath.Join(tempRoot, "root_file.yml") subDir = filepath.Join(tempRoot, "sub_dir") subDirFile = filepath.Join(tempRoot, "sub_dir", "sub_dir_file.yml") emptyDir = filepath.Join(tempRoot, "empty_dir") - Expect(ioutil.WriteFile(rootFile, []byte("foo:\n bar"), 0600)).To(Succeed()) Expect(os.Mkdir(subDir, 0700)).To(Succeed()) Expect(ioutil.WriteFile(subDirFile, []byte("foo:\n bar:\n baz"), 0600)).To(Succeed()) Expect(os.Mkdir(emptyDir, 0700)).To(Succeed()) @@ -64,7 +62,7 @@ var _ = Describe("filetree", func() { Expect(tree.FullPath).To(Equal(tempRoot)) Expect(tree.Info.Name()).To(Equal(filepath.Base(tempRoot))) - Expect(tree.Children).To(HaveLen(3)) + Expect(tree.Children).To(HaveLen(2)) sort.Slice(tree.Children, func(i, j int) bool { return tree.Children[i].FullPath < tree.Children[j].FullPath }) @@ -72,14 +70,12 @@ var _ = Describe("filetree", func() { Expect(tree.Children[0].Info.Name()).To(Equal("empty_dir")) Expect(tree.Children[0].FullPath).To(Equal(emptyDir)) - Expect(tree.Children[1].Info.Name()).To(Equal("root_file.yml")) - Expect(tree.Children[1].FullPath).To(Equal(rootFile)) - Expect(tree.Children[2].Info.Name()).To(Equal("sub_dir")) - Expect(tree.Children[2].FullPath).To(Equal(subDir)) + Expect(tree.Children[1].Info.Name()).To(Equal("sub_dir")) + Expect(tree.Children[1].FullPath).To(Equal(subDir)) - Expect(tree.Children[2].Children).To(HaveLen(1)) - Expect(tree.Children[2].Children[0].Info.Name()).To(Equal("sub_dir_file.yml")) - Expect(tree.Children[2].Children[0].FullPath).To(Equal(subDirFile)) + Expect(tree.Children[1].Children).To(HaveLen(1)) + Expect(tree.Children[1].Children[0].Info.Name()).To(Equal("sub_dir_file.yml")) + Expect(tree.Children[1].Children[0].FullPath).To(Equal(subDirFile)) }) It("renders to YAML", func() { @@ -88,10 +84,7 @@ var _ = Describe("filetree", func() { out, err := yaml.Marshal(tree) Expect(err).ToNot(HaveOccurred()) - Expect(out).To(MatchYAML(`root_file.yml: - foo: - bar -empty_dir: null + Expect(out).To(MatchYAML(`empty_dir: null sub_dir: sub_dir_file.yml: foo: